ConservativeMethod Class Reference

#include <conservativemethod.h>

Inheritance diagram for ConservativeMethod:
Inheritance graph
[legend]
Collaboration diagram for ConservativeMethod:
Collaboration graph
[legend]

List of all members.

Public Member Functions

void getValuesOfTheFaceCells (OrthoMesh &mesh, const VecDouble &fBCValues, const VecDouble &cValues, Index face_index, Index CellNeg, Index CellPos, double &SwNeg, double &SwPos)
void getValuesOfTheFaceCells (OrthoMesh &mesh, const VecDouble &fBCValues, const VecDouble &cValues, OrthoMesh::Cash_Face_It &face, double &SwNeg, double &SwPos)
void getValuesOfTheFaceCells (OrthoMesh &mesh, const VecDouble &fBCValues, const VecDouble &cValues, OrthoMesh::Face_It &face, double &SwNeg, double &SwPos)
double calculateTimeStep (OrthoMesh &mesh, double tEnd, double MaxCFL, const VecDouble &vPorosity, FaceFluxFunction &flux)
 ConservativeMethod ()
virtual ~ConservativeMethod ()

Protected Member Functions

void buildDerivatives (OrthoMesh &mesh, const VecDouble &cV, Matrix &MG)
void getCellDerivatives (const VecDouble &sol, const OrthoMesh::Cell_It &cell, double *s0, double *s1, double *s2)

Detailed Description

The base class of all conservative scalar methods. See Leveque for a definition of conservative method. This class implement some methods common to all classes that solve the hyperbolic equation doing expression Sw(n+1) = Sw(n) + div(NumericFlux) where the div are aproximated doing a computation along the cells of the grid.

This class assumes that we have an orthonormal uniform grid since it holds a reference for an OrtoMesh object.

Definition at line 17 of file conservativemethod.h.


Constructor & Destructor Documentation

ConservativeMethod::ConservativeMethod (  )  [inline]

Definition at line 32 of file conservativemethod.h.

00032 {}

virtual ConservativeMethod::~ConservativeMethod (  )  [inline, virtual]

Definition at line 33 of file conservativemethod.h.

00033 {}


Member Function Documentation

void ConservativeMethod::buildDerivatives ( OrthoMesh mesh,
const VecDouble cV,
Matrix MG 
) [protected]

Store the min mod derivatives of the three directions of each cell in a matrix with dimensions [NUM_CELLS][3]

Parameters:
cV Vector with solution in each cell
MG The matrix containing the derivatives.
Returns:

Definition at line 199 of file conservativemethod.cpp.

00200 {
00201  
00202   assert(MG.m() == mesh.numCells());
00203   assert(MG.n() == 3);
00204   assert(cV.size() == mesh.numCells());
00205 
00206   OrthoMesh::Cell_It cell = mesh.begin_cell();
00207   OrthoMesh::Cell_It endc = mesh.end_cell();
00208   double s0,s1,s2;
00209   for (;cell != endc; cell++)
00210   {
00211     getCellDerivatives(cV,cell,&s0,&s1,&s2);
00212     MG(cell->index(),0)=s0;
00213     MG(cell->index(),1)=s1;
00214     MG(cell->index(),2)=s2;
00215   } 
00216 }

double ConservativeMethod::calculateTimeStep ( OrthoMesh mesh,
double  tEnd,
double  MaxCFL,
const VecDouble vPorosity,
FaceFluxFunction flux 
)

This function calculates the right time step to iterate throw t=0 to t=tEnd such that the Maximum CFL does not exceed the value of the parameter MaxCFL. For orthoMesh this is a easy calculation. The CFL condition for 1D states that Max(VelX) * dt < CFL *dX where dt,dx are the discretization in time and space and Max(VelX) is the maximum velocity of a characteristic line (in other way, the slope of the characteristic line in the time x space plane). For 3D orthogonal meshes in 3D this can be easy extended changing Max(VelX) to Max(VelX,VelY,VelZ) where X,Y,Z are the main axes. IN the case of immiscible flows VelX = fMobW*Vdt where fMob is the mobility function and Vdt is the velocity supplied by the dynamic modules. The calculation principles of these method follows for the case of immiscible flow. fMob(Sw)*Vdt *dt < MaxCFL*dX <=> (1) fMob(Sw)*(Vdt/dX) * dt < MaxCFL <=> (2) Max(fMob(Sw))* Max (Vdt/dX) * dt < MaxCFL (3) Substituting dt = tEnd/numSteps where the numSteps is the number of subdivisions in time, we have to find the max possible value of numSteps such that inequation (3) is obeyed.

Parameters:
tEnd The end time of the iteration
MaxCFL The Max CFL number the method should have at all domain
dMaxGradMobW The max derivative of the mobility function.
fVelocity The velocity field supplied by the dinamic module.
Returns:
The right time step;

Definition at line 159 of file conservativemethod.cpp.

00160 {
00161   double dMinPor = NumericMethods::vectorMinValue(vPorosity);
00162   double dMinTravelTime; //Travel time is the time the solution needs to cross a cell.
00163 
00164   //Get the discretization steps in each dimension
00165   double dX = mesh.getDX()[0];
00166   double dY = mesh.getDX()[1];
00167   double dZ = mesh.getDX()[2];
00168 
00169   //Get the maximum chracteristic velocity in the three components
00170   double MaxCharVel[3];
00171   flux.maxGlobalCharVelocity(MaxCharVel);
00172   dMinTravelTime=0.0;
00173 
00174   //Min time to cross a cell  in the X direction
00175   if (MaxCharVel[X] != 0.0)
00176     dMinTravelTime = dX/fabs(MaxCharVel[X]);
00177   printf("Max Vel %g %g %g\n",MaxCharVel[0],MaxCharVel[1],MaxCharVel[2]);
00178 
00179   //Min time to cross a cell  in the Y direction
00180   if (MaxCharVel[Y] != 0.0)
00181     dMinTravelTime = fmin(dY/fabs(MaxCharVel[Y]), dMinTravelTime);
00182 
00183  //Min time to cross a cell  in the Z direction
00184   if (MaxCharVel[Z] != 0.0)
00185     dMinTravelTime = fmin(dZ/fabs(MaxCharVel[Z]), dMinTravelTime);
00186 
00187  return tEnd/ceil(tEnd/(dMinPor*dMinTravelTime*MaxCFL));
00188  
00189 }

void ConservativeMethod::getCellDerivatives ( const VecDouble sol,
const OrthoMesh::Cell_It cell,
double *  s0,
double *  s1,
double *  s2 
) [protected]

Return the MinMod Derivatives of a Cell

Parameters:
sol = Solution
OrthoMesh mesh
s0 Derivative in X
s1 Derivative in Y
s2 Derivative in Z
Returns:

Definition at line 228 of file conservativemethod.cpp.

00229 {
00230   //Derivative for x
00231   const OrthoMesh &mesh=cell->getMesh();
00232   Index li,ri;
00233   double u = sol(cell->index());
00234   li = cell->neighbor_index(LEFT_CELL);
00235   ri = cell->neighbor_index(RIGHT_CELL);
00236   if (li == OrthoMesh::INVALID_INDEX || ri == OrthoMesh::INVALID_INDEX)
00237      *s0 = 0.0;
00238   else
00239     *s0=NumericMethods::minMod(u-sol(li),sol(ri)-u)/mesh.get_dx();
00240   
00241 
00242   li = cell->neighbor_index(FRONT_CELL);
00243   ri = cell->neighbor_index(BACK_CELL);
00244   if (li == OrthoMesh::INVALID_INDEX || ri == OrthoMesh::INVALID_INDEX)
00245      *s1 = 0.0;
00246   else
00247     *s1=NumericMethods::minMod(u-sol(li),sol(ri)-u)/mesh.get_dy();
00248 
00249   li = cell->neighbor_index(BOTTOM_CELL);
00250   ri = cell->neighbor_index(UP_CELL);
00251   if (li == OrthoMesh::INVALID_INDEX || ri == OrthoMesh::INVALID_INDEX)
00252      *s2 = 0.0;
00253   else
00254     *s2=NumericMethods::minMod(u-sol(li),sol(ri)-u)/mesh.get_dz();
00255 }

void ConservativeMethod::getValuesOfTheFaceCells ( OrthoMesh mesh,
const VecDouble fBCValues,
const VecDouble cValues,
OrthoMesh::Face_It face,
double &  SwNeg,
double &  SwPos 
)

Definition at line 95 of file conservativemethod.cpp.

00096 {
00097   assert(fBCValues.size() == mesh.numFaces());
00098   assert(cValues.size() == mesh.numCells());
00099   unsigned cPos,cNeg;
00100   face->getAdjCellIndices(cNeg,cPos);
00101 
00102   unsigned Null = OrthoMesh::invalidIndex();
00103   if (cPos != Null)
00104   {
00105     //get the positive value
00106     SwPos = cValues(cPos);
00107     //get the negative value if it exist
00108     if (cNeg != Null)
00109       SwNeg = cValues(cNeg);
00110     else
00111     {
00112 
00113       //if the neg value doesnt exist,
00114       //try to see if there is boundary condition
00115       //for the face
00116       SwNeg = fBCValues(face->index());
00117       if (SwNeg == INFINITY) //boundary condition is not defined ?
00118         SwNeg = SwPos; //If not exist boundary condition, use the value of the positive cell
00119     }
00120   }
00121   else
00122   {
00123     //The positive value does not exist,
00124     //So the Negative value must exist. Get it
00125     SwNeg = cValues(cNeg);
00126 
00127     //Now take the value for SwPos from the boundary
00128     //condition or make it equal to the value of the negative cell.
00129     SwPos = fBCValues(face->index());
00130     if (SwPos == INFINITY) //Is boundary condition not defined ?
00131       SwPos = SwNeg;
00132   }
00133 }

void ConservativeMethod::getValuesOfTheFaceCells ( OrthoMesh mesh,
const VecDouble fBCValues,
const VecDouble cValues,
OrthoMesh::Cash_Face_It face,
double &  SwNeg,
double &  SwPos 
)

Definition at line 54 of file conservativemethod.cpp.

00055 {
00056   assert(fBCValues.size() == mesh.numFaces());
00057   assert(cValues.size() == mesh.numCells());
00058   unsigned cPos,cNeg;
00059   face->getAdjCellIndices(cNeg,cPos);
00060 
00061   unsigned Null = OrthoMesh::invalidIndex();
00062   if (cPos != Null)
00063   {
00064     //get the positive value
00065     SwPos = cValues(cPos);
00066     //get the negative value if it exist
00067     if (cNeg != Null)
00068       SwNeg = cValues(cNeg);
00069     else
00070     {
00071 
00072       //if the neg value doesnt exist,
00073       //try to see if there is boundary condition
00074       //for the face
00075       SwNeg = fBCValues(face->index());
00076       if (SwNeg == INFINITY) //boundary condition is not defined ?
00077         SwNeg = SwPos; //If not exist boundary condition, use the value of the positive cell
00078     }
00079   }
00080   else
00081   {
00082     //The positive value does not exist,
00083     //So the Negative value must exist. Get it
00084     SwNeg = cValues(cNeg);
00085 
00086     //Now take the value for SwPos from the boundary
00087     //condition or make it equal to the value of the negative cell.
00088     SwPos = fBCValues(face->index());
00089     if (SwPos == INFINITY) //Is boundary condition not defined ?
00090       SwPos = SwNeg;
00091   }
00092 }

void ConservativeMethod::getValuesOfTheFaceCells ( OrthoMesh mesh,
const VecDouble fBCValues,
const VecDouble cValues,
Index  face_index,
Index  cNeg,
Index  cPos,
double &  SwNeg,
double &  SwPos 
)

First of all, this is an internal method used to get the values in the left and in the right of a face. This function exist because there is complications to get this values from the cells adjacents to the faces at boundary. In this case the face has just one neighbour cell and the value in the other inexistent cell must be get from the boundary conditions for the face in the case that condition exist. If not exist we make the value of the inexistent cell (ghost cell) identical to the value of the cell inside the mesh.

Parameters:
face The face from wich we get the two values of saturation
SwNeg To contain the value in the vector cValues for the cell in the negative direction from the face.
SwPos To contain the value in the vector cValues for the cell in the positive direction from the face.

Definition at line 14 of file conservativemethod.cpp.

00015 {
00016   assert(fBCValues.size() == mesh.numFaces());
00017   assert(cValues.size() == mesh.numCells());
00018 
00019   static unsigned Null = OrthoMesh::invalidIndex();
00020   if (cNeg != Null)
00021   {
00022     //get the negative value
00023     SwNeg = cValues(cNeg);
00024 
00025     //get the positive value if it exist
00026     if (cPos != Null)
00027       SwPos = cValues(cPos);
00028     else
00029     {
00030 
00031       //if the pos value doesnt exist,
00032       //try to see if there is boundary condition
00033       //for the face
00034       SwPos = fBCValues(face_index);
00035       if (SwPos == INFINITY) //boundary condition is not defined ?
00036         SwPos=SwNeg; //If not exist boundary condition, use the value of the negative cell
00037     }
00038   }
00039   else
00040   {
00041     //The negative  value does not exist,
00042     //So the Positive value must exist. Get it
00043     SwPos = cValues(cPos);
00044 
00045     //Now take the value for SwNeg from the boundary
00046     //condition or make it equal to the value of the positive cell.
00047     SwNeg = fBCValues(face_index);
00048     if (SwNeg == INFINITY) //Is boundary condition not defined ?
00049       SwNeg = SwPos;
00050   }
00051 }


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Sun Apr 8 23:12:59 2012 for CO2INJECTION by  doxygen 1.6.3