#include <conservativemethod.h>
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) |
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.
ConservativeMethod::ConservativeMethod | ( | ) | [inline] |
Definition at line 32 of file conservativemethod.h.
virtual ConservativeMethod::~ConservativeMethod | ( | ) | [inline, virtual] |
Definition at line 33 of file conservativemethod.h.
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]
cV | Vector with solution in each cell | |
MG | The matrix containing the derivatives. |
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.
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. |
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
sol | = Solution | |
OrthoMesh | mesh | |
s0 | Derivative in X | |
s1 | Derivative in Y | |
s2 | Derivative in Z |
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.
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 }