void wrfparflowadvance_(double *current_time, double *dt, float * wrf_flux, float * wrf_pressure, float * wrf_porosity, float * wrf_saturation, int * num_soil_layers, int * ghost_size_i_lower, int * ghost_size_j_lower, int * ghost_size_i_upper, int * ghost_size_j_upper) { ProblemData *problem_data = GetProblemDataRichards(amps_ThreadLocal(solver)); double stop_time = *current_time + *dt; Vector *pressure_out; Vector *porosity_out; Vector *saturation_out; VectorUpdateCommHandle *handle; WRF2PF(wrf_flux, *num_soil_layers, *ghost_size_i_lower, *ghost_size_j_lower, *ghost_size_i_upper, *ghost_size_j_upper, amps_ThreadLocal(evap_trans), ProblemDataIndexOfDomainTop(problem_data)); /* * Exchange ghost layer data for the newly set fluxes */ handle = InitVectorUpdate(evap_trans, VectorUpdateAll); FinalizeVectorUpdate(handle); // SGS this is somewhat inefficient as we are allocating // a pf module for each timestep. double initial_step = *dt; double growth_factor = 2.0; double max_step = *dt; // SGS what should this be set to? double min_step = *dt * 1e-8; PFModule *time_step_control; time_step_control = NewPFModule((void*)SelectTimeStep, (void*)WRFSelectTimeStepInitInstanceXtra, \ (void*)SelectTimeStepFreeInstanceXtra, \ (void*)WRFSelectTimeStepNewPublicXtra, \ (void*)WRFSelectTimeStepFreePublicXtra, \ (void*)SelectTimeStepSizeOfTempData, \ NULL, NULL); ThisPFModule = time_step_control; WRFSelectTimeStepNewPublicXtra(initial_step, growth_factor, max_step, min_step); ThisPFModule = NULL; PFModule *time_step_control_instance = PFModuleNewInstance(time_step_control, ()); AdvanceRichards(amps_ThreadLocal(solver), *current_time, stop_time, time_step_control_instance, amps_ThreadLocal(evap_trans), &pressure_out, &porosity_out, &saturation_out); PFModuleFreeInstance(time_step_control_instance); PFModuleFreeModule(time_step_control); /* TODO: SGS * Are these needed here? Decided to put them in just be safe but * they could be unnecessary. */ handle = InitVectorUpdate(pressure_out, VectorUpdateAll); FinalizeVectorUpdate(handle); handle = InitVectorUpdate(porosity_out, VectorUpdateAll); FinalizeVectorUpdate(handle); handle = InitVectorUpdate(saturation_out, VectorUpdateAll); FinalizeVectorUpdate(handle); PF2WRF(pressure_out, wrf_pressure, *num_soil_layers, *ghost_size_i_lower, *ghost_size_j_lower, *ghost_size_i_upper, *ghost_size_j_upper, ProblemDataIndexOfDomainTop(problem_data)); PF2WRF(porosity_out, wrf_porosity, *num_soil_layers, *ghost_size_i_lower, *ghost_size_j_lower, *ghost_size_i_upper, *ghost_size_j_upper, ProblemDataIndexOfDomainTop(problem_data)); PF2WRF(saturation_out, wrf_saturation, *num_soil_layers, *ghost_size_i_lower, *ghost_size_j_lower, *ghost_size_i_upper, *ghost_size_j_upper, ProblemDataIndexOfDomainTop(problem_data)); }
void OverlandSum(ProblemData *problem_data, Vector *pressure, /* Current pressure values */ double dt, Vector *overland_sum) { GrGeomSolid *gr_domain = ProblemDataGrDomain(problem_data); double dx, dy, dz; int i, j, r, is; int ix, iy, iz; int nx, ny; Subgrid *subgrid; Grid *grid = VectorGrid(pressure); Vector *slope_x = ProblemDataTSlopeX(problem_data); Vector *slope_y = ProblemDataTSlopeY(problem_data); Vector *mannings = ProblemDataMannings(problem_data); Vector *top = ProblemDataIndexOfDomainTop(problem_data); Subvector *overland_sum_subvector; Subvector *slope_x_subvector; Subvector *slope_y_subvector; Subvector *mannings_subvector; Subvector *pressure_subvector; Subvector *top_subvector; int index_overland_sum; int index_slope_x; int index_slope_y; int index_mannings; int index_pressure; int index_top; double *overland_sum_ptr; double *slope_x_ptr; double *slope_y_ptr; double *mannings_ptr; double *pressure_ptr; double *top_ptr; int ipatch; BCStruct *bc_struct; BCPressureData *bc_pressure_data = ProblemDataBCPressureData(problem_data); int num_patches = BCPressureDataNumPatches(bc_pressure_data); bc_struct = NewBCStruct(GridSubgrids(grid), gr_domain, num_patches, BCPressureDataPatchIndexes(bc_pressure_data), BCPressureDataBCTypes(bc_pressure_data), NULL); if (num_patches > 0) { for (ipatch = 0; ipatch < num_patches; ipatch++) { switch(BCPressureDataType(bc_pressure_data,ipatch)) { case 7: { ForSubgridI(is, GridSubgrids(grid)) { subgrid = GridSubgrid(grid, is); overland_sum_subvector = VectorSubvector(overland_sum, is); slope_x_subvector = VectorSubvector(slope_x, is); slope_y_subvector = VectorSubvector(slope_y, is); mannings_subvector = VectorSubvector(mannings, is); pressure_subvector = VectorSubvector(pressure, is); top_subvector = VectorSubvector(top, is); r = SubgridRX(subgrid); ix = SubgridIX(subgrid); iy = SubgridIY(subgrid); iz = SubgridIZ(subgrid); nx = SubgridNX(subgrid); ny = SubgridNY(subgrid); dx = SubgridDX(subgrid); dy = SubgridDY(subgrid); dz = SubgridDZ(subgrid); overland_sum_ptr = SubvectorData(overland_sum_subvector); slope_x_ptr = SubvectorData(slope_x_subvector); slope_y_ptr = SubvectorData(slope_y_subvector); mannings_ptr = SubvectorData(mannings_subvector); pressure_ptr = SubvectorData(pressure_subvector); top_ptr = SubvectorData(top_subvector); int state; const int inactive = -1; const int active = 1; for(i = ix; i < ix + nx; i++) { j = iy - 1; index_top = SubvectorEltIndex(top_subvector, i, j, 0); int k = (int)top_ptr[index_top]; if( k < 0 ) { state = inactive; } else { state = active; } while( j < iy + ny) { if( state == inactive) { index_top = SubvectorEltIndex(top_subvector, i, j, 0); k = (int)top_ptr[index_top]; while( k < 0 && j <= iy + ny) { j++; index_top = SubvectorEltIndex(top_subvector, i, j, 0); k = (int)top_ptr[index_top]; } // If still in interior if( j < iy + ny) { if ( k >=0 ) { // inactive to active index_slope_y = SubvectorEltIndex(slope_y_subvector, i, j, 0); // sloping to inactive active from active if( slope_y_ptr[index_slope_y] > 0) { index_pressure = SubvectorEltIndex(pressure_subvector, i, j, k); if(pressure_ptr[index_pressure] > 0) { index_overland_sum = SubvectorEltIndex(overland_sum_subvector, i, j, 0); index_mannings = SubvectorEltIndex(mannings_subvector, i, j, 0); overland_sum_ptr[index_overland_sum] += (sqrt( fabs(slope_y_ptr[index_slope_y]) ) / mannings_ptr[index_mannings] ) * pow(pressure_ptr[index_pressure], 5.0 / 3.0) * dx * dt; } } } state = active; } } else { index_top = SubvectorEltIndex(top_subvector, i, j+1, 0); k = (int)top_ptr[index_top]; while( k >= 0 && j <= iy + ny) { j++; index_top = SubvectorEltIndex(top_subvector, i, j+1, 0); k = (int)top_ptr[index_top]; } // If still in interior if( j < iy + ny) { index_top = SubvectorEltIndex(top_subvector, i, j, 0); k = (int)top_ptr[index_top]; // active to inactive index_slope_y = SubvectorEltIndex(slope_y_subvector, i, j, 0); // sloping from active to inactive if( slope_y_ptr[index_slope_y] < 0) { index_pressure = SubvectorEltIndex(pressure_subvector, i, j, k); if(pressure_ptr[index_pressure] > 0) { index_overland_sum = SubvectorEltIndex(overland_sum_subvector, i, j, 0); index_mannings = SubvectorEltIndex(mannings_subvector, i, j, 0); overland_sum_ptr[index_overland_sum] += (sqrt( fabs(slope_y_ptr[index_slope_y]) ) / mannings_ptr[index_mannings] ) * pow(pressure_ptr[index_pressure], 5.0 / 3.0) * dx * dt; } } } state = inactive; } j++; } } #if 0 for(i = ix; i < ix + nx; i++) { for(j = iy; j < iy + ny; j++) { index_top = SubvectorEltIndex(top_subvector, i, j, 0); int k = (int)top_ptr[index_top]; if ( !(k < 0)) { /* Compute runnoff if slope is running off of active region */ index_overland_sum = SubvectorEltIndex(overland_sum_subvector, i, j, 0); index_slope_x = SubvectorEltIndex(slope_x_subvector, i, j, 0); index_slope_y = SubvectorEltIndex(slope_y_subvector, i, j, 0); index_mannings = SubvectorEltIndex(mannings_subvector, i, j, 0); index_pressure = SubvectorEltIndex(pressure_subvector, i, j, k); if( slope_y_ptr[index_slope_y] > 0 ) { if(pressure_ptr[index_pressure] > 0) { overland_sum_ptr[index_overland_sum] += (sqrt( fabs(slope_y_ptr[index_slope_y]) ) / mannings_ptr[index_mannings] ) * pow(pressure_ptr[index_pressure], 5.0 / 3.0) * dx * dt; } } /* Loop until going back outside of active area */ while( (j + 1 < iy + ny) && !(top_ptr[SubvectorEltIndex(top_subvector, i, j+1, 0)] < 0) ) { j++; } /* Found either domain boundary or outside of active area. Compute runnoff if slope is running off of active region. */ index_top = SubvectorEltIndex(top_subvector, i, j, 0); k = (int)top_ptr[index_top]; index_overland_sum = SubvectorEltIndex(overland_sum_subvector, i, j, 0); index_slope_x = SubvectorEltIndex(slope_x_subvector, i, j, 0); index_slope_y = SubvectorEltIndex(slope_y_subvector, i, j, 0); index_mannings = SubvectorEltIndex(mannings_subvector, i, j, 0); index_pressure = SubvectorEltIndex(pressure_subvector, i, j, k); if( slope_y_ptr[index_slope_y] < 0 ) { if(pressure_ptr[index_pressure] > 0) { overland_sum_ptr[index_overland_sum] += (sqrt( fabs(slope_y_ptr[index_slope_y]) ) / mannings_ptr[index_mannings] ) * pow(pressure_ptr[index_pressure], 5.0 / 3.0) * dx * dt; } } } } } #endif for(j = iy; j < iy + ny; j++) { i = ix - 1; index_top = SubvectorEltIndex(top_subvector, i, j, 0); int k = (int)top_ptr[index_top]; if( k < 0 ) { state = inactive; } else { state = active; } while( i < ix + nx) { if( state == inactive) { index_top = SubvectorEltIndex(top_subvector, i, j, 0); k = (int)top_ptr[index_top]; while( k < 0 && i <= ix + nx) { i++; index_top = SubvectorEltIndex(top_subvector, i, j, 0); k = (int)top_ptr[index_top]; } // If still in interior if( i < ix + nx) { if ( k >=0 ) { // inactive to active index_slope_x = SubvectorEltIndex(slope_x_subvector, i, j, 0); // sloping to inactive active from active if( slope_x_ptr[index_slope_x] > 0) { index_pressure = SubvectorEltIndex(pressure_subvector, i, j, k); if(pressure_ptr[index_pressure] > 0) { index_overland_sum = SubvectorEltIndex(overland_sum_subvector, i, j, 0); index_mannings = SubvectorEltIndex(mannings_subvector, i, j, 0); overland_sum_ptr[index_overland_sum] += (sqrt( fabs(slope_x_ptr[index_slope_x]) ) / mannings_ptr[index_mannings] ) * pow(pressure_ptr[index_pressure], 5.0 / 3.0) * dy * dt; } } } state = active; } } else { index_top = SubvectorEltIndex(top_subvector, i+1, j, 0); k = (int)top_ptr[index_top]; while( k >= 0 && i <= ix + nx) { i++; index_top = SubvectorEltIndex(top_subvector, i+1, j, 0); k = (int)top_ptr[index_top]; } // If still in interior if( i < ix + nx) { index_top = SubvectorEltIndex(top_subvector, i, j, 0); k = (int)top_ptr[index_top]; // active to inactive index_slope_x = SubvectorEltIndex(slope_x_subvector, i, j, 0); // sloping from active to inactive if( slope_x_ptr[index_slope_x] < 0) { index_pressure = SubvectorEltIndex(pressure_subvector, i, j, k); if(pressure_ptr[index_pressure] > 0) { index_overland_sum = SubvectorEltIndex(overland_sum_subvector, i, j, 0); index_mannings = SubvectorEltIndex(mannings_subvector, i, j, 0); overland_sum_ptr[index_overland_sum] += (sqrt( fabs(slope_x_ptr[index_slope_x]) ) / mannings_ptr[index_mannings] ) * pow(pressure_ptr[index_pressure], 5.0 / 3.0) * dy * dt; } } } state = inactive; } i++; } } #if 0 for(j = iy; j < iy + ny; j++) { for(i = ix; i < ix + nx; i++) { index_top = SubvectorEltIndex(top_subvector, i, j, 0); int k = (int)top_ptr[index_top]; if ( !(k < 0)) { /* Compute runnoff if slope is running off of active region */ index_overland_sum = SubvectorEltIndex(overland_sum_subvector, i, j, 0); index_slope_x = SubvectorEltIndex(slope_x_subvector, i, j, 0); index_slope_y = SubvectorEltIndex(slope_y_subvector, i, j, 0); index_mannings = SubvectorEltIndex(mannings_subvector, i, j, 0); index_pressure = SubvectorEltIndex(pressure_subvector, i, j, k); if( slope_x_ptr[index_slope_x] > 0 ) { if(pressure_ptr[index_pressure] > 0) { overland_sum_ptr[index_overland_sum] += (sqrt( fabs(slope_x_ptr[index_slope_y]) ) / mannings_ptr[index_mannings] ) * pow(pressure_ptr[index_pressure], 5.0 / 3.0) * dy * dt; } } /* Loop until going back outside of active area */ while( (i + 1 < ix + nx) && !(top_ptr[SubvectorEltIndex(top_subvector, i+1, j, 0)] < 0) ) { i++; } /* Found either domain boundary or outside of active area. Compute runnoff if slope is running off of active region. */ index_top = SubvectorEltIndex(top_subvector, i, j, 0); k = (int)top_ptr[index_top]; index_overland_sum = SubvectorEltIndex(overland_sum_subvector, i, j, 0); index_slope_x = SubvectorEltIndex(slope_x_subvector, i, j, 0); index_slope_y = SubvectorEltIndex(slope_y_subvector, i, j, 0); index_mannings = SubvectorEltIndex(mannings_subvector, i, j, 0); index_pressure = SubvectorEltIndex(pressure_subvector, i, j, k); if( slope_x_ptr[index_slope_x] < 0 ) { if(pressure_ptr[index_pressure] > 0) { overland_sum_ptr[index_overland_sum] += (sqrt( fabs(slope_x_ptr[index_slope_x]) ) / mannings_ptr[index_mannings] ) * pow(pressure_ptr[index_pressure], 5.0 / 3.0) * dy * dt; } } } } } #endif } } } } }
void ComputeTop(Problem * problem, /* General problem information */ ProblemData *problem_data /* Contains geometry information for the problem */ ) { GrGeomSolid *gr_solid = ProblemDataGrDomain(problem_data); Vector *top = ProblemDataIndexOfDomainTop(problem_data); Vector *perm_x = ProblemDataPermeabilityX(problem_data); Grid *grid2d = VectorGrid(top); SubgridArray *grid2d_subgrids = GridSubgrids(grid2d); /* use perm grid as top is 2D and want to loop over Z */ Grid *grid3d = VectorGrid(perm_x); SubgridArray *grid3d_subgrids = GridSubgrids(grid3d); double *top_data; int index; VectorUpdateCommHandle *handle; (void)problem; InitVectorAll(top, -1); // PFVConstInit(-1, top); int is; ForSubgridI(is, grid3d_subgrids) { Subgrid *grid2d_subgrid = SubgridArraySubgrid(grid2d_subgrids, is); Subgrid *grid3d_subgrid = SubgridArraySubgrid(grid3d_subgrids, is); Subvector *top_subvector = VectorSubvector(top, is); int grid3d_ix = SubgridIX(grid3d_subgrid); int grid3d_iy = SubgridIY(grid3d_subgrid); int grid3d_iz = SubgridIZ(grid3d_subgrid); int grid2d_iz = SubgridIZ(grid2d_subgrid); int grid3d_nx = SubgridNX(grid3d_subgrid); int grid3d_ny = SubgridNY(grid3d_subgrid); int grid3d_nz = SubgridNZ(grid3d_subgrid); int grid3d_r = SubgridRX(grid3d_subgrid); top_data = SubvectorData(top_subvector); int i, j, k; GrGeomInLoop(i, j, k, gr_solid, grid3d_r, grid3d_ix, grid3d_iy, grid3d_iz, grid3d_nx, grid3d_ny, grid3d_nz, { index = SubvectorEltIndex(top_subvector, i, j, grid2d_iz); if (top_data[index] < k) { top_data[index] = k; } });