float SWE::simulate(float tStart, float tEnd) { static int iter = 0; float t = tStart; do { //do debug output //writeVTKFile(generateFileName("detailed_out/out", iter)); float tMax = getMaxTimestep(); cout << "max dt: " << tMax << endl; setTimestep(tMax); setBoundaryLayer(); computeBathymetrySources(); t += eulerTimestep(); iter++; } while (t < tEnd); return t; }
void River::flowSingleTimestep(Grid<FlowData> &source, Grid<FlowData> &dest, Configuration &config) { for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { if( !source(x,y).hasWater || source(x,y).velocity <= 0.0 ) { continue; } double px_vector = source(x,y).px_vector; double py_vector = source(x,y).py_vector; double corner_patch = fabs( py_vector * px_vector ) / PATCH_AREA; double tb_patch = fabs( py_vector*( PATCH_LENGTH - fabs(px_vector) ) ) / PATCH_AREA; double rl_patch = fabs( px_vector*( PATCH_LENGTH - fabs(py_vector) ) ) / PATCH_AREA; // if a neighbor patch is dry, the carbon does not move in that direction double max_timestep = getMaxTimestep(); int tb_moved = 0; int corner_moved = 0; int rl_moved = 0; int px = (int)(max_timestep * px_vector); int py = (int)(max_timestep * py_vector); // is this the opposite of what is waned? if (config.adjacent) { if (px >= 1) { px = 1; } else if (px <= -1) { px = -1; } else { px = 0; } if (py >= 1) { py = 1; } else if (py <= -1) { py = -1; } else { py = 0; } } // flow carbon to the top/bottom patches if ( is_valid_patch(x, y+py) && (py!=0) ) { if (is_calc_nan(x,y+py,tb_patch, dest)) { g.nan_trigger = true; } else { dest(x, y+py).DOC += source(x,y).DOC*tb_patch; dest(x, y+py).POC += source(x,y).POC*tb_patch; dest(x, y+py).phyto += source(x,y).phyto*tb_patch; dest(x, y+py).waterdecomp += source(x,y).waterdecomp*tb_patch; tb_moved = 1; } } // flow carbon to the corner patch if ( is_valid_patch(x+px, y+py) && (px!=0) && (py!=0)) { if (is_calc_nan(x+px,y+py,corner_patch, dest)) { g.nan_trigger = true; } else { dest(x+px, y+py).DOC += source(x,y).DOC*corner_patch; dest(x+px, y+py).POC += source(x,y).POC*corner_patch; dest(x+px, y+py).phyto += source(x,y).phyto*corner_patch; dest(x+px, y+py).waterdecomp += source(x,y).waterdecomp*corner_patch; corner_moved = 1; } } // flow carbon to the left/right patches //TODO code pushes carbon onto land patches... if ( is_valid_patch(x+px, y) && (px!=0) ) { if ( is_calc_nan(x+px,y,rl_patch, dest) ) { g.nan_trigger = true; } else { dest(x+px, y).DOC += source(x,y).DOC*rl_patch; dest(x+px, y).POC += source(x,y).POC*rl_patch; dest(x+px, y).phyto += source(x,y).phyto*rl_patch; dest(x+px, y).waterdecomp += source(x,y).waterdecomp*rl_patch; rl_moved = 1; } } // how much components did we loose double patch_loss = tb_patch*tb_moved + corner_patch*corner_moved + rl_patch*rl_moved; dest(x,y).DOC = source(x,y).DOC - source(x,y).DOC*patch_loss; dest(x,y).POC = source(x,y).POC - source(x,y).POC*patch_loss; dest(x,y).phyto = source(x,y).phyto - source(x,y).phyto*patch_loss; dest(x,y).waterdecomp = source(x,y).waterdecomp - source(x,y).waterdecomp*patch_loss; } } }