00001 #include "upwindforsystem.h"
00002 #include "numericmethods.h"
00003
00004
00005 UpwindForSystem::~UpwindForSystem()
00006 {
00007
00008 }
00009
00010 UpwindForSystem::UpwindForSystem(OrthoMesh &mesh,Function3D &fInitU,const VecDouble &cPor,Function3D &fPrescribedU,FaceFluxFunction &flux, FixedValueCondition &fixedC,double CFL,DiffusiveStep *diffStp)
00011 :LaxFriedrichsForSystem(mesh,fInitU,cPor,fPrescribedU,flux,fixedC,CFL)
00012 {
00013
00014 }
00015
00016
00017
00018
00019 void UpwindForSystem::iterateN(unsigned nSteps, double dt)
00020 {
00021 unsigned posCell,negCell;
00022
00023
00024
00025
00026
00027 VecDouble vBC(n_components),vFluxPos(n_components),vFluxNeg(n_components);
00028 VecDoubleRef vQPos(n_components),vQNeg(n_components);
00029
00030
00031 for (unsigned count = 0; count < nSteps; count++)
00032 {
00033
00034 OrthoMesh::Face_It face = m_mesh.begin_face();
00035 OrthoMesh::Face_It endf = m_mesh.end_face();
00036
00037
00038
00039
00040 m_solAnt = m_sol;
00041
00042
00043 for (;face!=endf;face++)
00044 {
00045
00046 face->getAdjCellIndices(negCell,posCell);
00047
00048
00049 this->getValuesOfTheFaceCells(m_mesh,m_vbc,m_solAnt,face->index(),negCell,posCell,vQNeg,vQPos);
00050
00051
00052
00053
00054 if (posCell == OrthoMesh::INVALID_INDEX)
00055 posCell=negCell;
00056 else if (negCell == OrthoMesh::INVALID_INDEX)
00057 negCell=posCell;
00058
00059
00060 double posPor = getPorosity()(posCell);
00061 double negPor = getPorosity()(negCell);
00062
00063
00064 m_flux.fluxAtFace(vFluxPos,face,vQPos,vQPos);
00065 m_flux.fluxAtFace(vFluxNeg,face,vQNeg,vQNeg);
00066
00067
00068 for (unsigned cmp=0;cmp<n_components;cmp++)
00069 {
00070 assert(vQPos(cmp) >= 0.0 && vQNeg(cmp) >= 0.0);
00071
00072 double fluxPos,fluxNeg,flux;
00073
00074
00075 fluxPos = dt*face->areaPerCellVol() * vFluxPos(cmp);
00076 fluxNeg = dt*face->areaPerCellVol() * vFluxNeg(cmp);
00077
00078
00079
00080 if (fluxPos >= 0.0 && fluxNeg >= 0.0)
00081 flux = fluxNeg;
00082 else if (fluxPos <0.0 && fluxNeg < 0.0)
00083 flux = fluxPos;
00084 else
00085 {
00086 flux = (fluxPos + fluxNeg)/2.0 - (posPor+negPor)/2.0 * (vQPos(cmp)-vQNeg(cmp))/6.0;
00087
00088 }
00089 if (OrthoMesh::isValid(posCell))
00090 m_sol(posCell,cmp) += + flux/posPor;
00091
00092 if (OrthoMesh::isValid(negCell))
00093 m_sol(posCell,cmp) += - flux/negPor;
00094
00095 }
00096 }
00097 }
00098
00099 }