summaryrefslogtreecommitdiff
path: root/new/agent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'new/agent.cpp')
-rw-r--r--new/agent.cpp155
1 files changed, 136 insertions, 19 deletions
diff --git a/new/agent.cpp b/new/agent.cpp
index a6bb9e9..fc8c1f1 100644
--- a/new/agent.cpp
+++ b/new/agent.cpp
@@ -2,6 +2,33 @@
#include "agent.hpp"
+// ------------------------------------------------------------------------
+// -- PUBLIC METHODS
+// ------------------------------------------------------------------------
+
+void Agent::advance(Mesh* mesh, size_t step)
+{
+
+ switch(domain[step-1]) {
+ case SURFACE_FLAG:
+ advance_surface(mesh,step);
+ break;
+ case SUBSURFACE_FLAG:
+ advance_subsurface(mesh,step);
+ break;
+ default:
+ set_path(path[step-1][0], path[step-1][1], path[step-1][2], step);
+ time[step] = time[step-1];
+ domain[step] = OUTSIDE_FLAG;
+ break;
+ }
+
+}
+
+// ------------------------------------------------------------------------
+// GETTERS AND SETTERS
+// ------------------------------------------------------------------------
+
Agent::Agent()
{
time.resize(N_ITERATION);
@@ -38,32 +65,108 @@ double Agent::get_timestepsize()
return time_step_size;
}
-// std::vector<std::vector<double>> Agent::get_path()
-// {
-// return path;
-// }
-
double Agent::get_path(size_t step, size_t index)
{
return path[step][index];
}
-void Agent::advance(Mesh* mesh, size_t step)
+int Agent::get_domain(size_t step)
{
+ return domain[step];
+}
- switch(domain[step-1]) {
- case SUBSURFACE_FLAG:
- advance_subsurface(mesh,step);
- break;
- default:
- set_path(path[step-1][0], path[step-1][1], path[step-1][2], step);
- time[step] = time[step-1];
+// ------------------------------------------------------------------------
+// -- PRIVATE METHODS
+// ------------------------------------------------------------------------
+
+void Agent::advance_surface(Mesh* mesh, size_t step)
+{
+ Cell *location = mesh->get_cell(cell_index, SURFACE_FLAG);
+
+ std::vector<double> velocity(DIM);
+ std::vector<double> coordinates(DIM-1);
+ std::vector<double> coordinates_neighbor(DIM-1);
+ std::vector<double> distance(DIM-1);
+
+ domain[step] = SURFACE_FLAG; // set domain for this step, may change later if agent infiltrates
+
+ for (size_t i = 0; i < DIM; i ++)
+ velocity[i] = location->get_velocity(i);
+
+ // CFL criteria
+ double length = location->get_characteristic_length();
+ double velocity_norm = sqrt(velocity[0]*velocity[0] + velocity[1]*velocity[1]);
+
+ if (velocity_norm > EPS) {
+ time_step_size = CFL * length / velocity_norm;
+ } else {
+ time_step_size = MAXTIMESTEP;
+ }
+
+ time[step] = time[step-1] + time_step_size;
+
+ // check if agent infiltrates
+ double h = location->get_water_depth();
+ int flag = INFILTRATE_FALSE;
+
+ if (h > EPS) { // only wet cell can infiltrate
+ double qe = std::min(velocity[2], 0.0);
+ double pi = fabs(qe) * time_step_size / h;
+ double trial = (double) (rand()%100) / 100.0;
+ if (trial < pi)
+ flag = INFILTRATE_TRUE;
+ }
+
+ if (flag == INFILTRATE_FALSE) {
+
+ // advect the agent horizontally, which means the last dimension
+ // (z-direction) is omitted
+ for (size_t i = 0; i < DIM-1; i ++) {
+ coordinates[i] = path[step-1][i] + time_step_size * velocity[i];
+ distance[i] = location->get_coordinate(i) - coordinates[i];
+ }
+
+ // horizontal distance to the centroid of current cell
+ double distance_norm = sqrt(distance[0]*distance[0]+distance[1]*distance[1]);
+
+ // check if cell has changed
+ size_t n_cells = mesh->get_n_cells(SURFACE_FLAG);
+ for (size_t i = 0; i < n_cells; i ++) {
+
+ for (size_t j = 0; j < DIM-1; j ++) {
+ coordinates_neighbor[j] = mesh->get_cell(i, SURFACE_FLAG)->get_coordinate(j);
+ distance[j] = coordinates_neighbor[j] - coordinates[j];
+ }
+
+ double distance_norm_ = sqrt(distance[0]*distance[0]+distance[1]*distance[1]);
+
+ if (distance_norm > distance_norm_) {
+ cell_index = i;
+ distance_norm = distance_norm_;
+ }
+
+ }
+
+ // check if out of the domain: if the agent travelled thrice the
+ // maximum length of the cell and still can't find a neighboring
+ // cell, it must be advected out of the domain
+ if (distance_norm > 10.0 * location->get_maximum_length())
domain[step] = OUTSIDE_FLAG;
- break;
+
+
+ } else {
+ // infiltration detected
+ domain[step] = SUBSURFACE_FLAG;
+ coordinates[0] = path[step-1][0];
+ coordinates[1] = path[step-1][1];
+ cell_index = mesh->get_cell(cell_index, SURFACE_FLAG)->get_coupled_neighbor();
}
+
+ set_path(coordinates[0], coordinates[1], location->get_coordinate(2), step);
}
+
void Agent::advance_subsurface(Mesh* mesh, size_t step)
{
Cell *location = mesh->get_cell(cell_index, SUBSURFACE_FLAG);
@@ -73,13 +176,13 @@ void Agent::advance_subsurface(Mesh* mesh, size_t step)
std::vector<double> coordinates_neighbor(DIM);
std::vector<double> distance(DIM);
- domain[step] = SUBSURFACE_FLAG; // set domain for this step
+ domain[step] = SUBSURFACE_FLAG; // set domain for this step, may change later if agent infiltrates
for (size_t i = 0; i < DIM; i ++)
velocity[i] = location->get_velocity(i);
// CFL criteria
- double length = location-> get_characteristic_length();
+ double length = location->get_characteristic_length();
double velocity_norm = sqrt(velocity[0] * velocity[0] + velocity[1] * velocity[1] + velocity[2] * velocity[2]);
if (velocity_norm > EPS) {
@@ -88,7 +191,6 @@ void Agent::advance_subsurface(Mesh* mesh, size_t step)
time_step_size = MAXTIMESTEP;
}
- // time_step_size = 1e6;
time[step] = time[step-1] + time_step_size;
// advect the agent
@@ -119,11 +221,26 @@ void Agent::advance_subsurface(Mesh* mesh, size_t step)
}
}
-
+
// check if out of the domain: if the agent travelled thrice the
// maximum length of the cell and still can't find a neighboring
// cell, it must be advected out of the domain
- if (distance_norm > 10.0 * location->get_maximum_length())
+ if (distance_norm > 10.0 * location->get_maximum_length()) {
domain[step] = OUTSIDE_FLAG;
+ }
+
+ // check if exfiltrates
+ int neighbor_index = mesh->get_cell(cell_index, SUBSURFACE_FLAG)->get_coupled_neighbor();
+ double z_surface;
+ if (neighbor_index > -1) {
+ // border to surface detected
+ z_surface = mesh->get_cell(neighbor_index, SURFACE_FLAG)->get_coordinate(2);
+ if (coordinates[2] >= z_surface) {
+ // exfiltration detected
+ cell_index = (int) neighbor_index;
+ domain[step] = SURFACE_FLAG;
+ set_path(coordinates[0], coordinates[1], z_surface, step);
+ }
+ }
}