00001 #include "conservativemethod.h"
00002 #include "numericmethods.h"
00003
00004
00014 void ConservativeMethod::getValuesOfTheFaceCells(OrthoMesh &mesh,const VecDouble &fBCValues,const VecDouble& cValues,Index face_index, Index cNeg,Index cPos,double &SwNeg,double &SwPos)
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
00023 SwNeg = cValues(cNeg);
00024
00025
00026 if (cPos != Null)
00027 SwPos = cValues(cPos);
00028 else
00029 {
00030
00031
00032
00033
00034 SwPos = fBCValues(face_index);
00035 if (SwPos == INFINITY)
00036 SwPos=SwNeg;
00037 }
00038 }
00039 else
00040 {
00041
00042
00043 SwPos = cValues(cPos);
00044
00045
00046
00047 SwNeg = fBCValues(face_index);
00048 if (SwNeg == INFINITY)
00049 SwNeg = SwPos;
00050 }
00051 }
00052
00053
00054 void ConservativeMethod::getValuesOfTheFaceCells(OrthoMesh &mesh,const VecDouble &fBCValues,const VecDouble& cValues,OrthoMesh::Cash_Face_It & face,double &SwNeg,double &SwPos)
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
00065 SwPos = cValues(cPos);
00066
00067 if (cNeg != Null)
00068 SwNeg = cValues(cNeg);
00069 else
00070 {
00071
00072
00073
00074
00075 SwNeg = fBCValues(face->index());
00076 if (SwNeg == INFINITY)
00077 SwNeg = SwPos;
00078 }
00079 }
00080 else
00081 {
00082
00083
00084 SwNeg = cValues(cNeg);
00085
00086
00087
00088 SwPos = fBCValues(face->index());
00089 if (SwPos == INFINITY)
00090 SwPos = SwNeg;
00091 }
00092 }
00093
00094
00095 void ConservativeMethod::getValuesOfTheFaceCells(OrthoMesh &mesh,const VecDouble &fBCValues,const VecDouble& cValues,OrthoMesh::Face_It & face,double &SwNeg,double &SwPos)
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
00106 SwPos = cValues(cPos);
00107
00108 if (cNeg != Null)
00109 SwNeg = cValues(cNeg);
00110 else
00111 {
00112
00113
00114
00115
00116 SwNeg = fBCValues(face->index());
00117 if (SwNeg == INFINITY)
00118 SwNeg = SwPos;
00119 }
00120 }
00121 else
00122 {
00123
00124
00125 SwNeg = cValues(cNeg);
00126
00127
00128
00129 SwPos = fBCValues(face->index());
00130 if (SwPos == INFINITY)
00131 SwPos = SwNeg;
00132 }
00133 }
00134
00135
00136
00137
00159 double ConservativeMethod::calculateTimeStep(OrthoMesh &mesh,double tEnd,double MaxCFL, const VecDouble &vPorosity, FaceFluxFunction &flux)
00160 {
00161 double dMinPor = NumericMethods::vectorMinValue(vPorosity);
00162 double dMinTravelTime;
00163
00164
00165 double dX = mesh.getDX()[0];
00166 double dY = mesh.getDX()[1];
00167 double dZ = mesh.getDX()[2];
00168
00169
00170 double MaxCharVel[3];
00171 flux.maxGlobalCharVelocity(MaxCharVel);
00172 dMinTravelTime=0.0;
00173
00174
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
00180 if (MaxCharVel[Y] != 0.0)
00181 dMinTravelTime = fmin(dY/fabs(MaxCharVel[Y]), dMinTravelTime);
00182
00183
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 }
00190
00191
00192
00199 void ConservativeMethod::buildDerivatives(OrthoMesh &mesh,const VecDouble &cV,Matrix &MG)
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 }
00217
00218
00219
00228 void ConservativeMethod::getCellDerivatives(const VecDouble &sol,const OrthoMesh::Cell_It &cell,double *s0,double *s1, double *s2)
00229 {
00230
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 }
00256
00257
00258