void LBInitializeBC( Lattice * lattice, Problem * problem, ProblemData *problem_data) { /*------------------------------------------------------------* * Local variables *------------------------------------------------------------*/ /* Lattice variables */ Grid *grid = (lattice->grid); Vector *pressure = (lattice->pressure); Vector *perm = (lattice->perm); CharVector *cellType = (lattice->cellType); double time = (lattice->t); /* Structures */ BCPressureData *bc_pressure_data = ProblemDataBCPressureData(problem_data); TimeCycleData *time_cycle_data; SubgridArray *subgrids = GridSubgrids(grid); GrGeomSolid *gr_domain; /* Patch variables */ double ***values; double *patch_values = NULL; int *fdir; /* Grid parameters */ Subgrid *subgrid; int nx, ny, nz; int ix, iy, iz; int nx_v, ny_v, nz_v; /* Indices and counters */ int num_patches; int num_phases; int ipatch, is, i, j, k, ival; int cycle_number, interval_number; int r; /* Physical variables and coefficients */ Subvector *sub_p; double *pp; Subvector *sub_perm; double *permp; Subcharvector *sub_cellType; char *cellTypep; double rho_g; /* Communications */ VectorUpdateCommHandle *handle; /*-------------------------- * Initializations *--------------------------*/ rho_g = ProblemGravity(problem) * RHO; num_patches = BCPressureDataNumPatches(bc_pressure_data); gr_domain = ProblemDataGrDomain(problem_data); num_phases = BCPressureDataNumPhases(bc_pressure_data); if (num_patches > 0) { time_cycle_data = BCPressureDataTimeCycleData(bc_pressure_data); values = ctalloc(double **, num_patches); for (ipatch = 0; ipatch < num_patches; ipatch++) { values[ipatch] = ctalloc(double *, SubgridArraySize(subgrids)); cycle_number = BCPressureDataCycleNumber(bc_pressure_data, ipatch); interval_number = TimeCycleDataComputeIntervalNumber(problem, time, time_cycle_data, cycle_number); switch (BCPressureDataType(bc_pressure_data, ipatch)) { case 0: { BCPressureType0 *bc_pressure_type0; GeomSolid *ref_solid; double z, dz2; double **elevations; int ref_patch, iel; bc_pressure_type0 = (BCPressureType0*)BCPressureDataIntervalValue( bc_pressure_data, ipatch, interval_number); ref_solid = ProblemDataSolid(problem_data, BCPressureType0RefSolid(bc_pressure_type0)); ref_patch = BCPressureType0RefPatch(bc_pressure_type0); /* Calculate elevations at (x,y) points on reference patch. */ elevations = CalcElevations(ref_solid, ref_patch, subgrids, problem_data); ForSubgridI(is, subgrids) { /* subgrid = GridSubgrid(grid, is); */ subgrid = SubgridArraySubgrid(subgrids, is); sub_p = VectorSubvector(pressure, is); sub_perm = VectorSubvector(perm, is); sub_cellType = CharVectorSubcharvector(cellType, is); nx = SubgridNX(subgrid); ny = SubgridNY(subgrid); nz = SubgridNZ(subgrid); ix = SubgridIX(subgrid); iy = SubgridIY(subgrid); iz = SubgridIZ(subgrid); /* RDF: assume resolution is the same in all 3 directions */ r = SubgridRX(subgrid); pp = SubvectorData(sub_p); permp = SubvectorData(sub_perm); cellTypep = SubcharvectorData(sub_cellType); nx_v = SubvectorNX(sub_p); ny_v = SubvectorNY(sub_p); nz_v = SubvectorNZ(sub_p); values[ipatch][is] = patch_values; dz2 = RealSpaceDZ(0) / 2.0; GrGeomPatchLoop(i, j, k, fdir, gr_domain, ipatch, r, ix, iy, iz, nx, ny, nz, { ival = SubvectorEltIndex(sub_p, i, j, k); iel = (i - ix) + (j - iy) * nx; z = RealSpaceZ(k, 0) + fdir[2] * dz2; pp[ival] = BCPressureType0Value(bc_pressure_type0) - rho_g * (z - elevations[is][iel]); cellTypep[ival] = 0; }); tfree(elevations[is]); } /* End subgrid loop */ tfree(elevations); break; } case 1: { BCPressureType1 *bc_pressure_type1; int num_points; double x, y, z, dx2, dy2, dz2; double unitx, unity, line_min, line_length, xy, slope; int ip; bc_pressure_type1 = (BCPressureType1*)BCPressureDataIntervalValue(bc_pressure_data, ipatch, interval_number); ForSubgridI(is, subgrids) { /* subgrid = GridSubgrid(grid, is); */ subgrid = SubgridArraySubgrid(subgrids, is); sub_p = VectorSubvector(pressure, is); sub_perm = VectorSubvector(perm, is); sub_cellType = CharVectorSubcharvector(cellType, is); nx = SubgridNX(subgrid); ny = SubgridNY(subgrid); nz = SubgridNZ(subgrid); ix = SubgridIX(subgrid); iy = SubgridIY(subgrid); iz = SubgridIZ(subgrid); /* RDF: assume resolution is the same in all 3 directions */ r = SubgridRX(subgrid); pp = SubvectorData(sub_p); permp = SubvectorData(sub_perm); cellTypep = SubcharvectorData(sub_cellType); nx_v = SubvectorNX(sub_p); ny_v = SubvectorNY(sub_p); nz_v = SubvectorNZ(sub_p); values[ipatch][is] = patch_values; dx2 = RealSpaceDX(0) / 2.0; dy2 = RealSpaceDY(0) / 2.0; dz2 = RealSpaceDZ(0) / 2.0; /* compute unit direction vector for piecewise linear line */ unitx = BCPressureType1XUpper(bc_pressure_type1) - BCPressureType1XLower(bc_pressure_type1); unity = BCPressureType1YUpper(bc_pressure_type1) - BCPressureType1YLower(bc_pressure_type1); line_length = sqrt(unitx * unitx + unity * unity); unitx /= line_length; unity /= line_length; line_min = BCPressureType1XLower(bc_pressure_type1) * unitx + BCPressureType1YLower(bc_pressure_type1) * unity; GrGeomPatchLoop(i, j, k, fdir, gr_domain, ipatch, r, ix, iy, iz, nx, ny, nz, { ival = SubvectorEltIndex(sub_p, i, j, k); x = RealSpaceX(i, 0) + fdir[0] * dx2; y = RealSpaceY(j, 0) + fdir[1] * dy2; z = RealSpaceZ(k, 0) + fdir[2] * dz2; /* project center of BC face onto piecewise line */ xy = (x * unitx + y * unity - line_min) / line_length; /* find two neighboring points */ ip = 1; /* Kludge; this needs to be fixed. */ num_points = 2; for (; ip < (num_points - 1); ip++) { if (xy < BCPressureType1Point(bc_pressure_type1, ip)) break; } /* compute the slope */ slope = ((BCPressureType1Value(bc_pressure_type1, ip) - BCPressureType1Value(bc_pressure_type1, (ip - 1))) / (BCPressureType1Point(bc_pressure_type1, ip) - BCPressureType1Point(bc_pressure_type1, (ip - 1)))); pp[ival] = BCPressureType1Value(bc_pressure_type1, ip - 1) + slope * (xy - BCPressureType1Point( bc_pressure_type1, ip - 1)) - rho_g * z; cellTypep[ival] = 0; }); } /* End subgrid loop */
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 SelectTimeStep( double *dt, /* Time step size */ char *dt_info, /* Character flag indicating what requirement chose the time step */ double time, Problem *problem, ProblemData *problem_data) { PFModule *this_module = ThisPFModule; PublicXtra *public_xtra = (PublicXtra *)PFModulePublicXtra(this_module); Type0 *dummy0; Type1 *dummy1; double well_dt, bc_dt; switch((public_xtra -> type)) { case 0: { double constant; dummy0 = (Type0 *)(public_xtra -> data); constant = (dummy0 -> step); (*dt) = constant; break; } /* End case 0 */ case 1: { double initial_step; double factor; double max_step; double min_step; dummy1 = (Type1 *)(public_xtra -> data); initial_step = (dummy1 -> initial_step); factor = (dummy1 -> factor); max_step = (dummy1 -> max_step); min_step = (dummy1 -> min_step); if ((*dt) == 0.0) { (*dt) = initial_step; } else { (*dt) = (*dt)*factor; if ((*dt) < min_step) (*dt) = min_step; if ((*dt) > max_step) (*dt) = max_step; } break; } /* End case 1 */ } /* End switch */ /*----------------------------------------------------------------- * Get delta t's for all wells and boundary conditions. *-----------------------------------------------------------------*/ well_dt = TimeCycleDataComputeNextTransition(problem, time, WellDataTimeCycleData(ProblemDataWellData(problem_data))); bc_dt = TimeCycleDataComputeNextTransition(problem, time, BCPressureDataTimeCycleData(ProblemDataBCPressureData(problem_data))); /*----------------------------------------------------------------- * Compute the new dt value based on time stepping criterion imposed * by the user or on system parameter changes. Indicate what * determined the value of `dt'. *-----------------------------------------------------------------*/ if ( well_dt <= 0.0 ) well_dt = (*dt); if ( bc_dt <= 0.0 ) bc_dt = (*dt); if ((*dt) > well_dt) { (*dt) = well_dt; (*dt_info) = 'w'; } else if ((*dt) > bc_dt) { (*dt) = bc_dt; (*dt_info) = 'b'; } else { (*dt_info) = 'p'; } }