00001 #include "conservativemethodforsystem.h"
00002 #include "numericmethods.h"
00003 #include "flashbase.h"
00004 #include "vecincbc.h"
00005 #include "arrayofvecdouble.h"
00006
00048 double ConservativeMethodForSystem::calculateTimeStep(OrthoMesh &mesh,double tEnd,double MaxCFL, const VecDouble &vPorosity, FaceFluxFunction &flux)
00049 {
00050 double dMinPor = NumericMethods::vectorMinValue(vPorosity);
00051 double dInvMinTravelTime;
00052
00053
00054 double dX = mesh.getDX()[0];
00055 double dY = mesh.getDX()[1];
00056 double dZ = mesh.getDX()[2];
00057
00058
00059 double MaxCharVel[3];
00060 flux.maxGlobalCharVelocity(MaxCharVel);
00061
00062
00063
00064
00065
00066 dInvMinTravelTime = fabs(MaxCharVel[X])/dX;
00067
00068
00069 dInvMinTravelTime = fmax(fabs(MaxCharVel[Y])/dY, dInvMinTravelTime);
00070
00071
00072 dInvMinTravelTime = fmax(fabs(MaxCharVel[Z])/dZ, dInvMinTravelTime);
00073
00074
00075 if (dInvMinTravelTime == 0)
00076 return tEnd;
00077
00078
00079
00080 if (tEnd == INFINITY)
00081 return dMinPor*MaxCFL/dInvMinTravelTime;
00082 else
00083 return tEnd/ceil(tEnd*dInvMinTravelTime/(dMinPor*MaxCFL));
00084
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00122 bool ConservativeMethodForSystem::getValuesOfTheFaceCells(OrthoMesh &mesh,VecIncBC &vbc,const ArrayOfVecDouble& cvcValues, Index face_index, Index negCell, Index posCell,VecDoubleRef &vSwNeg,VecDoubleRef &vSwPos)
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
00130 vcValues.getVecValues(posCell,&vSwPos);
00131
00132
00133 if (negCell != OrthoMesh::invalidIndex())
00134 {
00135 vcValues.getVecValues(negCell,&vSwNeg);
00136 return false;
00137 }
00138 else
00139 {
00140
00141
00142
00143
00144 if (vbc.get_ref_bc(face_index,vSwNeg))
00145 {
00146 return true;
00147 }
00148 else
00149 {
00150
00151 vcValues.getVecValues(posCell,&vSwNeg);
00152 return false;
00153 }
00154 }
00155 }
00156 else
00157 {
00158
00159
00160 vcValues.getVecValues(negCell,&vSwNeg);
00161
00162
00163
00164 if (vbc.get_ref_bc(face_index,vSwPos))
00165 {
00166 return true;
00167 }
00168 else
00169 {
00170
00171 vcValues.getVecValues(negCell,&vSwPos);
00172 return false;
00173 }
00174 }
00175 assert(0);
00176 return false;
00177 }
00178
00179 bool ConservativeMethodForSystem::getValuesOfTheFaceCellsScalar(OrthoMesh &mesh,VecIncBC &vbc,const VecDouble &cValues, Index face_index, Index negCell, Index posCell,double *dNeg,double *dPos)
00180 {
00181 bool result=false;
00182 static VecDouble vSw(1);
00183 assert(vbc.bc_dim()==1);
00184 if (posCell != OrthoMesh::invalidIndex())
00185 {
00186
00187 *dPos = cValues(posCell);
00188
00189
00190 if (negCell != OrthoMesh::invalidIndex())
00191 *dNeg=cValues(negCell);
00192 else
00193 {
00194
00195
00196
00197
00198 if (vbc.copy_bc(face_index,vSw))
00199 {
00200 result=true;
00201 *dNeg=vSw(0);
00202 }
00203 else
00204 {
00205
00206 *dNeg=*dPos;
00207 }
00208 }
00209 }
00210 else
00211 {
00212
00213
00214 *dNeg = cValues(negCell);
00215
00216
00217
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 }
00231
00232
00233
00234
00241 void ConservativeMethodForSystem::buildDerivatives(OrthoMesh &mesh,const VecDouble &cV,Matrix &MG)
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 }
00259
00260
00261
00270 void ConservativeMethodForSystem::getCellDerivatives(const VecDouble &sol,const OrthoMesh::Cell_It &cell,double *s0,double *s1, double *s2)
00271 {
00272
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 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311