00001 #include "ktmethoddbyd.h"
00002
00003
00004
00005
00006
00007 KTMethodDByD::KTMethodDByD(OrthoMesh &mesh,Function3D &fInitU,const VecDouble &cPor,Function3D &fPrescribedU,FaceFluxFunction &flux, FixedValueCondition &fixedC,double CFL)
00008 :LaxFriedrichsForSystem(mesh,fInitU,cPor,fPrescribedU,flux,fixedC,CFL)
00009 {
00010 DX_2[0]=mesh.get_dx()/2.0;
00011 DX_2[1]=mesh.get_dy()/2.0;
00012 DX_2[2]=mesh.get_dz()/2.0;
00013 assert(n_components == 1);
00014 m_cValues.setRef(&(m_sol(0,0)),m_sol.size());
00015 m_cValuesPrev.setRef(&(m_solAnt(0,0)),m_sol.size());
00016
00017
00018 _MG.reinit(mesh.numCells(),3);
00019 m_cValuesAux.reinit(mesh.numCells());
00020
00021
00022 return;
00023
00024
00025 }
00026
00027
00028 void KTMethodDByD::iterate(double t, double tEnd)
00029 {
00030
00031 double timeInterval = tEnd-t;
00032 double dt = this->calculateTimeStep(m_mesh,timeInterval,m_CFL,getPorosity(),m_flux);
00033 int nIteraction = (int) round(timeInterval/dt);
00034
00035 printf("KT dt = %g\n",dt);
00036
00037 for (int count = 0; count < nIteraction; count++)
00038 {
00039 iterateOnce(m_cValuesPrev,m_cValues,dt);
00040 iterateOnce(m_cValuesAux,m_cValues,dt);
00041 m_cValues.sadd(0.5,0.5,m_cValuesPrev);
00042 }
00043 }
00044
00045
00046 void KTMethodDByD::iterateOnce(VecDouble &vAux, VecDouble &vSol, double dt)
00047 {
00048 buildDerivatives(m_mesh,vSol,_MG);
00049
00050
00051
00052
00053
00054 OrthoMesh::Face_It face = m_mesh.begin_face();
00055 OrthoMesh::Face_It endf = m_mesh.end_face();
00056 m_vbc.rewind();
00057 bool hasbc;
00058
00059 vAux=vSol;
00060
00061
00062 for (;face!=endf;face++)
00063 {
00064
00065 static VecDouble SwNeg(1),SwPos(1),vFlux(1);
00066 unsigned negCell,posCell;
00067
00068 face->getAdjCellIndices(negCell,posCell);
00069
00070
00071 hasbc=this->getValuesOfTheFaceCellsScalar(m_mesh,m_vbc,vAux,face->index(),negCell,posCell,&SwNeg(0),&SwPos(0));
00072
00073
00074
00075
00076
00077 if (posCell == OrthoMesh::INVALID_INDEX)
00078 posCell=negCell;
00079 else if (negCell == OrthoMesh::INVALID_INDEX)
00080 negCell=posCell;
00081
00082
00083
00084 unsigned normal = face->getNormalOrientation();
00085
00086 double posPor = getPorosity()(posCell);
00087 double negPor = getPorosity()(negCell);
00088
00089
00090 SwNeg(0) += DX_2[normal]*_MG(negCell,normal);
00091 SwPos(0) -= DX_2[normal]*_MG(posCell,normal);
00092
00093
00094 double a;
00095 a = fabs(m_flux.maxLocalCharVelocity(face,SwNeg,SwPos));
00096
00097
00098
00099 m_flux.fluxAtFace(vFlux,face,SwNeg,SwPos);
00100 double flux = dt*face->areaPerCellVol()* (vFlux(0) - a*(SwPos(0)-SwNeg(0))/2.0);
00101
00102 if (face->hasNegCell())
00103 vSol(negCell) += - flux/negPor;
00104
00105 if (face->hasPosCell())
00106 vSol(posCell) += + flux/posPor;
00107 }
00108 }
00109