コード例 #1
0
ファイル: wrf_parflow.c プロジェクト: cvoter/Parflow
/*
 * Copy data from a WRF array to a PF vector based on the
 * k-index data for the top of the domain.
 */
void WRF2PF(
            float * wrf_array, /* WRF array */
            int     wrf_depth, /* Depth (Z) of WRF array, X,Y are assumed
                                * to be same as PF vector subgrid */
            int     ghost_size_i_lower, /* Number of ghost cells */
            int     ghost_size_j_lower,
            int     ghost_size_i_upper,
            int     ghost_size_j_upper,
            Vector *pf_vector,
            Vector *top)
{
  Grid       *grid = VectorGrid(pf_vector);
  int sg;

  (void)ghost_size_j_upper;

  ForSubgridI(sg, GridSubgrids(grid))
  {
    Subgrid *subgrid = GridSubgrid(grid, sg);

    int ix = SubgridIX(subgrid);
    int iy = SubgridIY(subgrid);

    int nx = SubgridNX(subgrid);
    int ny = SubgridNY(subgrid);

    int wrf_nx = nx + ghost_size_i_lower + ghost_size_i_upper;

    Subvector *subvector = VectorSubvector(pf_vector, sg);
    double *subvector_data = SubvectorData(subvector);

    Subvector *top_subvector = VectorSubvector(top, sg);
    double    *top_data = SubvectorData(top_subvector);

    int i, j, k;

    for (i = ix; i < ix + nx; i++)
    {
      for (j = iy; j < iy + ny; j++)
      {
        int top_index = SubvectorEltIndex(top_subvector, i, j, 0);

        // SGS What to do if near bottom such that
        // there are not wrf_depth values?
        int iz = (int)top_data[top_index] - (wrf_depth - 1);
        for (k = iz; k < iz + wrf_depth; k++)
        {
          int pf_index = SubvectorEltIndex(subvector, i, j, k);
          int wrf_index = (i - ix + ghost_size_i_lower) +
                          ((wrf_depth - (k - iz) - 1) * wrf_nx) +
                          ((j - iy + ghost_size_j_lower) * (wrf_nx * wrf_depth));
          subvector_data[pf_index] = (double)(wrf_array[wrf_index]);
        }
      }
    }
  }
コード例 #2
0
double   InnerProd(
   Vector  *x,
   Vector  *y)
{
   Grid         *grid = VectorGrid(x);
   Subgrid      *subgrid;
 
   Subvector    *y_sub;
   Subvector    *x_sub;

   double       *yp, *xp;

   double        result = 0.0;

   int           ix,   iy,   iz;
   int           nx,   ny,   nz;
   int           nx_v, ny_v, nz_v;
                 
   int           i_s, i, j, k, iv;

   amps_Invoice  result_invoice;


   result_invoice = amps_NewInvoice("%d", &result);
   
   ForSubgridI(i_s, GridSubgrids(grid))
   {
      subgrid = GridSubgrid(grid, i_s);

      ix = SubgridIX(subgrid);
      iy = SubgridIY(subgrid);
      iz = SubgridIZ(subgrid);

      nx = SubgridNX(subgrid);
      ny = SubgridNY(subgrid);
      nz = SubgridNZ(subgrid);

      y_sub = VectorSubvector(y, i_s);
      x_sub = VectorSubvector(x, i_s);

      nx_v = SubvectorNX(y_sub);
      ny_v = SubvectorNY(y_sub);
      nz_v = SubvectorNZ(y_sub);

      yp = SubvectorElt(y_sub, ix, iy, iz);
      xp = SubvectorElt(x_sub, ix, iy, iz);
 
      iv = 0;
      BoxLoopI1(i, j, k, ix, iy, iz, nx, ny, nz,
		iv, nx_v, ny_v, nz_v, 1, 1, 1,
		{
		   result += yp[iv] * xp[iv];
		});
コード例 #3
0
ファイル: axpy.c プロジェクト: Watershed-Function-SFA/parflow
void     Axpy(
   double   alpha,
   Vector  *x,
   Vector  *y)
{
   Grid       *grid    = VectorGrid(x);
   Subgrid    *subgrid;
 
   Subvector  *y_sub;
   Subvector  *x_sub;

   double     *yp, *xp;

   int         ix,   iy,   iz;
   int         nx,   ny,   nz;
   int         nx_v, ny_v, nz_v;

   int         i_s, i, j, k, iv;


   ForSubgridI(i_s, GridSubgrids(grid))
   {
      subgrid = GridSubgrid(grid, i_s);
      
      ix = SubgridIX(subgrid);
      iy = SubgridIY(subgrid);
      iz = SubgridIZ(subgrid);
      
      nx = SubgridNX(subgrid);
      ny = SubgridNY(subgrid);
      nz = SubgridNZ(subgrid);
      
      y_sub = VectorSubvector(y, i_s);
      x_sub = VectorSubvector(x, i_s);
      
      nx_v = SubvectorNX(y_sub);
      ny_v = SubvectorNY(y_sub);
      nz_v = SubvectorNZ(y_sub);
      
      yp = SubvectorElt(y_sub, ix, iy, iz);
      xp = SubvectorElt(x_sub, ix, iy, iz);
	 
      iv = 0;
      BoxLoopI1(i, j, k, ix, iy, iz, nx, ny, nz,
		iv, nx_v, ny_v, nz_v, 1, 1, 1,
		{
		   yp[iv] += alpha * xp[iv];
		});
コード例 #4
0
double       ComputeTotalConcen(
                                GrGeomSolid *gr_domain,
                                Grid *       grid,
                                Vector *     substance)
{
  Subgrid        *subgrid;
  double cell_volume, field_sum;
  double dx, dy, dz;

  Subvector      *s_sub;

  int i, j, k, r, ix, iy, iz, nx, ny, nz, is, ips;
  int            *fdir;
  double         *data;
  amps_Invoice result_invoice;

  field_sum = 0.0;
  ForSubgridI(is, GridSubgrids(grid))
  {
    subgrid = GridSubgrid(grid, is);

    s_sub = VectorSubvector(substance, is);

    ix = SubgridIX(subgrid);
    iy = SubgridIY(subgrid);
    iz = SubgridIZ(subgrid);

    nx = SubgridNX(subgrid);
    ny = SubgridNY(subgrid);
    nz = SubgridNZ(subgrid);

    dx = SubgridDX(subgrid);
    dy = SubgridDY(subgrid);
    dz = SubgridDZ(subgrid);

    /* RDF: assume resolution is the same in all 3 directions */
    r = SubgridRX(subgrid);

    data = SubvectorData(s_sub);

    cell_volume = dx * dy * dz;

    GrGeomSurfLoop(i, j, k, fdir, gr_domain, r, ix, iy, iz, nx, ny, nz,
    {
      ips = SubvectorEltIndex(s_sub, i, j, k);
      data[ips] = 0.0;
    });
コード例 #5
0
ファイル: vector_utilities.c プロジェクト: cvoter/Parflow
void PFVLinearSum(
/* LinearSum : z = a * x + b * y              */
                  double  a,
                  Vector *x,
                  double  b,
                  Vector *y,
                  Vector *z)

{
  double c;
  Vector *v1, *v2;
  int test;

  Grid       *grid = VectorGrid(x);
  Subgrid    *subgrid;

  Subvector  *x_sub;
  Subvector  *y_sub;
  Subvector  *z_sub;

  double     *yp, *xp, *zp;

  int ix, iy, iz;
  int nx, ny, nz;
  int nx_x, ny_x, nz_x;
  int nx_y, ny_y, nz_y;
  int nx_z, ny_z, nz_z;

  int sg, i, j, k, i_x, i_y, i_z;

  if ((b == ONE) && (z == y))      /* BLAS usage: axpy y <- ax+y */
  {
    PFVAxpy(a, x, y);
    return;
  }

  if ((a == ONE) && (z == x))      /* BLAS usage: axpy x <- by+x */
  {
    PFVAxpy(b, y, x);
    return;
  }

  /* Case: a == b == 1.0 */

  if ((a == ONE) && (b == ONE))
  {
    PFVSum(x, y, z);
    return;
  }

  /* Cases: (1) a == 1.0, b = -1.0, (2) a == -1.0, b == 1.0 */

  if ((test = ((a == ONE) && (b == -ONE))) || ((a == -ONE) && (b == ONE)))
  {
    v1 = test ? y : x;
    v2 = test ? x : y;
    PFVDiff(v2, v1, z);
    return;
  }

  /* Cases: (1) a == 1.0, b == other or 0.0, (2) a == other or 0.0, b == 1.0 */
  /* if a or b is 0.0, then user should have called N_VScale */

  if ((test = (a == ONE)) || (b == ONE))
  {
    c = test ? b : a;
    v1 = test ? y : x;
    v2 = test ? x : y;
    PFVLin1(c, v1, v2, z);
    return;
  }

  /* Cases: (1) a == -1.0, b != 1.0, (2) a != 1.0, b == -1.0 */

  if ((test = (a == -ONE)) || (b == -ONE))
  {
    c = test ? b : a;
    v1 = test ? y : x;
    v2 = test ? x : y;
    PFVLin2(c, v1, v2, z);
    return;
  }

  /* Case: a == b */
  /* catches case both a and b are 0.0 - user should have called N_VConst */

  if (a == b)
  {
    PFVScaleSum(a, x, y, z);
    return;
  }

  /* Case: a == -b */

  if (a == -b)
  {
    PFVScaleDiff(a, x, y, z);
    return;
  }

  /* Do all cases not handled above:
   * (1) a == other, b == 0.0 - user should have called N_VScale
   * (2) a == 0.0, b == other - user should have called N_VScale
   * (3) a,b == other, a !=b, a != -b */

  ForSubgridI(sg, GridSubgrids(grid))
  {
    subgrid = GridSubgrid(grid, sg);

    z_sub = VectorSubvector(z, sg);
    x_sub = VectorSubvector(x, sg);
    y_sub = VectorSubvector(y, sg);

    ix = SubgridIX(subgrid);
    iy = SubgridIY(subgrid);
    iz = SubgridIZ(subgrid);

    nx = SubgridNX(subgrid);
    ny = SubgridNY(subgrid);
    nz = SubgridNZ(subgrid);

    nx_x = SubvectorNX(x_sub);
    ny_x = SubvectorNY(x_sub);
    nz_x = SubvectorNZ(x_sub);

    nx_y = SubvectorNX(y_sub);
    ny_y = SubvectorNY(y_sub);
    nz_y = SubvectorNZ(y_sub);

    nx_z = SubvectorNX(z_sub);
    ny_z = SubvectorNY(z_sub);
    nz_z = SubvectorNZ(z_sub);

    zp = SubvectorElt(z_sub, ix, iy, iz);
    xp = SubvectorElt(x_sub, ix, iy, iz);
    yp = SubvectorElt(y_sub, ix, iy, iz);

    i_x = 0;
    i_y = 0;
    i_z = 0;
    BoxLoopI3(i, j, k, ix, iy, iz, nx, ny, nz,
              i_x, nx_x, ny_x, nz_x, 1, 1, 1,
              i_y, nx_y, ny_y, nz_y, 1, 1, 1,
              i_z, nx_z, ny_z, nz_z, 1, 1, 1,
    {
      zp[i_z] = a * xp[i_x] + b * yp[i_y];
    });
コード例 #6
0
void    PhaseDensity(
   int     phase,           /* Phase */
   Vector *phase_pressure,  /* Vector of phase pressures at each block */
   Vector *density_v,       /* Vector of return densities at each block */
   double *pressure_d,      /* Double array of pressures */
   double *density_d,       /* Double array return density */
   int     fcn)             /* Flag determining what to calculate 
			     * fcn = CALCFCN => calculate the function value
			     * fcn = CALCDER => calculate the function 
			     *                  derivative */
   
/*  Module returns either a double array or Vector of densities.
 *  If density_v is NULL, then a double array is returned. 
 *  This "overloading" was provided so that the density module written
 *  for the Richards' solver modules would be backward compatible with
 *  the Impes modules.
 */
{
   PFModule      *this_module   = ThisPFModule;
   PublicXtra    *public_xtra   = (PublicXtra *)PFModulePublicXtra(this_module);

   Type0         *dummy0;
   Type1         *dummy1;

   Grid          *grid;

   Subvector     *p_sub;
   Subvector     *d_sub;

   double        *pp; 
   double        *dp; 

   Subgrid       *subgrid;

   int            sg;

   int            ix,   iy,   iz;
   int            nx,   ny,   nz;
   int            nx_p, ny_p, nz_p;
   int            nx_d, ny_d, nz_d;

   int            i, j, k, ip, id;


   switch((public_xtra -> type[phase]))
   {

   case 0:
   {
      double  constant;
      dummy0 = (Type0 *)(public_xtra -> data[phase]);
      constant = (dummy0 -> constant);

      if ( density_v != NULL)
      {
         grid = VectorGrid(density_v);
	 ForSubgridI(sg, GridSubgrids(grid))
	 {
	    subgrid = GridSubgrid(grid, sg);

	    d_sub = VectorSubvector(density_v,  sg);

	    ix = SubgridIX(subgrid) - 1;
	    iy = SubgridIY(subgrid) - 1;
	    iz = SubgridIZ(subgrid) - 1;

	    nx = SubgridNX(subgrid) + 2;
	    ny = SubgridNY(subgrid) + 2;
	    nz = SubgridNZ(subgrid) + 2;

	    nx_d = SubvectorNX(d_sub);
	    ny_d = SubvectorNY(d_sub);
	    nz_d = SubvectorNZ(d_sub);

	    dp = SubvectorElt(d_sub, ix, iy, iz);

	    id = 0;
	    if ( fcn == CALCFCN )
	    {
	       BoxLoopI1(i, j, k, ix, iy, iz, nx, ny, nz,
			 id, nx_d, ny_d, nz_d, 1, 1, 1,
			 {
			    dp[id] = constant;
			 });
	    }
コード例 #7
0
void         ICPhaseSatur(
Vector      *ic_phase_satur,
int          phase,
ProblemData *problem_data)
{
   PFModule      *this_module   = ThisPFModule;
   PublicXtra    *public_xtra   = (PublicXtra *)PFModulePublicXtra(this_module);

   Grid          *grid = VectorGrid(ic_phase_satur);

   Type0          *dummy0;

   SubgridArray   *subgrids = GridSubgrids(grid);

   Subgrid        *subgrid;
   Subvector      *ps_sub;

   double         *data;

   int             ix, iy, iz;
   int             nx, ny, nz;
   int             r;

   double          field_sum;

   int             is, i, j, k, ips;


   /*-----------------------------------------------------------------------
    * Initial saturation conditions for this phase
    *-----------------------------------------------------------------------*/

   InitVector(ic_phase_satur, 0.0);

   switch((public_xtra -> type[phase]))
   {
   case 0:
   {
      int      num_regions;
      int     *region_indices;
      double  *values;

      GrGeomSolid  *gr_solid;
      double        value;
      int           ir;


      dummy0 = (Type0 *)(public_xtra -> data[phase]);

      num_regions    = (dummy0 -> num_regions);
      region_indices = (dummy0 -> region_indices);
      values         = (dummy0 -> values);

      for (ir = 0; ir < num_regions; ir++)
      {
	 gr_solid = ProblemDataGrSolid(problem_data, region_indices[ir]);
	 value    = values[ir];

	 ForSubgridI(is, subgrids)
	 {
            subgrid = SubgridArraySubgrid(subgrids, is);
            ps_sub  = VectorSubvector(ic_phase_satur, is);
	    
	    ix = SubgridIX(subgrid);
	    iy = SubgridIY(subgrid);
	    iz = SubgridIZ(subgrid);
	    
	    nx = SubgridNX(subgrid);
	    ny = SubgridNY(subgrid);
	    nz = SubgridNZ(subgrid);
	    
	    /* RDF: assume resolution is the same in all 3 directions */
	    r = SubgridRX(subgrid);
	    
	    data = SubvectorData(ps_sub);
	    GrGeomInLoop(i, j, k, gr_solid, r, ix, iy, iz, nx, ny, nz,
            {
	       ips = SubvectorEltIndex(ps_sub, i, j, k);

	       data[ips] = value;
	    });
	 }
      }

      break;
   }
コード例 #8
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


	       }
	    }
	 }
      }
   }
コード例 #9
0
ファイル: bc_lb.c プロジェクト: cvoter/Parflow
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 */
コード例 #10
0
ファイル: problem_toposlope_x.c プロジェクト: cvoter/Parflow
void         XSlope(
                    ProblemData *problem_data,
                    Vector *     x_slope,
                    Vector *     dummy)
{
  PFModule      *this_module = ThisPFModule;
  PublicXtra    *public_xtra = (PublicXtra*)PFModulePublicXtra(this_module);
  InstanceXtra *instance_xtra = (InstanceXtra*)PFModuleInstanceXtra(this_module);

  Grid             *grid3d = instance_xtra->grid3d;

  GrGeomSolid      *gr_solid, *gr_domain;

  Type0            *dummy0;
  Type1            *dummy1;
  Type2            *dummy2;
  Type3            *dummy3;

  VectorUpdateCommHandle       *handle;

  SubgridArray     *subgrids = GridSubgrids(grid3d);

  Subgrid          *subgrid;
  Subvector        *ps_sub;
  Subvector        *sx_values_sub;

  double           *data;
  double           *psdat, *sx_values_dat;
  //double            slopex[60][32][392];

  int ix, iy, iz;
  int nx, ny, nz;
  int r;

  int is, i, j, k, ips, ipicv;
  double time = 0.0;

  (void)dummy;

  /*-----------------------------------------------------------------------
   * Put in any user defined sources for this phase
   *-----------------------------------------------------------------------*/

  InitVectorAll(x_slope, 0.0);

  switch ((public_xtra->type))
  {
    case 0:
    {
      int num_regions;
      int     *region_indices;
      double  *values;
      double x, y, z;
      double value;
      int ir;

      dummy0 = (Type0*)(public_xtra->data);

      num_regions = (dummy0->num_regions);
      region_indices = (dummy0->region_indices);
      values = (dummy0->values);

      for (ir = 0; ir < num_regions; ir++)
      {
        gr_solid = ProblemDataGrSolid(problem_data, region_indices[ir]);
        value = values[ir];

        ForSubgridI(is, subgrids)
        {
          subgrid = SubgridArraySubgrid(subgrids, is);
          ps_sub = VectorSubvector(x_slope, is);

          ix = SubgridIX(subgrid);
          iy = SubgridIY(subgrid);
          iz = SubgridIZ(subgrid);

          nx = SubgridNX(subgrid);
          ny = SubgridNY(subgrid);
          nz = SubgridNZ(subgrid);

          /* RDF: assume resolution is the same in all 3 directions */
          r = SubgridRX(subgrid);

          /*
           * TODO
           * SGS this does not match the loop in nl_function_eval.  That
           * loop is going over more than the inner geom locations.  Is that
           * important?  Originally the x_slope array was not being allocated
           * by ctalloc, just alloc and unitialized memory reads were being
           * caused.   Switched that to be ctalloc to init to 0 to "hack" a
           * fix but is this really a sign of deeper indexing problems?
           */
          /* @RMM: todo. the looping to set slopes only goes over interior nodes
           * not ALL nodes (including ghost) as in nl fn eval and now the overland eval
           * routines.  THis is fine in the KW approximation which only needs interior values
           * but for diffusive wave and for the terrain following grid (which uses the surface
           * topo slopes as subsurface slopes) this can cuase bddy problems.  */

          data = SubvectorData(ps_sub);
          GrGeomInLoop(i, j, k, gr_solid, r, ix, iy, iz, nx, ny, nz,
          {
            ips = SubvectorEltIndex(ps_sub, i, j, 0);
            x = RealSpaceX(i, SubgridRX(subgrid));
            //data[ips] = sin(x)/8.0 + (1/8)*pow(x,-(7/8)) +sin(x/5.0)/(5.0*8.0);
            data[ips] = value;
          });
        }
      }

      break;
    }     /* End case 0 */
コード例 #11
0
void          BCPhaseSaturation(
                                Vector *     saturation,
                                int          phase,
                                GrGeomSolid *gr_domain)
{
  PFModule       *this_module = ThisPFModule;
  PublicXtra     *public_xtra = (PublicXtra*)PFModulePublicXtra(this_module);

  Type0          *dummy0;
  Type1          *dummy1;
  Type2          *dummy2;

  int num_patches = (public_xtra->num_patches);
  int            *patch_indexes = (public_xtra->patch_indexes);
  int            *input_types = (public_xtra->input_types);
  int            *bc_types = (public_xtra->bc_types);

  Grid           *grid = VectorGrid(saturation);
  SubgridArray   *subgrids = GridSubgrids(grid);

  Subgrid        *subgrid;

  Subvector      *sat_sub;
  double         *satp;

  BCStruct       *bc_struct;

  int patch_index;

  int nx_v, ny_v, nz_v;
  int sx_v, sy_v, sz_v;

  int            *fdir;

  int indx, ipatch, is, i, j, k, ival, iv, sv;


  /*-----------------------------------------------------------------------
   * Get an offset into the PublicXtra data
   *-----------------------------------------------------------------------*/

  indx = (phase * num_patches);

  /*-----------------------------------------------------------------------
   * Set up bc_struct with NULL values component
   *-----------------------------------------------------------------------*/

  bc_struct = NewBCStruct(subgrids, gr_domain,
                          num_patches, patch_indexes, bc_types, NULL);

  /*-----------------------------------------------------------------------
   * Implement BC's
   *-----------------------------------------------------------------------*/

  for (ipatch = 0; ipatch < num_patches; ipatch++)
  {
    patch_index = patch_indexes[ipatch];

    ForSubgridI(is, subgrids)
    {
      subgrid = SubgridArraySubgrid(subgrids, is);


      sat_sub = VectorSubvector(saturation, is);

      nx_v = SubvectorNX(sat_sub);
      ny_v = SubvectorNY(sat_sub);
      nz_v = SubvectorNZ(sat_sub);

      sx_v = 1;
      sy_v = nx_v;
      sz_v = ny_v * nx_v;

      satp = SubvectorData(sat_sub);

      switch (input_types[indx + ipatch])
      {
        case 0:
        {
          double constant;


          dummy0 = (Type0*)(public_xtra->data[indx + ipatch]);

          constant = (dummy0->constant);

          BCStructPatchLoop(i, j, k, fdir, ival, bc_struct, ipatch, is,
          {
            sv = 0;
            if (fdir[0])
              sv = fdir[0] * sx_v;
            else if (fdir[1])
              sv = fdir[1] * sy_v;
            else if (fdir[2])
              sv = fdir[2] * sz_v;

            iv = SubvectorEltIndex(sat_sub, i, j, k);

            satp[iv       ] = constant;
            satp[iv + sv] = constant;
            satp[iv + 2 * sv] = constant;
          });

          break;
        }

        case 1:
        {
          double height;
          double lower;
          double upper;

          double z, dz2;


          dummy1 = (Type1*)(public_xtra->data[indx + ipatch]);

          height = (dummy1->height);
          lower = (dummy1->lower);
          upper = (dummy1->upper);

          dz2 = SubgridDZ(subgrid) / 2.0;

          BCStructPatchLoop(i, j, k, fdir, ival, bc_struct, ipatch, is,
          {
            sv = 0;
            if (fdir[0])
              sv = fdir[0] * sx_v;
            else if (fdir[1])
              sv = fdir[1] * sy_v;
            else if (fdir[2])
              sv = fdir[2] * sz_v;

            iv = SubvectorEltIndex(sat_sub, i, j, k);

            z = RealSpaceZ(k, SubgridRZ(subgrid)) + fdir[2] * dz2;

            if (z <= height)
            {
              satp[iv       ] = lower;
              satp[iv + sv] = lower;
              satp[iv + 2 * sv] = lower;
            }
            else
            {
              satp[iv       ] = upper;
              satp[iv + sv] = upper;
              satp[iv + 2 * sv] = upper;
            }
          });

          break;
        }

        case 2:
        {
          int ip, num_points;
          double  *point;
          double  *height;
          double lower;
          double upper;

          double x, y, z, dx2, dy2, dz2;
          double unitx, unity, line_min, line_length, xy, slope;
          double interp_height;


          dummy2 = (Type2*)(public_xtra->data[indx + ipatch]);

          num_points = (dummy2->num_points);
          point = (dummy2->point);
          height = (dummy2->height);
          lower = (dummy2->lower);
          upper = (dummy2->upper);

          dx2 = SubgridDX(subgrid) / 2.0;
          dy2 = SubgridDY(subgrid) / 2.0;
          dz2 = SubgridDZ(subgrid) / 2.0;

          /* compute unit direction vector for piecewise linear line */
          unitx = (dummy2->xupper) - (dummy2->xlower);
          unity = (dummy2->yupper) - (dummy2->ylower);
          line_length = sqrt(unitx * unitx + unity * unity);
          unitx /= line_length;
          unity /= line_length;
          line_min = (dummy2->xlower) * unitx + (dummy2->ylower) * unity;

          BCStructPatchLoop(i, j, k, fdir, ival, bc_struct, ipatch, is,
          {
            sv = 0;
            if (fdir[0])
              sv = fdir[0] * sx_v;
            else if (fdir[1])
              sv = fdir[1] * sy_v;
            else if (fdir[2])
              sv = fdir[2] * sz_v;

            iv = SubvectorEltIndex(sat_sub, i, j, k);

            x = RealSpaceX(i, SubgridRX(subgrid)) + fdir[0] * dx2;
            y = RealSpaceY(j, SubgridRY(subgrid)) + fdir[1] * dy2;
            z = RealSpaceZ(k, SubgridRZ(subgrid)) + fdir[2] * dz2;

            /* project center of BC face onto piecewise linear line */
            xy = x * unitx + y * unity;
            xy = (xy - line_min) / line_length;

            /* find two neighboring points */
            ip = 1;
            for (; ip < (num_points - 1); ip++)
            {
              if (xy < point[ip])
                break;
            }

            /* compute the slope */
            slope = ((height[ip] - height[ip - 1]) /
                     (point[ip] - point[ip - 1]));

            interp_height = height[ip - 1] + slope * (xy - point[ip - 1]);

            if (z <= interp_height)
            {
              satp[iv       ] = lower;
              satp[iv + sv] = lower;
              satp[iv + 2 * sv] = lower;
            }
            else
            {
              satp[iv       ] = upper;
              satp[iv + sv] = upper;
              satp[iv + 2 * sv] = upper;
            }
          });

          break;
        }
コード例 #12
0
ファイル: compute_top.c プロジェクト: cvoter/Parflow
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;
      }
    });
コード例 #13
0
void    PermeabilityFace(
   Vector *zperm,
   Vector *permeability)
{
   PFModule      *this_module      = ThisPFModule;
   InstanceXtra  *instance_xtra    = (InstanceXtra  *)PFModuleInstanceXtra(this_module);
   PublicXtra   *public_xtra       = (PublicXtra   *)PFModulePublicXtra(this_module);

   Grid         *z_grid   = (instance_xtra -> z_grid);

   VectorUpdateCommHandle   *handle;

   SubgridArray *subgrids;
   Subgrid      *subgrid;

   Subvector    *subvector_pc, *subvector_pf;

   int           ix, iy, iz;
   int           nx, ny, nz;
   double        dx, dy, dz;

   int           nx_pc, ny_pc, nz_pc;
   int           nx_pf, ny_pf, nz_pf;

   int           pci, pfi;

   int           sg, i, j, k;
   int           flopest;

   double       *pf,  *pc_l, *pc_u;

   /*-----------------------------------------------------------------------
    * Begin timing
    *-----------------------------------------------------------------------*/

    BeginTiming(public_xtra -> time_index);

   /*-----------------------------------------------------------------------
    * exchange boundary data for cell permeability values
    *-----------------------------------------------------------------------*/
   handle = InitVectorUpdate(permeability, VectorUpdateAll);
   FinalizeVectorUpdate(handle);

   /*-----------------------------------------------------------------------
    * compute the z-face permeabilities for each subgrid
    *-----------------------------------------------------------------------*/

   subgrids = GridSubgrids(z_grid);
   ForSubgridI(sg, subgrids)
   {
      subgrid = SubgridArraySubgrid(subgrids, sg);

      subvector_pc    = VectorSubvector(permeability, sg);
      subvector_pf    = VectorSubvector(zperm, sg);

      ix = SubgridIX(subgrid);
      iy = SubgridIY(subgrid);
      iz = SubgridIZ(subgrid);

      nx = SubgridNX(subgrid);
      ny = SubgridNY(subgrid);
      nz = SubgridNZ(subgrid);

      dx = SubgridDX(subgrid);
      dy = SubgridDY(subgrid);
      dz = SubgridDZ(subgrid);

      nx_pc = SubvectorNX(subvector_pc);
      ny_pc = SubvectorNY(subvector_pc);
      nz_pc = SubvectorNZ(subvector_pc);

      nx_pf = SubvectorNX(subvector_pf);
      ny_pf = SubvectorNY(subvector_pf);
      nz_pf = SubvectorNZ(subvector_pf);

      flopest = nx_pf * ny_pf * nz_pf;

      pc_l = SubvectorElt(subvector_pc, ix  ,iy  ,iz-1);
      pc_u = SubvectorElt(subvector_pc, ix  ,iy  ,iz  );

      pf = SubvectorElt(subvector_pf, ix  ,iy  ,iz);

      pci = 0; pfi = 0;

      BoxLoopI2(i,j,k,
                ix,iy,iz,nx,ny,nz,
                pci,nx_pc,ny_pc,nz_pc,1,1,1,
                pfi,nx_pf,ny_pf,nz_pf,1,1,1,
      {
         pf[pfi] = Mean( pc_l[pci], pc_u[pci] );
      });
コード例 #14
0
ファイル: pf_pfmg.c プロジェクト: parflow/parflow
void         PFMG(
                  Vector *soln,
                  Vector *rhs,
                  double  tol,
                  int     zero)
{
  (void)zero;

#ifdef HAVE_HYPRE
  PFModule           *this_module = ThisPFModule;
  InstanceXtra       *instance_xtra = (InstanceXtra*)PFModuleInstanceXtra(this_module);
  PublicXtra         *public_xtra = (PublicXtra*)PFModulePublicXtra(this_module);

  HYPRE_StructMatrix hypre_mat = instance_xtra->hypre_mat;
  HYPRE_StructVector hypre_b = instance_xtra->hypre_b;
  HYPRE_StructVector hypre_x = instance_xtra->hypre_x;

  HYPRE_StructSolver hypre_pfmg_data = instance_xtra->hypre_pfmg_data;

  Grid               *grid = VectorGrid(rhs);
  Subgrid            *subgrid;
  int sg;

  Subvector          *rhs_sub;
  Subvector          *soln_sub;

  double             *rhs_ptr;
  double             *soln_ptr;
  double value;

  int index[3];

  int ix, iy, iz;
  int nx, ny, nz;
  int nx_v, ny_v, nz_v;
  int i, j, k;
  int iv;

  int num_iterations;
  double rel_norm;

  /* Copy rhs to hypre_b vector. */
  BeginTiming(public_xtra->time_index_copy_hypre);

  ForSubgridI(sg, GridSubgrids(grid))
  {
    subgrid = SubgridArraySubgrid(GridSubgrids(grid), sg);
    rhs_sub = VectorSubvector(rhs, sg);

    rhs_ptr = SubvectorData(rhs_sub);

    ix = SubgridIX(subgrid);
    iy = SubgridIY(subgrid);
    iz = SubgridIZ(subgrid);

    nx = SubgridNX(subgrid);
    ny = SubgridNY(subgrid);
    nz = SubgridNZ(subgrid);

    nx_v = SubvectorNX(rhs_sub);
    ny_v = SubvectorNY(rhs_sub);
    nz_v = SubvectorNZ(rhs_sub);

    iv = SubvectorEltIndex(rhs_sub, ix, iy, iz);

    BoxLoopI1(i, j, k, ix, iy, iz, nx, ny, nz,
              iv, nx_v, ny_v, nz_v, 1, 1, 1,
    {
      index[0] = i;
      index[1] = j;
      index[2] = k;

      HYPRE_StructVectorSetValues(hypre_b, index, rhs_ptr[iv]);
    });
コード例 #15
0
void          TurningBandsRF(
GeomSolid    *geounit,
GrGeomSolid  *gr_geounit,
Vector       *field,
RFCondData   *cdata)
{
   PFModule      *this_module   = ThisPFModule;
   PublicXtra    *public_xtra   = (PublicXtra *)PFModulePublicXtra(this_module);
   InstanceXtra  *instance_xtra = (InstanceXtra *)PFModuleInstanceXtra(this_module);

   double      lambdaX    = (public_xtra -> lambdaX);
   double      lambdaY    = (public_xtra -> lambdaY);
   double      lambdaZ    = (public_xtra -> lambdaZ);
   double      mean       = (public_xtra -> mean);
   double      sigma      = (public_xtra -> sigma);
   int         num_lines  = (public_xtra -> num_lines);
   double      rzeta      = (public_xtra -> rzeta);
   double      Kmax       = (public_xtra -> Kmax);
   double      dK         = (public_xtra -> dK);
   int         log_normal = (public_xtra -> log_normal);
   int         strat_type = (public_xtra -> strat_type);
   double      low_cutoff = (public_xtra -> low_cutoff);
   double      high_cutoff= (public_xtra -> high_cutoff);

   double      pi = acos(-1.0);

   Grid       *grid = (instance_xtra -> grid);

   Subgrid    *subgrid;
   Subvector  *field_sub;

   double      xlo, ylo, zlo, sh_zlo;
   double      xhi, yhi, zhi, sh_zhi;

   int	       ix, iy, iz;
   int         nx, ny, nz;
   int         r;
   double      dx, dy, dz;

   double      phi, theta;
   double     *theta_array, *phi_array;

   double      unitx, unity, unitz;

   double    **shear_arrays, *shear_array;
   double     *shear_min, *shear_max;

   double      zeta, dzeta;
   int         izeta, nzeta;

   double     *Z;

   int         is, l, i, j, k;
   int	       index;
   int         doing_TB;
   double      x, y, z;
   double     *fieldp;
   double      sqrtnl;

   Statistics *stats;


   /*-----------------------------------------------------------------------
    * start turning bands algorithm
    *-----------------------------------------------------------------------*/

   /* initialize random number generator */
   SeedRand(public_xtra -> seed);

   /* malloc space for theta_array and phi_array */
   theta_array = talloc(double, num_lines);
   phi_array = talloc(double, num_lines);

   /* compute line directions */
   for (l = 0; l < num_lines; l++)
   {
      theta_array[l] = 2.0*pi*Rand();
      phi_array[l] = acos(1.0 - 2.0*Rand());
   }

   /*-----------------------------------------------------------------------
    * Determine by how much to shear the field:
    *   If there is no GeomSolid representation of the geounit, then
    *   we do regular turning bands (by setting the shear_arrays to
    *   all zeros).
    *-----------------------------------------------------------------------*/
   
   /* Do regular turning bands */
   if ( (strat_type == 0) || (!geounit) )
   {
      shear_arrays = ctalloc(double *, GridNumSubgrids(grid));
      shear_min    = ctalloc(double,   GridNumSubgrids(grid));
      shear_max    = ctalloc(double,   GridNumSubgrids(grid));

      ForSubgridI(is, GridSubgrids(grid))
      {
	 subgrid = GridSubgrid(grid, is);

	 shear_arrays[is] =
	    ctalloc(double, (SubgridNX(subgrid)*SubgridNY(subgrid)));
      }