[pooma-dev] Chevron Code Using New Field Abstractions

Jeffrey Oldham oldham at codesourcery.com
Wed Jul 25 21:28:37 UTC 2001


I cleaned out the old code near the top of the file.

Jeffrey D. Oldham
oldham at codesourcery.com



-------------- next part --------------
// Oldham, Jeffrey D.
// 2001Jul25
// Pooma

// Chevron Kernel Written Using POOMA's Proposed Field Abstraction

#include <iostream>
#include <cstdlib>
#include "Pooma/NewFields.h"

// This program implements "Implementation of a Flux-Continuous Fnite
// Difference Method for Stratigraphic, Hexahedron Grids," by
// S. H. Lee, H. Tchelepi, and L. J. DeChant, \emph{1999 SPE Reservoir
// Simulation Symposium}, SPE (Society of Petroleum Engineers) 51901.

// Preprocessor symbols:
// PSEUDOCODE: Do not define this symbol.  Surrounds desired code to
//	       deal with different granularity fields.
// DEBUG: If defined, print some information about internal program
//	  values.


/** THE PROGRAM **/

int main(int argc, char *argv[])
{
  // Set up the Pooma library.
  Pooma::initialize(argc,argv);
#ifdef DEBUG
  std::cout << "Start program." << std::endl;
#endif // DEBUG

  /* DECLARATIONS */

  // Create a simple layout.
  const unsigned Dim = 2;		// Work in a 2D world.
  const unsigned nXs = 5;		// number of horizontal vertices
  const unsigned nYs = 4;		// number of vertical vertices
  Interval<Dim> meshDomain;
  meshDomain[0] = Interval<1>(nXs);
  meshDomain[1] = Interval<1>(nYs);
  DomainLayout<Dim> meshLayout(meshDomain, GuardLayers<Dim>(1));

  // Preparation for Field creation.

  Vector<Dim> origin(0.0);
  Vector<Dim> spacings(1.0,1.0);
  typedef UniformRectilinear<Dim, double, Cartesian<Dim> > Geometry_t;
  typedef Field<Geometry_t, double, Brick> Fields_t;
  typedef Field<Geometry_t, double, Brick> ConstFields_t; // TODO: Change to ConstField when ConstField is available.
  typedef Tensor<Dim,double,Full> Tensor_t;
  typedef Field<Geometry_t, Tensor_t, Brick> FieldT_t;
  typedef Field<Geometry_t, Tensor_t, Brick> ConstFieldT_t; // TODO: Change to ConstField when ConstField is available.
  typedef Field<Geometry_t, Vector<Dim>, Brick> Fieldv_t;
  typedef Field<Geometry_t, Vector<Dim>, Brick> ConstFieldv_t; // TODO: Change to ConstField when ConstField is available.

  // Cell-centered Fields.

  Centering<Dim> cell = canonicalCentering<Dim>(CellType, Continuous);
  ConstFieldT_t permeability	(cell, meshLayout, origin, spacings);
  ConstFields_t pressure	(cell, meshLayout, origin, spacings);
  Fields_t totalFlux		(cell, meshLayout, origin, spacings);

  // Subcell-centered Field.

  typedef Centering<Dim>::Orientation Orientation;
  typedef Centering<Dim>::Position Position;
  Position position;
  Centering<Dim> subcell(CellType, Continuous);
  position(0) = 0.25;
  position(1) = 0.25; subcell.addValue(Orientation(1), position);
  position(1) = 0.75; subcell.addValue(Orientation(1), position);
  position(0) = 0.75; subcell.addValue(Orientation(1), position);
  position(1) = 0.25; subcell.addValue(Orientation(1), position);
  Fields_t pressureGradient	(subcell, meshLayout, origin, spacings);

  // Spoke-centered Field.

  Centering<Dim> spoke(FaceType, Discontinuous);
  // QUESTION: These are supposed to be Discontinuous, right?
  Orientation orientation;
  // NOTE: This code is not dimension-independent.
  for (int zeroFace = 0; zeroFace < 2; ++zeroFace) {
    orientation = 1; orientation[zeroFace] = 0;
    position(zeroFace) = 0.0;
    position(1-zeroFace) = 0.25; spoke.addValue(orientation, position);
    position(1-zeroFace) = 0.75; spoke.addValue(orientation, position);
    position(zeroFace) = 1.0;
    position(1-zeroFace) = 0.25; spoke.addValue(orientation, position);
    position(1-zeroFace) = 0.75; spoke.addValue(orientation, position);
  }
  Fields_t spokeFlux		(spoke, meshLayout, origin, spacings);

  // Face-centered.

  Centering<Dim> disFace = canonicalCentering<Dim>(FaceType, Discontinuous);


  /* INITIALIZATION */

#ifdef PSEUDOCODE
  // Initialize tensors.
  // Initialize the pressures.
  // Initialize coordinates.
#endif // PSEUDOCODE


  /* COMPUTATION */

#ifdef PSEUDOCODE
  // Compute pressureGradients by simultaneously solving several
  // linear equations.  The operands have different centerings.
  // FIXME
  pressureGradients =
    linearAlgebra<2>(pressure /* cell-centered */,
		     /* Interpolate from vertex-centered to cell-centered: */
		     interpolate<Cell,Vertex>(coordinates),
		     permeability /* cell-centered */,
		     normals /* face-centered */);
#endif // PSEUDOCODE

  // Compute the spoke fluxes.

  // We must multiply three quantities, each with a different
  // centering, to yield values at a fourth-centering.  permeability
  // is cell-centered.  pressureGradient is subcell-centered.  The
  // normals are face-centered.  The product is spoke-centered.

  spokeFlux = 
    dot(replicate(dot(replicate(permeability, nearestNeighbors(cell, subcell)),
		      pressureGradient),
		  nearestNeighbors(subcell, spoke)),
	replicate(meshLayout.unitCoordinateNormals(),
		  nearestNeighbors(disFace, spoke)));

  // Sum the spoke fluxes into a cell flux.

  // Q = \sum_{faces f of cell} sign_f area_f \sum_{subfaces sf of f} q_{sf}
  // We compute this in three steps:
  // 1. Add together the flux values on each face to form a
  //    face-centered field.
  // 2. Multiply each value by the magnitude of the face's normal.
  // 3. Add together each face's value.

  totalFlux =
    sum(spokeFlux.mesh().normals().signedMagnitude() *
	sum(spokeFlux, nearestNeighbors(spoke, disFace)),
	findFieldOffsetList(disFace, cell));


  /* TERMINATION */

  std::cout << "total flux:\n" << totalFlux << std::endl;
#ifdef DEBUG
  std::cout << "End program." << std::endl;
#endif // DEBUG
  Pooma::finalize();
  return EXIT_SUCCESS;
}




More information about the pooma-dev mailing list