4 * Created on: Sep 15, 2014
8 #include "SinglePhase.hxx"
12 SinglePhase::SinglePhase(phaseType fluid, pressureEstimate pEstimate, int dim, bool useDellacherieEOS){
16 _dragCoeffs=vector<double>(1,0);
18 _useDellacherieEOS=useDellacherieEOS;
21 if(pEstimate==around1bar300K){//EOS at 1 bar and 300K
25 cout<<"Fluid is air around 1 bar and 300 K (27°C)"<<endl;
26 *_runLogFile<<"Fluid is air around 1 bar and 300 K (27°C)"<<endl;
27 _fluides[0] = new StiffenedGas(1.4,743,_Tref,2.22e5); //ideal gas law for nitrogen at pressure 1 bar and temperature 27°C, e=2.22e5, c_v=743
30 cout<<"Fluid is water around 1 bar and 300 K (27°C)"<<endl;
31 *_runLogFile<<"Fluid is water around 1 bar and 300 K (27°C)"<<endl;
32 _fluides[0] = new StiffenedGas(996,_Pref,_Tref,1.12e5,1501,4130); //stiffened gas law for water at pressure 1 bar and temperature 27°C, e=1.12e5, c_v=4130
35 else{//EOS at 155 bars and 618K
39 cout<<"Fluid is Gas around saturation point 155 bars and 618 K (345°C)"<<endl;
40 *_runLogFile<<"Fluid is Gas around saturation point 155 bars and 618 K (345°C)"<<endl;
41 _fluides[0] = new StiffenedGas(102,_Pref,_Tref,2.44e6, 433,3633); //stiffened gas law for Gas at pressure 155 bar and temperature 345°C
43 else{//To do : change to normal regime: 155 bars and 573K
44 cout<<"Fluid is water around saturation point 155 bars and 618 K (345°C)"<<endl;
45 *_runLogFile<<"Fluid is water around saturation point 155 bars and 618 K (345°C)"<<endl;
46 if(_useDellacherieEOS)
47 _fluides[0]= new StiffenedGasDellacherie(2.35,1e9,-1.167e6,1816); //stiffened gas law for water from S. Dellacherie
49 _fluides[0]= new StiffenedGas(594.,_Pref,_Tref,1.6e6, 621.,3100.); //stiffened gas law for water at pressure 155 bar, and temperature 345°C
53 void SinglePhase::initialize(){
54 cout<<"Initialising the Navier-Stokes model"<<endl;
55 *_runLogFile<<"Initialising the Navier-Stokes model"<<endl;
57 _Uroe = new double[_nVar];
58 _gravite = vector<double>(_nVar,0);//Not to be confused with _GravityField3d (size _Ndim). _gravite (size _Nvar) is usefull for dealing with source term and implicitation of gravity vector
59 for(int i=0; i<_Ndim; i++)
60 _gravite[i+1]=_GravityField3d[i];
62 _GravityImplicitationMatrix = new PetscScalar[_nVar*_nVar];
63 if(_saveVelocity || _saveAllFields)
64 _Vitesse=Field("Velocity",CELLS,_mesh,3);//Forcement en dimension 3 pour le posttraitement des lignes de courant
68 _Enthalpy=Field("Enthalpy",CELLS,_mesh,1);
69 _Pressure=Field("Pressure",CELLS,_mesh,1);
70 _Density=Field("Density",CELLS,_mesh,1);
71 _Temperature=Field("Temperature",CELLS,_mesh,1);
72 _VitesseX=Field("Velocity x",CELLS,_mesh,1);
75 _VitesseY=Field("Velocity y",CELLS,_mesh,1);
77 _VitesseZ=Field("Velocity z",CELLS,_mesh,1);
81 if(_entropicCorrection)
82 _entropicShift=vector<double>(3,0);//at most 3 distinct eigenvalues
84 ProblemFluid::initialize();
87 bool SinglePhase::iterateTimeStep(bool &converged)
89 if(_timeScheme == Explicit || !_usePrimitiveVarsInNewton)
90 return ProblemFluid::iterateTimeStep(converged);
95 if(_NEWTON_its>0){//Pas besoin de computeTimeStep à la première iteration de Newton
97 computeTimeStep(stop);
99 if(stop){//Le compute time step ne s'est pas bien passé
100 cout<<"ComputeTimeStep failed"<<endl;
105 computeNewtonVariation();
107 //converged=convergence des iterations
108 if(_timeScheme == Explicit)
110 else{//Implicit scheme
112 KSPGetIterationNumber(_ksp, &_PetscIts);
113 if( _MaxIterLinearSolver < _PetscIts)//save the maximum number of iterations needed during the newton scheme
114 _MaxIterLinearSolver = _PetscIts;
115 if(_PetscIts>=_maxPetscIts)//solving the linear system failed
117 cout<<"Systeme lineaire : pas de convergence de Petsc. Itérations maximales "<<_maxPetscIts<<" atteintes"<<endl;
118 *_runLogFile<<"Systeme lineaire : pas de convergence de Petsc. Itérations maximales "<<_maxPetscIts<<" atteintes"<<endl;
122 else{//solving the linear system succeeded
123 //Calcul de la variation relative Uk+1-Uk
127 for(int j=1; j<=_Nmailles; j++)
129 for(int k=0; k<_nVar; k++)
132 VecGetValues(_newtonVariation, 1, &I, &dx);
133 VecGetValues(_primitiveVars, 1, &I, &x);
134 if (fabs(x)*fabs(x)< _precision)
136 if(_erreur_rel < fabs(dx))
137 _erreur_rel = fabs(dx);
139 else if(_erreur_rel < fabs(dx/x))
140 _erreur_rel = fabs(dx/x);
144 converged = _erreur_rel <= _precision_Newton;
147 double relaxation=1;//Vk+1=Vk+relaxation*deltaV
149 VecAXPY(_primitiveVars, relaxation, _newtonVariation);
151 //mise a jour du champ primitif
152 updateConservatives();
154 if(_nbPhases==2 && fabs(_err_press_max) > _precision)//la pression n'a pu être calculée en diphasique à partir des variables conservatives
156 cout<<"Warning consToPrim: nbiter max atteint, erreur relative pression= "<<_err_press_max<<" precision= " <<_precision<<endl;
157 *_runLogFile<<"Warning consToPrim: nbiter max atteint, erreur relative pression= "<<_err_press_max<<" precision= " <<_precision<<endl;
163 cout<<"Vecteur Vkp1-Vk "<<endl;
164 VecView(_newtonVariation, PETSC_VIEWER_STDOUT_SELF);
165 cout << "Nouvel etat courant Vk de l'iteration Newton: " << endl;
166 VecView(_primitiveVars, PETSC_VIEWER_STDOUT_SELF);
169 if(_nbPhases==2 && _nbTimeStep%_freqSave ==0){
170 if(_minm1<-_precision || _minm2<-_precision)
172 cout<<"!!!!!!!!! WARNING masse partielle negative sur " << _nbMaillesNeg << " faces, min m1= "<< _minm1 << " , minm2= "<< _minm2<< " precision "<<_precision<<endl;
173 *_runLogFile<<"!!!!!!!!! WARNING masse partielle negative sur " << _nbMaillesNeg << " faces, min m1= "<< _minm1 << " , minm2= "<< _minm2<< " precision "<<_precision<<endl;
177 cout << "!!!!!!!!!!!!!!!!!!!!!!!! Complex eigenvalues on " << _nbVpCplx << " cells, max imag= " << _part_imag_max << endl;
178 *_runLogFile << "!!!!!!!!!!!!!!!!!!!!!!!! Complex eigenvalues on " << _nbVpCplx << " cells, max imag= " << _part_imag_max << endl;
190 void SinglePhase::computeNewtonVariation()
192 if(!_usePrimitiveVarsInNewton)
193 ProblemFluid::computeNewtonVariation();
198 cout<<"Vecteur courant Vk "<<endl;
199 VecView(_primitiveVars,PETSC_VIEWER_STDOUT_SELF);
201 cout << "Matrice du système linéaire avant contribution delta t" << endl;
202 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
204 cout << "Second membre du système linéaire avant contribution delta t" << endl;
205 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
208 if(_timeScheme == Explicit)
210 VecCopy(_b,_newtonVariation);
211 VecScale(_newtonVariation, _dt);
212 if(_verbose && _nbTimeStep%_freqSave ==0)
214 cout<<"Vecteur _newtonVariation =_b*dt"<<endl;
215 VecView(_newtonVariation,PETSC_VIEWER_STDOUT_SELF);
221 MatAssemblyBegin(_A, MAT_FINAL_ASSEMBLY);
223 VecAXPY(_b, 1/_dt, _old);
224 VecAXPY(_b, -1/_dt, _conservativeVars);
226 for(int imaille = 0; imaille<_Nmailles; imaille++){
227 _idm[0] = _nVar*imaille;
228 for(int k=1; k<_nVar; k++)
229 _idm[k] = _idm[k-1] + 1;
230 VecGetValues(_primitiveVars, _nVar, _idm, _Vi);
231 primToConsJacobianMatrix(_Vi);
232 for(int k=0; k<_nVar*_nVar; k++)
233 _primToConsJacoMat[k]*=1/_dt;
234 MatSetValuesBlocked(_A, 1, &imaille, 1, &imaille, _primToConsJacoMat, ADD_VALUES);
236 MatAssemblyEnd(_A, MAT_FINAL_ASSEMBLY);
238 #if PETSC_VERSION_GREATER_3_5
239 KSPSetOperators(_ksp, _A, _A);
241 KSPSetOperators(_ksp, _A, _A,SAME_NONZERO_PATTERN);
246 cout << "Matrice du système linéaire" << endl;
247 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
249 cout << "Second membre du système linéaire" << endl;
250 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
255 KSPSetComputeEigenvalues(_ksp,PETSC_TRUE);
258 KSPSolve(_ksp, _b, _newtonVariation);
262 computeScaling(_maxvp);
264 VecAssemblyBegin(_vecScaling);
265 VecAssemblyBegin(_invVecScaling);
266 for(int imaille = 0; imaille<_Nmailles; imaille++)
269 VecSetValuesBlocked(_vecScaling,1 , &indice, _blockDiag, INSERT_VALUES);
270 VecSetValuesBlocked(_invVecScaling,1,&indice,_invBlockDiag, INSERT_VALUES);
272 VecAssemblyEnd(_vecScaling);
273 VecAssemblyEnd(_invVecScaling);
277 cout << "Matrice avant le preconditionneur des vecteurs propres " << endl;
278 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
280 cout << "Second membre avant le preconditionneur des vecteurs propres " << endl;
281 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
284 MatDiagonalScale(_A,_vecScaling,_invVecScaling);
287 cout << "Matrice apres le preconditionneur des vecteurs propres " << endl;
288 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
291 VecCopy(_b,_bScaling);
292 VecPointwiseMult(_b,_vecScaling,_bScaling);
295 cout << "Produit du second membre par le preconditionneur bloc diagonal a gauche" << endl;
296 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
300 KSPSolve(_ksp,_b, _bScaling);
301 VecPointwiseMult(_newtonVariation,_invVecScaling,_bScaling);
305 cout << "solution du systeme lineaire local:" << endl;
306 VecView(_newtonVariation, PETSC_VIEWER_STDOUT_SELF);
312 void SinglePhase::convectionState( const long &i, const long &j, const bool &IsBord){
313 //First conservative state then further down we will compute interface (Roe) state and then compute primitive state
315 for(int k=1; k<_nVar; k++)
316 _idm[k] = _idm[k-1] + 1;
317 VecGetValues(_conservativeVars, _nVar, _idm, _Ui);
320 for(int k=1; k<_nVar; k++)
321 _idm[k] = _idm[k-1] + 1;
323 VecGetValues(_Uext, _nVar, _idm, _Uj);
325 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
326 if(_verbose && _nbTimeStep%_freqSave ==0)
328 cout<<"Convection Left state cell " << i<< ": "<<endl;
329 for(int k =0; k<_nVar; k++)
331 cout<<"Convection Right state cell " << j<< ": "<<endl;
332 for(int k =0; k<_nVar; k++)
335 if(_Ui[0]<0||_Uj[0]<0)
337 cout<<"!!!!!!!!!!!!!!!!!!!!!!!!densite negative, arret de calcul!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
338 *_runLogFile<<"!!!!!!!!!!!!!!!!!!!!!!!!densite negative, arret de calcul!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
339 _runLogFile->close();
340 throw CdmathException("densite negative, arret de calcul");
343 //Computation of Roe state
344 PetscScalar ri, rj, xi, xj, pi, pj;
346 ri = sqrt(_Ui[0]);//racine carre de phi_i rho_i
348 _Uroe[0] = ri*rj; //moyenne geometrique des densites
349 if(_verbose && _nbTimeStep%_freqSave ==0)
350 cout << "Densité moyenne Roe gauche " << i << ": " << ri*ri << ", droite " << j << ": " << rj*rj << "->" << _Uroe[0] << endl;
351 for(int k=0;k<_Ndim;k++){
354 _Uroe[1+k] = (xi/ri + xj/rj)/(ri + rj);
355 //"moyenne" des vitesses
356 if(_verbose && _nbTimeStep%_freqSave ==0)
357 cout << "Vitesse de Roe composante "<< k<<" gauche " << i << ": " << xi/(ri*ri) << ", droite " << j << ": " << xj/(rj*rj) << "->" << _Uroe[k+1] << endl;
359 // H = (rho E + p)/rho
360 xi = _Ui[_nVar-1];//phi rho E
362 Ii = i*_nVar; // correct Kieu
363 VecGetValues(_primitiveVars, 1, &Ii, &pi);// _primitiveVars pour p
367 for(int k=1;k<=_Ndim;k++)
368 q_2 += _Uj[k]*_Uj[k];
369 q_2 /= _Uj[0]; //phi rho u²
370 pj = _fluides[0]->getPressure((_Uj[(_Ndim+2)-1]-q_2/2)/_porosityj,_Uj[0]/_porosityj);
374 Ii = j*_nVar; // correct Kieu
375 VecGetValues(_primitiveVars, 1, &Ii, &pj);
377 xi = (xi + pi)/(ri*ri);
378 xj = (xj + pj)/(rj*rj);
379 _Uroe[_nVar-1] = (ri*xi + rj*xj)/(ri + rj);
380 //on se donne l enthalpie ici
381 if(_verbose && _nbTimeStep%_freqSave ==0)
382 cout << "Enthalpie totale de Roe H gauche " << i << ": " << xi << ", droite " << j << ": " << xj << "->" << _Uroe[_nVar-1] << endl;
384 if(_verbose && _nbTimeStep%_freqSave ==0)
386 cout<<"Convection interfacial state"<<endl;
387 for(int k=0;k<_nVar;k++)
388 cout<< _Uroe[k]<<" , "<<endl;
391 //Extraction of primitive states
392 _idm[0] = _nVar*i; // Kieu
393 for(int k=1; k<_nVar; k++)
394 _idm[k] = _idm[k-1] + 1;
396 VecGetValues(_primitiveVars, _nVar, _idm, _Vi);
397 if (_verbose && _nbTimeStep%_freqSave ==0)
399 cout << "Convection state: variables primitives maille " << i<<endl;
400 for(int q=0; q<_nVar; q++)
401 cout << _Vi[q] << endl;
406 for(int k=0; k<_nVar; k++)
407 _idn[k] = _nVar*j + k;
409 VecGetValues(_primitiveVars, _nVar, _idn, _Vj);
413 for(int k=0; k<_nVar; k++)
416 VecGetValues(_Uextdiff, _nVar, _idn, _phi);
417 consToPrim(_phi,_Vj,1);
420 if (_verbose && _nbTimeStep%_freqSave ==0)
422 cout << "Convection state: variables primitives maille " <<j <<endl;
423 for(int q=0; q<_nVar; q++)
424 cout << _Vj[q] << endl;
429 void SinglePhase::diffusionStateAndMatrices(const long &i,const long &j, const bool &IsBord){
430 //sortie: matrices et etat de diffusion (rho, q, T)
432 for(int k=1; k<_nVar; k++)
433 _idm[k] = _idm[k-1] + 1;
435 VecGetValues(_conservativeVars, _nVar, _idm, _Ui);
436 for(int k=0; k<_nVar; k++)
440 VecGetValues(_Uextdiff, _nVar, _idn, _Uj);
442 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
444 if(_verbose && _nbTimeStep%_freqSave ==0)
446 cout << "SinglePhase::diffusionStateAndMatrices cellule gauche" << i << endl;
448 for(int q=0; q<_nVar; q++)
449 cout << _Ui[q] << "\t";
451 cout << "SinglePhase::diffusionStateAndMatrices cellule droite" << j << endl;
453 for(int q=0; q<_nVar; q++)
454 cout << _Uj[q] << "\t";
458 for(int k=0; k<_nVar; k++)
459 _Udiff[k] = (_Ui[k]/_porosityi+_Uj[k]/_porosityj)/2;
461 if(_verbose && _nbTimeStep%_freqSave ==0)
463 cout << "SinglePhase::diffusionStateAndMatrices conservative diffusion state" << endl;
465 for(int q=0; q<_nVar; q++)
466 cout << _Udiff[q] << "\t";
468 cout << "porosite gauche= "<<_porosityi<< ", porosite droite= "<<_porosityj<<endl;
470 consToPrim(_Udiff,_phi,1);
471 _Udiff[_nVar-1]=_phi[_nVar-1];
473 if(_timeScheme==Implicit)
476 for (int i = 0; i<_Ndim;i++)
477 q_2+=_Udiff[i+1]*_Udiff[i+1];
478 double mu = _fluides[0]->getViscosity(_Udiff[_nVar-1]);
479 double lambda = _fluides[0]->getConductivity(_Udiff[_nVar-1]);
480 double Cv= _fluides[0]->constante("Cv");
481 for(int i=0; i<_nVar*_nVar;i++)
483 for(int i=1;i<(_nVar-1);i++)
485 _Diffusion[i*_nVar] = mu*_Udiff[i]/(_Udiff[0]*_Udiff[0]);
486 _Diffusion[i*_nVar+i] = -mu/_Udiff[0];
488 int i = (_nVar-1)*_nVar;
489 _Diffusion[i]=lambda*(_Udiff[_nVar-1]/_Udiff[0]-q_2/(2*Cv*_Udiff[0]*_Udiff[0]*_Udiff[0]));
490 for(int k=1;k<(_nVar-1);k++)
492 _Diffusion[i+k]= lambda*_Udiff[k]/(_Udiff[0]*_Udiff[0]*Cv);
494 _Diffusion[_nVar*_nVar-1]=-lambda/(_Udiff[0]*Cv);
497 void SinglePhase::setBoundaryState(string nameOfGroup, const int &j,double *normale){
499 for(int k=1; k<_nVar; k++)
500 _idm[k] = _idm[k-1] + 1;
502 double porosityj=_porosityField(j);
504 if(_verbose && _nbTimeStep%_freqSave ==0)
506 cout << "setBoundaryState for group "<< nameOfGroup << ", inner cell j= "<<j<< " face unit normal vector "<<endl;
507 for(int k=0; k<_Ndim; k++){
508 cout<<normale[k]<<", ";
513 if (_limitField[nameOfGroup].bcType==Wall){
514 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne conservatif
515 double q_n=0;//q_n=quantité de mouvement normale à la face frontière;
516 for(int k=0; k<_Ndim; k++)
517 q_n+=_externalStates[(k+1)]*normale[k];
519 //Pour la convection, inversion du sens de la vitesse normale
520 for(int k=0; k<_Ndim; k++)
521 _externalStates[(k+1)]-= 2*q_n*normale[k];
524 for(int k=1; k<_nVar; k++)
525 _idm[k] = _idm[k-1] + 1;
527 VecAssemblyBegin(_Uext);
528 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
529 VecAssemblyEnd(_Uext);
531 //Pour la diffusion, paroi à vitesse et temperature imposees
533 for(int k=1; k<_nVar; k++)
534 _idm[k] = _idm[k-1] + 1;
535 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);//L'état fantome contient à présent les variables primitives internes
536 double pression=_externalStates[0];
537 double T=_limitField[nameOfGroup].T;
538 double rho=_fluides[0]->getDensity(pression,T);
540 _externalStates[0]=porosityj*rho;
541 _externalStates[1]=_externalStates[0]*_limitField[nameOfGroup].v_x[0];
543 v2 +=_limitField[nameOfGroup].v_x[0]*_limitField[nameOfGroup].v_x[0];
546 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
547 _externalStates[2]=_externalStates[0]*_limitField[nameOfGroup].v_y[0];
550 _externalStates[3]=_externalStates[0]*_limitField[nameOfGroup].v_z[0];
551 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
554 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2);
556 for(int k=1; k<_nVar; k++)
557 _idm[k] = _idm[k-1] + 1;
558 VecAssemblyBegin(_Uextdiff);
559 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
560 VecAssemblyEnd(_Uextdiff);
562 else if (_limitField[nameOfGroup].bcType==Neumann){
563 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On prend l'état fantôme égal à l'état interne (conditions limites de Neumann)
566 for(int k=1; k<_nVar; k++)
567 _idm[k] = _idm[k-1] + 1;
569 VecAssemblyBegin(_Uext);
570 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
571 VecAssemblyEnd(_Uext);
573 VecAssemblyBegin(_Uextdiff);
574 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
575 VecAssemblyEnd(_Uextdiff);
577 else if (_limitField[nameOfGroup].bcType==Inlet){
578 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne (conditions limites de Neumann)
579 double q_int_n=0;//q_int_n=composante normale de la quantité de mouvement à la face frontière;
580 for(int k=0; k<_Ndim; k++)
581 q_int_n+=_externalStates[(k+1)]*normale[k];//On calcule la vitesse normale sortante
583 double q_ext_n=_limitField[nameOfGroup].v_x[0]*normale[0];
586 q_ext_n+=_limitField[nameOfGroup].v_y[0]*normale[1];
588 q_ext_n+=_limitField[nameOfGroup].v_z[0]*normale[2];
591 if(q_int_n+q_ext_n<=0){//Interfacial velocity goes inward
592 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);//On met à jour l'état fantome avec les variables primitives internes
593 double pression=_externalStates[0];
594 double T=_limitField[nameOfGroup].T;
595 double rho=_fluides[0]->getDensity(pression,T);
597 _externalStates[0]=porosityj*rho;//Composante fantome de masse
598 _externalStates[1]=_externalStates[0]*(_limitField[nameOfGroup].v_x[0]);//Composante fantome de qdm x
600 v2 +=(_limitField[nameOfGroup].v_x[0])*(_limitField[nameOfGroup].v_x[0]);
603 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
604 _externalStates[2]=_externalStates[0]*_limitField[nameOfGroup].v_y[0];//Composante fantome de qdm y
607 _externalStates[3]=_externalStates[0]*_limitField[nameOfGroup].v_z[0];//Composante fantome de qdm z
608 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
611 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2);//Composante fantome de l'nrj
613 else if(_nbTimeStep%_freqSave ==0)
614 cout<< "Warning : fluid possibly going out through inlet boundary "<<nameOfGroup<<". Applying Neumann boundary condition"<<endl;
617 for(int k=1; k<_nVar; k++)
618 _idm[k] = _idm[k-1] + 1;
619 VecAssemblyBegin(_Uext);
620 VecAssemblyBegin(_Uextdiff);
621 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
622 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
623 VecAssemblyEnd(_Uext);
624 VecAssemblyEnd(_Uextdiff);
626 else if (_limitField[nameOfGroup].bcType==InletRotationVelocity){
627 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
628 double u_int_n=0;//u_int_n=composante normale de la vitesse intérieure à la face frontière;
629 for(int k=0; k<_Ndim; k++)
630 u_int_n+=_externalStates[(k+1)]*normale[k];
637 omega[0]=_limitField[nameOfGroup].v_x[0];
638 omega[1]=_limitField[nameOfGroup].v_y[0];
641 Normale[0]=normale[0];
642 Normale[1]=normale[1];
646 omega[2]=_limitField[nameOfGroup].v_z[0];
647 Normale[2]=normale[2];
650 Vector tangent_vel=omega%Normale;
651 u_ext_n=-0.01*tangent_vel.norm();
652 //Changing external state velocity
653 for(int k=0; k<_Ndim; k++)
654 _externalStates[(k+1)]=u_ext_n*normale[k] + tangent_vel[k];
657 if(u_ext_n + u_int_n <= 0){
658 double pression=_externalStates[0];
659 double T=_limitField[nameOfGroup].T;
660 double rho=_fluides[0]->getDensity(pression,T);
663 v2 +=_externalStates[1]*_externalStates[1];//v_x*v_x
664 _externalStates[0]=porosityj*rho;
665 _externalStates[1]*=_externalStates[0];
668 v2 +=_externalStates[2]*_externalStates[2];//+v_y*v_y
669 _externalStates[2]*=_externalStates[0];
672 v2 +=_externalStates[3]*_externalStates[3];//+v_z*v_z
673 _externalStates[3]*=_externalStates[0];
676 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2);
678 else if(_nbTimeStep%_freqSave ==0)
681 * cout<< "Warning : fluid going out through inlet boundary "<<nameOfGroup<<". Applying Neumann boundary condition"<<endl;
683 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On définit l'état fantôme avec l'état interne
684 if(_nbTimeStep%_freqSave ==0)
685 cout<< "Warning : fluid going out through inletPressure boundary "<<nameOfGroup<<". Applying Wall boundary condition."<<endl;
687 //Changing external state momentum
688 for(int k=0; k<_Ndim; k++)
689 _externalStates[(k+1)]-=2*_externalStates[0]*u_int_n*normale[k];
693 for(int k=1; k<_nVar; k++)
694 _idm[k] = _idm[k-1] + 1;
695 VecAssemblyBegin(_Uext);
696 VecAssemblyBegin(_Uextdiff);
697 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
698 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
699 VecAssemblyEnd(_Uext);
700 VecAssemblyEnd(_Uextdiff);
702 else if (_limitField[nameOfGroup].bcType==InletPressure){
703 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne
705 //Computation of the hydrostatic contribution : scalar product between gravity vector and position vector
706 Cell Cj=_mesh.getCell(j);
707 double hydroPress=Cj.x()*_GravityField3d[0];
709 hydroPress+=Cj.y()*_GravityField3d[1];
711 hydroPress+=Cj.z()*_GravityField3d[2];
713 hydroPress*=_externalStates[0]/porosityj;//multiplication by rho the total density
715 //Building the primitive external state
716 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
717 double u_n=0;//u_n=vitesse normale à la face frontière;
718 for(int k=0; k<_Ndim; k++)
719 u_n+=_externalStates[(k+1)]*normale[k];
723 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress,_limitField[nameOfGroup].T);
725 //Contribution from the tangential velocity
729 omega[0]=_limitField[nameOfGroup].v_x[0];
730 omega[1]=_limitField[nameOfGroup].v_y[0];
733 Normale[0]=normale[0];
734 Normale[1]=normale[1];
738 omega[2]=_limitField[nameOfGroup].v_z[0];
739 Normale[2]=normale[2];
742 Vector tangent_vel=omega%Normale;
744 //Changing external state velocity
745 for(int k=0; k<_Ndim; k++)
746 _externalStates[(k+1)]=u_n*normale[k] + abs(u_n)*tangent_vel[k];
751 if(_nbTimeStep%_freqSave ==0)
752 cout<< "Warning : fluid going out through inletPressure boundary "<<nameOfGroup<<". Applying Neumann boundary condition for velocity and temperature (only pressure value is imposed as in outlet BC)."<<endl;
753 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress, _externalStates[_nVar-1]);
755 if(_nbTimeStep%_freqSave ==0)
756 cout<< "Warning : fluid going out through inletPressure boundary "<<nameOfGroup<<". Applying Wall boundary condition."<<endl;
757 _externalStates[0]=porosityj*_fluides[0]->getDensity(_externalStates[0]+hydroPress, _externalStates[_nVar-1]);
758 //Changing external state velocity
759 for(int k=0; k<_Ndim; k++)
760 _externalStates[(k+1)]-=2*u_n*normale[k];
764 for(int k=0; k<_Ndim; k++)
766 v2+=_externalStates[(k+1)]*_externalStates[(k+1)];
767 _externalStates[(k+1)]*=_externalStates[0] ;//qdm component
769 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy( _externalStates[_nVar-1],_externalStates[0]) + v2/2);//nrj component
773 for(int k=1; k<_nVar; k++)
774 _idm[k] = _idm[k-1] + 1;
775 VecAssemblyBegin(_Uext);
776 VecAssemblyBegin(_Uextdiff);
777 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
778 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
779 VecAssemblyEnd(_Uext);
780 VecAssemblyEnd(_Uextdiff);
782 else if (_limitField[nameOfGroup].bcType==Outlet){
783 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne conservatif
784 double q_n=0;//q_n=quantité de mouvement normale à la face frontière;
785 for(int k=0; k<_Ndim; k++)
786 q_n+=_externalStates[(k+1)]*normale[k];
788 if(q_n < -_precision && _nbTimeStep%_freqSave ==0)
790 cout<< "Warning : fluid going in through outlet boundary "<<nameOfGroup<<" with flow rate "<< q_n<<endl;
791 cout<< "Applying Neumann boundary condition for velocity and temperature"<<endl;
793 //Computation of the hydrostatic contribution : scalar product between gravity vector and position vector
794 Cell Cj=_mesh.getCell(j);
795 double hydroPress=Cj.x()*_GravityField3d[0];
797 hydroPress+=Cj.y()*_GravityField3d[1];
799 hydroPress+=Cj.z()*_GravityField3d[2];
801 hydroPress*=_externalStates[0]/porosityj;//multiplication by rho the total density
803 if(_verbose && _nbTimeStep%_freqSave ==0)
805 cout<<"Cond lim outlet densite= "<<_externalStates[0]<<" gravite= "<<_GravityField3d[0]<<" Cj.x()= "<<Cj.x()<<endl;
806 cout<<"Cond lim outlet pression ref= "<<_limitField[nameOfGroup].p<<" pression hydro= "<<hydroPress<<" total= "<<_limitField[nameOfGroup].p+hydroPress<<endl;
808 //Building the external state
809 _idm[0] = _nVar*j;// Kieu
810 for(int k=1; k<_nVar; k++)
811 _idm[k] = _idm[k-1] + 1;
812 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
814 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress, _externalStates[_nVar-1]);
816 for(int k=0; k<_Ndim; k++)
818 v2+=_externalStates[(k+1)]*_externalStates[(k+1)];
819 _externalStates[(k+1)]*=_externalStates[0] ;
821 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy( _externalStates[_nVar-1],_externalStates[0]) + v2/2);
823 for(int k=1; k<_nVar; k++)
824 _idm[k] = _idm[k-1] + 1;
825 VecAssemblyBegin(_Uext);
826 VecAssemblyBegin(_Uextdiff);
827 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
828 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
829 VecAssemblyEnd(_Uext);
830 VecAssemblyEnd(_Uextdiff);
832 cout<<"Boundary condition not set for boundary named "<<nameOfGroup<< " _limitField[nameOfGroup].bcType= "<<_limitField[nameOfGroup].bcType<<endl;
833 cout<<"Accepted boundary condition are Neumann, Wall, Inlet, and Outlet"<<endl;
834 *_runLogFile<<"Boundary condition not set for boundary named. Accepted boundary condition are Neumann, Wall, Inlet, and Outlet"<<endl;
835 _runLogFile->close();
836 throw CdmathException("Unknown boundary condition");
840 void SinglePhase::convectionMatrices()
842 //entree: URoe = rho, u, H
843 //sortie: matrices Roe+ et Roe-
845 if(_verbose && _nbTimeStep%_freqSave ==0)
846 cout<<"SinglePhase::convectionMatrices()"<<endl;
848 double u_n=0, u_2=0;//vitesse normale et carré du module
850 for(int i=0;i<_Ndim;i++)
852 u_2 += _Uroe[1+i]*_Uroe[1+i];
853 u_n += _Uroe[1+i]*_vec_normal[i];
856 vector<complex<double> > vp_dist(3,0);
858 if(_spaceScheme==staggered && _nonLinearFormulation==VFFC)//special case
860 staggeredVFFCMatricesConservativeVariables(u_n);//Computation of classical upwinding matrices
861 if(_timeScheme==Implicit && _usePrimitiveVarsInNewton)//For use in implicit matrix
862 staggeredVFFCMatricesPrimitiveVariables(u_n);
866 Vector vitesse(_Ndim);
867 for(int idim=0;idim<_Ndim;idim++)
868 vitesse[idim]=_Uroe[1+idim];
871 /***********Calcul des valeurs propres ********/
873 c = _fluides[0]->vitesseSonEnthalpie(H-u_2/2);//vitesse du son a l'interface
874 k = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
875 K = u_2*k/2; //g-1/2 *|u|²
877 vp_dist[0]=u_n-c;vp_dist[1]=u_n;vp_dist[2]=u_n+c;
879 _maxvploc=fabs(u_n)+c;
883 if(_verbose && _nbTimeStep%_freqSave ==0)
884 cout<<"SinglePhase::convectionMatrices Eigenvalues "<<u_n-c<<" , "<<u_n<<" , "<<u_n+c<<endl;
886 RoeMatrixConservativeVariables( u_n, H,vitesse,k,K);
888 /******** Construction des matrices de decentrement ********/
889 if( _spaceScheme ==centered){
890 if(_entropicCorrection)
892 *_runLogFile<<"SinglePhase::convectionMatrices: entropy scheme not available for centered scheme"<<endl;
893 _runLogFile->close();
894 throw CdmathException("SinglePhase::convectionMatrices: entropy scheme not available for centered scheme");
897 for(int i=0; i<_nVar*_nVar;i++)
900 else if(_spaceScheme == upwind || _spaceScheme ==pressureCorrection || _spaceScheme ==lowMach){
901 if(_entropicCorrection)
902 entropicShift(_vec_normal);
904 _entropicShift=vector<double>(3,0);//at most 3 distinct eigenvalues
906 vector< complex< double > > y (3,0);
907 for( int i=0 ; i<3 ; i++)
908 y[i] = Polynoms::abs_generalise(vp_dist[i])+_entropicShift[i];
909 Polynoms::abs_par_interp_directe(3,vp_dist, _Aroe, _nVar,_precision, _absAroe,y);
911 if( _spaceScheme ==pressureCorrection)
912 for( int i=0 ; i<_Ndim ; i++)
913 for( int j=0 ; j<_Ndim ; j++)
914 _absAroe[(1+i)*_nVar+1+j]-=(vp_dist[2].real()-vp_dist[0].real())/2*_vec_normal[i]*_vec_normal[j];
915 else if( _spaceScheme ==lowMach){
916 double M=sqrt(u_2)/c;
917 for( int i=0 ; i<_Ndim ; i++)
918 for( int j=0 ; j<_Ndim ; j++)
919 _absAroe[(1+i)*_nVar+1+j]-=(1-M)*(vp_dist[2].real()-vp_dist[0].real())/2*_vec_normal[i]*_vec_normal[j];
922 else if( _spaceScheme ==staggered ){
923 if(_entropicCorrection)//To do: study entropic correction for staggered
925 *_runLogFile<<"SinglePhase::convectionMatrices: entropy scheme not available for staggered scheme"<<endl;
926 _runLogFile->close();
927 throw CdmathException("SinglePhase::convectionMatrices: entropy scheme not available for staggered scheme");
930 staggeredRoeUpwindingMatrixConservativeVariables( u_n, H, vitesse, k, K);
934 *_runLogFile<<"SinglePhase::convectionMatrices: scheme not treated"<<endl;
935 _runLogFile->close();
936 throw CdmathException("SinglePhase::convectionMatrices: scheme not treated");
939 for(int i=0; i<_nVar*_nVar;i++)
941 _AroeMinus[i] = (_Aroe[i]-_absAroe[i])/2;
942 _AroePlus[i] = (_Aroe[i]+_absAroe[i])/2;
944 if(_timeScheme==Implicit)
946 if(_usePrimitiveVarsInNewton)//Implicitation using primitive variables
948 _Vij[0]=_fluides[0]->getPressureFromEnthalpy(_Uroe[_nVar-1]-u_2/2, _Uroe[0]);//pressure
949 _Vij[_nVar-1]=_fluides[0]->getTemperatureFromPressure( _Vij[0], _Uroe[0]);//Temperature
950 for(int idim=0;idim<_Ndim; idim++)
951 _Vij[1+idim]=_Uroe[1+idim];
952 primToConsJacobianMatrix(_Vij);
953 Polynoms::matrixProduct(_AroeMinus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroeMinusImplicit);
954 Polynoms::matrixProduct(_AroePlus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroePlusImplicit);
957 for(int i=0; i<_nVar*_nVar;i++)
959 _AroeMinusImplicit[i] = _AroeMinus[i];
960 _AroePlusImplicit[i] = _AroePlus[i];
963 if(_verbose && _nbTimeStep%_freqSave ==0)
965 displayMatrix(_Aroe, _nVar,"Matrice de Roe");
966 displayMatrix(_absAroe, _nVar,"Valeur absolue matrice de Roe");
967 displayMatrix(_AroeMinus, _nVar,"Matrice _AroeMinus");
968 displayMatrix(_AroePlus, _nVar,"Matrice _AroePlus");
972 if(_verbose && _nbTimeStep%_freqSave ==0 && _timeScheme==Implicit)
974 displayMatrix(_AroeMinusImplicit, _nVar,"Matrice _AroeMinusImplicit");
975 displayMatrix(_AroePlusImplicit, _nVar,"Matrice _AroePlusImplicit");
978 /*********Calcul de la matrice signe pour VFFC, VFRoe et décentrement des termes source*****/
979 if(_entropicCorrection)
981 InvMatriceRoe( vp_dist);
982 Polynoms::matrixProduct(_absAroe, _nVar, _nVar, _invAroe, _nVar, _nVar, _signAroe);
984 else if (_spaceScheme==upwind || (_spaceScheme ==pressureCorrection ) || (_spaceScheme ==lowMach ))//upwind sans entropic
985 SigneMatriceRoe( vp_dist);
986 else if (_spaceScheme==centered)//centre sans entropic
987 for(int i=0; i<_nVar*_nVar;i++)
989 else if( _spaceScheme ==staggered )//à tester
998 for(int i=0; i<_nVar*_nVar;i++)
1000 _signAroe[0] = signu;
1001 for(int i=1; i<_nVar-1;i++)
1002 _signAroe[i*_nVar+i] = -signu;
1003 _signAroe[_nVar*(_nVar-1)+_nVar-1] = signu;
1007 *_runLogFile<<"SinglePhase::convectionMatrices: well balanced option not treated"<<endl;
1008 _runLogFile->close();
1009 throw CdmathException("SinglePhase::convectionMatrices: well balanced option not treated");
1012 void SinglePhase::computeScaling(double maxvp)
1016 for(int q=1; q<_nVar-1; q++)
1018 _blockDiag[q]=1./maxvp;//
1019 _invBlockDiag[q]= maxvp;//1.;//
1021 _blockDiag[_nVar - 1]=(_fluides[0]->constante("gamma")-1)/(maxvp*maxvp);//1
1022 _invBlockDiag[_nVar - 1]= 1./_blockDiag[_nVar - 1] ;// 1.;//
1025 void SinglePhase::addDiffusionToSecondMember
1031 double lambda = _fluides[0]->getConductivity(_Udiff[_nVar-1]);
1032 double mu = _fluides[0]->getViscosity(_Udiff[_nVar-1]);
1035 lambda=max(lambda,_heatTransfertCoeff);//wall nucleate boing -> larger heat transfer
1037 if(lambda==0 && mu ==0 && _heatTransfertCoeff==0)
1041 for(int k=1; k<_nVar; k++)
1042 _idm[k] = _idm[k-1] + 1;
1045 VecGetValues(_Uextdiff, _nVar, _idm, _Uj);
1049 //on n'a pas de contribution sur la masse
1051 //contribution visqueuse sur la quantite de mouvement
1052 for(int k=1; k<_nVar-1; k++)
1053 _phi[k] = _inv_dxi*2/(1/_inv_dxi+1/_inv_dxj)*mu*(_porosityj*_Vj[k] - _porosityi*_Vi[k]);
1054 //contribution visqueuse sur l'energie
1055 _phi[_nVar-1] = _inv_dxi*2/(1/_inv_dxi+1/_inv_dxj)*lambda*(_porosityj*_Vj[_nVar-1] - _porosityi*_Vi[_nVar-1]);
1058 VecSetValuesBlocked(_b, 1, _idm, _phi, ADD_VALUES);
1060 if(_verbose && _nbTimeStep%_freqSave ==0)
1062 cout << "Contribution diffusion au 2nd membre pour la maille " << i << ": "<<endl;
1063 for(int q=0; q<_nVar; q++)
1064 cout << _phi[q] << endl;
1070 //On change de signe pour l'autre contribution
1071 for(int k=0; k<_nVar; k++)
1072 _phi[k] *= -_inv_dxj/_inv_dxi;
1075 VecSetValuesBlocked(_b, 1, _idn, _phi, ADD_VALUES);
1076 if(_verbose && _nbTimeStep%_freqSave ==0)
1078 cout << "Contribution diffusion au 2nd membre pour la maille " << j << ": "<<endl;
1079 for(int q=0; q<_nVar; q++)
1080 cout << _phi[q] << endl;
1085 if(_verbose && _nbTimeStep%_freqSave ==0 && _timeScheme==Implicit)
1087 cout << "Matrice de diffusion D, pour le couple (" << i << "," << j<< "):" << endl;
1088 for(int i=0; i<_nVar; i++)
1090 for(int j=0; j<_nVar; j++)
1091 cout << _Diffusion[i*_nVar+j]<<", ";
1098 void SinglePhase::sourceVector(PetscScalar * Si, PetscScalar * Ui, PetscScalar * Vi, int i)
1100 double phirho=Ui[0], T=Vi[_nVar-1];
1102 for(int k=0; k<_Ndim; k++)
1103 norm_u+=Vi[1+k]*Vi[1+k];
1104 norm_u=sqrt(norm_u);
1106 Si[0]=_heatPowerField(i)/_latentHeat;
1109 for(int k=1; k<_nVar-1; k++)
1110 Si[k] =(_gravite[k]-_dragCoeffs[0]*norm_u*Vi[1+k])*phirho;
1112 Si[_nVar-1]=_heatPowerField(i);
1114 for(int k=0; k<_Ndim; k++)
1115 Si[_nVar-1] +=(_GravityField3d[k]-_dragCoeffs[0]*norm_u*Vi[1+k])*Vi[1+k]*phirho;
1117 if(_timeScheme==Implicit)
1119 for(int k=0; k<_nVar*_nVar;k++)
1120 _GravityImplicitationMatrix[k] = 0;
1121 if(!_usePrimitiveVarsInNewton)
1122 for(int k=0; k<_nVar;k++)
1123 _GravityImplicitationMatrix[k*_nVar]=-_gravite[k];
1126 double pression=Vi[0];
1127 getDensityDerivatives( pression, T, norm_u*norm_u);
1128 for(int k=0; k<_nVar;k++)
1130 _GravityImplicitationMatrix[k*_nVar+0] =-_gravite[k]*_drho_sur_dp;
1131 _GravityImplicitationMatrix[k*_nVar+_nVar-1]=-_gravite[k]*_drho_sur_dT;
1135 if(_verbose && _nbTimeStep%_freqSave ==0)
1137 cout<<"SinglePhase::sourceVector"<<endl;
1139 for(int k=0;k<_nVar;k++)
1143 for(int k=0;k<_nVar;k++)
1147 for(int k=0;k<_nVar;k++)
1150 if(_timeScheme==Implicit)
1151 displayMatrix(_GravityImplicitationMatrix, _nVar, "Gravity implicitation matrix");
1155 void SinglePhase::pressureLossVector(PetscScalar * pressureLoss, double K, PetscScalar * Ui, PetscScalar * Vi, PetscScalar * Uj, PetscScalar * Vj)
1157 double norm_u=0, u_n=0, rho;
1158 for(int i=0;i<_Ndim;i++)
1159 u_n += _Uroe[1+i]*_vec_normal[i];
1163 for(int i=0;i<_Ndim;i++)
1164 norm_u += Vi[1+i]*Vi[1+i];
1165 norm_u=sqrt(norm_u);
1167 for(int i=0;i<_Ndim;i++)
1168 pressureLoss[1+i]=-1/2*K*rho*norm_u*Vi[1+i];
1171 for(int i=0;i<_Ndim;i++)
1172 norm_u += Vj[1+i]*Vj[1+i];
1173 norm_u=sqrt(norm_u);
1175 for(int i=0;i<_Ndim;i++)
1176 pressureLoss[1+i]=-1/2*K*rho*norm_u*Vj[1+i];
1178 pressureLoss[_nVar-1]=-1/2*K*rho*norm_u*norm_u*norm_u;
1180 if(_verbose && _nbTimeStep%_freqSave ==0)
1182 cout<<"SinglePhase::pressureLossVector K= "<<K<<endl;
1184 for(int k=0;k<_nVar;k++)
1188 for(int k=0;k<_nVar;k++)
1192 for(int k=0;k<_nVar;k++)
1196 for(int k=0;k<_nVar;k++)
1199 cout<<"pressureLoss="<<endl;
1200 for(int k=0;k<_nVar;k++)
1201 cout<<pressureLoss[k]<<", ";
1206 void SinglePhase::porosityGradientSourceVector()
1208 double u_ni=0, u_nj=0, rhoi,rhoj, pi=_Vi[0], pj=_Vj[0],pij;
1209 for(int i=0;i<_Ndim;i++) {
1210 u_ni += _Vi[1+i]*_vec_normal[i];
1211 u_nj += _Vj[1+i]*_vec_normal[i];
1213 _porosityGradientSourceVector[0]=0;
1214 rhoj=_Uj[0]/_porosityj;
1215 rhoi=_Ui[0]/_porosityi;
1216 pij=(pi+pj)/2+rhoi*rhoj/2/(rhoi+rhoj)*(u_ni-u_nj)*(u_ni-u_nj);
1217 for(int i=0;i<_Ndim;i++)
1218 _porosityGradientSourceVector[1+i]=pij*(_porosityi-_porosityj)*2/(1/_inv_dxi+1/_inv_dxj);
1219 _porosityGradientSourceVector[_nVar-1]=0;
1222 void SinglePhase::jacobian(const int &j, string nameOfGroup,double * normale)
1224 if(_verbose && _nbTimeStep%_freqSave ==0)
1225 cout<<"Jacobienne condition limite convection bord "<< nameOfGroup<<endl;
1228 for(k=0; k<_nVar*_nVar;k++)
1229 _Jcb[k] = 0;//No implicitation at this stage
1232 for(k=1; k<_nVar; k++)
1233 _idm[k] = _idm[k-1] + 1;
1234 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);
1235 double q_n=0;//quantité de mouvement normale à la paroi
1236 for(k=0; k<_Ndim; k++)
1237 q_n+=_externalStates[(k+1)]*normale[k];
1239 // loop of boundary types
1240 if (_limitField[nameOfGroup].bcType==Wall)
1242 for(k=0; k<_nVar;k++)
1243 _Jcb[k*_nVar + k] = 1;
1244 for(k=1; k<_nVar-1;k++)
1245 for(int l=1; l<_nVar-1;l++)
1246 _Jcb[k*_nVar + l] -= 2*normale[k-1]*normale[l-1];
1248 else if (_limitField[nameOfGroup].bcType==Inlet)
1252 double v[_Ndim], ve[_Ndim], v2, ve2;
1255 for(k=1; k<_nVar; k++)
1256 _idm[k] = _idm[k-1] + 1;
1257 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1258 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
1260 ve[0] = _limitField[nameOfGroup].v_x[0];
1265 ve[1] = _limitField[nameOfGroup].v_y[0];
1271 ve[2] = _limitField[nameOfGroup].v_z[0];
1276 double internal_energy=_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,_Uj[0]);
1277 double total_energy=internal_energy+ve2/2;
1280 _Jcb[0]=v2/(2*internal_energy);
1281 for(k=0; k<_Ndim;k++)
1282 _Jcb[1+k]=-v[k]/internal_energy;
1283 _Jcb[_nVar-1]=1/internal_energy;
1285 for(int l =1;l<1+_Ndim;l++){
1286 _Jcb[l*_nVar]=v2*ve[l-1]/(2*internal_energy);
1287 for(k=0; k<_Ndim;k++)
1288 _Jcb[l*_nVar+1+k]=-v[k]*ve[l-1]/internal_energy;
1289 _Jcb[l*_nVar+_nVar-1]=ve[l-1]/internal_energy;
1292 _Jcb[(_nVar-1)*_nVar]=v2*total_energy/(2*internal_energy);
1293 for(k=0; k<_Ndim;k++)
1294 _Jcb[(_nVar-1)*_nVar+1+k]=-v[k]*total_energy/internal_energy;
1295 _Jcb[(_nVar-1)*_nVar+_nVar-1]=total_energy/internal_energy;
1298 for(k=0;k<_nVar;k++)
1303 _Jcb[_nVar]=_limitField[nameOfGroup].v_x[0];//Kieu
1304 v2 +=(_limitField[nameOfGroup].v_x[0])*(_limitField[nameOfGroup].v_x[0]);
1307 _Jcb[2*_nVar]= _limitField[nameOfGroup].v_y[0];
1308 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
1310 _Jcb[3*_nVar]=_limitField[nameOfGroup].v_z[0];
1311 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
1314 _Jcb[(_nVar-1)*_nVar]=_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2;
1317 else if (_limitField[nameOfGroup].bcType==InletPressure && q_n<0){
1319 double v[_Ndim], v2=0;
1321 for(k=1; k<_nVar; k++)
1322 _idm[k] = _idm[k-1] + 1;
1323 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1325 for(k=0; k<_Ndim;k++){
1330 double rho_ext=_fluides[0]->getDensity(_limitField[nameOfGroup].p, _limitField[nameOfGroup].T);
1331 double rho_int = _externalStates[0];
1332 double density_ratio=rho_ext/rho_int;
1334 for(int l =1;l<1+_Ndim;l++){
1335 _Jcb[l*_nVar]=-density_ratio*v[l-1];
1336 _Jcb[l*_nVar+l]=density_ratio;
1339 _Jcb[(_nVar-1)*_nVar]=-v2*density_ratio;
1340 for(k=0; k<_Ndim;k++)
1341 _Jcb[(_nVar-1)*_nVar+1+k]=density_ratio*v[k];
1343 // not wall, not inlet, not inletPressure
1344 else if(_limitField[nameOfGroup].bcType==Outlet || (_limitField[nameOfGroup].bcType==InletPressure && q_n>=0))
1347 double v[_Ndim], v2=0;
1349 for(k=1; k<_nVar; k++)
1350 _idm[k] = _idm[k-1] + 1;
1351 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1353 for(k=0; k<_Ndim;k++){
1358 double rho_ext=_fluides[0]->getDensity(_limitField[nameOfGroup].p, _externalStates[_nVar-1]);
1359 double rho_int = _externalStates[0];
1360 double density_ratio=rho_ext/rho_int;
1361 double internal_energy=_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho_int);
1362 double total_energy=internal_energy+v2/2;
1365 _Jcb[0]=density_ratio*(1-v2/(2*internal_energy));
1366 for(k=0; k<_Ndim;k++)
1367 _Jcb[1+k]=density_ratio*v[k]/internal_energy;
1368 _Jcb[_nVar-1]=-density_ratio/internal_energy;
1370 for(int l =1;l<1+_Ndim;l++){
1371 _Jcb[l*_nVar]=density_ratio*v2*v[l-1]/(2*internal_energy);
1372 for(k=0; k<_Ndim;k++)
1373 _Jcb[l*_nVar+1+k]=density_ratio*v[k]*v[l-1]/internal_energy;
1374 _Jcb[l*_nVar+1+k]-=density_ratio;
1375 _Jcb[l*_nVar+_nVar-1]=-density_ratio*v[l-1]/internal_energy;
1378 _Jcb[(_nVar-1)*_nVar]=density_ratio*v2*total_energy/(2*internal_energy);
1379 for(k=0; k<_Ndim;k++)
1380 _Jcb[(_nVar-1)*_nVar+1+k]=density_ratio*v[k]*total_energy/internal_energy;
1381 _Jcb[(_nVar-1)*_nVar+_nVar-1]=density_ratio*(1-total_energy/internal_energy);
1385 double cd = 1,cn=0,p0, gamma;
1386 _idm[0] = j*_nVar;// Kieu
1387 for(k=1; k<_nVar;k++)
1388 _idm[k] = _idm[k-1] + 1;
1389 VecGetValues(_conservativeVars, _nVar, _idm, _phi);
1390 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
1392 // compute the common numerator and common denominator
1393 p0=_fluides[0]->constante("p0");
1394 gamma =_fluides[0]->constante("gamma");
1395 cn =_limitField[nameOfGroup].p +p0;
1396 cd = _phi[0]*_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho)-p0;
1400 for(k=1; k<_nVar-1;k++)
1401 v2+=_externalStates[k]*_externalStates[k];
1403 _JcbDiff[0] = cn*(_phi[_nVar-1] -v2 -p0)/cd;
1404 for(k=1; k<_nVar-1;k++)
1405 _JcbDiff[k]=cn*_phi[k]/cd;
1406 _JcbDiff[_nVar-1]= -cn*_phi[0]/cd;
1408 for(idim=0; idim<_Ndim;idim++)
1411 _JcbDiff[(1+idim)*_nVar]=-(v2*cn*_phi[idim+1])/(2*cd);
1412 //colonnes intermediaire
1413 for(jdim=0; jdim<_Ndim;jdim++)
1415 _JcbDiff[(1+idim)*_nVar + jdim + 1] =_externalStates[idim+1]*_phi[jdim+1];
1416 _JcbDiff[(1+idim)*_nVar + jdim + 1]*=cn/cd;
1418 //matrice identite*cn*(rhoe- p0)
1419 _JcbDiff[(1+idim)*_nVar + idim + 1] +=( cn*(_phi[0]*_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho)-p0))/cd;
1422 _JcbDiff[(1+idim)*_nVar + _nVar-1]=-_phi[idim+1]*cn/cd;
1425 _JcbDiff[_nVar*(_nVar-1)] = -(v2*_phi[_nVar -1]*cn)/(2*cd);
1426 for(int idim=0; idim<_Ndim;idim++)
1427 _JcbDiff[_nVar*(_nVar-1)+idim+1]=_externalStates[idim+1]*_phi[_nVar -1]*cn/cd;
1428 _JcbDiff[_nVar*_nVar -1] = -(v2/2+p0)*cn/cd;
1431 else if (_limitField[nameOfGroup].bcType!=Neumann)// not wall, not inlet, not outlet
1433 cout << "group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1434 *_runLogFile<<"group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1435 _runLogFile->close();
1436 throw CdmathException("SinglePhase::jacobian: This boundary condition is not treated");
1440 //calcule la jacobienne pour une CL de diffusion
1441 void SinglePhase::jacobianDiff(const int &j, string nameOfGroup)
1443 if(_verbose && _nbTimeStep%_freqSave ==0)
1444 cout<<"Jacobienne condition limite diffusion bord "<< nameOfGroup<<endl;
1447 for(k=0; k<_nVar*_nVar;k++)
1450 if (_limitField[nameOfGroup].bcType==Wall){
1451 double v[_Ndim], ve[_Ndim], v2, ve2;
1454 for(k=1; k<_nVar; k++)
1455 _idm[k] = _idm[k-1] + 1;
1456 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1457 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
1459 ve[0] = _limitField[nameOfGroup].v_x[0];
1464 ve[1] = _limitField[nameOfGroup].v_y[0];
1470 ve[2] = _limitField[nameOfGroup].v_z[0];
1476 double internal_energy=_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho);
1477 double total_energy=internal_energy+ve2/2;
1480 _JcbDiff[0]=v2/(2*internal_energy);
1481 for(k=0; k<_Ndim;k++)
1482 _JcbDiff[1+k]=-v[k]/internal_energy;
1483 _JcbDiff[_nVar-1]=1/internal_energy;
1485 for(int l =1;l<1+_Ndim;l++){
1486 _JcbDiff[l*_nVar]=v2*ve[l-1]/(2*internal_energy);
1487 for(k=0; k<_Ndim;k++)
1488 _JcbDiff[l*_nVar+1+k]=-v[k]*ve[l-1]/internal_energy;
1489 _JcbDiff[l*_nVar+_nVar-1]=ve[l-1]/internal_energy;
1492 _JcbDiff[(_nVar-1)*_nVar]=v2*total_energy/(2*internal_energy);
1493 for(k=0; k<_Ndim;k++)
1494 _JcbDiff[(_nVar-1)*_nVar+1+k]=-v[k]*total_energy/internal_energy;
1495 _JcbDiff[(_nVar-1)*_nVar+_nVar-1]=total_energy/internal_energy;
1497 else if (_limitField[nameOfGroup].bcType==Outlet || _limitField[nameOfGroup].bcType==Neumann
1498 ||_limitField[nameOfGroup].bcType==Inlet || _limitField[nameOfGroup].bcType==InletPressure)
1500 for(k=0;k<_nVar;k++)
1501 _JcbDiff[k*_nVar+k]=1;
1504 cout << "group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1505 *_runLogFile<<"group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1506 _runLogFile->close();
1507 throw CdmathException("SinglePhase::jacobianDiff: This boundary condition is not recognised");
1511 void SinglePhase::primToCons(const double *P, const int &i, double *W, const int &j){
1512 //cout<<"SinglePhase::primToCons i="<<i<<", j="<<j<<", P[i*(_Ndim+2)]="<<P[i*(_Ndim+2)]<<", P[i*(_Ndim+2)+(_Ndim+1)]="<<P[i*(_Ndim+2)+(_Ndim+1)]<<endl;
1514 double rho=_fluides[0]->getDensity(P[i*(_Ndim+2)], P[i*(_Ndim+2)+(_Ndim+1)]);
1515 W[j*(_Ndim+2)] = _porosityField(j)*rho;//phi*rho
1516 for(int k=0; k<_Ndim; k++)
1517 W[j*(_Ndim+2)+(k+1)] = W[j*(_Ndim+2)]*P[i*(_Ndim+2)+(k+1)];//phi*rho*u
1519 W[j*(_Ndim+2)+(_Ndim+1)] = W[j*(_Ndim+2)]*_fluides[0]->getInternalEnergy(P[i*(_Ndim+2)+ (_Ndim+1)],rho);//rho*e
1520 for(int k=0; k<_Ndim; k++)
1521 W[j*(_Ndim+2)+(_Ndim+1)] += W[j*(_Ndim+2)]*P[i*(_Ndim+2)+(k+1)]*P[i*(_Ndim+2)+(k+1)]*0.5;//phi*rho*e+0.5*phi*rho*u^2
1524 void SinglePhase::primToConsJacobianMatrix(double *V)
1526 double pression=V[0];
1527 double temperature=V[_nVar-1];
1528 double vitesse[_Ndim];
1529 for(int idim=0;idim<_Ndim;idim++)
1530 vitesse[idim]=V[1+idim];
1532 for(int idim=0;idim<_Ndim;idim++)
1533 v2+=vitesse[idim]*vitesse[idim];
1535 double rho=_fluides[0]->getDensity(pression,temperature);
1536 double gamma=_fluides[0]->constante("gamma");
1537 double Pinf=_fluides[0]->constante("p0");
1538 double q=_fluides[0]->constante("q");
1539 double cv=_fluides[0]->constante("cv");
1541 for(int k=0;k<_nVar*_nVar; k++)
1542 _primToConsJacoMat[k]=0;
1544 if( !_useDellacherieEOS)
1546 StiffenedGas* fluide0=dynamic_cast<StiffenedGas*>(_fluides[0]);
1547 double e=fluide0->getInternalEnergy(temperature);
1550 _primToConsJacoMat[0]=1/((gamma-1)*(e-q));
1551 _primToConsJacoMat[_nVar-1]=-rho*cv/(e-q);
1553 for(int idim=0;idim<_Ndim;idim++)
1555 _primToConsJacoMat[_nVar+idim*_nVar]=vitesse[idim]/((gamma-1)*(e-q));
1556 _primToConsJacoMat[_nVar+idim*_nVar+1+idim]=rho;
1557 _primToConsJacoMat[_nVar+idim*_nVar+_nVar-1]=-rho*vitesse[idim]*cv/(e-q);
1559 _primToConsJacoMat[(_nVar-1)*_nVar]=E/((gamma-1)*(e-q));
1560 for(int idim=0;idim<_Ndim;idim++)
1561 _primToConsJacoMat[(_nVar-1)*_nVar+1+idim]=rho*vitesse[idim];
1562 _primToConsJacoMat[(_nVar-1)*_nVar+_nVar-1]=rho*cv*(1-E/(e-q));
1564 else if( _useDellacherieEOS)
1566 StiffenedGasDellacherie* fluide0=dynamic_cast<StiffenedGasDellacherie*>(_fluides[0]);
1567 double h=fluide0->getEnthalpy(temperature);
1569 double cp=_fluides[0]->constante("cp");
1571 _primToConsJacoMat[0]=gamma/((gamma-1)*(h-q));
1572 _primToConsJacoMat[_nVar-1]=-rho*cp/(h-q);
1574 for(int idim=0;idim<_Ndim;idim++)
1576 _primToConsJacoMat[_nVar+idim*_nVar]=gamma*vitesse[idim]/((gamma-1)*(h-q));
1577 _primToConsJacoMat[_nVar+idim*_nVar+1+idim]=rho;
1578 _primToConsJacoMat[_nVar+idim*_nVar+_nVar-1]=-rho*vitesse[idim]*cp/(h-q);
1580 _primToConsJacoMat[(_nVar-1)*_nVar]=gamma*H/((gamma-1)*(h-q))-1;
1581 for(int idim=0;idim<_Ndim;idim++)
1582 _primToConsJacoMat[(_nVar-1)*_nVar+1+idim]=rho*vitesse[idim];
1583 _primToConsJacoMat[(_nVar-1)*_nVar+_nVar-1]=rho*cp*(1-H/(h-q));
1587 *_runLogFile<<"SinglePhase::primToConsJacobianMatrix: eos should be StiffenedGas or StiffenedGasDellacherie"<<endl;
1588 _runLogFile->close();
1589 throw CdmathException("SinglePhase::primToConsJacobianMatrix: eos should be StiffenedGas or StiffenedGasDellacherie");
1592 if(_verbose && _nbTimeStep%_freqSave ==0)
1594 cout<<" SinglePhase::primToConsJacobianMatrix" << endl;
1595 displayVector(_Vi,_nVar," _Vi " );
1596 cout<<" Jacobienne primToCons: " << endl;
1597 displayMatrix(_primToConsJacoMat,_nVar," Jacobienne primToCons: ");
1601 void SinglePhase::consToPrim(const double *Wcons, double* Wprim,double porosity)
1604 for(int k=1;k<=_Ndim;k++)
1605 q_2 += Wcons[k]*Wcons[k];
1606 q_2 /= Wcons[0]; //phi rho u²
1607 double rhoe=(Wcons[(_Ndim+2)-1]-q_2/2)/porosity;
1608 double rho=Wcons[0]/porosity;
1609 Wprim[0] = _fluides[0]->getPressure(rhoe,rho);//pressure p
1611 cout << "pressure = "<< Wprim[0] << " < 0 " << endl;
1612 *_runLogFile<< "pressure = "<< Wprim[0] << " < 0 " << endl;
1613 _runLogFile->close();
1614 throw CdmathException("SinglePhase::consToPrim: negative pressure");
1616 for(int k=1;k<=_Ndim;k++)
1617 Wprim[k] = Wcons[k]/Wcons[0];//velocity u
1618 Wprim[(_Ndim+2)-1] = _fluides[0]->getTemperatureFromPressure(Wprim[0],Wcons[0]/porosity);
1620 if(_verbose && _nbTimeStep%_freqSave ==0)
1622 cout<<"ConsToPrim Vecteur conservatif"<<endl;
1623 for(int k=0;k<_nVar;k++)
1624 cout<<Wcons[k]<<endl;
1625 cout<<"ConsToPrim Vecteur primitif"<<endl;
1626 for(int k=0;k<_nVar;k++)
1627 cout<<Wprim[k]<<endl;
1631 void SinglePhase::entropicShift(double* n)//TO do: make sure _Vi and _Vj are well set
1633 /*Left and right values */
1634 double ul_n = 0, ul_2=0, ur_n=0, ur_2 = 0; //valeurs de vitesse normale et |u|² a droite et a gauche
1635 for(int i=0;i<_Ndim;i++)
1637 ul_n += _Vi[1+i]*n[i];
1638 ul_2 += _Vi[1+i]*_Vi[1+i];
1639 ur_n += _Vj[1+i]*n[i];
1640 ur_2 += _Vj[1+i]*_Vj[1+i];
1643 double cl = _fluides[0]->vitesseSonEnthalpie(_Vi[_Ndim+1]-ul_2/2);//vitesse du son a l'interface
1644 double cr = _fluides[0]->vitesseSonEnthalpie(_Vj[_Ndim+1]-ur_2/2);//vitesse du son a l'interface
1646 _entropicShift[0]=fabs(ul_n-cl - (ur_n-cr));
1647 _entropicShift[1]=fabs(ul_n - ur_n);
1648 _entropicShift[2]=fabs(ul_n+cl - (ur_n+cr));
1650 if(_verbose && _nbTimeStep%_freqSave ==0)
1652 cout<<"Entropic shift left eigenvalues: "<<endl;
1653 cout<<"("<< ul_n-cl<< ", " <<ul_n<<", "<<ul_n+cl << ")";
1655 cout<<"Entropic shift right eigenvalues: "<<endl;
1656 cout<<"("<< ur_n-cr<< ", " <<ur_n<<", "<<ur_n+cr << ")";
1658 cout<<"eigenvalue jumps "<<endl;
1659 cout<< _entropicShift[0] << ", " << _entropicShift[1] << ", "<< _entropicShift[2] <<endl;
1663 Vector SinglePhase::convectionFlux(Vector U,Vector V, Vector normale, double porosity){
1664 if(_verbose && _nbTimeStep%_freqSave ==0)
1666 cout<<"SinglePhase::convectionFlux start"<<endl;
1667 cout<<"Ucons"<<endl;
1669 cout<<"Vprim"<<endl;
1673 double phirho=U(0);//phi rho
1674 Vector phiq(_Ndim);//phi rho u
1675 for(int i=0;i<_Ndim;i++)
1678 double pression=V(0);
1679 Vector vitesse(_Ndim);
1680 for(int i=0;i<_Ndim;i++)
1682 double Temperature= V(1+_Ndim);
1684 double vitessen=vitesse*normale;
1685 double rho=phirho/porosity;
1686 double e_int=_fluides[0]->getInternalEnergy(Temperature,rho);
1689 F(0)=phirho*vitessen;
1690 for(int i=0;i<_Ndim;i++)
1691 F(1+i)=phirho*vitessen*vitesse(i)+pression*normale(i)*porosity;
1692 F(1+_Ndim)=phirho*(e_int+0.5*vitesse*vitesse+pression/rho)*vitessen;
1694 if(_verbose && _nbTimeStep%_freqSave ==0)
1696 cout<<"SinglePhase::convectionFlux end"<<endl;
1697 cout<<"Flux F(U,V)"<<endl;
1704 void SinglePhase::RoeMatrixConservativeVariables(double u_n, double H,Vector velocity, double k, double K)
1706 /******** Construction de la matrice de Roe *********/
1707 //premiere ligne (masse)
1709 for(int idim=0; idim<_Ndim;idim++)
1710 _Aroe[1+idim]=_vec_normal[idim];
1713 //lignes intermadiaires(qdm)
1714 for(int idim=0; idim<_Ndim;idim++)
1717 _Aroe[(1+idim)*_nVar]=K*_vec_normal[idim] - u_n*_Uroe[1+idim];
1718 //colonnes intermediaires
1719 for(int jdim=0; jdim<_Ndim;jdim++)
1720 _Aroe[(1+idim)*_nVar + jdim + 1] = _Uroe[1+idim]*_vec_normal[jdim]-k*_vec_normal[idim]*_Uroe[1+jdim];
1722 _Aroe[(1+idim)*_nVar + idim + 1] += u_n;
1724 _Aroe[(1+idim)*_nVar + _nVar-1]=k*_vec_normal[idim];
1727 //derniere ligne (energie)
1728 _Aroe[_nVar*(_nVar-1)] = (K - H)*u_n;
1729 for(int idim=0; idim<_Ndim;idim++)
1730 _Aroe[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] - k*u_n*_Uroe[idim+1];
1731 _Aroe[_nVar*_nVar -1] = (1 + k)*u_n;
1733 void SinglePhase::convectionMatrixPrimitiveVariables( double rho, double u_n, double H,Vector vitesse)
1735 //Not used. Suppress or use in alternative implicitation in primitive variable of the staggered-roe scheme
1736 //On remplit la matrice de Roe en variables primitives : F(V_L)-F(V_R)=Aroe (V_L-V_R)
1737 //EOS is more involved with primitive variables
1738 // call to getDensityDerivatives(double concentration, double pression, double temperature,double v2) needed
1739 _AroeImplicit[0*_nVar+0]=_drho_sur_dp*u_n;
1740 for(int i=0;i<_Ndim;i++)
1741 _AroeImplicit[0*_nVar+1+i]=rho*_vec_normal[i];
1742 _AroeImplicit[0*_nVar+1+_Ndim]=_drho_sur_dT*u_n;
1743 for(int i=0;i<_Ndim;i++)
1745 _AroeImplicit[(1+i)*_nVar+0]=_drho_sur_dp *u_n*vitesse[i]+_vec_normal[i];
1746 for(int j=0;j<_Ndim;j++)
1747 _AroeImplicit[(1+i)*_nVar+1+j]=rho*vitesse[i]*_vec_normal[j];
1748 _AroeImplicit[(1+i)*_nVar+1+i]+=rho*u_n;
1749 _AroeImplicit[(1+i)*_nVar+1+_Ndim]=_drho_sur_dT*u_n*vitesse[i];
1751 _AroeImplicit[(1+_Ndim)*_nVar+0]=(_drhoE_sur_dp+1)*u_n;
1752 for(int i=0;i<_Ndim;i++)
1753 _AroeImplicit[(1+_Ndim)*_nVar+1+i]=rho*(H*_vec_normal[i]+u_n*vitesse[i]);
1754 _AroeImplicit[(1+_Ndim)*_nVar+1+_Ndim]=_drhoE_sur_dT*u_n;
1756 void SinglePhase::staggeredRoeUpwindingMatrixConservativeVariables( double u_n, double H,Vector velocity, double k, double K)
1758 //Calcul de décentrement de type décalé pour formulation de Roe
1759 if(fabs(u_n)>_precision)
1761 //premiere ligne (masse)
1763 for(int idim=0; idim<_Ndim;idim++)
1764 _absAroe[1+idim]=_vec_normal[idim];
1765 _absAroe[_nVar-1]=0;
1767 //lignes intermadiaires(qdm)
1768 for(int idim=0; idim<_Ndim;idim++)
1771 _absAroe[(1+idim)*_nVar]=-K*_vec_normal[idim] - u_n*_Uroe[1+idim];
1772 //colonnes intermediaires
1773 for(int jdim=0; jdim<_Ndim;jdim++)
1774 _absAroe[(1+idim)*_nVar + jdim + 1] = _Uroe[1+idim]*_vec_normal[jdim]+k*_vec_normal[idim]*_Uroe[1+jdim];
1776 _absAroe[(1+idim)*_nVar + idim + 1] += u_n;
1778 _absAroe[(1+idim)*_nVar + _nVar-1]=-k*_vec_normal[idim];
1781 //derniere ligne (energie)
1782 _absAroe[_nVar*(_nVar-1)] = (-K - H)*u_n;
1783 for(int idim=0; idim<_Ndim;idim++)
1784 _absAroe[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] + k*u_n*_Uroe[idim+1];
1785 _absAroe[_nVar*_nVar -1] = (1 - k)*u_n;
1793 for(int i=0; i<_nVar*_nVar;i++)
1794 _absAroe[i] *= signu;
1796 else//umn=0 ->centered scheme
1798 for(int i=0; i<_nVar*_nVar;i++)
1802 void SinglePhase::staggeredRoeUpwindingMatrixPrimitiveVariables(double rho, double u_n,double H, Vector vitesse)
1804 //Not used. Suppress or use in alternative implicitation in primitive variable of the staggered-roe scheme
1805 //Calcul de décentrement de type décalé pour formulation Roe
1806 _AroeImplicit[0*_nVar+0]=_drho_sur_dp*u_n;
1807 for(int i=0;i<_Ndim;i++)
1808 _AroeImplicit[0*_nVar+1+i]=rho*_vec_normal[i];
1809 _AroeImplicit[0*_nVar+1+_Ndim]=_drho_sur_dT*u_n;
1810 for(int i=0;i<_Ndim;i++)
1812 _AroeImplicit[(1+i)*_nVar+0]=_drho_sur_dp *u_n*vitesse[i]-_vec_normal[i];
1813 for(int j=0;j<_Ndim;j++)
1814 _AroeImplicit[(1+i)*_nVar+1+j]=rho*vitesse[i]*_vec_normal[j];
1815 _AroeImplicit[(1+i)*_nVar+1+i]+=rho*u_n;
1816 _AroeImplicit[(1+i)*_nVar+1+_Ndim]=_drho_sur_dT*u_n*vitesse[i];
1818 _AroeImplicit[(1+_Ndim)*_nVar+0]=(_drhoE_sur_dp+1)*u_n;
1819 for(int i=0;i<_Ndim;i++)
1820 _AroeImplicit[(1+_Ndim)*_nVar+1+i]=rho*(H*_vec_normal[i]+u_n*vitesse[i]);
1821 _AroeImplicit[(1+_Ndim)*_nVar+1+_Ndim]=_drhoE_sur_dT*u_n;
1824 Vector SinglePhase::staggeredVFFCFlux()
1826 if(_verbose && _nbTimeStep%_freqSave ==0)
1827 cout<<"SinglePhase::staggeredVFFCFlux() start"<<endl;
1829 if(_spaceScheme!=staggered || _nonLinearFormulation!=VFFC)
1831 *_runLogFile<< "SinglePhase::staggeredVFFCFlux: staggeredVFFCFlux method should be called only for VFFC formulation and staggered upwinding, pressure = "<< endl;
1832 _runLogFile->close();
1833 throw CdmathException("SinglePhase::staggeredVFFCFlux: staggeredVFFCFlux method should be called only for VFFC formulation and staggered upwinding");
1835 else//_spaceScheme==staggered && _nonLinearFormulation==VFFC
1839 double uijn=0, phiqn=0, uin=0, ujn=0;
1840 for(int idim=0;idim<_Ndim;idim++)
1842 uijn+=_vec_normal[idim]*_Uroe[1+idim];//URoe = rho, u, H
1843 uin +=_vec_normal[idim]*_Ui[1+idim];
1844 ujn +=_vec_normal[idim]*_Uj[1+idim];
1847 if( (uin>0 && ujn >0) || (uin>=0 && ujn <=0 && uijn>0) ) // formerly (uijn>_precision)
1849 for(int idim=0;idim<_Ndim;idim++)
1850 phiqn+=_vec_normal[idim]*_Ui[1+idim];//phi rho u n
1852 for(int idim=0;idim<_Ndim;idim++)
1853 Fij(1+idim)=phiqn*_Vi[1+idim]+_Vj[0]*_vec_normal[idim]*_porosityj;
1854 Fij(_nVar-1)=phiqn/_Ui[0]*(_Ui[_nVar-1]+_Vj[0]*sqrt(_porosityj/_porosityi));
1856 else if( (uin<0 && ujn <0) || (uin>=0 && ujn <=0 && uijn<0) ) // formerly (uijn<-_precision)
1858 for(int idim=0;idim<_Ndim;idim++)
1859 phiqn+=_vec_normal[idim]*_Uj[1+idim];//phi rho u n
1861 for(int idim=0;idim<_Ndim;idim++)
1862 Fij(1+idim)=phiqn*_Vj[1+idim]+_Vi[0]*_vec_normal[idim]*_porosityi;
1863 Fij(_nVar-1)=phiqn/_Uj[0]*(_Uj[_nVar-1]+_Vi[0]*sqrt(_porosityi/_porosityj));
1865 else//case (uin<=0 && ujn >=0) or (uin>=0 && ujn <=0 && uijn==0), apply centered scheme
1867 Vector Ui(_nVar), Uj(_nVar), Vi(_nVar), Vj(_nVar), Fi(_nVar), Fj(_nVar);
1868 Vector normale(_Ndim);
1869 for(int i1=0;i1<_Ndim;i1++)
1870 normale(i1)=_vec_normal[i1];
1871 for(int i1=0;i1<_nVar;i1++)
1878 Fi=convectionFlux(Ui,Vi,normale,_porosityi);
1879 Fj=convectionFlux(Uj,Vj,normale,_porosityj);
1880 Fij=(Fi+Fj)/2;//+_maxvploc*(Ui-Uj)/2;
1882 if(_verbose && _nbTimeStep%_freqSave ==0)
1884 cout<<"SinglePhase::staggeredVFFCFlux() endf uijn="<<uijn<<endl;
1891 void SinglePhase::staggeredVFFCMatricesConservativeVariables(double un)//vitesse normale de Roe en entrée
1893 if(_verbose && _nbTimeStep%_freqSave ==0)
1894 cout<<"SinglePhase::staggeredVFFCMatrices()"<<endl;
1896 if(_spaceScheme!=staggered || _nonLinearFormulation!=VFFC)
1898 *_runLogFile<< "SinglePhase::staggeredVFFCMatrices: staggeredVFFCMatrices method should be called only for VFFC formulation and staggered upwinding"<< endl;
1899 _runLogFile->close();
1900 throw CdmathException("SinglePhase::staggeredVFFCMatrices: staggeredVFFCMatrices method should be called only for VFFC formulation and staggered upwinding");
1902 else//_spaceScheme==staggered && _nonLinearFormulation==VFFC
1904 double ui_n=0, ui_2=0, uj_n=0, uj_2=0;//vitesse normale et carré du module
1905 double H;//enthalpie totale (expression particulière)
1906 consToPrim(_Ui,_Vi,_porosityi);
1907 consToPrim(_Uj,_Vj,_porosityj);
1908 for(int i=0;i<_Ndim;i++)
1910 ui_2 += _Vi[1+i]*_Vi[1+i];
1911 ui_n += _Vi[1+i]*_vec_normal[i];
1912 uj_2 += _Vj[1+i]*_Vj[1+i];
1913 uj_n += _Vj[1+i]*_vec_normal[i];
1916 double rhoi,pj, Ei, rhoj;
1917 double cj, Kj, kj;//dérivées de la pression
1918 rhoi=_Ui[0]/_porosityi;
1919 Ei= _Ui[_Ndim+1]/(rhoi*_porosityi);
1921 rhoj=_Uj[0]/_porosityj;
1923 cj = _fluides[0]->vitesseSonTemperature(_Vj[_Ndim+1],rhoj);
1924 kj = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
1925 Kj = uj_2*kj/2; //g-1/2 *|u|²
1928 double ci, Ki, ki;//dérivées de la pression
1929 Ej= _Uj[_Ndim+1]/rhoj;
1932 ci = _fluides[0]->vitesseSonTemperature(_Vi[_Ndim+1],rhoi);
1933 ki = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
1934 Ki = ui_2*ki/2; //g-1/2 *|u|²
1938 /***********Calcul des valeurs propres ********/
1939 vector<complex<double> > vp_dist(3,0);
1940 vp_dist[0]=ui_n-cj;vp_dist[1]=ui_n;vp_dist[2]=ui_n+cj;
1942 _maxvploc=fabs(ui_n)+cj;
1943 if(_maxvploc>_maxvp)
1946 if(_verbose && _nbTimeStep%_freqSave ==0)
1947 cout<<"Valeurs propres "<<ui_n-cj<<" , "<<ui_n<<" , "<<ui_n+cj<<endl;
1949 /******** Construction de la matrice A^+ *********/
1950 //premiere ligne (masse)
1952 for(int idim=0; idim<_Ndim;idim++)
1953 _AroePlus[1+idim]=_vec_normal[idim];
1954 _AroePlus[_nVar-1]=0;
1956 //lignes intermadiaires(qdm)
1957 for(int idim=0; idim<_Ndim;idim++)
1960 _AroePlus[(1+idim)*_nVar]=- ui_n*_Vi[1+idim];
1961 //colonnes intermediaires
1962 for(int jdim=0; jdim<_Ndim;jdim++)
1963 _AroePlus[(1+idim)*_nVar + jdim + 1] = _Vi[1+idim]*_vec_normal[jdim];
1965 _AroePlus[(1+idim)*_nVar + idim + 1] += ui_n;
1967 _AroePlus[(1+idim)*_nVar + _nVar-1]=0;
1970 //derniere ligne (energie)
1971 _AroePlus[_nVar*(_nVar-1)] = - H*ui_n;
1972 for(int idim=0; idim<_Ndim;idim++)
1973 _AroePlus[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] ;
1974 _AroePlus[_nVar*_nVar -1] = ui_n;
1976 /******** Construction de la matrice A^- *********/
1977 //premiere ligne (masse)
1979 for(int idim=0; idim<_Ndim;idim++)
1980 _AroeMinus[1+idim]=0;
1981 _AroeMinus[_nVar-1]=0;
1983 //lignes intermadiaires(qdm)
1984 for(int idim=0; idim<_Ndim;idim++)
1987 _AroeMinus[(1+idim)*_nVar]=Kj*_vec_normal[idim] ;
1988 //colonnes intermediaires
1989 for(int jdim=0; jdim<_Ndim;jdim++)
1990 _AroeMinus[(1+idim)*_nVar + jdim + 1] = -kj*_vec_normal[idim]*_Vj[1+jdim];
1992 _AroeMinus[(1+idim)*_nVar + idim + 1] += 0;
1994 _AroeMinus[(1+idim)*_nVar + _nVar-1]=kj*_vec_normal[idim];
1997 //derniere ligne (energie)
1998 _AroeMinus[_nVar*(_nVar-1)] = Kj *ui_n;
1999 for(int idim=0; idim<_Ndim;idim++)
2000 _AroeMinus[_nVar*(_nVar-1)+idim+1]= - kj*uj_n*_Vi[idim+1];
2001 _AroeMinus[_nVar*_nVar -1] = kj*ui_n;
2003 else if(un<-_precision)
2005 /***********Calcul des valeurs propres ********/
2006 vector<complex<double> > vp_dist(3,0);
2007 vp_dist[0]=uj_n-ci;vp_dist[1]=uj_n;vp_dist[2]=uj_n+ci;
2009 _maxvploc=fabs(uj_n)+ci;
2010 if(_maxvploc>_maxvp)
2013 if(_verbose && _nbTimeStep%_freqSave ==0)
2014 cout<<"Valeurs propres "<<uj_n-ci<<" , "<<uj_n<<" , "<<uj_n+ci<<endl;
2016 /******** Construction de la matrice A^+ *********/
2017 //premiere ligne (masse)
2019 for(int idim=0; idim<_Ndim;idim++)
2020 _AroePlus[1+idim]=0;
2021 _AroePlus[_nVar-1]=0;
2023 //lignes intermadiaires(qdm)
2024 for(int idim=0; idim<_Ndim;idim++)
2027 _AroePlus[(1+idim)*_nVar]=Ki*_vec_normal[idim] ;
2028 //colonnes intermediaires
2029 for(int jdim=0; jdim<_Ndim;jdim++)
2030 _AroePlus[(1+idim)*_nVar + jdim + 1] = -ki*_vec_normal[idim]*_Vi[1+jdim];
2032 _AroePlus[(1+idim)*_nVar + idim + 1] += 0;
2034 _AroePlus[(1+idim)*_nVar + _nVar-1]=ki*_vec_normal[idim];
2037 //derniere ligne (energie)
2038 _AroePlus[_nVar*(_nVar-1)] = Ki *uj_n;
2039 for(int idim=0; idim<_Ndim;idim++)
2040 _AroePlus[_nVar*(_nVar-1)+idim+1]= - ki*ui_n*_Vj[idim+1];
2041 _AroePlus[_nVar*_nVar -1] = ki*uj_n;
2043 /******** Construction de la matrice A^- *********/
2044 //premiere ligne (masse)
2046 for(int idim=0; idim<_Ndim;idim++)
2047 _AroeMinus[1+idim]=_vec_normal[idim];
2048 _AroeMinus[_nVar-1]=0;
2050 //lignes intermadiaires(qdm)
2051 for(int idim=0; idim<_Ndim;idim++)
2054 _AroeMinus[(1+idim)*_nVar]= - uj_n*_Vj[1+idim];
2055 //colonnes intermediaires
2056 for(int jdim=0; jdim<_Ndim;jdim++)
2057 _AroeMinus[(1+idim)*_nVar + jdim + 1] = _Vj[1+idim]*_vec_normal[jdim];
2059 _AroeMinus[(1+idim)*_nVar + idim + 1] += uj_n;
2061 _AroeMinus[(1+idim)*_nVar + _nVar-1]=0;
2064 //derniere ligne (energie)
2065 _AroeMinus[_nVar*(_nVar-1)] = - H*uj_n;
2066 for(int idim=0; idim<_Ndim;idim++)
2067 _AroeMinus[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] ;
2068 _AroeMinus[_nVar*_nVar -1] = uj_n;
2070 else//case nil velocity on the interface, apply centered scheme
2072 double u_n=0, u_2=0;//vitesse normale et carré du module
2073 for(int i=0;i<_Ndim;i++)
2075 u_2 += _Uroe[1+i]*_Uroe[1+i];
2076 u_n += _Uroe[1+i]*_vec_normal[i];
2078 Vector vitesse(_Ndim);
2079 for(int idim=0;idim<_Ndim;idim++)
2080 vitesse[idim]=_Uroe[1+idim];
2083 /***********Calcul des valeurs propres ********/
2085 c = _fluides[0]->vitesseSonEnthalpie(H-u_2/2);//vitesse du son a l'interface
2086 k = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
2087 K = u_2*k/2; //g-1/2 *|u|²
2089 _maxvploc=fabs(u_n)+c;
2090 if(_maxvploc>_maxvp)
2093 /******** Construction de la matrice A^+ *********/
2094 //premiere ligne (masse)
2096 for(int idim=0; idim<_Ndim;idim++)
2097 _AroePlus[1+idim]=0;
2098 _AroePlus[_nVar-1]=0;
2100 //lignes intermadiaires(qdm)
2101 for(int idim=0; idim<_Ndim;idim++)
2104 _AroePlus[(1+idim)*_nVar]=- ui_n*_Vi[1+idim];
2105 //colonnes intermediaires
2106 for(int jdim=0; jdim<_Ndim;jdim++)
2107 _AroePlus[(1+idim)*_nVar + jdim + 1] = _Vi[1+idim]*_vec_normal[jdim]-0.5*ki*_vec_normal[idim]*_Vi[1+jdim];
2109 _AroePlus[(1+idim)*_nVar + idim + 1] += 0.5*ui_n;
2111 _AroePlus[(1+idim)*_nVar + _nVar-1]=0.5*ki*_vec_normal[idim];
2114 //derniere ligne (energie)
2115 _AroePlus[_nVar*(_nVar-1)] = 0;
2116 for(int idim=0; idim<_Ndim;idim++)
2117 _AroePlus[_nVar*(_nVar-1)+idim+1]=0 ;
2118 _AroePlus[_nVar*_nVar -1] = 0;
2120 /******** Construction de la matrice A^- *********/
2121 //premiere ligne (masse)
2123 for(int idim=0; idim<_Ndim;idim++)
2124 _AroeMinus[1+idim]=0;
2125 _AroeMinus[_nVar-1]=0;
2127 //lignes intermadiaires(qdm)
2128 for(int idim=0; idim<_Ndim;idim++)
2131 _AroeMinus[(1+idim)*_nVar]=Kj*_vec_normal[idim] - uj_n*_Vj[1+idim];
2132 //colonnes intermediaires
2133 for(int jdim=0; jdim<_Ndim;jdim++)
2134 _AroeMinus[(1+idim)*_nVar + jdim + 1] = -0.5*kj*_vec_normal[idim]*_Vj[1+jdim];
2136 _AroeMinus[(1+idim)*_nVar + idim + 1] += 0.5*uj_n;
2138 _AroeMinus[(1+idim)*_nVar + _nVar-1]=0.5*kj*_vec_normal[idim];
2141 //derniere ligne (energie)
2142 _AroeMinus[_nVar*(_nVar-1)] = 0;
2143 for(int idim=0; idim<_Ndim;idim++)
2144 _AroeMinus[_nVar*(_nVar-1)+idim+1]= 0;
2145 _AroeMinus[_nVar*_nVar -1] = 0;
2148 if(_timeScheme==Implicit)
2149 for(int i=0; i<_nVar*_nVar;i++)
2151 _AroeMinusImplicit[i] = _AroeMinus[i];
2152 _AroePlusImplicit[i] = _AroePlus[i];
2155 /******** Construction de la matrices Aroe *********/
2157 //premiere ligne (masse)
2159 for(int idim=0; idim<_Ndim;idim++)
2160 _Aroe[1+idim]=_vec_normal[idim];
2163 //lignes intermadiaires(qdm)
2164 for(int idim=0; idim<_Ndim;idim++)
2167 _Aroe[(1+idim)*_nVar]=Ki*_vec_normal[idim] - uj_n*_Uj[1+idim];
2168 //colonnes intermediaires
2169 for(int jdim=0; jdim<_Ndim;jdim++)
2170 _Aroe[(1+idim)*_nVar + jdim + 1] = _Uj[1+idim]*_vec_normal[jdim]-ki*_vec_normal[idim]*_Ui[1+jdim];
2172 _Aroe[(1+idim)*_nVar + idim + 1] += uj_n;
2174 _Aroe[(1+idim)*_nVar + _nVar-1]=ki*_vec_normal[idim];
2177 //derniere ligne (energie)
2178 _Aroe[_nVar*(_nVar-1)] = (Ki - H)*uj_n;
2179 for(int idim=0; idim<_Ndim;idim++)
2180 _Aroe[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] - ki*ui_n*_Uj[idim+1];
2181 _Aroe[_nVar*_nVar -1] = (1 + ki)*uj_n;
2185 void SinglePhase::staggeredVFFCMatricesPrimitiveVariables(double un)//vitesse normale de Roe en entrée
2187 if(_verbose && _nbTimeStep%_freqSave ==0)
2188 cout<<"SinglePhase::staggeredVFFCMatricesPrimitiveVariables()"<<endl;
2190 if(_spaceScheme!=staggered || _nonLinearFormulation!=VFFC)
2192 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: staggeredVFFCMatricesPrimitiveVariables method should be called only for VFFC formulation and staggered upwinding" << endl;
2193 _runLogFile->close();
2194 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: staggeredVFFCMatricesPrimitiveVariables method should be called only for VFFC formulation and staggered upwinding");
2196 else//_spaceScheme==staggered && _nonLinearFormulation==VFFC
2198 double ui_n=0., ui_2=0., uj_n=0., uj_2=0.;//vitesse normale et carré du module
2199 double H;//enthalpie totale (expression particulière)
2200 consToPrim(_Ui,_Vi,_porosityi);
2201 consToPrim(_Uj,_Vj,_porosityj);
2203 for(int i=0;i<_Ndim;i++)
2205 ui_2 += _Vi[1+i]*_Vi[1+i];
2206 ui_n += _Vi[1+i]*_vec_normal[i];
2207 uj_2 += _Vj[1+i]*_Vj[1+i];
2208 uj_n += _Vj[1+i]*_vec_normal[i];
2211 if(_verbose && _nbTimeStep%_freqSave ==0){
2212 cout <<"SinglePhase::staggeredVFFCMatricesPrimitiveVariables " << endl;
2213 cout<<"Vecteur primitif _Vi" << endl;
2214 for(int i=0;i<_nVar;i++)
2217 cout<<"Vecteur primitif _Vj" << endl;
2218 for(int i=0;i<_nVar;i++)
2223 double gamma=_fluides[0]->constante("gamma");
2224 double q=_fluides[0]->constante("q");
2226 if(fabs(un)>_precision)//non zero velocity on the interface
2228 if( !_useDellacherieEOS)
2230 StiffenedGas* fluide0=dynamic_cast<StiffenedGas*>(_fluides[0]);
2231 double cv=fluide0->constante("cv");
2235 double rhoi,rhoj,pj, Ei, ei;
2236 double cj;//vitesse du son pour calcul valeurs propres
2237 rhoi=_Ui[0]/_porosityi;
2238 Ei= _Ui[_Ndim+1]/(rhoi*_porosityi);
2241 rhoj=_Uj[0]/_porosityj;
2242 cj = _fluides[0]->vitesseSonTemperature(_Vj[_Ndim+1],rhoj);
2244 /***********Calcul des valeurs propres ********/
2245 vector<complex<double> > vp_dist(3,0);
2246 vp_dist[0]=ui_n-cj;vp_dist[1]=ui_n;vp_dist[2]=ui_n+cj;
2248 _maxvploc=fabs(ui_n)+cj;
2249 if(_maxvploc>_maxvp)
2252 if(_verbose && _nbTimeStep%_freqSave ==0)
2253 cout<<"Valeurs propres "<<ui_n-cj<<" , "<<ui_n<<" , "<<ui_n+cj<<endl;
2255 /******** Construction de la matrice A^+ *********/
2256 //premiere ligne (masse)
2257 _AroePlusImplicit[0]=ui_n/((gamma-1)*(ei-q));
2258 for(int idim=0; idim<_Ndim;idim++)
2259 _AroePlusImplicit[1+idim]=rhoi*_vec_normal[idim];
2260 _AroePlusImplicit[_nVar-1]=-rhoi*ui_n*cv/(ei-q);
2262 //lignes intermadiaires(qdm)
2263 for(int idim=0; idim<_Ndim;idim++)
2266 _AroePlusImplicit[(1+idim)*_nVar]=ui_n/((gamma-1)*(ei-q))*_Vi[1+idim];
2267 //colonnes intermediaires
2268 for(int jdim=0; jdim<_Ndim;jdim++)
2269 _AroePlusImplicit[(1+idim)*_nVar + jdim + 1] = rhoi*_Vi[1+idim]*_vec_normal[jdim];
2271 _AroePlusImplicit[(1+idim)*_nVar + idim + 1] += rhoi*ui_n;
2273 _AroePlusImplicit[(1+idim)*_nVar + _nVar-1]=-rhoi*ui_n*cv/(ei-q)*_Vi[1+idim];
2276 //derniere ligne (energie)
2277 _AroePlusImplicit[_nVar*(_nVar-1)] = Ei*ui_n/((gamma-1)*(ei-q));
2278 for(int idim=0; idim<_Ndim;idim++)
2279 _AroePlusImplicit[_nVar*(_nVar-1)+idim+1]=(rhoi*Ei+pj)*_vec_normal[idim]+rhoi*ui_n*_Vi[1+idim];
2280 _AroePlusImplicit[_nVar*_nVar -1] = rhoi*ui_n*(1-Ei/(ei-q))*cv;
2282 /******** Construction de la matrice A^- *********/
2283 //premiere ligne (masse)
2284 _AroeMinusImplicit[0]=0;
2285 for(int idim=0; idim<_Ndim;idim++)
2286 _AroeMinusImplicit[1+idim]=0;
2287 _AroeMinusImplicit[_nVar-1]=0;
2289 //lignes intermadiaires(qdm)
2290 for(int idim=0; idim<_Ndim;idim++)
2293 _AroeMinusImplicit[(1+idim)*_nVar]=_vec_normal[idim] ;
2294 //colonnes intermediaires
2295 for(int jdim=0; jdim<_Ndim;jdim++)
2296 _AroeMinusImplicit[(1+idim)*_nVar + jdim + 1] = 0;
2298 _AroeMinusImplicit[(1+idim)*_nVar + idim + 1] += 0;
2300 _AroeMinusImplicit[(1+idim)*_nVar + _nVar-1]=0;
2303 //derniere ligne (energie)
2304 _AroeMinusImplicit[_nVar*(_nVar-1)] = ui_n;
2305 for(int idim=0; idim<_Ndim;idim++)
2306 _AroeMinusImplicit[_nVar*(_nVar-1)+idim+1]= 0;
2307 _AroeMinusImplicit[_nVar*_nVar -1] = 0;
2309 else if(un<-_precision)
2311 double pi, Ej, rhoi, rhoj, ej;
2312 double ci;//vitesse du son pour calcul valeurs propres
2313 rhoj=_Uj[0]/_porosityj;
2314 Ej= _Uj[_Ndim+1]/rhoj;
2317 rhoi=_Ui[0]/_porosityi;
2318 ci = _fluides[0]->vitesseSonTemperature(_Vi[_Ndim+1],rhoi);
2320 /***********Calcul des valeurs propres ********/
2321 vector<complex<double> > vp_dist(3,0);
2322 vp_dist[0]=uj_n-ci;vp_dist[1]=uj_n;vp_dist[2]=uj_n+ci;
2324 _maxvploc=fabs(uj_n)+ci;
2325 if(_maxvploc>_maxvp)
2328 if(_verbose && _nbTimeStep%_freqSave ==0)
2329 cout<<"Valeurs propres "<<uj_n-ci<<" , "<<uj_n<<" , "<<uj_n+ci<<endl;
2331 /******** Construction de la matrice A^+ *********/
2332 //premiere ligne (masse)
2333 _AroePlusImplicit[0]=0;
2334 for(int idim=0; idim<_Ndim;idim++)
2335 _AroePlusImplicit[1+idim]=0;
2336 _AroePlusImplicit[_nVar-1]=0;
2338 //lignes intermadiaires(qdm)
2339 for(int idim=0; idim<_Ndim;idim++)
2342 _AroePlusImplicit[(1+idim)*_nVar]=0;
2343 //colonnes intermediaires
2344 for(int jdim=0; jdim<_Ndim;jdim++)
2345 _AroePlusImplicit[(1+idim)*_nVar + jdim + 1] = 0;
2347 _AroePlusImplicit[(1+idim)*_nVar + idim + 1] += 0;
2349 _AroePlusImplicit[(1+idim)*_nVar + _nVar-1]=0;
2352 //derniere ligne (energie)
2353 _AroePlusImplicit[_nVar*(_nVar-1)] = uj_n;
2354 for(int idim=0; idim<_Ndim;idim++)
2355 _AroePlusImplicit[_nVar*(_nVar-1)+idim+1]= 0;
2356 _AroePlusImplicit[_nVar*_nVar -1] = 0;
2358 /******** Construction de la matrice A^- *********/
2359 //premiere ligne (masse)
2360 _AroeMinusImplicit[0]=uj_n/((gamma-1)*(ej-q));
2361 for(int idim=0; idim<_Ndim;idim++)
2362 _AroeMinusImplicit[1+idim]=rhoj*_vec_normal[idim];
2363 _AroeMinusImplicit[_nVar-1]=-rhoj*uj_n*cv/(ej-q);
2365 //lignes intermadiaires(qdm)
2366 for(int idim=0; idim<_Ndim;idim++)
2369 _AroeMinusImplicit[(1+idim)*_nVar]= uj_n/((gamma-1)*(ej-q))*_Vj[1+idim];
2370 //colonnes intermediaires
2371 for(int jdim=0; jdim<_Ndim;jdim++)
2372 _AroeMinusImplicit[(1+idim)*_nVar + jdim + 1] = rhoj*_Vj[1+idim]*_vec_normal[jdim];
2374 _AroeMinusImplicit[(1+idim)*_nVar + idim + 1] += rhoj*uj_n;
2376 _AroeMinusImplicit[(1+idim)*_nVar + _nVar-1]=-rhoj*uj_n*cv/(ej-q)*_Vj[1+idim];
2379 //derniere ligne (energie)
2380 _AroeMinusImplicit[_nVar*(_nVar-1)] = Ej*uj_n/((gamma-1)*(ej-q));
2381 for(int idim=0; idim<_Ndim;idim++)
2382 _AroeMinusImplicit[_nVar*(_nVar-1)+idim+1]=(rhoj*Ej+pi)*_vec_normal[idim]+rhoj*uj_n*_Vj[1+idim];
2383 _AroeMinusImplicit[_nVar*_nVar -1] = rhoj*uj_n*(1-Ej/(ej-q))*cv;
2387 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: velocity un should be non zero" << endl;
2388 _runLogFile->close();
2389 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: velocity un should be non zero");
2392 else if(_useDellacherieEOS )
2394 StiffenedGasDellacherie* fluide0=dynamic_cast<StiffenedGasDellacherie*>(_fluides[0]);
2395 double cp=fluide0->constante("cp");
2399 double rhoi,rhoj,pj, Ei, hi, Hi;
2400 double cj;//vitesse du son pour calcul valeurs propres
2401 rhoi=_Ui[0]/_porosityi;
2402 Ei= _Ui[_Ndim+1]/(rhoi*_porosityi);
2406 rhoj=_Uj[0]/_porosityj;
2407 cj = _fluides[0]->vitesseSonTemperature(_Vj[_Ndim+1],rhoj);
2409 /***********Calcul des valeurs propres ********/
2410 vector<complex<double> > vp_dist(3,0);
2411 vp_dist[0]=ui_n-cj;vp_dist[1]=ui_n;vp_dist[2]=ui_n+cj;
2413 _maxvploc=fabs(ui_n)+cj;
2414 if(_maxvploc>_maxvp)
2417 if(_verbose && _nbTimeStep%_freqSave ==0)
2418 cout<<"Valeurs propres "<<ui_n-cj<<" , "<<ui_n<<" , "<<ui_n+cj<<endl;
2420 /******** Construction de la matrice A^+ *********/
2421 //premiere ligne (masse)
2422 _AroePlusImplicit[0]=ui_n*gamma/((gamma-1)*(hi-q));
2423 for(int idim=0; idim<_Ndim;idim++)
2424 _AroePlusImplicit[1+idim]=rhoi*_vec_normal[idim];
2425 _AroePlusImplicit[_nVar-1]=-rhoi*ui_n*cp/(hi-q);
2427 //lignes intermadiaires(qdm)
2428 for(int idim=0; idim<_Ndim;idim++)
2431 _AroePlusImplicit[(1+idim)*_nVar]=ui_n*gamma/((gamma-1)*(hi-q))*_Vi[1+idim];
2432 //colonnes intermediaires
2433 for(int jdim=0; jdim<_Ndim;jdim++)
2434 _AroePlusImplicit[(1+idim)*_nVar + jdim + 1] = rhoi*_Vi[1+idim]*_vec_normal[jdim];
2436 _AroePlusImplicit[(1+idim)*_nVar + idim + 1] += rhoi*ui_n;
2438 _AroePlusImplicit[(1+idim)*_nVar + _nVar-1]=-rhoi*ui_n*cp/(hi-q)*_Vi[1+idim];
2441 //derniere ligne (energie)
2442 _AroePlusImplicit[_nVar*(_nVar-1)] = ui_n*(Hi*gamma/((gamma-1)*(hi-q))-1);
2443 for(int idim=0; idim<_Ndim;idim++)
2444 _AroePlusImplicit[_nVar*(_nVar-1)+idim+1]=(rhoi*Ei+pj)*_vec_normal[idim]+rhoi*ui_n*_Vi[1+idim];
2445 _AroePlusImplicit[_nVar*_nVar -1] = rhoi*ui_n*(1-Hi/(hi-q))*cp;
2447 /******** Construction de la matrice A^- *********/
2448 //premiere ligne (masse)
2449 _AroeMinusImplicit[0]=0;
2450 for(int idim=0; idim<_Ndim;idim++)
2451 _AroeMinusImplicit[1+idim]=0;
2452 _AroeMinusImplicit[_nVar-1]=0;
2454 //lignes intermadiaires(qdm)
2455 for(int idim=0; idim<_Ndim;idim++)
2458 _AroeMinusImplicit[(1+idim)*_nVar]=_vec_normal[idim] ;
2459 //colonnes intermediaires
2460 for(int jdim=0; jdim<_Ndim;jdim++)
2461 _AroeMinusImplicit[(1+idim)*_nVar + jdim + 1] = 0;
2463 _AroeMinusImplicit[(1+idim)*_nVar + idim + 1] += 0;
2465 _AroeMinusImplicit[(1+idim)*_nVar + _nVar-1]=0;
2468 //derniere ligne (energie)
2469 _AroeMinusImplicit[_nVar*(_nVar-1)] = ui_n;
2470 for(int idim=0; idim<_Ndim;idim++)
2471 _AroeMinusImplicit[_nVar*(_nVar-1)+idim+1]= 0;
2472 _AroeMinusImplicit[_nVar*_nVar -1] = 0;
2474 else if(un<-_precision)
2476 double pi, Ej, rhoi,rhoj, Hj, hj;
2477 double ci;//vitesse du son pour calcul valeurs propres
2478 rhoj=_Uj[0]/_porosityj;
2479 Ej= _Uj[_Ndim+1]/rhoj;
2483 rhoi=_Ui[0]/_porosityi;
2484 ci = _fluides[0]->vitesseSonTemperature(_Vi[_Ndim+1],rhoi);
2486 /***********Calcul des valeurs propres ********/
2487 vector<complex<double> > vp_dist(3,0);
2488 vp_dist[0]=uj_n-ci;vp_dist[1]=uj_n;vp_dist[2]=uj_n+ci;
2490 _maxvploc=fabs(uj_n)+ci;
2491 if(_maxvploc>_maxvp)
2494 if(_verbose && _nbTimeStep%_freqSave ==0)
2495 cout<<"Valeurs propres "<<uj_n-ci<<" , "<<uj_n<<" , "<<uj_n+ci<<endl;
2497 /******** Construction de la matrice A^+ *********/
2498 //premiere ligne (masse)
2499 _AroePlusImplicit[0]=0;
2500 for(int idim=0; idim<_Ndim;idim++)
2501 _AroePlusImplicit[1+idim]=0;
2502 _AroePlusImplicit[_nVar-1]=0;
2504 //lignes intermadiaires(qdm)
2505 for(int idim=0; idim<_Ndim;idim++)
2508 _AroePlusImplicit[(1+idim)*_nVar]=0;
2509 //colonnes intermediaires
2510 for(int jdim=0; jdim<_Ndim;jdim++)
2511 _AroePlusImplicit[(1+idim)*_nVar + jdim + 1] = 0;
2513 _AroePlusImplicit[(1+idim)*_nVar + idim + 1] += 0;
2515 _AroePlusImplicit[(1+idim)*_nVar + _nVar-1]=0;
2518 //derniere ligne (energie)
2519 _AroePlusImplicit[_nVar*(_nVar-1)] = uj_n;
2520 for(int idim=0; idim<_Ndim;idim++)
2521 _AroePlusImplicit[_nVar*(_nVar-1)+idim+1]= 0;
2522 _AroePlusImplicit[_nVar*_nVar -1] = 0;
2524 /******** Construction de la matrice A^- *********/
2525 //premiere ligne (masse)
2526 _AroeMinusImplicit[0]=uj_n*gamma/((gamma-1)*(hj-q));
2527 for(int idim=0; idim<_Ndim;idim++)
2528 _AroeMinusImplicit[1+idim]=rhoj*_vec_normal[idim];
2529 _AroeMinusImplicit[_nVar-1]=-rhoj*uj_n*cp/(hj-q);
2531 //lignes intermadiaires(qdm)
2532 for(int idim=0; idim<_Ndim;idim++)
2535 _AroeMinusImplicit[(1+idim)*_nVar]= uj_n*gamma/((gamma-1)*(hj-q))*_Vj[1+idim];
2536 //colonnes intermediaires
2537 for(int jdim=0; jdim<_Ndim;jdim++)
2538 _AroeMinusImplicit[(1+idim)*_nVar + jdim + 1] = rhoj*_Vj[1+idim]*_vec_normal[jdim];
2540 _AroeMinusImplicit[(1+idim)*_nVar + idim + 1] += rhoj*uj_n;
2542 _AroeMinusImplicit[(1+idim)*_nVar + _nVar-1]=-rhoj*uj_n*cp/(hj-q)*_Vj[1+idim];
2545 //derniere ligne (energie)
2546 _AroeMinusImplicit[_nVar*(_nVar-1)] = uj_n*(Hj*gamma/((gamma-1)*(hj-q))-1);
2547 for(int idim=0; idim<_Ndim;idim++)
2548 _AroeMinusImplicit[_nVar*(_nVar-1)+idim+1]=(rhoj*Ej+pi)*_vec_normal[idim]+rhoj*uj_n*_Vj[1+idim];
2549 _AroeMinusImplicit[_nVar*_nVar -1] = rhoj*uj_n*(1-Hj/(hj-q))*cp;
2553 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: velocity un should be non zero" << endl;
2554 _runLogFile->close();
2555 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: velocity un should be non zero");
2560 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie" << endl;
2561 _runLogFile->close();
2562 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie");
2565 else//case nil velocity on the interface, apply centered scheme
2567 primToConsJacobianMatrix(_Vj);
2568 Polynoms::matrixProduct(_AroeMinus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroeMinusImplicit);
2569 primToConsJacobianMatrix(_Vi);
2570 Polynoms::matrixProduct(_AroePlus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroePlusImplicit);
2574 void SinglePhase::applyVFRoeLowMachCorrections(bool isBord, string groupname)
2576 if(_nonLinearFormulation!=VFRoe)
2578 *_runLogFile<< "SinglePhase::applyVFRoeLowMachCorrections: applyVFRoeLowMachCorrections method should be called only for VFRoe formulation" << endl;
2579 _runLogFile->close();
2580 throw CdmathException("SinglePhase::applyVFRoeLowMachCorrections: applyVFRoeLowMachCorrections method should be called only for VFRoe formulation");
2582 else//_nonLinearFormulation==VFRoe
2584 if(_spaceScheme==lowMach){
2586 for(int i=0;i<_Ndim;i++)
2587 u_2 += _Uroe[1+i]*_Uroe[1+i];
2588 double c = _maxvploc;//vitesse du son a l'interface
2589 double M=sqrt(u_2)/c;//Mach number
2590 _Vij[0]=M*_Vij[0]+(1-M)*(_Vi[0]+_Vj[0])/2;
2592 else if(_spaceScheme==pressureCorrection)
2593 {//order 1 : no correction, oarder 2 : correction everywhere, order 3 : correction only inside, orders 4 and 5 : special correction at boundaries
2594 if(_pressureCorrectionOrder==2 || (!isBord && _pressureCorrectionOrder==3) || (!isBord && _pressureCorrectionOrder==4) || (!isBord && _pressureCorrectionOrder==5) )
2596 double norm_uij=0, uij_n=0, ui_n=0, uj_n=0;
2597 for(int i=0;i<_Ndim;i++)
2599 norm_uij += _Uroe[1+i]*_Uroe[1+i];
2600 uij_n += _Uroe[1+i]*_vec_normal[i];
2601 ui_n += _Vi[1+i]*_vec_normal[i];
2602 uj_n += _Vj[1+i]*_vec_normal[i];
2604 norm_uij=sqrt(norm_uij);
2605 if(norm_uij>_precision)//avoid division by zero
2606 _Vij[0]=(_Vi[0]+_Vj[0])/2 + uij_n/norm_uij*(_Vj[0]-_Vi[0])/4 - _Uroe[0]*norm_uij*(uj_n-ui_n)/4;
2608 _Vij[0]=(_Vi[0]+_Vj[0])/2 - _Uroe[0]*norm_uij*(uj_n-ui_n)/4;
2610 else if(_pressureCorrectionOrder==4 && isBord)
2612 else if(_pressureCorrectionOrder==5 && isBord)
2614 double g_n=0;//scalar product of gravity and normal vector
2615 for(int i=0;i<_Ndim;i++)
2616 g_n += _GravityField3d[i]*_vec_normal[i];
2617 _Vij[0]=_Vi[0]- _Ui[0]*g_n/_inv_dxi/2;
2620 else if(_spaceScheme==staggered)
2623 for(int i=0;i<_Ndim;i++)
2624 uij_n += _Uroe[1+i]*_vec_normal[i];
2626 if(uij_n>_precision){
2628 for(int i=0;i<_Ndim;i++)
2630 _Vij[_nVar-1]=_Vi[_nVar-1];
2632 else if(uij_n<-_precision){
2634 for(int i=0;i<_Ndim;i++)
2636 _Vij[_nVar-1]=_Vj[_nVar-1];
2639 _Vij[0]=(_Vi[0]+_Vi[0])/2;
2640 for(int i=0;i<_Ndim;i++)
2641 _Vij[1+i]=(_Vj[1+i]+_Vj[1+i])/2;
2642 _Vij[_nVar-1]=(_Vj[_nVar-1]+_Vj[_nVar-1])/2;
2645 primToCons(_Vij,0,_Uij,0);
2649 void SinglePhase::testConservation()
2651 double SUM, DELTA, x;
2653 for(int i=0; i<_nVar; i++)
2657 cout << "Masse totale (kg): ";
2661 cout << "Energie totale (J): ";
2663 cout << "Quantite de mouvement totale (kg.m.s^-1): ";
2669 for(int j=0; j<_Nmailles; j++)
2671 if(!_usePrimitiveVarsInNewton)
2672 VecGetValues(_conservativeVars, 1, &I, &x);//on recupere la valeur du champ
2674 VecGetValues(_primitiveVars, 1, &I, &x);//on recupere la valeur du champ
2675 SUM += x*_mesh.getCell(j).getMeasure();
2676 VecGetValues(_newtonVariation, 1, &I, &x);//on recupere la variation du champ
2677 DELTA += x*_mesh.getCell(j).getMeasure();
2680 if(fabs(SUM)>_precision)
2681 cout << SUM << ", variation relative: " << fabs(DELTA /SUM) << endl;
2683 cout << " a une somme quasi nulle, variation absolue: " << fabs(DELTA) << endl;
2687 void SinglePhase::getDensityDerivatives( double pressure, double temperature, double v2)
2689 double rho=_fluides[0]->getDensity(pressure,temperature);
2690 double gamma=_fluides[0]->constante("gamma");
2691 double q=_fluides[0]->constante("q");
2693 if( !_useDellacherieEOS)
2695 StiffenedGas* fluide0=dynamic_cast<StiffenedGas*>(_fluides[0]);
2696 double e = fluide0->getInternalEnergy(temperature);
2697 double cv=fluide0->constante("cv");
2700 _drho_sur_dp=1/((gamma-1)*(e-q));
2701 _drho_sur_dT=-rho*cv/(e-q);
2702 _drhoE_sur_dp=E/((gamma-1)*(e-q));
2703 _drhoE_sur_dT=rho*cv*(1-E/(e-q));
2705 else if(_useDellacherieEOS )
2707 StiffenedGasDellacherie* fluide0=dynamic_cast<StiffenedGasDellacherie*>(_fluides[0]);
2708 double h=fluide0->getEnthalpy(temperature);
2710 double cp=fluide0->constante("cp");
2712 _drho_sur_dp=gamma/((gamma-1)*(h-q));
2713 _drho_sur_dT=-rho*cp/(h-q);
2714 _drhoE_sur_dp=gamma*H/((gamma-1)*(h-q))-1;
2715 _drhoE_sur_dT=rho*cp*(1-H/(h-q));
2719 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie" << endl;
2720 _runLogFile->close();
2721 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie");
2724 if(_verbose && _nbTimeStep%_freqSave ==0)
2726 cout<<"_drho_sur_dp= "<<_drho_sur_dp<<", _drho_sur_dT= "<<_drho_sur_dT<<endl;
2727 cout<<"_drhoE_sur_dp= "<<_drhoE_sur_dp<<", _drhoE_sur_dT= "<<_drhoE_sur_dT<<endl;
2730 void SinglePhase::save(){
2731 string prim(_path+"/SinglePhasePrim_");///Results
2732 string cons(_path+"/SinglePhaseCons_");
2733 string allFields(_path+"/");
2736 allFields+=_fileName;
2739 for (long i = 0; i < _Nmailles; i++){
2740 // j = 0 : pressure; j = _nVar - 1: temperature; j = 1,..,_nVar-2: velocity
2741 for (int j = 0; j < _nVar; j++){
2743 VecGetValues(_primitiveVars,1,&Ii,&_VV(i,j));
2746 if(_saveConservativeField){
2747 for (long i = 0; i < _Nmailles; i++){
2748 // j = 0 : density; j = _nVar - 1 : energy j = 1,..,_nVar-2: momentum
2749 for (int j = 0; j < _nVar; j++){
2751 VecGetValues(_conservativeVars,1,&Ii,&_UU(i,j));
2754 _UU.setTime(_time,_nbTimeStep);
2756 _VV.setTime(_time,_nbTimeStep);
2758 // create mesh and component info
2759 if (_nbTimeStep ==0 || _restartWithNewFileName){
2760 string prim_suppress ="rm -rf "+prim+"_*";
2761 string cons_suppress ="rm -rf "+cons+"_*";
2763 system(prim_suppress.c_str());//Nettoyage des précédents calculs identiques
2764 system(cons_suppress.c_str());//Nettoyage des précédents calculs identiques
2766 if(_saveConservativeField){
2767 _UU.setInfoOnComponent(0,"Density_(kg/m^3)");
2768 _UU.setInfoOnComponent(1,"Momentum_x");// (kg/m^2/s)
2770 _UU.setInfoOnComponent(2,"Momentum_y");// (kg/m^2/s)
2772 _UU.setInfoOnComponent(3,"Momentum_z");// (kg/m^2/s)
2774 _UU.setInfoOnComponent(_nVar-1,"Energy_(J/m^3)");
2789 _VV.setInfoOnComponent(0,"Pressure_(Pa)");
2790 _VV.setInfoOnComponent(1,"Velocity_x_(m/s)");
2792 _VV.setInfoOnComponent(2,"Velocity_y_(m/s)");
2794 _VV.setInfoOnComponent(3,"Velocity_z_(m/s)");
2795 _VV.setInfoOnComponent(_nVar-1,"Temperature_(K)");
2811 // do not create mesh
2816 _VV.writeVTK(prim,false);
2819 _VV.writeMED(prim,false);
2825 if(_saveConservativeField){
2829 _UU.writeVTK(cons,false);
2832 _UU.writeMED(cons,false);
2840 if(_saveVelocity || _saveAllFields){
2841 for (long i = 0; i < _Nmailles; i++){
2842 // j = 0 : pressure; j = _nVar - 1: temperature; j = 1,..,_nVar-2: velocity
2843 for (int j = 0; j < _Ndim; j++)//On récupère les composantes de vitesse
2845 int Ii = i*_nVar +1+j;
2846 VecGetValues(_primitiveVars,1,&Ii,&_Vitesse(i,j));
2848 for (int j = _Ndim; j < 3; j++)//On met à zero les composantes de vitesse si la dimension est <3
2851 _Vitesse.setTime(_time,_nbTimeStep);
2852 if (_nbTimeStep ==0 || _restartWithNewFileName){
2853 _Vitesse.setInfoOnComponent(0,"Velocity_x_(m/s)");
2854 _Vitesse.setInfoOnComponent(1,"Velocity_y_(m/s)");
2855 _Vitesse.setInfoOnComponent(2,"Velocity_z_(m/s)");
2860 _Vitesse.writeVTK(prim+"_Velocity");
2863 _Vitesse.writeMED(prim+"_Velocity");
2866 _Vitesse.writeCSV(prim+"_Velocity");
2874 _Vitesse.writeVTK(prim+"_Velocity",false);
2877 _Vitesse.writeMED(prim+"_Velocity",false);
2880 _Vitesse.writeCSV(prim+"_Velocity");
2888 double p,T,rho, h, vx,vy,vz;
2890 for (long i = 0; i < _Nmailles; i++){
2892 VecGetValues(_conservativeVars,1,&Ii,&rho);
2894 VecGetValues(_primitiveVars,1,&Ii,&p);
2895 Ii = i*_nVar +_nVar-1;
2896 VecGetValues(_primitiveVars,1,&Ii,&T);
2898 VecGetValues(_primitiveVars,1,&Ii,&vx);
2902 VecGetValues(_primitiveVars,1,&Ii,&vy);
2905 VecGetValues(_primitiveVars,1,&Ii,&vz);
2909 h = _fluides[0]->getEnthalpy(T,rho);
2923 _Enthalpy.setTime(_time,_nbTimeStep);
2924 _Density.setTime(_time,_nbTimeStep);
2925 _Pressure.setTime(_time,_nbTimeStep);
2926 _Temperature.setTime(_time,_nbTimeStep);
2927 _VitesseX.setTime(_time,_nbTimeStep);
2930 _VitesseY.setTime(_time,_nbTimeStep);
2932 _VitesseZ.setTime(_time,_nbTimeStep);
2934 if (_nbTimeStep ==0 || _restartWithNewFileName){
2938 _Enthalpy.writeVTK(allFields+"_Enthalpy");
2939 _Density.writeVTK(allFields+"_Density");
2940 _Pressure.writeVTK(allFields+"_Pressure");
2941 _Temperature.writeVTK(allFields+"_Temperature");
2942 _VitesseX.writeVTK(allFields+"_VelocityX");
2945 _VitesseY.writeVTK(allFields+"_VelocityY");
2947 _VitesseZ.writeVTK(allFields+"_VelocityZ");
2951 _Enthalpy.writeMED(allFields+"_Enthalpy");
2952 _Density.writeMED(allFields+"_Density");
2953 _Pressure.writeMED(allFields+"_Pressure");
2954 _Temperature.writeMED(allFields+"_Temperature");
2955 _VitesseX.writeMED(allFields+"_VelocityX");
2958 _VitesseY.writeMED(allFields+"_VelocityY");
2960 _VitesseZ.writeMED(allFields+"_VelocityZ");
2964 _Enthalpy.writeCSV(allFields+"_Enthalpy");
2965 _Density.writeCSV(allFields+"_Density");
2966 _Pressure.writeCSV(allFields+"_Pressure");
2967 _Temperature.writeCSV(allFields+"_Temperature");
2968 _VitesseX.writeCSV(allFields+"_VelocityX");
2971 _VitesseY.writeCSV(allFields+"_VelocityY");
2973 _VitesseZ.writeCSV(allFields+"_VelocityZ");
2982 _Enthalpy.writeVTK(allFields+"_Enthalpy",false);
2983 _Density.writeVTK(allFields+"_Density",false);
2984 _Pressure.writeVTK(allFields+"_Pressure",false);
2985 _Temperature.writeVTK(allFields+"_Temperature",false);
2986 _VitesseX.writeVTK(allFields+"_VelocityX",false);
2989 _VitesseY.writeVTK(allFields+"_VelocityY",false);
2991 _VitesseZ.writeVTK(allFields+"_VelocityZ",false);
2995 _Enthalpy.writeMED(allFields+"_Enthalpy",false);
2996 _Density.writeMED(allFields+"_Density",false);
2997 _Pressure.writeMED(allFields+"_Pressure",false);
2998 _Temperature.writeMED(allFields+"_Temperature",false);
2999 _VitesseX.writeMED(allFields+"_VelocityX",false);
3002 _VitesseY.writeMED(allFields+"_VelocityY",false);
3004 _VitesseZ.writeMED(allFields+"_VelocityZ",false);
3008 _Enthalpy.writeCSV(allFields+"_Enthalpy");
3009 _Density.writeCSV(allFields+"_Density");
3010 _Pressure.writeCSV(allFields+"_Pressure");
3011 _Temperature.writeCSV(allFields+"_Temperature");
3012 _VitesseX.writeCSV(allFields+"_VelocityX");
3015 _VitesseY.writeCSV(allFields+"_VelocityY");
3017 _VitesseZ.writeCSV(allFields+"_VelocityZ");
3042 if(_saveConservativeField){
3057 if(_saveVelocity || _saveAllFields){
3061 _Vitesse.writeVTK(prim+"_Velocity");
3064 _Vitesse.writeMED(prim+"_Velocity");
3067 _Vitesse.writeCSV(prim+"_Velocity");
3073 if (_restartWithNewFileName)
3074 _restartWithNewFileName=false;
3077 Field& SinglePhase::getPressureField()
3081 _Pressure=Field("Pressure",CELLS,_mesh,1);
3083 for (long i = 0; i < _Nmailles; i++){
3085 VecGetValues(_primitiveVars,1,&Ii,&_Pressure(i));
3087 _Pressure.setTime(_time,_nbTimeStep);
3092 Field& SinglePhase::getTemperatureField()
3096 _Temperature=Field("Temperature",CELLS,_mesh,1);
3098 for (long i = 0; i < _Nmailles; i++){
3099 Ii = i*_nVar +_nVar-1;
3100 VecGetValues(_primitiveVars,1,&Ii,&_Temperature(i));
3102 _Temperature.setTime(_time,_nbTimeStep);
3104 return _Temperature;
3107 Field& SinglePhase::getVelocityField()
3109 if(!_saveAllFields )
3111 _Vitesse=Field("Vitesse",CELLS,_mesh,3);
3113 for (long i = 0; i < _Nmailles; i++)
3115 for (int j = 0; j < _Ndim; j++)//On récupère les composantes de vitesse
3117 int Ii = i*_nVar +1+j;
3118 VecGetValues(_primitiveVars,1,&Ii,&_Vitesse(i,j));
3120 for (int j = _Ndim; j < 3; j++)//On met à zero les composantes de vitesse si la dimension est <3
3123 _Vitesse.setTime(_time,_nbTimeStep);
3124 _Vitesse.setInfoOnComponent(0,"Velocity_x_(m/s)");
3125 _Vitesse.setInfoOnComponent(1,"Velocity_y_(m/s)");
3126 _Vitesse.setInfoOnComponent(2,"Velocity_z_(m/s)");
3132 Field& SinglePhase::getVelocityXField()
3134 if(!_saveAllFields )
3136 _VitesseX=Field("Velocity X",CELLS,_mesh,1);
3138 for (long i = 0; i < _Nmailles; i++)
3140 int Ii = i*_nVar +1;
3141 VecGetValues(_primitiveVars,1,&Ii,&_VitesseX(i));
3143 _VitesseX.setTime(_time,_nbTimeStep);
3144 _VitesseX.setInfoOnComponent(0,"Velocity_x_(m/s)");
3150 Field& SinglePhase::getDensityField()
3152 if(!_saveAllFields )
3154 _Density=Field("Density",CELLS,_mesh,1);
3156 for (long i = 0; i < _Nmailles; i++){
3158 VecGetValues(_conservativeVars,1,&Ii,&_Density(i));
3160 _Density.setTime(_time,_nbTimeStep);
3165 Field& SinglePhase::getMomentumField()//not yet managed by parameter _saveAllFields
3167 _Momentum=Field("Momentum",CELLS,_mesh,_Ndim);
3169 for (long i = 0; i < _Nmailles; i++)
3170 for (int j = 0; j < _Ndim; j++)//On récupère les composantes de qdm
3172 int Ii = i*_nVar +1+j;
3173 VecGetValues(_conservativeVars,1,&Ii,&_Momentum(i,j));
3175 _Momentum.setTime(_time,_nbTimeStep);
3180 Field& SinglePhase::getTotalEnergyField()//not yet managed by parameter _saveAllFields
3182 _TotalEnergy=Field("TotalEnergy",CELLS,_mesh,1);
3184 for (long i = 0; i < _Nmailles; i++){
3185 Ii = i*_nVar +_nVar-1;
3186 VecGetValues(_conservativeVars,1,&Ii,&_TotalEnergy(i));
3188 _TotalEnergy.setTime(_time,_nbTimeStep);
3190 return _TotalEnergy;
3193 Field& SinglePhase::getEnthalpyField()
3195 if(!_saveAllFields )
3197 _Enthalpy=Field("Enthalpy",CELLS,_mesh,1);
3200 for (long i = 0; i < _Nmailles; i++){
3202 VecGetValues(_primitiveVars,1,&Ii,&p);
3203 Ii = i*_nVar +_nVar-1;
3204 VecGetValues(_primitiveVars,1,&Ii,&T);
3206 rho=_fluides[0]->getDensity(p,T);
3207 _Enthalpy(i)=_fluides[0]->getEnthalpy(T,rho);
3209 _Enthalpy.setTime(_time,_nbTimeStep);
3215 vector<string> SinglePhase::getOutputFieldsNames()
3217 vector<string> result(8);
3219 result[0]="Pressure";
3220 result[1]="Velocity";
3221 result[2]="Temperature";
3222 result[3]="Density";
3223 result[4]="Momentum";
3224 result[5]="TotalEnergy";
3225 result[6]="Enthalpy";
3226 result[7]="VelocityX";
3231 Field& SinglePhase::getOutputField(const string& nameField )
3233 if(nameField=="pressure" || nameField=="Pressure" || nameField=="PRESSURE" || nameField=="PRESSION" || nameField=="Pression" || nameField=="pression" )
3234 return getPressureField();
3235 else if(nameField=="velocity" || nameField=="Velocity" || nameField=="VELOCITY" || nameField=="Vitesse" || nameField=="VITESSE" || nameField=="vitesse" )
3236 return getVelocityField();
3237 else if(nameField=="velocityX" || nameField=="VelocityX" || nameField=="VELOCITYX" || nameField=="VitesseX" || nameField=="VITESSEX" || nameField=="vitesseX" )
3238 return getVelocityXField();
3239 else if(nameField=="temperature" || nameField=="Temperature" || nameField=="TEMPERATURE" || nameField=="temperature" )
3240 return getTemperatureField();
3241 else if(nameField=="density" || nameField=="Density" || nameField=="DENSITY" || nameField=="Densite" || nameField=="DENSITE" || nameField=="densite" )
3242 return getDensityField();
3243 else if(nameField=="momentum" || nameField=="Momentum" || nameField=="MOMENTUM" || nameField=="Qdm" || nameField=="QDM" || nameField=="qdm" )
3244 return getMomentumField();
3245 else if(nameField=="enthalpy" || nameField=="Enthalpy" || nameField=="ENTHALPY" || nameField=="Enthalpie" || nameField=="ENTHALPIE" || nameField=="enthalpie" )
3246 return getEnthalpyField();
3247 else if(nameField=="totalenergy" || nameField=="TotalEnergy" || nameField=="TOTALENERGY" || nameField=="ENERGIETOTALE" || nameField=="EnergieTotale" || nameField=="energietotale" )
3248 return getTotalEnergyField();
3251 cout<<"Error : Field name "<< nameField << " does not exist, call getOutputFieldsNames first" << endl;
3252 throw CdmathException("SinglePhase::getOutputField error : Unknown Field name");