Skip to content

Simple Example

Giorgos Kourakos edited this page Dec 17, 2024 · 5 revisions

Simple Example

In this example we will demonstrate how to prepare the input files for the various interpolation options that are currently available.

This example is totally fictional and the velocity data are read from a file that we have prepared and contain some sort of random data based on a simple perlin noise generator. Don't worry if that last part it is not clear.

Domain

The domain is rectanglular with dimensions 300 x 300 x 10 m.

Outline

First we need to define the domain outline in the 2D coordinate space.

domain_poly = [0 0;300 0;300 300; 0 300];

Print the Ichnos input file

fid = fopen('simple_outline.ich', 'w');
fprintf(fid, '%d %d\n', [size(domain_poly,1) 1]);
fprintf(fid, '%.1f %.1f\n', domain_poly');
fclose(fid);

Top and Bottom

For simplicity we will keep the top and bottom elevations constant. Therefore we can define under the Domain section the following options:

TopFile = 10
BottomFile = 0

Prepare MESH2D files

For CLOUD based interpolation the following mesh files are not needed.

The MESH2D requires the preparation of 3 files: i) Node file, ii) Mesh file, iii) Elevation file.

First we are going to define the discretization options or density of mesh points/elements

nNodesX = 6;
nNodesY = 5;
nNodesZ = 3;

Node file

Nodes
[NDX, NDY] = meshgrid(linspace(0,300,nNodesX),linspace(0,300,nNodesY));
NDY = flipud(NDY);
[IX, IY] = meshgrid(1:nNodesX,1:nNodesY);
linind = sub2ind(size(IX),IY,IX);
idx = reshape(linind,nNodesX*nNodesY,1);
ND = [NDX(idx) NDY(idx)];

Print node file

fid = fopen('Simple_Node.ich','w');
fprintf(fid,'%.2f %.2f\n', ND');
fclose(fid);

Mesh file

msh = nan((nNodesX-1)*(nNodesY-1),4);
cnt = 1;
for ii = 1:size(linind,1)-1
    for jj = 1:size(linind,2)-1
        msh(cnt,:) = [linind(ii,jj) linind(ii+1,jj) linind(ii+1,jj+1) linind(ii,jj+1)];
        cnt = cnt + 1;
    end
end

The elements must be oriented in counter clockwise direction. To check this we do the following which should result all zeros

for ii = 1:9
    c(ii,1) = ispolycw(ND(msh(ii,:),1), ND(msh(ii,:),2));
end

Print the mesh file

fid = fopen('Simple_Mesh.ich','w');
fprintf(fid,'%d %d %d %d %d\n', [msh zeros(size(msh,1),1)]');
fclose(fid);

Let's visualize the mesh

figure()
clf
plot(domain_poly([1:4 1],1), domain_poly([1:4 1],2))
hold on
for ii = 1:size(msh)
    plot(ND(msh(ii,[1:4 1]),1),ND(msh(ii,[1:4 1]),2),'b')
end
plot(ND(:,1), ND(:,2),'.r','MarkerSize',20)
Simple example mesh

Elevation file

Elev = repmat(linspace(10,0,nNodesZ),size(ND,1),1);

Print the file

fid = fopen('Simple_Elev.ich','w');
fprintf(fid,['%.2f' repmat(' %.2f',1,size(Elev,2) - 1) '\n'], Elev');
fclose(fid);

Velocity

The velocity is based on a random perlin noise. The velocity data can be read from the file test_cloudall_0.dat. In the following we read it as table, rename the columns and transform the coordinates appropriately.

v = readtable('G:\UCDAVIS\ichnos\ichnos_hou\ichnos\test_cloudall_0.dat');
v = renamevars(v,["Var1","Var2","Var3","Var4","Var5","Var6","Var7"], ...
                 ["dummy","X","Y","Z", "VX","VY","VZ"]);

v.X = v.X/1.5 + 150;
v.Y = v.Y/1.5 + 150;
v.Z = v.Z + 5;

This dataset will be the base for the velocity data. First we will create an interpolant and then interpolate the data to the cloud points, mesh nodes or mesh elements.

Fvel = scatteredInterpolant(v.X,v.Y,v.Z,[v.VX, v.VY, v.VZ],'linear','nearest');

Velocity on Mesh NODES

MESH2D_NODE_VEL = [];
for ii = 1:nNodesZ
    MESH2D_NODE_VEL = [MESH2D_NODE_VEL; Fvel(ND(:,1),ND(:,2),Elev(:,ii))];
end

Print the file

fid = fopen('Simple_MESH2D_NODE_Vel_000.ich','w');
fprintf(fid,'%.7e %.7e %.7e\n', MESH2D_NODE_VEL');
fclose(fid);

Velocity on Mesh Elements

To keep this simple we assume that the velocity on a mesh with element interpolation is defined on the barycnters of the elements. Therefore first we compute the barycenters of the elements and then we interpolate the velocity on those barycenters using the interpolant that we created previously

bcXYZ = [];
for ii = 1:(nNodesZ-1)
    for j = 1:size(msh,1)
        bcXYZ = [bcXYZ;mean([repmat(ND(msh(j,:),1),2,1) repmat(ND(msh(j,:),2),2,1) [Elev(msh(j,:),ii);Elev(msh(j,:),ii+1)]])];
    end
end
MESH2D_ELEM_VEL = Fvel(bcXYZ(:,1), bcXYZ(:,2), bcXYZ(:,3));

Print the mesh element velocity

fid = fopen('Simple_MESH2D_ELEM_Vel_000.ich','w');
fprintf(fid,'%.7e %.7e %.7e\n', MESH2D_ELEM_VEL');
fclose(fid);

Velocity on mesh Faces

The velocity on mesh faces is the most complex case and we present a separate Simple Face Example.

Velocity on Cloud

For the velocity using cloud we do not need any mesh. We simply provide the coordinates of the velocity points along with the velocity values. However because Ichnos uses adaptive and anisotropic IDW interpolation for each point we need to define two additional parameters: i) The diameter and ii) the ratio. The diameter is related to the horizontal extent of the influence of each point, which depends on the mesh density and can be approximated by the maximum diagonal of the elements if the velocity is the result of a finite element/difference numerical simulation. The ratio is related to the influence of each point in the vertical direction and shoulf be equal to the diameter over the largest height of the element. In this simple example where the elements have identical dimensions the diameter and ratio can be approximated as follows:

diagXY = sqrt((300/(nNodesX-1))^2 + (300/(nNodesY-1))^2);
diagXYZ = sqrt(diagXY^2 + (10/(nNodesZ-1))^2);
ratio = diagXYZ/(10/(nNodesZ-1));

Prepare the velocity data on a cloud. The format of the file is explained here

Simple_CLOUD_VEL = [];
for ii = 1:nNodesZ
    Simple_CLOUD_VEL = [Simple_CLOUD_VEL; ...
        ND(:,1), ND(:,2), Elev(:,ii) zeros(size(ND,1),1) diagXYZ*ones(size(ND,1),1) ...
        ratio*ones(size(ND,1),1) Fvel(ND(:,1),ND(:,2),Elev(:,ii))];
end

Print the file

fid = fopen('Simple_CLOUD_Vel_000.ich','w');
fprintf(fid,'%.2f %.2f %.2f %d %.2f %.2f %.7e %.7e %.7e\n', Simple_CLOUD_VEL');
fclose(fid);

Setup particles

We will distribute a number of particles scattered randomly in the domain. To avoid particles exiting the domain very quickly we will distribute the particles 20 m away from the boundary in the horizontal direction and 1 m in the vertical direction. The following snippet distributes 1000 particles and print them to a file

nPart = 1000;
pt = [50 + 200*rand(nPart,2) 1+8*rand(nPart,1)];

fid = fopen('Simple_Example_particles.ich','w');
fprintf(fid,'%d %d %.2f %.2f %.2f 0\n', [ones(nPart,1) [1:nPart]' pt]');
fclose(fid);

Configuration files

Main Configuration file options

In the following we list the required options to run Ichnos using the files we prepare in the previous section

Velocity section

For Cloud we need to change the MESH2D to CLOUD. The SimpleExample_vf.ini is the velocity configuration file that is explained in the next section.

[Velocity]
XYZType = MESH2D
Type = DETRM
ConfigFile = SimpleExample_vf.ini

Domain section

[Domain]
Outline = simpleFace_outline.ich
TopFile = 10
BottomFile = 0

Step configuration section

There are other options but they do not affect this simple tracing simulation

[StepConfig]
Method = Euler
Direction = 1
StepSize = 5

Input - Output section

[InputOutput]
ParticleFile = Simple_Example_particles.ich
WellFile = 
OutputFile = output/SimpleExample_NODE_out
PrintH5 = 1
PrintASCII = 1

Other section

[Other]
Version = 0.5.06
Nrealizations = 1
nThreads = 1
RunAsThread = 1
OutFreq = 10

Velocity configuration file

Velocity section

[Velocity]
Prefix = SimpleFace_vel_
LeadingZeros = 3
Suffix = .ich
Type = DETRM
RepeatTime = 0
Multiplier = 1

MESH2D section

For the MESH2D we define a MESH2D section with the following options:

[MESH2D]
NodeFile = SimpleFace_Node.ich
MeshFile = SimpleFace_Mesh.ich
ElevationFile = SimpleFace_Elev.ich
FaceIdFile = SimpleFace_faceIds.ich
Nlayers = 2
INTERP = NODE

The number of layers is equal to nNodesZ - 1, while the INTERP should be set to NODE or ELEMENT depending the velocity interpolation that we use.

CLOUD section

For CLOUD interpolation we ommit the MESH2D section and instead we set up a CLOUD section as follows:

[CLOUD]
Power = 3.0
Scale = 1.0
InitDiameter = 100
InitRatio = 20
GraphPrefix = 
Threshold = 0.1

The initial diameter is used for the first particle position of the streamline and should be set equal to the largest diagonal of the cloud points. The ration should be set equal to the average point ratio.

Run Ichnos

Ichnos is a console application and can be run in a terminal using the following command

ichnos.exe -c SimpleExample_config.ini

Alternatively, you can run the simulation using more cores as follows:

C:\"Program Files\Microsoft MPI"\Bin\mpiexec.exe -n 4 ichnos.exe -c SimpleExample_config.ini

Results

To read the results within matlab requires one line of code using the function readICHNOStraj function which is part of our gwtools repository.

In this example we first run the three simulations i) MESH2D (NODE interpolation), ii) MESH2D (ELEMENT interpolation) and iii) CLOUD interpolation. We did that by changing the keywords in the two configuration files.

Once the simulations were run we can read the results as follows

Snode = readICHNOStraj('output\SimpleExample_NODE_out_iter_0000.traj');
Selem = readICHNOStraj('output\SimpleExample_ELEM_out_iter_0000.traj');
Scloud = readICHNOStraj('output\SimpleExample_CLOUD_out_iter_0000.traj');

The following snippet plots the streamlines. First we plot the outline of the 3D domain and the last 3 code lines plot the actual streamlines

figure()
clf
plot3(domain_poly([1:4 1],1), domain_poly([1:4 1],2), 0*ones(1,5),'b')
hold on
plot3(domain_poly([1:4 1],1), domain_poly([1:4 1],2), 10*ones(1,5),'b')
for ii = 1:4
    plot3([domain_poly(ii,1);domain_poly(ii,1)], [domain_poly(ii,2);domain_poly(ii,2)], [0 10],'b')
end
for ii = 1:length(Snode)
plot3(Snode(ii,1).p(:,1), Snode(ii,1).p(:,2), Snode(ii,1).p(:,3))
end

By changing the Snode to Selem and Scloud we can print all of them as follows

Simple example mesh Simple example mesh Simple example mesh

Due to the very coarse discretization it is expected that the particle tracking resutls may be very different for each interpolation method even though the velocity fields are derived from the same data.

FACE interpolation

For the face interpolation we provide a separate example Simple Face Example on how to prepare the files.