00001 #include "laxfriedrichsforsystem.h"
00002 #include "numericmethods.h"
00003 #include "hdf5orthowriter.h"
00004 #include "gnuplotanim.h"
00005 #include "flashcompositional.h"
00006 #include "dynamicbase.h"
00007
00008 LaxFriedrichsForSystem::LaxFriedrichsForSystem(OrthoMesh &mesh,Function3D &fInitU,const VecDouble &cPor,Function3D &fPrescribedU,FaceFluxFunction &flux, FixedValueCondition &fixedC,double CFL)
00009 :m_mesh(mesh),m_cPor(cPor),m_flux(flux),n_components(flux.numComponents()),m_fixedC(fixedC)
00010
00011
00012 {
00013 assert(fInitU.n_components() == n_components);
00014 assert(fPrescribedU.n_components() == n_components);
00015 assert(cPor.size() == mesh.numCells());
00016 m_CFL = CFL;
00017
00018
00019
00020 m_sol.reinit(mesh.numCells(),n_components);
00021 m_solAnt.reinit(mesh.numCells(),n_components);
00022
00023
00024
00025 mesh.setCentralValuesFromFunction(fInitU,m_sol);
00026
00027
00028
00029 m_vbc.set_bc_from_function(mesh,fPrescribedU);
00030
00031
00032
00033
00034
00035
00036
00037
00038 }
00039
00040
00041
00042 ArrayOfVecDouble& LaxFriedrichsForSystem::getSolutionAtCells()
00043 {
00044 return m_sol;
00045 }
00046
00047
00048
00053 void LaxFriedrichsForSystem::updateVelocities(DynamicBase &dynMod)
00054 {
00055 m_flux.updateDynamicData(dynMod);
00056 FlashCompositional *flash = getFlash();
00057
00058 if (flash)
00059 this->updateBCForCompressibility(m_vbc,dynMod,*flash);
00060
00061 }
00062
00063
00064
00065 double LaxFriedrichsForSystem::getDt(double t,double tEnd)
00066 {
00067 assert(tEnd >= t);
00068 double timeInterval = tEnd-t;
00069 double dt = this->calculateTimeStep(m_mesh,timeInterval,m_CFL,getPorosity(),m_flux);
00070 return dt;
00071 }
00072
00073
00074 void LaxFriedrichsForSystem::iterateN(unsigned nSteps, double dt)
00075 {
00076 unsigned posCell,negCell;
00077
00078
00079
00080
00081
00082 static VecDouble vBC(n_components),vFlux(n_components);
00083 static VecDoubleRef vQPos(n_components),vQNeg(n_components);
00084
00085 for (unsigned count = 0; count < nSteps; count++)
00086 {
00087
00088 OrthoMesh::Cash_Face_It face = m_mesh.begin_cash_face();
00089 OrthoMesh::Cash_Face_It endf = m_mesh.end_cash_face();
00090 m_vbc.rewind();
00091 bool hasbc;
00092
00093 m_solAnt=m_sol;
00094
00095
00096 for (;face!=endf;face++)
00097 {
00098 face->getAdjCellIndices(negCell,posCell);
00099
00100 hasbc=this->getValuesOfTheFaceCells(m_mesh,m_vbc,m_solAnt,face->index(),negCell,posCell,vQNeg,vQPos);
00101
00102
00103
00104
00105
00106
00107 if (posCell == OrthoMesh::INVALID_INDEX)
00108 posCell=negCell;
00109 else if (negCell == OrthoMesh::INVALID_INDEX)
00110 negCell=posCell;
00111
00112
00113
00114 double posPor = getPorosity()(posCell);
00115 double negPor = getPorosity()(negCell);
00116 double mPor = (posPor + negPor)/2.0;
00117
00118
00119
00120 m_flux.fluxAtFace(vFlux,face,vQNeg,vQPos);
00121
00122
00123 for (unsigned cmp=0;cmp<n_components;cmp++)
00124 {
00125
00126
00127 double flux;
00128 if (!hasbc)
00129 {
00130
00131
00132
00133
00134
00135
00136
00137 flux = dt*face->areaPerCellVol() * vFlux(cmp) - mPor*(vQPos(cmp)-vQNeg(cmp))/2.0;
00138 }
00139 else
00140 {
00141 flux = dt*face->areaPerCellVol() * vFlux(cmp);
00142 }
00143
00144
00145
00146
00147 if (face->hasPosCell())
00148 m_sol(posCell,cmp) += + flux/posPor;
00149
00150 if (face->hasNegCell())
00151 m_sol(negCell,cmp) += - flux/negPor;
00152
00153 }
00154 }
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163 void LaxFriedrichsForSystem::printOutput()
00164 {
00165 VecDouble vValues(m_mesh.numVertices());
00166 VecDouble cValues(m_mesh.numCells());
00167
00168 double acum=0.0;
00169 for (unsigned cmp=0;cmp<n_components;cmp++)
00170 {
00171 char str[100];
00172 m_sol.getComponent(cValues,cmp);
00173 this->m_mesh.projectCentralValuesAtVertices(cValues,vValues);
00174
00175 acum+=m_mesh.getIntegralAtCells(cValues);
00176 HDF5OrthoWriter &hdf5 = HDF5OrthoWriter::getHDF5OrthoWriter();
00177 sprintf(str,"S%d",cmp+1);
00178 hdf5.writeScalarField(vValues,str);
00179
00180 }
00181 }
00182
00183
00184
00185
00186 void LaxFriedrichsForSystem::updateFixedPressureBC(Function3D *fDP,FlashCompositional &flash)
00187 {
00188 FlashData flashData(flash.numPhases(),flash.numComponents());
00189 VecDouble phasesVol(flash.numPhases());
00190 assert(n_components == flash.numComponents());
00191 OrthoMesh::Face_It fend = m_mesh.end_face();
00192 flashData.allocateOwnMemory();
00193 Point3D pt;
00194 VecDoubleRef bc(n_components);
00195 m_vbc.rewind();
00196
00197
00198 for (OrthoMesh::Face_It face=m_mesh.begin_face(); face!=fend; face++)
00199 {
00200
00201 unsigned i = face->index();
00202 if (m_vbc.get_ref_bc(i,bc))
00203 {
00204 face->barycenter(pt);
00205 if (fDP->isInDomain(pt))
00206 {
00207
00208
00209 double P = (*fDP)(pt);
00210
00211
00212 flash.flash(P,bc,flashData);
00213 flash.getPhasesVolume(P,flashData,phasesVol);
00214
00215
00216 double factor=1.0/NumericMethods::vectorSum(phasesVol);
00217
00218
00219 bc*=factor;
00220 }
00221 }
00222 }
00223 std::cout << m_vbc;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 void LaxFriedrichsForSystem::updateBCForCompressibility(VecIncBC &vbc,DynamicBase &dyn,FlashCompositional &flash)
00235 {
00236 const VecDouble &P = dyn.getPressureAtCells();
00237 VecIncBC::data_iterator itBC = vbc.begin_data();
00238 VecDouble phasesVol(flash.numPhases());
00239 FlashData flashData(flash.numPhases(),flash.numComponents());
00240 VecDoubleRef m(vbc.bc_dim());
00241 for (;itBC!= vbc.end_data();itBC++)
00242 {
00243
00244 m.setData(itBC->data.p);
00245
00246 flash.flash(P(itBC->data.nearCell),m,flashData);
00247
00248 flash.getPhasesVolume(P(itBC->data.nearCell),flashData,phasesVol);
00249 double factor=1.0/NumericMethods::vectorSum(phasesVol);
00250
00251 m*=factor;
00252 }
00253 }