Пример #1
0
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));
}
Пример #2
0
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


	       }
	    }
	 }
      }
   }
Пример #3
0
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;
      }
    });