#include <conservativemethodforsystem.h>
Public Member Functions | |
ConservativeMethodForSystem () | |
virtual | ~ConservativeMethodForSystem () |
virtual void | updateFixedPressureBC (Function3D *fDP, FlashCompositional &flash)=0 |
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) |
bool | getValuesOfTheFaceCells (OrthoMesh &mesh, VecIncBC &vbc, const ArrayOfVecDouble &vcValues, Index face_index, Index negCell, Index posCell, VecDoubleRef &vSwNeg, VecDoubleRef &vSwPos) |
bool | getValuesOfTheFaceCellsScalar (OrthoMesh &mesh, VecIncBC &vbc, const VecDouble &cValues, Index face_index, Index negCell, Index posCell, double *dNeg, double *dPos) |
double | calculateTimeStep (OrthoMesh &mesh, double tEnd, double MaxCFL, const VecDouble &vPorosity, FaceFluxFunction &flux) |
The base class of all conservative methods for hyperbolic systems. See Leveque for a definition of conservative method. This class implement some methods common to all classes that solve the system of hyperbolic equations of the form 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 its methods usually uses reference for an OrtoMesh object.
Definition at line 22 of file conservativemethodforsystem.h.
ConservativeMethodForSystem::ConservativeMethodForSystem | ( | ) | [inline] |
Definition at line 38 of file conservativemethodforsystem.h.
virtual ConservativeMethodForSystem::~ConservativeMethodForSystem | ( | ) | [inline, virtual] |
Definition at line 39 of file conservativemethodforsystem.h.
void ConservativeMethodForSystem::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 241 of file conservativemethodforsystem.cpp.
00242 { 00243 00244 assert(MG.m() == mesh.numCells()); 00245 assert(MG.n() == 3); 00246 assert(cV.size() == mesh.numCells()); 00247 00248 OrthoMesh::Cell_It cell = mesh.begin_cell(); 00249 OrthoMesh::Cell_It endc = mesh.end_cell(); 00250 double s0,s1,s2; 00251 for (;cell != endc; cell++) 00252 { 00253 getCellDerivatives(cV,cell,&s0,&s1,&s2); 00254 MG(cell->index(),0)=s0; 00255 MG(cell->index(),1)=s1; 00256 MG(cell->index(),2)=s2; 00257 } 00258 }
double ConservativeMethodForSystem::calculateTimeStep | ( | OrthoMesh & | mesh, | |
double | tEnd, | |||
double | MaxCFL, | |||
const VecDouble & | vPorosity, | |||
FaceFluxFunction & | flux | |||
) | [protected] |
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 | Vector to contain the value for the cell in the negative direction from the face for each component of the system. | |
SwPos | Vector to contain the value for the cell in the positive direction from the face for each component of the system. |
void ConservativeMethodForSystem::getValuesOfTheFaceCells(OrthoMesh &mesh, const VecIncBC &vbc, const ArrayOfVectors& vcValues, Index face_index, Index negCell, Index posCell, VecDouble &vSwNeg,VecDouble &vSwPos) { check vector dimensions const unsigned n_components = vSwPos.size(); assert(vfBCValues.size() == n_components); assert(vSwNeg.size() == n_components); assert(vcValues.size() == n_components);
for each variable (component) of the system for (unsigned cmp=0;cmp<n_components;cmp++) { getValuesOfTheFaceCells(mesh,vfBCValues[cmp],vcValues[cmp],face_index,negCell,posCell,vSwNeg(cmp),vSwPos(cmp)); } } Calculate the time step to advance the transport method. The time step is returned as a multiple of tEnd If tEnd == INFINITY, than the procedure returns an exact mathc for the time step
mesh | ||
tEnd | Amount of time the transport should iterate | |
MaxCFL | ||
vPorosity | ||
flux |
Definition at line 48 of file conservativemethodforsystem.cpp.
00049 { 00050 double dMinPor = NumericMethods::vectorMinValue(vPorosity); 00051 double dInvMinTravelTime; //Travel time is the time the solution needs to cross a cell. 00052 00053 //Get the discretization steps in each dimension 00054 double dX = mesh.getDX()[0]; 00055 double dY = mesh.getDX()[1]; 00056 double dZ = mesh.getDX()[2]; 00057 00058 //Get the maximum chracteristic velocity in the three components 00059 double MaxCharVel[3]; 00060 flux.maxGlobalCharVelocity(MaxCharVel); 00061 00062 //To avoid division by zero we calculate the inverse 00063 //of the min travel time and then we invert the number. 00064 00065 //Min time to cross a cell in the X direction 00066 dInvMinTravelTime = fabs(MaxCharVel[X])/dX; 00067 00068 //Min time to cross a cell in the Y direction 00069 dInvMinTravelTime = fmax(fabs(MaxCharVel[Y])/dY, dInvMinTravelTime); 00070 00071 //Min time to cross a cell in the Z direction 00072 dInvMinTravelTime = fmax(fabs(MaxCharVel[Z])/dZ, dInvMinTravelTime); 00073 00074 00075 if (dInvMinTravelTime == 0) 00076 return tEnd; 00077 00078 //double dTravelTime = 1.0/dInvMinTravelTime; 00079 00080 if (tEnd == INFINITY) 00081 return dMinPor*MaxCFL/dInvMinTravelTime; 00082 else 00083 return tEnd/ceil(tEnd*dInvMinTravelTime/(dMinPor*MaxCFL)); 00084 00085 }
void ConservativeMethodForSystem::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 270 of file conservativemethodforsystem.cpp.
00271 { 00272 //Derivative for x 00273 const OrthoMesh &mesh=cell->getMesh(); 00274 Index li,ri; 00275 double u = sol(cell->index()); 00276 li = cell->neighbor_index(LEFT_CELL); 00277 ri = cell->neighbor_index(RIGHT_CELL); 00278 if (li == OrthoMesh::INVALID_INDEX || ri == OrthoMesh::INVALID_INDEX) 00279 *s0 = 0.0; 00280 else 00281 *s0=NumericMethods::minMod(u-sol(li),sol(ri)-u)/mesh.get_dx(); 00282 00283 00284 li = cell->neighbor_index(FRONT_CELL); 00285 ri = cell->neighbor_index(BACK_CELL); 00286 if (li == OrthoMesh::INVALID_INDEX || ri == OrthoMesh::INVALID_INDEX) 00287 *s1 = 0.0; 00288 else 00289 *s1=NumericMethods::minMod(u-sol(li),sol(ri)-u)/mesh.get_dy(); 00290 00291 li = cell->neighbor_index(BOTTOM_CELL); 00292 ri = cell->neighbor_index(UP_CELL); 00293 if (li == OrthoMesh::INVALID_INDEX || ri == OrthoMesh::INVALID_INDEX) 00294 *s2 = 0.0; 00295 else 00296 *s2=NumericMethods::minMod(u-sol(li),sol(ri)-u)/mesh.get_dz(); 00297 }
bool ConservativeMethodForSystem::getValuesOfTheFaceCells | ( | OrthoMesh & | mesh, | |
VecIncBC & | vbc, | |||
const ArrayOfVecDouble & | cvcValues, | |||
Index | face_index, | |||
Index | negCell, | |||
Index | posCell, | |||
VecDoubleRef & | vSwNeg, | |||
VecDoubleRef & | vSwPos | |||
) | [protected] |
Usefull method to get the Solution of the cells located between a face. This method consider the boundary condition information stored in the parameter vbc to get always valid values, even for the faces in the boundary. For a face inside the domain it just return the values based on the solution passed in the cvcValues parameter.
If the face is at boundary, and there is no boundary condition prescribed the value of the cell out of the mesh is equal to the value of the cell inside the mesh. This is called a mirror condition
If there is a boundary condition, this value is returned.
mesh | The OrthoMesh | |
vbc | Vector containing the bc info | |
cvcValues | ArrayOfVectors containing the solution for each component of the solution (Remember that we are solving a system of equations) | |
face | The index of the face | |
negCell | The cell on the negative side of the face, -1 if it does not exist (Remember: face can be on the boundary) | |
posCell | The cell on the positive side of the face, -1 if it does not exist (Remember: face can be on the boundary) | |
vSwNeg | To contain the solution of the negative cell | |
vSwPos | To contain the solution of the positive cell |
Definition at line 122 of file conservativemethodforsystem.cpp.
00123 { 00124 ArrayOfVecDouble &vcValues=const_cast<ArrayOfVecDouble&>(cvcValues); 00125 assert(vSwNeg.size() == vbc.bc_dim()); 00126 assert(vSwPos.size() == vbc.bc_dim()); 00127 if (posCell != OrthoMesh::invalidIndex()) 00128 { 00129 //get the positive value 00130 vcValues.getVecValues(posCell,&vSwPos); 00131 00132 //get the negative value if it exist 00133 if (negCell != OrthoMesh::invalidIndex()) 00134 { 00135 vcValues.getVecValues(negCell,&vSwNeg); 00136 return false; 00137 } 00138 else 00139 { 00140 00141 //if the neg value doesnt exist, 00142 //try to see if there is boundary condition 00143 //for the face 00144 if (vbc.get_ref_bc(face_index,vSwNeg)) 00145 { 00146 return true; 00147 } 00148 else 00149 { 00150 //If not use mirror condition 00151 vcValues.getVecValues(posCell,&vSwNeg); 00152 return false; 00153 } 00154 } 00155 } 00156 else 00157 { 00158 //The positive value does not exist, 00159 //So the Negative value must exist. Get it 00160 vcValues.getVecValues(negCell,&vSwNeg); 00161 00162 //Now take the value for SwPos from the boundary 00163 //condition or make it equal to the value of the negative cell. 00164 if (vbc.get_ref_bc(face_index,vSwPos)) //Ok BC exists 00165 { 00166 return true; 00167 } 00168 else 00169 { 00170 //If not use mirror condition 00171 vcValues.getVecValues(negCell,&vSwPos); 00172 return false; 00173 } 00174 } 00175 assert(0); 00176 return false; 00177 }
bool ConservativeMethodForSystem::getValuesOfTheFaceCellsScalar | ( | OrthoMesh & | mesh, | |
VecIncBC & | vbc, | |||
const VecDouble & | cValues, | |||
Index | face_index, | |||
Index | negCell, | |||
Index | posCell, | |||
double * | dNeg, | |||
double * | dPos | |||
) | [protected] |
Definition at line 179 of file conservativemethodforsystem.cpp.
00180 { 00181 bool result=false; 00182 static VecDouble vSw(1); 00183 assert(vbc.bc_dim()==1); 00184 if (posCell != OrthoMesh::invalidIndex()) 00185 { 00186 //get the positive value 00187 *dPos = cValues(posCell); 00188 00189 //get the negative value if it exist 00190 if (negCell != OrthoMesh::invalidIndex()) 00191 *dNeg=cValues(negCell); 00192 else 00193 { 00194 00195 //if the neg value doesnt exist, 00196 //try to see if there is boundary condition 00197 //for the face 00198 if (vbc.copy_bc(face_index,vSw)) 00199 { 00200 result=true; 00201 *dNeg=vSw(0); 00202 } 00203 else 00204 { 00205 //If not use mirror condition 00206 *dNeg=*dPos; 00207 } 00208 } 00209 } 00210 else 00211 { 00212 //The positive value does not exist, 00213 //So the Negative value must exist. Get it 00214 *dNeg = cValues(negCell); 00215 00216 //Now take the value for SwPos from the boundary 00217 //condition or make it equal to the value of the negative cell. 00218 if (vbc.copy_bc(face_index,vSw)) 00219 { 00220 *dPos=vSw(0); 00221 result=true; 00222 } 00223 else 00224 { 00225 *dPos=*dNeg; 00226 } 00227 } 00228 return result; 00229 00230 }
virtual void ConservativeMethodForSystem::updateFixedPressureBC | ( | Function3D * | fDP, | |
FlashCompositional & | flash | |||
) | [pure virtual] |
Implemented in LaxFriedrichsForSystem.