diff options
author | Ilhan Özgen Xian <iozgen@lbl.gov> | 2021-09-01 15:15:50 -0700 |
---|---|---|
committer | Ilhan Özgen Xian <iozgen@lbl.gov> | 2021-09-01 15:15:50 -0700 |
commit | 14e2736fba65b87d81063f004c75770354b95ca9 (patch) | |
tree | a2d21b3cdf0e38a1ed967a36fc290c417ed75219 | |
parent | 80336763aafe3aa565c24e4eedaf53e74698efb7 (diff) |
add advecting with different time horizons
-rw-r--r-- | environment.hpp | 94 | ||||
-rw-r--r-- | header.hpp | 1 | ||||
-rw-r--r-- | input/options.input | 11 | ||||
-rw-r--r-- | input/subtimes.txt | 84 | ||||
-rw-r--r-- | input/times.txt | 149 | ||||
-rw-r--r-- | main.cpp | 73 | ||||
-rw-r--r-- | parser.hpp | 118 | ||||
-rw-r--r-- | particle.hpp | 114 | ||||
-rw-r--r-- | tools/extract.sh | 2 | ||||
-rw-r--r-- | tools/plot-paths-integrated.gp | 4 |
10 files changed, 377 insertions, 273 deletions
diff --git a/environment.hpp b/environment.hpp index fb2eec6..dedf017 100644 --- a/environment.hpp +++ b/environment.hpp @@ -63,32 +63,39 @@ public: Environment(Parser &value) { parser = value; - timestep = 0; + timestep_surface = 0; + timestep_subsurface = 0; std::cout << "[env] building the environment" << std::endl; read_grid(); - read_environment(timestep); + read_environment(timestep_surface); std::cout << std::endl; std::cout << "[env] initialised 0th environment" << std::endl; } - void update() - { - - timestep = timestep + 1; - read_environment(timestep); - std::cout << "[env] updated to " << timestep << "th environment" << std::endl; + void update_surface() + { + timestep_surface = timestep_surface + 1; + read_environment_surface(timestep_surface); + std::cout << "[env] updated surface to " << timestep_surface << "th environment" << std::endl; + } + void update_subsurface() + { + timestep_subsurface = timestep_subsurface + 1; + read_environment_subsurface(timestep_subsurface); + std::cout << "[env] updated subsurface to " << timestep_subsurface << "th environment" << std::endl; } private: Parser parser; - int timestep; + int timestep_surface; + int timestep_subsurface; // ------------------------------------------------------------------------ // generic read function for dataset @@ -271,15 +278,34 @@ private: } - // ------------------------------------------------------------------------ - // read in environment variables - // ------------------------------------------------------------------------ - void read_environment(int timestep) + void read_environment_subsurface(int timestep) { + H5::H5File fp_subsurface = H5::H5File(parser.subsurface_data_file.c_str(), + H5F_ACC_RDONLY); - // - // we start with surface environment variables - // + // darcy velocity in x-direction + read_variable(fp_subsurface, + DARCY_VELOCITY_X, + parser.subsurface_data_group[timestep], + darcy_velocity_x); + + // darcy velocity in y-direction + read_variable(fp_subsurface, + DARCY_VELOCITY_Y, + parser.subsurface_data_group[timestep], + darcy_velocity_y); + + // darcy velocity in z-direction + read_variable(fp_subsurface, + DARCY_VELOCITY_Z, + parser.subsurface_data_group[timestep], + darcy_velocity_z); + + fp_subsurface.close(); + } + + void read_environment_surface(int timestep) + { H5::H5File fp_surface = H5::H5File(parser.surface_data_file.c_str(), H5F_ACC_RDONLY); @@ -316,33 +342,23 @@ private: evaporation_flux); fp_surface.close(); + } + + // ------------------------------------------------------------------------ + // read in environment variables + // ------------------------------------------------------------------------ + void read_environment(int timestep) + { // - // now we read in subsurface + // we start with surface environment variables // - H5::H5File fp_subsurface = H5::H5File(parser.subsurface_data_file.c_str(), - H5F_ACC_RDONLY); - - // darcy velocity in x-direction - read_variable(fp_subsurface, - DARCY_VELOCITY_X, - parser.subsurface_data_group[timestep], - darcy_velocity_x); - - // darcy velocity in y-direction - read_variable(fp_subsurface, - DARCY_VELOCITY_Y, - parser.subsurface_data_group[timestep], - darcy_velocity_y); - - // darcy velocity in z-direction - read_variable(fp_subsurface, - DARCY_VELOCITY_Z, - parser.subsurface_data_group[timestep], - darcy_velocity_z); - - fp_subsurface.close(); + read_environment_surface(timestep); + // + // now we read in subsurface + // + read_environment_subsurface(timestep); } }; @@ -46,6 +46,7 @@ #define OUTLET_FLAG 3 #define EVAPORATION_FLAG 4 +#define TIME_FUZZ 1.0e-3 #define WATERDEPTH_DRY 1.0e-8 #define ZERO_VELOCITY 1.0e-10 #define DT_MAX 432000.0 diff --git a/input/options.input b/input/options.input index f48010d..2ec212f 100644 --- a/input/options.input +++ b/input/options.input @@ -6,13 +6,14 @@ seed : 108 // Random seed n_iteration : 1000 // Number of iteration steps subgrid_dx : 5.0 // Subgrid cell size -surfacemesh : ./input/test/ats_vis_surface_mesh.h5 // Surface mesh file -surfacedata : ./input/test/ats_vis_surface_data.h5 // Surface data file -surfacetime : ./input/times.txt // Time levels for surface +surfacemesh : ./example/ats_vis_surface_mesh.h5 // Surface mesh file +surfacedata : ./example/ats_vis_surface_data.h5 // Surface data file +surfacetime : ./input/times.txt // Time levels for surface surfacegroup : ./input/groups.txt // Group names for surface -subsurfacemesh : ./input/test/ats_vis_mesh.h5 // Subsurface mesh file -subsurfacedata : ./input/test/ats_vis_data.h5 // Subsurface data file +subsurfacemesh : ./example/ats_vis_mesh.h5 // Subsurface mesh file +subsurfacedata : ./example/ats_vis_data.h5 // Subsurface data file subsurfacetime : ./input/subtimes.txt // Time levels for subsurface subsurfacegroup : ./input/subgroups.txt // Group names for subsurface +restartfile : none
\ No newline at end of file diff --git a/input/subtimes.txt b/input/subtimes.txt index 45adcab..d4bdb70 100644 --- a/input/subtimes.txt +++ b/input/subtimes.txt @@ -1,43 +1,43 @@ 0 -118276 -236550 -354826 -473100 -591376 -709651 -827926 -946201 -1.06447e+06 -1.18276e+06 -1.30103e+06 -1.4193e+06 -1.53757e+06 -1655856 -1.77413e+06 -1.8924e+06 -2.01067e+06 -2.12896e+06 -2.24723e+06 -2.3655e+06 -2.48378e+06 -2.60206e+06 -2.72033e+06 -2.8386e+06 -2.95688e+06 -3.07516e+06 -3.19343e+06 -3.3117e+06 -3.42998e+06 -3.54826e+06 -3.66653e+06 -3.7848e+06 -3.90308e+06 -4.02136e+06 -4.13963e+06 -4.2579e+06 -4.37618e+06 -4.49446e+06 -4.61273e+06 -4.731e+06 -4.84928e+06 -4.96756e+06 +432001 +864000 +1.296e+06 +1.728e+06 +2.16e+06 +2.592e+06 +3.024e+06 +3.456e+06 +3.88799e+06 +4.32001e+06 +4.75201e+06 +5.184e+06 +5.61599e+06 +6.04801e+06 +6.48001e+06 +6.912e+06 +7.34399e+06 +7.77601e+06 +8.20801e+06 +8.64e+06 +9.07199e+06 +9.50401e+06 +9.93601e+06 +1.0368e+07 +1.08e+07 +1.1232e+07 +1.1664e+07 +1.2096e+07 +1.2528e+07 +1.296e+07 +1.3392e+07 +1.3824e+07 +1.4256e+07 +1.4688e+07 +1.512e+07 +1.5552e+07 +1.5984e+07 +1.6416e+07 +1.6848e+07 +1.728e+07 +1.7712e+07 +1.8144e+07 diff --git a/input/times.txt b/input/times.txt index 45adcab..dbbe0ca 100644 --- a/input/times.txt +++ b/input/times.txt @@ -1,43 +1,108 @@ 0 -118276 -236550 -354826 -473100 -591376 -709651 -827926 -946201 -1.06447e+06 -1.18276e+06 -1.30103e+06 -1.4193e+06 -1.53757e+06 -1655856 -1.77413e+06 -1.8924e+06 -2.01067e+06 -2.12896e+06 -2.24723e+06 -2.3655e+06 -2.48378e+06 -2.60206e+06 -2.72033e+06 -2.8386e+06 -2.95688e+06 -3.07516e+06 -3.19343e+06 -3.3117e+06 -3.42998e+06 -3.54826e+06 -3.66653e+06 -3.7848e+06 -3.90308e+06 -4.02136e+06 -4.13963e+06 -4.2579e+06 -4.37618e+06 -4.49446e+06 -4.61273e+06 -4.731e+06 -4.84928e+06 -4.96756e+06 +172800 +345600 +518400 +691200 +864000 +1.0368e+06 +1.2096e+06 +1.3824e+06 +1.5552e+06 +1.728e+06 +1.9008e+06 +2.0736e+06 +2.2464e+06 +2.4192e+06 +2.592e+06 +2.7648e+06 +2.9376e+06 +3.1104e+06 +3.28319e+06 +3.456e+06 +3.62881e+06 +3.80159e+06 +3.9744e+06 +4.14721e+06 +4.32001e+06 +4.49279e+06 +4.6656e+06 +4.83841e+06 +5.01119e+06 +5.184e+06 +5.35681e+06 +5.52959e+06 +5.7024e+06 +5.8752e+06 +6.04801e+06 +6.22079e+06 +6.3936e+06 +6.56641e+06 +6.73919e+06 +6.912e+06 +7.08481e+06 +7.25759e+06 +7.43039e+06 +7.6032e+06 +7.77601e+06 +7.94879e+06 +8.1216e+06 +8.29441e+06 +8.46719e+06 +8.64e+06 +8.81281e+06 +8.98558e+06 +9.15839e+06 +9.3312e+06 +9.50401e+06 +9.67679e+06 +9.8496e+06 +1.00224e+07 +1.01952e+07 +1.0368e+07 +1.05408e+07 +1.07136e+07 +1.08864e+07 +1.10592e+07 +1.1232e+07 +1.14048e+07 +1.15776e+07 +1.17504e+07 +1.19232e+07 +1.2096e+07 +1.22688e+07 +1.24416e+07 +1.26144e+07 +1.27872e+07 +1.296e+07 +1.31328e+07 +1.33056e+07 +1.34784e+07 +1.36512e+07 +1.3824e+07 +1.39968e+07 +1.41696e+07 +1.43424e+07 +1.45152e+07 +1.4688e+07 +1.48608e+07 +1.50336e+07 +1.52064e+07 +1.53792e+07 +1.5552e+07 +1.57248e+07 +1.58976e+07 +1.60704e+07 +1.62432e+07 +1.6416e+07 +1.65888e+07 +1.67616e+07 +1.69344e+07 +1.71072e+07 +1.728e+07 +1.74528e+07 +1.76256e+07 +1.77984e+07 +1.79712e+07 +1.8144e+07 +1.83168e+07 +1.84896e+07 @@ -44,8 +44,6 @@ int main(int argc, char* argv[]) if (flag == "-c") { Mesh mesh = Mesh(parser); mesh.compile(); - // mesh.subgrid(); - // mesh.map(); mesh.dump(); std::cout << "[ ] meshing completed, enjoy the subgrid" << std::endl; std::cout << std::endl; @@ -59,11 +57,76 @@ int main(int argc, char* argv[]) ParticleManager pmanager = ParticleManager(parser); - for (size_t t = 1; t < parser.surface_time.size(); ++t) { - pmanager.advect(parser.surface_time[t]); - pmanager.environment.update(); + size_t nstep_surface = parser.surface_time.size(); + size_t nstep_subsurface = parser.subsurface_time.size(); + + size_t step_surface = 1; + size_t step_subsurface = 1; + + // bootstrap + double t_surface = parser.surface_time[0]; + double t_subsurface = parser.subsurface_time[0]; + double t_combined = std::min(t_surface, t_subsurface); + + // we compute the difference between the next time level + // and the combined time level to check if we need to + // update the environment. the first step is "free". + double dt_surface = 0.0; + double dt_subsurface = 0.0; + + bool fin_surface = false; + bool fin_subsurface = false; + + // (step_surface < nstep_surface) || (step_subsurface < nstep_subsurface) + while (!fin_surface || !fin_subsurface) { + + // advect all particles + pmanager.advect(t_combined); + + // check if the surface environment needs to be updated + if (!fin_surface && dt_surface <= TIME_FUZZ) { + + step_surface ++; + t_surface = parser.surface_time[step_surface]; // get new time step + pmanager.environment.update_surface(); // update environment + t_combined = std::min(t_surface, t_subsurface); + + if (step_surface == nstep_surface - 1) { + fin_surface = true; + } + + } + + // check if the subsurface environment needs to be updated + if (!fin_subsurface && dt_subsurface <= TIME_FUZZ) { + + step_subsurface ++; + t_subsurface = parser.subsurface_time[step_subsurface]; + pmanager.environment.update_subsurface(); + t_combined = std::min(t_surface, t_subsurface); + + if (step_subsurface == nstep_subsurface - 1) { + fin_subsurface = true; + } + + } + + dt_surface = std::fabs(t_combined - t_surface); + dt_subsurface = std::fabs(t_combined - t_subsurface); + + if (fin_surface) { + t_combined = t_subsurface; + } + + if (fin_subsurface) { + t_combined = t_surface; + } + } + std::cout << "[ ] particle advecting completed, enjoy the results!" << std::endl; + std::cout << std::endl; + for (size_t i = 0; i < pmanager.particles.size(); ++i) { pmanager.particles[i].dump(i); } @@ -72,6 +72,7 @@ public: std::string surface_data_file; std::string subsurface_mesh_file; std::string subsurface_data_file; + std::string checkfile; std::vector<std::string> surface_data_group; std::vector<double> surface_time; @@ -119,6 +120,7 @@ public: for (uint i = 0; i < subsurface_data_group.size(); i ++) std::cout << subsurface_data_group[i] << " "; std::cout << std::endl; + std::cout << "[prs] restart file: " << checkfile << std::endl; std::cout << std::endl; } @@ -151,41 +153,45 @@ public: pline.value >> surface_data_file; } else if (!strcmp("surfacetime", pline.key.c_str())) { - std::string timefile; - pline.value >> timefile; + std::string timefile; + pline.value >> timefile; - std::ifstream in(timefile); - double time; + std::ifstream in(timefile); + double time; - if (in.is_open()) { - - while (!in.eof()) { - in >> time; - surface_time.push_back(time); - } + if (in.is_open()) { + + while (!in.eof()) { + in >> time; + if (in.good()) { + surface_time.push_back(time); + } + } + + } else { + std::cerr << "[err] file " << timefile << " can't be opened" << std::endl; + } - } else { - std::cerr << "[err] file " << timefile << " can't be opened" << std::endl; - } - } else if (!strcmp("surfacegroup", pline.key.c_str())) { - std::string groupfile; - pline.value >> groupfile; + std::string groupfile; + pline.value >> groupfile; - std::ifstream in(groupfile); - std::string group; + std::ifstream in(groupfile); + std::string group; - if (in.is_open()) { + if (in.is_open()) { - while (!in.eof()) { - in >> group; - surface_data_group.push_back(group); - } + while (!in.eof()) { + in >> group; + if (in.good()) { + surface_data_group.push_back(group); + } + } - } else { - std::cerr << "[err] file " << groupfile << " can't be opened" << std::endl; - } + } else { + std::cerr << "[err] file " << groupfile << " can't be opened" << std::endl; + } } else if (!strcmp("subsurfacemesh", pline.key.c_str())) { pline.value >> subsurface_mesh_file; @@ -193,42 +199,46 @@ public: pline.value >> subsurface_data_file; } else if (!strcmp("subsurfacetime", pline.key.c_str())) { - std::string timefile; - pline.value >> timefile; + std::string timefile; + pline.value >> timefile; + + std::ifstream in(timefile); + double time; - std::ifstream in(timefile); - double time; + if (in.is_open()) { - if (in.is_open()) { - - while (!in.eof()) { - in >> time; - subsurface_time.push_back(time); - } + while (!in.eof()) { + in >> time; + if (in.good()) { + subsurface_time.push_back(time); + } + } + + } else { + std::cerr << "[err] file " << timefile << " can't be opened" << std::endl; + } - } else { - std::cerr << "[err] file " << timefile << " can't be opened" << std::endl; - } - } else if (!strcmp("subsurfacegroup", pline.key.c_str())) { - std::string groupfile; - pline.value >> groupfile; + std::string groupfile; + pline.value >> groupfile; + + std::ifstream in(groupfile); + std::string group; - std::ifstream in(groupfile); - std::string group; + if (in.is_open()) { - if (in.is_open()) { + while (!in.eof()) { + in >> group; + if (in.good()) { + subsurface_data_group.push_back(group); + } + } - while (!in.eof()) { - in >> group; - subsurface_data_group.push_back(group); - } + } else { + std::cerr << "[err] file " << groupfile << " can't be opened" << std::endl; + } - } else { - std::cerr << "[err] file " << groupfile << " can't be opened" << std::endl; - } - } else if (!strcmp("n_agent", pline.key.c_str())) { pline.value >> n_agent; } else if (!strcmp("fuzz", pline.key.c_str())) { @@ -239,6 +249,8 @@ public: pline.value >> seed; } else if (!strcmp("n_iteration", pline.key.c_str())) { pline.value >> n_iteration; + } else if (!strcmp("restartfile", pline.key.c_str())) { + pline.value >> checkfile; } else { std::cerr << "[err] unrecognised option key" << std::endl; } diff --git a/particle.hpp b/particle.hpp index 0f5026a..5f95ff5 100644 --- a/particle.hpp +++ b/particle.hpp @@ -116,41 +116,45 @@ public: rng = std::default_random_engine(parser.seed); dist = std::uniform_real_distribution<double>(0.0, 1.0); - for (int i = 0; i < parser.n_agent; ++ i) { + if (!strcmp("none", parser.checkfile.c_str())) { - Particle p; + for (int i = 0; i < parser.n_agent; ++ i) { - p.cell_index = -9999; - int ix, iy, iz; + Particle p; - while (p.cell_index == -9999) { + p.cell_index = -9999; + int ix, iy, iz; - ix = xdist(rng); - iy = ydist(rng); - iz = zdist(rng) * 0; + while (p.cell_index == -9999) { - p.cell_index = environment.indices[ix][iy][iz]; + ix = xdist(rng); + iy = ydist(rng); + iz = zdist(rng) * 0; - } + p.cell_index = environment.indices[ix][iy][iz]; - // get the coordinates - p.x = environment.xll_corner + 0.5 * dx + ix * dx; - p.y = environment.yhl_corner - 0.5 * dx - iy * dx; - p.z = environment.elevations[ix][iy][iz]; - p.t = parser.start_time; - - if (iz > 0) { - // if the particle is not in the top layer, it's in the subsurface - p.domain.push_back(SUBSURFACE_FLAG); - } else { - // otherwise, it's at the surface - p.domain.push_back(SURFACE_FLAG); - } + } - p.coordinates.push_back({ p.x, p.y, p.z }); - p.time.push_back(p.t); + // get the coordinates + p.x = environment.xll_corner + 0.5 * dx + ix * dx; + p.y = environment.yhl_corner - 0.5 * dx - iy * dx; + p.z = environment.elevations[ix][iy][iz]; + p.t = parser.start_time; + + if (iz > 0) { + // if the particle is not in the top layer, it's in the subsurface + p.domain.push_back(SUBSURFACE_FLAG); + } else { + // otherwise, it's at the surface + p.domain.push_back(SURFACE_FLAG); + } - particles.push_back(p); + p.coordinates.push_back({ p.x, p.y, p.z }); + p.time.push_back(p.t); + + particles.push_back(p); + + } } @@ -369,64 +373,6 @@ public: } - - // // move particle in the subsurface - // void advectv() - // { - - // std::cout << "[ptl] advecting particles" << std::endl; - - // size_t i; - // double dx = parser.subgrid_dx; - - // #pragma omp parallel - // { - - // #pragma omp for private(i) - // for (i = 0; i < particles.size(); ++i) { - - // while (particles[i].time.back() < timehorizon) { - - // int flag = particles[i].domain.back(); - - // double vx, vy, vz, vmag, dt; - - // vx = environment.velocity_x[particles[i].cell_index]; - // vy = environment.velocity_y[particles[i].cell_index]; - - // vmag = std::sqrt(vx * vx + vy * vy); - - // dt = CFL * dx / (vmag + 1.0e-10); - // dt = std::min(dt, DT_MAX); - // dt = std::min(dt, timehorizon - particles[i].time.back()); - - // particles[i].advect(vx, vy, 0.0, dt); - - // // get the indices - // int ix, iy, iz; - // ix = (int) floor((particles[i].x - environment.xll_corner) / dx); - // iy = (int) floor((environment.yhl_corner - particles[i].y) / dx); - // iz = 0; - - // // update the particle - // particles[i].time.push_back(particles[i].t); - // particles[i].cell_index = environment.indices[ix][iy][iz]; - // particles[i].z = environment.elevations[ix][iy][iz]; - // particles[i].coordinates.push_back({particles[i].x, - // particles[i].y, - // particles[i].z}); - // particles[i].domain.push_back(flag); - - // } - - // } - - // } - - // } - - - private: Parser parser; diff --git a/tools/extract.sh b/tools/extract.sh index 7222f83..79cd72b 100644 --- a/tools/extract.sh +++ b/tools/extract.sh @@ -5,4 +5,4 @@ groupname=$2 ./extract-groups.sh ${filename} ${groupname} > _tmpgroups.txt cat _tmpgroups.txt | ./extract-times.sh ${filename} ${groupname} > _tmptimes.txt -cat _tmptimes.txt | awk '{ print $1 * 360000.0 * 24 }' +cat _tmptimes.txt | awk '{ print $1 * 365.25 * 3600 * 24 }' diff --git a/tools/plot-paths-integrated.gp b/tools/plot-paths-integrated.gp index 8fe4a06..723c693 100644 --- a/tools/plot-paths-integrated.gp +++ b/tools/plot-paths-integrated.gp @@ -1,7 +1,7 @@ #!/usr/bin/env gnuplot set term png font "hack" -set output "output/figure.png" +set output "../output/figure.png" set border linecolor rgbcolor "white" set key textcolor rgbcolor "white" @@ -20,7 +20,7 @@ set ytics 1 set size ratio -1 splot \ - for [i = 100:999] "output/p-000".i.".csv" \ + for [i = 100:999] "../output/p-000".i.".csv" \ u ($3/1000):($4/1000):($5/1000)\ with lines\ notitle |