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 _fileName = "SolverlabSinglePhase";
54 PetscPrintf(PETSC_COMM_WORLD,"\n Navier-Stokes equations for single phase flow\n");
56 void SinglePhase::initialize(){
57 cout<<"\n Initialising the Navier-Stokes model\n"<<endl;
58 *_runLogFile<<"\n Initialising the Navier-Stokes model\n"<<endl;
60 _Uroe = new double[_nVar];
61 _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
62 for(int i=0; i<_Ndim; i++)
63 _gravite[i+1]=_GravityField3d[i];
65 _GravityImplicitationMatrix = new PetscScalar[_nVar*_nVar];
66 if(_saveVelocity || _saveAllFields)
67 _Vitesse=Field("Velocity",CELLS,_mesh,3);//Forcement en dimension 3 pour le posttraitement des lignes de courant
71 _Enthalpy=Field("Enthalpy",CELLS,_mesh,1);
72 _Pressure=Field("Pressure",CELLS,_mesh,1);
73 _Density=Field("Density",CELLS,_mesh,1);
74 _Temperature=Field("Temperature",CELLS,_mesh,1);
75 _MachNumber=Field("MachNumber",CELLS,_mesh,1);
76 _VitesseX=Field("Velocity x",CELLS,_mesh,1);
79 _VitesseY=Field("Velocity y",CELLS,_mesh,1);
81 _VitesseZ=Field("Velocity z",CELLS,_mesh,1);
85 if(_entropicCorrection)
86 _entropicShift=vector<double>(3,0);//at most 3 distinct eigenvalues
88 ProblemFluid::initialize();
91 bool SinglePhase::iterateTimeStep(bool &converged)
93 if(_timeScheme == Explicit || !_usePrimitiveVarsInNewton)
94 return ProblemFluid::iterateTimeStep(converged);
99 if(_NEWTON_its>0){//Pas besoin de computeTimeStep à la première iteration de Newton
101 computeTimeStep(stop);
103 if(stop){//Le compute time step ne s'est pas bien passé
104 cout<<"ComputeTimeStep failed"<<endl;
109 computeNewtonVariation();
111 //converged=convergence des iterations
112 if(_timeScheme == Explicit)
114 else{//Implicit scheme
116 KSPGetIterationNumber(_ksp, &_PetscIts);
117 if( _MaxIterLinearSolver < _PetscIts)//save the maximum number of iterations needed during the newton scheme
118 _MaxIterLinearSolver = _PetscIts;
119 if(_PetscIts>=_maxPetscIts)//solving the linear system failed
121 cout<<"Systeme lineaire : pas de convergence de Petsc. Itérations maximales "<<_maxPetscIts<<" atteintes"<<endl;
122 *_runLogFile<<"Systeme lineaire : pas de convergence de Petsc. Itérations maximales "<<_maxPetscIts<<" atteintes"<<endl;
126 else{//solving the linear system succeeded
127 //Calcul de la variation relative Uk+1-Uk
131 for(int j=1; j<=_Nmailles; j++)
133 for(int k=0; k<_nVar; k++)
136 VecGetValues(_newtonVariation, 1, &I, &dx);
137 VecGetValues(_primitiveVars, 1, &I, &x);
138 if (fabs(x)*fabs(x)< _precision)
140 if(_erreur_rel < fabs(dx))
141 _erreur_rel = fabs(dx);
143 else if(_erreur_rel < fabs(dx/x))
144 _erreur_rel = fabs(dx/x);
148 converged = _erreur_rel <= _precision_Newton;
151 double relaxation=1;//Vk+1=Vk+relaxation*deltaV
153 VecAXPY(_primitiveVars, relaxation, _newtonVariation);
155 //mise a jour du champ primitif
156 updateConservatives();
158 if(_nbPhases==2 && fabs(_err_press_max) > _precision)//la pression n'a pu être calculée en diphasique à partir des variables conservatives
160 cout<<"Warning consToPrim: nbiter max atteint, erreur relative pression= "<<_err_press_max<<" precision= " <<_precision<<endl;
161 *_runLogFile<<"Warning consToPrim: nbiter max atteint, erreur relative pression= "<<_err_press_max<<" precision= " <<_precision<<endl;
167 cout<<"Vecteur Vkp1-Vk "<<endl;
168 VecView(_newtonVariation, PETSC_VIEWER_STDOUT_SELF);
169 cout << "Nouvel etat courant Vk de l'iteration Newton: " << endl;
170 VecView(_primitiveVars, PETSC_VIEWER_STDOUT_SELF);
173 if(_nbPhases==2 && _nbTimeStep%_freqSave ==0){
174 if(_minm1<-_precision || _minm2<-_precision)
176 cout<<"!!!!!!!!! WARNING masse partielle negative sur " << _nbMaillesNeg << " faces, min m1= "<< _minm1 << " , minm2= "<< _minm2<< " precision "<<_precision<<endl;
177 *_runLogFile<<"!!!!!!!!! WARNING masse partielle negative sur " << _nbMaillesNeg << " faces, min m1= "<< _minm1 << " , minm2= "<< _minm2<< " precision "<<_precision<<endl;
181 cout << "!!!!!!!!!!!!!!!!!!!!!!!! Complex eigenvalues on " << _nbVpCplx << " cells, max imag= " << _part_imag_max << endl;
182 *_runLogFile << "!!!!!!!!!!!!!!!!!!!!!!!! Complex eigenvalues on " << _nbVpCplx << " cells, max imag= " << _part_imag_max << endl;
194 void SinglePhase::computeNewtonVariation()
196 if(!_usePrimitiveVarsInNewton)
197 ProblemFluid::computeNewtonVariation();
202 cout<<"Vecteur courant Vk "<<endl;
203 VecView(_primitiveVars,PETSC_VIEWER_STDOUT_SELF);
205 cout << "Matrice du système linéaire avant contribution delta t" << endl;
206 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
208 cout << "Second membre du système linéaire avant contribution delta t" << endl;
209 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
212 if(_timeScheme == Explicit)
214 VecCopy(_b,_newtonVariation);
215 VecScale(_newtonVariation, _dt);
216 if(_verbose && _nbTimeStep%_freqSave ==0)
218 cout<<"Vecteur _newtonVariation =_b*dt"<<endl;
219 VecView(_newtonVariation,PETSC_VIEWER_STDOUT_SELF);
225 MatAssemblyBegin(_A, MAT_FINAL_ASSEMBLY);
227 VecAXPY(_b, 1/_dt, _old);
228 VecAXPY(_b, -1/_dt, _conservativeVars);
230 for(int imaille = 0; imaille<_Nmailles; imaille++){
231 _idm[0] = _nVar*imaille;
232 for(int k=1; k<_nVar; k++)
233 _idm[k] = _idm[k-1] + 1;
234 VecGetValues(_primitiveVars, _nVar, _idm, _Vi);
235 primToConsJacobianMatrix(_Vi);
236 for(int k=0; k<_nVar*_nVar; k++)
237 _primToConsJacoMat[k]*=1/_dt;
238 MatSetValuesBlocked(_A, 1, &imaille, 1, &imaille, _primToConsJacoMat, ADD_VALUES);
240 MatAssemblyEnd(_A, MAT_FINAL_ASSEMBLY);
242 #if PETSC_VERSION_GREATER_3_5
243 KSPSetOperators(_ksp, _A, _A);
245 KSPSetOperators(_ksp, _A, _A,SAME_NONZERO_PATTERN);
250 cout << "Matrice du système linéaire" << endl;
251 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
253 cout << "Second membre du système linéaire" << endl;
254 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
259 KSPSetComputeEigenvalues(_ksp,PETSC_TRUE);
262 KSPSolve(_ksp, _b, _newtonVariation);
266 computeScaling(_maxvp);
268 VecAssemblyBegin(_vecScaling);
269 VecAssemblyBegin(_invVecScaling);
270 for(int imaille = 0; imaille<_Nmailles; imaille++)
273 VecSetValuesBlocked(_vecScaling,1 , &indice, _blockDiag, INSERT_VALUES);
274 VecSetValuesBlocked(_invVecScaling,1,&indice,_invBlockDiag, INSERT_VALUES);
276 VecAssemblyEnd(_vecScaling);
277 VecAssemblyEnd(_invVecScaling);
281 cout << "Matrice avant le preconditionneur des vecteurs propres " << endl;
282 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
284 cout << "Second membre avant le preconditionneur des vecteurs propres " << endl;
285 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
288 MatDiagonalScale(_A,_vecScaling,_invVecScaling);
291 cout << "Matrice apres le preconditionneur des vecteurs propres " << endl;
292 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
295 VecCopy(_b,_bScaling);
296 VecPointwiseMult(_b,_vecScaling,_bScaling);
299 cout << "Produit du second membre par le preconditionneur bloc diagonal a gauche" << endl;
300 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
304 KSPSolve(_ksp,_b, _bScaling);
305 VecPointwiseMult(_newtonVariation,_invVecScaling,_bScaling);
309 cout << "solution du systeme lineaire local:" << endl;
310 VecView(_newtonVariation, PETSC_VIEWER_STDOUT_SELF);
316 void SinglePhase::convectionState( const long &i, const long &j, const bool &IsBord){
317 //First conservative state then further down we will compute interface (Roe) state and then compute primitive state
319 for(int k=1; k<_nVar; k++)
320 _idm[k] = _idm[k-1] + 1;
321 VecGetValues(_conservativeVars, _nVar, _idm, _Ui);
324 for(int k=1; k<_nVar; k++)
325 _idm[k] = _idm[k-1] + 1;
327 VecGetValues(_Uext, _nVar, _idm, _Uj);
329 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
330 if(_verbose && _nbTimeStep%_freqSave ==0)
332 cout<<"Convection Left state cell " << i<< ": "<<endl;
333 for(int k =0; k<_nVar; k++)
335 cout<<"Convection Right state cell " << j<< ": "<<endl;
336 for(int k =0; k<_nVar; k++)
339 if(_Ui[0]<0||_Uj[0]<0)
341 cout<<"!!!!!!!!!!!!!!!!!!!!!!!!densite negative, arret de calcul!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
342 *_runLogFile<<"!!!!!!!!!!!!!!!!!!!!!!!!densite negative, arret de calcul!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
343 _runLogFile->close();
344 throw CdmathException("densite negative, arret de calcul");
347 //Computation of Roe state
348 PetscScalar ri, rj, xi, xj, pi, pj;
350 ri = sqrt(_Ui[0]);//racine carre de phi_i rho_i
352 _Uroe[0] = ri*rj; //moyenne geometrique des densites
353 if(_verbose && _nbTimeStep%_freqSave ==0)
354 cout << "Densité moyenne Roe gauche " << i << ": " << ri*ri << ", droite " << j << ": " << rj*rj << "->" << _Uroe[0] << endl;
355 for(int k=0;k<_Ndim;k++){
358 _Uroe[1+k] = (xi/ri + xj/rj)/(ri + rj);
359 //"moyenne" des vitesses
360 if(_verbose && _nbTimeStep%_freqSave ==0)
361 cout << "Vitesse de Roe composante "<< k<<" gauche " << i << ": " << xi/(ri*ri) << ", droite " << j << ": " << xj/(rj*rj) << "->" << _Uroe[k+1] << endl;
363 // H = (rho E + p)/rho
364 xi = _Ui[_nVar-1];//phi rho E
366 Ii = i*_nVar; // correct Kieu
367 VecGetValues(_primitiveVars, 1, &Ii, &pi);// _primitiveVars pour p
371 for(int k=1;k<=_Ndim;k++)
372 q_2 += _Uj[k]*_Uj[k];
373 q_2 /= _Uj[0]; //phi rho u²
374 pj = _fluides[0]->getPressure((_Uj[(_Ndim+2)-1]-q_2/2)/_porosityj,_Uj[0]/_porosityj);
378 Ii = j*_nVar; // correct Kieu
379 VecGetValues(_primitiveVars, 1, &Ii, &pj);
381 xi = (xi + pi)/(ri*ri);
382 xj = (xj + pj)/(rj*rj);
383 _Uroe[_nVar-1] = (ri*xi + rj*xj)/(ri + rj);
384 //on se donne l enthalpie ici
385 if(_verbose && _nbTimeStep%_freqSave ==0)
386 cout << "Enthalpie totale de Roe H gauche " << i << ": " << xi << ", droite " << j << ": " << xj << "->" << _Uroe[_nVar-1] << endl;
388 if(_verbose && _nbTimeStep%_freqSave ==0)
390 cout<<"Convection interfacial state"<<endl;
391 for(int k=0;k<_nVar;k++)
392 cout<< _Uroe[k]<<" , "<<endl;
395 //Extraction of primitive states
396 _idm[0] = _nVar*i; // Kieu
397 for(int k=1; k<_nVar; k++)
398 _idm[k] = _idm[k-1] + 1;
400 VecGetValues(_primitiveVars, _nVar, _idm, _Vi);
401 if (_verbose && _nbTimeStep%_freqSave ==0)
403 cout << "Convection state: variables primitives maille " << i<<endl;
404 for(int q=0; q<_nVar; q++)
405 cout << _Vi[q] << endl;
410 for(int k=0; k<_nVar; k++)
411 _idn[k] = _nVar*j + k;
413 VecGetValues(_primitiveVars, _nVar, _idn, _Vj);
417 for(int k=0; k<_nVar; k++)
420 VecGetValues(_Uextdiff, _nVar, _idn, _phi);
421 consToPrim(_phi,_Vj,1);
424 if (_verbose && _nbTimeStep%_freqSave ==0)
426 cout << "Convection state: variables primitives maille " <<j <<endl;
427 for(int q=0; q<_nVar; q++)
428 cout << _Vj[q] << endl;
433 void SinglePhase::diffusionStateAndMatrices(const long &i,const long &j, const bool &IsBord){
434 //sortie: matrices et etat de diffusion (rho, q, T)
436 for(int k=1; k<_nVar; k++)
437 _idm[k] = _idm[k-1] + 1;
439 VecGetValues(_conservativeVars, _nVar, _idm, _Ui);
440 for(int k=0; k<_nVar; k++)
444 VecGetValues(_Uextdiff, _nVar, _idn, _Uj);
446 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
448 if(_verbose && _nbTimeStep%_freqSave ==0)
450 cout << "SinglePhase::diffusionStateAndMatrices cellule gauche" << i << endl;
452 for(int q=0; q<_nVar; q++)
453 cout << _Ui[q] << "\t";
455 cout << "SinglePhase::diffusionStateAndMatrices cellule droite" << j << endl;
457 for(int q=0; q<_nVar; q++)
458 cout << _Uj[q] << "\t";
462 for(int k=0; k<_nVar; k++)
463 _Udiff[k] = (_Ui[k]/_porosityi+_Uj[k]/_porosityj)/2;
465 if(_verbose && _nbTimeStep%_freqSave ==0)
467 cout << "SinglePhase::diffusionStateAndMatrices conservative diffusion state" << endl;
469 for(int q=0; q<_nVar; q++)
470 cout << _Udiff[q] << "\t";
472 cout << "porosite gauche= "<<_porosityi<< ", porosite droite= "<<_porosityj<<endl;
474 consToPrim(_Udiff,_phi,1);
475 _Udiff[_nVar-1]=_phi[_nVar-1];
477 if(_timeScheme==Implicit)
480 for (int i = 0; i<_Ndim;i++)
481 q_2+=_Udiff[i+1]*_Udiff[i+1];
482 double mu = _fluides[0]->getViscosity(_Udiff[_nVar-1]);
483 double lambda = _fluides[0]->getConductivity(_Udiff[_nVar-1]);
484 double Cv= _fluides[0]->constante("Cv");
485 for(int i=0; i<_nVar*_nVar;i++)
487 for(int i=1;i<(_nVar-1);i++)
489 _Diffusion[i*_nVar] = mu*_Udiff[i]/(_Udiff[0]*_Udiff[0]);
490 _Diffusion[i*_nVar+i] = -mu/_Udiff[0];
492 int i = (_nVar-1)*_nVar;
493 _Diffusion[i]=lambda*(_Udiff[_nVar-1]/_Udiff[0]-q_2/(2*Cv*_Udiff[0]*_Udiff[0]*_Udiff[0]));
494 for(int k=1;k<(_nVar-1);k++)
496 _Diffusion[i+k]= lambda*_Udiff[k]/(_Udiff[0]*_Udiff[0]*Cv);
498 _Diffusion[_nVar*_nVar-1]=-lambda/(_Udiff[0]*Cv);
501 void SinglePhase::setBoundaryState(string nameOfGroup, const int &j,double *normale){
503 for(int k=1; k<_nVar; k++)
504 _idm[k] = _idm[k-1] + 1;
506 double porosityj=_porosityField(j);
508 if(_verbose && _nbTimeStep%_freqSave ==0)
510 cout << "setBoundaryState for group "<< nameOfGroup << ", inner cell j= "<<j<< " face unit normal vector "<<endl;
511 for(int k=0; k<_Ndim; k++){
512 cout<<normale[k]<<", ";
517 if (_limitField[nameOfGroup].bcType==Wall){
518 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne conservatif
519 double q_n=0;//q_n=quantité de mouvement normale à la face frontière;
520 for(int k=0; k<_Ndim; k++)
521 q_n+=_externalStates[(k+1)]*normale[k];
523 //Pour la convection, inversion du sens de la vitesse normale
524 for(int k=0; k<_Ndim; k++)
525 _externalStates[(k+1)]-= 2*q_n*normale[k];
528 for(int k=1; k<_nVar; k++)
529 _idm[k] = _idm[k-1] + 1;
531 VecAssemblyBegin(_Uext);
532 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
533 VecAssemblyEnd(_Uext);
535 //Pour la diffusion, paroi à vitesse et temperature imposees
537 for(int k=1; k<_nVar; k++)
538 _idm[k] = _idm[k-1] + 1;
539 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);//L'état fantome contient à présent les variables primitives internes
540 double pression=_externalStates[0];
541 double T=_limitField[nameOfGroup].T;
542 double rho=_fluides[0]->getDensity(pression,T);
544 _externalStates[0]=porosityj*rho;
545 _externalStates[1]=_externalStates[0]*_limitField[nameOfGroup].v_x[0];
547 v2 +=_limitField[nameOfGroup].v_x[0]*_limitField[nameOfGroup].v_x[0];
550 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
551 _externalStates[2]=_externalStates[0]*_limitField[nameOfGroup].v_y[0];
554 _externalStates[3]=_externalStates[0]*_limitField[nameOfGroup].v_z[0];
555 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
558 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2);
560 for(int k=1; k<_nVar; k++)
561 _idm[k] = _idm[k-1] + 1;
562 VecAssemblyBegin(_Uextdiff);
563 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
564 VecAssemblyEnd(_Uextdiff);
566 else if (_limitField[nameOfGroup].bcType==Neumann){
567 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On prend l'état fantôme égal à l'état interne (conditions limites de Neumann)
570 for(int k=1; k<_nVar; k++)
571 _idm[k] = _idm[k-1] + 1;
573 VecAssemblyBegin(_Uext);
574 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
575 VecAssemblyEnd(_Uext);
577 VecAssemblyBegin(_Uextdiff);
578 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
579 VecAssemblyEnd(_Uextdiff);
581 else if (_limitField[nameOfGroup].bcType==Inlet){
582 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne (conditions limites de Neumann)
583 double q_int_n=0;//q_int_n=composante normale de la quantité de mouvement à la face frontière;
584 for(int k=0; k<_Ndim; k++)
585 q_int_n+=_externalStates[(k+1)]*normale[k];//On calcule la vitesse normale sortante
587 double q_ext_n=_limitField[nameOfGroup].v_x[0]*normale[0];
590 q_ext_n+=_limitField[nameOfGroup].v_y[0]*normale[1];
592 q_ext_n+=_limitField[nameOfGroup].v_z[0]*normale[2];
595 if(q_int_n+q_ext_n<=0){//Interfacial velocity goes inward
596 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);//On met à jour l'état fantome avec les variables primitives internes
597 double pression=_externalStates[0];
598 double T=_limitField[nameOfGroup].T;
599 double rho=_fluides[0]->getDensity(pression,T);
601 _externalStates[0]=porosityj*rho;//Composante fantome de masse
602 _externalStates[1]=_externalStates[0]*(_limitField[nameOfGroup].v_x[0]);//Composante fantome de qdm x
604 v2 +=(_limitField[nameOfGroup].v_x[0])*(_limitField[nameOfGroup].v_x[0]);
607 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
608 _externalStates[2]=_externalStates[0]*_limitField[nameOfGroup].v_y[0];//Composante fantome de qdm y
611 _externalStates[3]=_externalStates[0]*_limitField[nameOfGroup].v_z[0];//Composante fantome de qdm z
612 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
615 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2);//Composante fantome de l'nrj
617 else if(_nbTimeStep%_freqSave ==0)
618 cout<< "Warning : fluid possibly going out through inlet boundary "<<nameOfGroup<<". Applying Neumann boundary condition"<<endl;
621 for(int k=1; k<_nVar; k++)
622 _idm[k] = _idm[k-1] + 1;
623 VecAssemblyBegin(_Uext);
624 VecAssemblyBegin(_Uextdiff);
625 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
626 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
627 VecAssemblyEnd(_Uext);
628 VecAssemblyEnd(_Uextdiff);
630 else if (_limitField[nameOfGroup].bcType==InletRotationVelocity){
631 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
632 double u_int_n=0;//u_int_n=composante normale de la vitesse intérieure à la face frontière;
633 for(int k=0; k<_Ndim; k++)
634 u_int_n+=_externalStates[(k+1)]*normale[k];
641 omega[0]=_limitField[nameOfGroup].v_x[0];
642 omega[1]=_limitField[nameOfGroup].v_y[0];
645 Normale[0]=normale[0];
646 Normale[1]=normale[1];
650 omega[2]=_limitField[nameOfGroup].v_z[0];
651 Normale[2]=normale[2];
654 Vector tangent_vel=omega%Normale;
655 u_ext_n=-0.01*tangent_vel.norm();
656 //Changing external state velocity
657 for(int k=0; k<_Ndim; k++)
658 _externalStates[(k+1)]=u_ext_n*normale[k] + tangent_vel[k];
661 if(u_ext_n + u_int_n <= 0){
662 double pression=_externalStates[0];
663 double T=_limitField[nameOfGroup].T;
664 double rho=_fluides[0]->getDensity(pression,T);
667 v2 +=_externalStates[1]*_externalStates[1];//v_x*v_x
668 _externalStates[0]=porosityj*rho;
669 _externalStates[1]*=_externalStates[0];
672 v2 +=_externalStates[2]*_externalStates[2];//+v_y*v_y
673 _externalStates[2]*=_externalStates[0];
676 v2 +=_externalStates[3]*_externalStates[3];//+v_z*v_z
677 _externalStates[3]*=_externalStates[0];
680 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2);
682 else if(_nbTimeStep%_freqSave ==0)
685 * cout<< "Warning : fluid going out through inlet boundary "<<nameOfGroup<<". Applying Neumann boundary condition"<<endl;
687 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On définit l'état fantôme avec l'état interne
688 if(_nbTimeStep%_freqSave ==0)
689 cout<< "Warning : fluid going out through inletPressure boundary "<<nameOfGroup<<". Applying Wall boundary condition."<<endl;
691 //Changing external state momentum
692 for(int k=0; k<_Ndim; k++)
693 _externalStates[(k+1)]-=2*_externalStates[0]*u_int_n*normale[k];
697 for(int k=1; k<_nVar; k++)
698 _idm[k] = _idm[k-1] + 1;
699 VecAssemblyBegin(_Uext);
700 VecAssemblyBegin(_Uextdiff);
701 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
702 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
703 VecAssemblyEnd(_Uext);
704 VecAssemblyEnd(_Uextdiff);
706 else if (_limitField[nameOfGroup].bcType==InletPressure){
707 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne
709 //Computation of the hydrostatic contribution : scalar product between gravity vector and position vector
710 Cell Cj=_mesh.getCell(j);
711 double hydroPress=Cj.x()*_GravityField3d[0];
713 hydroPress+=Cj.y()*_GravityField3d[1];
715 hydroPress+=Cj.z()*_GravityField3d[2];
717 hydroPress*=_externalStates[0]/porosityj;//multiplication by rho the total density
719 //Building the primitive external state
720 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
721 double u_n=0;//u_n=vitesse normale à la face frontière;
722 for(int k=0; k<_Ndim; k++)
723 u_n+=_externalStates[(k+1)]*normale[k];
727 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress,_limitField[nameOfGroup].T);
729 //Contribution from the tangential velocity
733 omega[0]=_limitField[nameOfGroup].v_x[0];
734 omega[1]=_limitField[nameOfGroup].v_y[0];
737 Normale[0]=normale[0];
738 Normale[1]=normale[1];
742 omega[2]=_limitField[nameOfGroup].v_z[0];
743 Normale[2]=normale[2];
746 Vector tangent_vel=omega%Normale;
748 //Changing external state velocity
749 for(int k=0; k<_Ndim; k++)
750 _externalStates[(k+1)]=u_n*normale[k] + abs(u_n)*tangent_vel[k];
755 if(_nbTimeStep%_freqSave ==0)
756 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;
757 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress, _externalStates[_nVar-1]);
759 if(_nbTimeStep%_freqSave ==0)
760 cout<< "Warning : fluid going out through inletPressure boundary "<<nameOfGroup<<". Applying Wall boundary condition."<<endl;
761 _externalStates[0]=porosityj*_fluides[0]->getDensity(_externalStates[0]+hydroPress, _externalStates[_nVar-1]);
762 //Changing external state velocity
763 for(int k=0; k<_Ndim; k++)
764 _externalStates[(k+1)]-=2*u_n*normale[k];
768 for(int k=0; k<_Ndim; k++)
770 v2+=_externalStates[(k+1)]*_externalStates[(k+1)];
771 _externalStates[(k+1)]*=_externalStates[0] ;//qdm component
773 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy( _externalStates[_nVar-1],_externalStates[0]) + v2/2);//nrj component
777 for(int k=1; k<_nVar; k++)
778 _idm[k] = _idm[k-1] + 1;
779 VecAssemblyBegin(_Uext);
780 VecAssemblyBegin(_Uextdiff);
781 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
782 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
783 VecAssemblyEnd(_Uext);
784 VecAssemblyEnd(_Uextdiff);
786 else if (_limitField[nameOfGroup].bcType==Outlet){
787 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne conservatif
788 double q_n=0;//q_n=quantité de mouvement normale à la face frontière;
789 for(int k=0; k<_Ndim; k++)
790 q_n+=_externalStates[(k+1)]*normale[k];
792 if(q_n < -_precision && _nbTimeStep%_freqSave ==0)
794 cout<< "Warning : fluid going in through outlet boundary "<<nameOfGroup<<" with flow rate "<< q_n<<endl;
795 cout<< "Applying Neumann boundary condition for velocity and temperature"<<endl;
797 //Computation of the hydrostatic contribution : scalar product between gravity vector and position vector
798 Cell Cj=_mesh.getCell(j);
799 double hydroPress=Cj.x()*_GravityField3d[0];
801 hydroPress+=Cj.y()*_GravityField3d[1];
803 hydroPress+=Cj.z()*_GravityField3d[2];
805 hydroPress*=_externalStates[0]/porosityj;//multiplication by rho the total density
807 if(_verbose && _nbTimeStep%_freqSave ==0)
809 cout<<"Cond lim outlet densite= "<<_externalStates[0]<<" gravite= "<<_GravityField3d[0]<<" Cj.x()= "<<Cj.x()<<endl;
810 cout<<"Cond lim outlet pression ref= "<<_limitField[nameOfGroup].p<<" pression hydro= "<<hydroPress<<" total= "<<_limitField[nameOfGroup].p+hydroPress<<endl;
812 //Building the external state
813 _idm[0] = _nVar*j;// Kieu
814 for(int k=1; k<_nVar; k++)
815 _idm[k] = _idm[k-1] + 1;
816 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
818 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress, _externalStates[_nVar-1]);
820 for(int k=0; k<_Ndim; k++)
822 v2+=_externalStates[(k+1)]*_externalStates[(k+1)];
823 _externalStates[(k+1)]*=_externalStates[0] ;
825 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy( _externalStates[_nVar-1],_externalStates[0]) + v2/2);
827 for(int k=1; k<_nVar; k++)
828 _idm[k] = _idm[k-1] + 1;
829 VecAssemblyBegin(_Uext);
830 VecAssemblyBegin(_Uextdiff);
831 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
832 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
833 VecAssemblyEnd(_Uext);
834 VecAssemblyEnd(_Uextdiff);
836 cout<<"Boundary condition not set for boundary named "<<nameOfGroup<< " _limitField[nameOfGroup].bcType= "<<_limitField[nameOfGroup].bcType<<endl;
837 cout<<"Accepted boundary condition are Neumann, Wall, Inlet, and Outlet"<<endl;
838 *_runLogFile<<"Boundary condition not set for boundary named. Accepted boundary condition are Neumann, Wall, Inlet, and Outlet"<<endl;
839 _runLogFile->close();
840 throw CdmathException("Unknown boundary condition");
844 void SinglePhase::convectionMatrices()
846 //entree: URoe = rho, u, H
847 //sortie: matrices Roe+ et Roe-
849 if(_verbose && _nbTimeStep%_freqSave ==0)
850 cout<<"SinglePhase::convectionMatrices()"<<endl;
852 double u_n=0, u_2=0;//vitesse normale et carré du module
854 for(int i=0;i<_Ndim;i++)
856 u_2 += _Uroe[1+i]*_Uroe[1+i];
857 u_n += _Uroe[1+i]*_vec_normal[i];
860 vector<complex<double> > vp_dist(3,0);
862 if(_spaceScheme==staggered && _nonLinearFormulation==VFFC)//special case
864 staggeredVFFCMatricesConservativeVariables(u_n);//Computation of classical upwinding matrices
865 if(_timeScheme==Implicit && _usePrimitiveVarsInNewton)//For use in implicit matrix
866 staggeredVFFCMatricesPrimitiveVariables(u_n);
870 Vector vitesse(_Ndim);
871 for(int idim=0;idim<_Ndim;idim++)
872 vitesse[idim]=_Uroe[1+idim];
875 /***********Calcul des valeurs propres ********/
877 c = _fluides[0]->vitesseSonEnthalpie(H-u_2/2);//vitesse du son a l'interface
878 k = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
879 K = u_2*k/2; //g-1/2 *|u|²
881 vp_dist[0]=u_n-c;vp_dist[1]=u_n;vp_dist[2]=u_n+c;
883 _maxvploc=fabs(u_n)+c;
887 if(_verbose && _nbTimeStep%_freqSave ==0)
888 cout<<"SinglePhase::convectionMatrices Eigenvalues "<<u_n-c<<" , "<<u_n<<" , "<<u_n+c<<endl;
890 RoeMatrixConservativeVariables( u_n, H,vitesse,k,K);
892 /******** Construction des matrices de decentrement ********/
893 if( _spaceScheme ==centered){
894 if(_entropicCorrection)
896 *_runLogFile<<"SinglePhase::convectionMatrices: entropy scheme not available for centered scheme"<<endl;
897 _runLogFile->close();
898 throw CdmathException("SinglePhase::convectionMatrices: entropy scheme not available for centered scheme");
901 for(int i=0; i<_nVar*_nVar;i++)
904 else if(_spaceScheme == upwind || _spaceScheme ==pressureCorrection || _spaceScheme ==lowMach){
905 if(_entropicCorrection)
906 entropicShift(_vec_normal);
908 _entropicShift=vector<double>(3,0);//at most 3 distinct eigenvalues
910 vector< complex< double > > y (3,0);
911 for( int i=0 ; i<3 ; i++)
912 y[i] = Polynoms::abs_generalise(vp_dist[i])+_entropicShift[i];
913 Polynoms::abs_par_interp_directe(3,vp_dist, _Aroe, _nVar,_precision, _absAroe,y);
915 if( _spaceScheme ==pressureCorrection)
916 for( int i=0 ; i<_Ndim ; i++)
917 for( int j=0 ; j<_Ndim ; j++)
918 _absAroe[(1+i)*_nVar+1+j]-=(vp_dist[2].real()-vp_dist[0].real())/2*_vec_normal[i]*_vec_normal[j];
919 else if( _spaceScheme ==lowMach){
920 double M=sqrt(u_2)/c;
921 for( int i=0 ; i<_Ndim ; i++)
922 for( int j=0 ; j<_Ndim ; j++)
923 _absAroe[(1+i)*_nVar+1+j]-=(1-M)*(vp_dist[2].real()-vp_dist[0].real())/2*_vec_normal[i]*_vec_normal[j];
926 else if( _spaceScheme ==staggered ){
927 if(_entropicCorrection)//To do: study entropic correction for staggered
929 *_runLogFile<<"SinglePhase::convectionMatrices: entropy scheme not available for staggered scheme"<<endl;
930 _runLogFile->close();
931 throw CdmathException("SinglePhase::convectionMatrices: entropy scheme not available for staggered scheme");
934 staggeredRoeUpwindingMatrixConservativeVariables( u_n, H, vitesse, k, K);
938 *_runLogFile<<"SinglePhase::convectionMatrices: scheme not treated"<<endl;
939 _runLogFile->close();
940 throw CdmathException("SinglePhase::convectionMatrices: scheme not treated");
943 for(int i=0; i<_nVar*_nVar;i++)
945 _AroeMinus[i] = (_Aroe[i]-_absAroe[i])/2;
946 _AroePlus[i] = (_Aroe[i]+_absAroe[i])/2;
948 if(_timeScheme==Implicit)
950 if(_usePrimitiveVarsInNewton)//Implicitation using primitive variables
952 _Vij[0]=_fluides[0]->getPressureFromEnthalpy(_Uroe[_nVar-1]-u_2/2, _Uroe[0]);//pressure
953 _Vij[_nVar-1]=_fluides[0]->getTemperatureFromPressure( _Vij[0], _Uroe[0]);//Temperature
954 for(int idim=0;idim<_Ndim; idim++)
955 _Vij[1+idim]=_Uroe[1+idim];
956 primToConsJacobianMatrix(_Vij);
957 Polynoms::matrixProduct(_AroeMinus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroeMinusImplicit);
958 Polynoms::matrixProduct(_AroePlus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroePlusImplicit);
961 for(int i=0; i<_nVar*_nVar;i++)
963 _AroeMinusImplicit[i] = _AroeMinus[i];
964 _AroePlusImplicit[i] = _AroePlus[i];
967 if(_verbose && _nbTimeStep%_freqSave ==0)
969 displayMatrix(_Aroe, _nVar,"Matrice de Roe");
970 displayMatrix(_absAroe, _nVar,"Valeur absolue matrice de Roe");
971 displayMatrix(_AroeMinus, _nVar,"Matrice _AroeMinus");
972 displayMatrix(_AroePlus, _nVar,"Matrice _AroePlus");
976 if(_verbose && _nbTimeStep%_freqSave ==0 && _timeScheme==Implicit)
978 displayMatrix(_AroeMinusImplicit, _nVar,"Matrice _AroeMinusImplicit");
979 displayMatrix(_AroePlusImplicit, _nVar,"Matrice _AroePlusImplicit");
982 /*********Calcul de la matrice signe pour VFFC, VFRoe et décentrement des termes source*****/
983 if(_entropicCorrection)
985 InvMatriceRoe( vp_dist);
986 Polynoms::matrixProduct(_absAroe, _nVar, _nVar, _invAroe, _nVar, _nVar, _signAroe);
988 else if (_spaceScheme==upwind || (_spaceScheme ==pressureCorrection ) || (_spaceScheme ==lowMach ))//upwind sans entropic
989 SigneMatriceRoe( vp_dist);
990 else if (_spaceScheme==centered)//centre sans entropic
991 for(int i=0; i<_nVar*_nVar;i++)
993 else if( _spaceScheme ==staggered )//à tester
1002 for(int i=0; i<_nVar*_nVar;i++)
1004 _signAroe[0] = signu;
1005 for(int i=1; i<_nVar-1;i++)
1006 _signAroe[i*_nVar+i] = -signu;
1007 _signAroe[_nVar*(_nVar-1)+_nVar-1] = signu;
1011 *_runLogFile<<"SinglePhase::convectionMatrices: well balanced option not treated"<<endl;
1012 _runLogFile->close();
1013 throw CdmathException("SinglePhase::convectionMatrices: well balanced option not treated");
1016 void SinglePhase::computeScaling(double maxvp)
1020 for(int q=1; q<_nVar-1; q++)
1022 _blockDiag[q]=1./maxvp;//
1023 _invBlockDiag[q]= maxvp;//1.;//
1025 _blockDiag[_nVar - 1]=(_fluides[0]->constante("gamma")-1)/(maxvp*maxvp);//1
1026 _invBlockDiag[_nVar - 1]= 1./_blockDiag[_nVar - 1] ;// 1.;//
1029 void SinglePhase::addDiffusionToSecondMember
1035 double lambda = _fluides[0]->getConductivity(_Udiff[_nVar-1]);
1036 double mu = _fluides[0]->getViscosity(_Udiff[_nVar-1]);
1039 lambda=max(lambda,_heatTransfertCoeff);//wall nucleate boing -> larger heat transfer
1041 if(lambda==0 && mu ==0 && _heatTransfertCoeff==0)
1045 for(int k=1; k<_nVar; k++)
1046 _idm[k] = _idm[k-1] + 1;
1049 VecGetValues(_Uextdiff, _nVar, _idm, _Uj);
1053 //on n'a pas de contribution sur la masse
1055 //contribution visqueuse sur la quantite de mouvement
1056 for(int k=1; k<_nVar-1; k++)
1057 _phi[k] = _inv_dxi*2/(1/_inv_dxi+1/_inv_dxj)*mu*(_porosityj*_Vj[k] - _porosityi*_Vi[k]);
1058 //contribution visqueuse sur l'energie
1059 _phi[_nVar-1] = _inv_dxi*2/(1/_inv_dxi+1/_inv_dxj)*lambda*(_porosityj*_Vj[_nVar-1] - _porosityi*_Vi[_nVar-1]);
1062 VecSetValuesBlocked(_b, 1, _idm, _phi, ADD_VALUES);
1064 if(_verbose && _nbTimeStep%_freqSave ==0)
1066 cout << "Contribution diffusion au 2nd membre pour la maille " << i << ": "<<endl;
1067 for(int q=0; q<_nVar; q++)
1068 cout << _phi[q] << endl;
1074 //On change de signe pour l'autre contribution
1075 for(int k=0; k<_nVar; k++)
1076 _phi[k] *= -_inv_dxj/_inv_dxi;
1079 VecSetValuesBlocked(_b, 1, _idn, _phi, ADD_VALUES);
1080 if(_verbose && _nbTimeStep%_freqSave ==0)
1082 cout << "Contribution diffusion au 2nd membre pour la maille " << j << ": "<<endl;
1083 for(int q=0; q<_nVar; q++)
1084 cout << _phi[q] << endl;
1089 if(_verbose && _nbTimeStep%_freqSave ==0 && _timeScheme==Implicit)
1091 cout << "Matrice de diffusion D, pour le couple (" << i << "," << j<< "):" << endl;
1092 for(int i=0; i<_nVar; i++)
1094 for(int j=0; j<_nVar; j++)
1095 cout << _Diffusion[i*_nVar+j]<<", ";
1102 void SinglePhase::sourceVector(PetscScalar * Si, PetscScalar * Ui, PetscScalar * Vi, int i)
1104 double phirho=Ui[0], T=Vi[_nVar-1];
1106 for(int k=0; k<_Ndim; k++)
1107 norm_u+=Vi[1+k]*Vi[1+k];
1108 norm_u=sqrt(norm_u);
1110 Si[0]=_heatPowerField(i)/_latentHeat;
1113 for(int k=1; k<_nVar-1; k++)
1114 Si[k] =(_gravite[k]-_dragCoeffs[0]*norm_u*Vi[1+k])*phirho;
1116 Si[_nVar-1]=_heatPowerField(i);
1118 for(int k=0; k<_Ndim; k++)
1119 Si[_nVar-1] +=(_GravityField3d[k]-_dragCoeffs[0]*norm_u*Vi[1+k])*Vi[1+k]*phirho;
1121 if(_timeScheme==Implicit)
1123 for(int k=0; k<_nVar*_nVar;k++)
1124 _GravityImplicitationMatrix[k] = 0;
1125 if(!_usePrimitiveVarsInNewton)
1126 for(int k=0; k<_nVar;k++)
1127 _GravityImplicitationMatrix[k*_nVar]=-_gravite[k];
1130 double pression=Vi[0];
1131 getDensityDerivatives( pression, T, norm_u*norm_u);
1132 for(int k=0; k<_nVar;k++)
1134 _GravityImplicitationMatrix[k*_nVar+0] =-_gravite[k]*_drho_sur_dp;
1135 _GravityImplicitationMatrix[k*_nVar+_nVar-1]=-_gravite[k]*_drho_sur_dT;
1139 if(_verbose && _nbTimeStep%_freqSave ==0)
1141 cout<<"SinglePhase::sourceVector"<<endl;
1143 for(int k=0;k<_nVar;k++)
1147 for(int k=0;k<_nVar;k++)
1151 for(int k=0;k<_nVar;k++)
1154 if(_timeScheme==Implicit)
1155 displayMatrix(_GravityImplicitationMatrix, _nVar, "Gravity implicitation matrix");
1159 void SinglePhase::pressureLossVector(PetscScalar * pressureLoss, double K, PetscScalar * Ui, PetscScalar * Vi, PetscScalar * Uj, PetscScalar * Vj)
1161 double norm_u=0, u_n=0, rho;
1162 for(int i=0;i<_Ndim;i++)
1163 u_n += _Uroe[1+i]*_vec_normal[i];
1167 for(int i=0;i<_Ndim;i++)
1168 norm_u += Vi[1+i]*Vi[1+i];
1169 norm_u=sqrt(norm_u);
1171 for(int i=0;i<_Ndim;i++)
1172 pressureLoss[1+i]=-1/2*K*rho*norm_u*Vi[1+i];
1175 for(int i=0;i<_Ndim;i++)
1176 norm_u += Vj[1+i]*Vj[1+i];
1177 norm_u=sqrt(norm_u);
1179 for(int i=0;i<_Ndim;i++)
1180 pressureLoss[1+i]=-1/2*K*rho*norm_u*Vj[1+i];
1182 pressureLoss[_nVar-1]=-1/2*K*rho*norm_u*norm_u*norm_u;
1184 if(_verbose && _nbTimeStep%_freqSave ==0)
1186 cout<<"SinglePhase::pressureLossVector K= "<<K<<endl;
1188 for(int k=0;k<_nVar;k++)
1192 for(int k=0;k<_nVar;k++)
1196 for(int k=0;k<_nVar;k++)
1200 for(int k=0;k<_nVar;k++)
1203 cout<<"pressureLoss="<<endl;
1204 for(int k=0;k<_nVar;k++)
1205 cout<<pressureLoss[k]<<", ";
1210 void SinglePhase::porosityGradientSourceVector()
1212 double u_ni=0, u_nj=0, rhoi,rhoj, pi=_Vi[0], pj=_Vj[0],pij;
1213 for(int i=0;i<_Ndim;i++) {
1214 u_ni += _Vi[1+i]*_vec_normal[i];
1215 u_nj += _Vj[1+i]*_vec_normal[i];
1217 _porosityGradientSourceVector[0]=0;
1218 rhoj=_Uj[0]/_porosityj;
1219 rhoi=_Ui[0]/_porosityi;
1220 pij=(pi+pj)/2+rhoi*rhoj/2/(rhoi+rhoj)*(u_ni-u_nj)*(u_ni-u_nj);
1221 for(int i=0;i<_Ndim;i++)
1222 _porosityGradientSourceVector[1+i]=pij*(_porosityi-_porosityj)*2/(1/_inv_dxi+1/_inv_dxj);
1223 _porosityGradientSourceVector[_nVar-1]=0;
1226 void SinglePhase::jacobian(const int &j, string nameOfGroup,double * normale)
1228 if(_verbose && _nbTimeStep%_freqSave ==0)
1229 cout<<"Jacobienne condition limite convection bord "<< nameOfGroup<<endl;
1232 for(k=0; k<_nVar*_nVar;k++)
1233 _Jcb[k] = 0;//No implicitation at this stage
1236 for(k=1; k<_nVar; k++)
1237 _idm[k] = _idm[k-1] + 1;
1238 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);
1239 double q_n=0;//quantité de mouvement normale à la paroi
1240 for(k=0; k<_Ndim; k++)
1241 q_n+=_externalStates[(k+1)]*normale[k];
1243 // loop of boundary types
1244 if (_limitField[nameOfGroup].bcType==Wall)
1246 for(k=0; k<_nVar;k++)
1247 _Jcb[k*_nVar + k] = 1;
1248 for(k=1; k<_nVar-1;k++)
1249 for(int l=1; l<_nVar-1;l++)
1250 _Jcb[k*_nVar + l] -= 2*normale[k-1]*normale[l-1];
1252 else if (_limitField[nameOfGroup].bcType==Inlet)
1256 double v[_Ndim], ve[_Ndim], v2, ve2;
1259 for(k=1; k<_nVar; k++)
1260 _idm[k] = _idm[k-1] + 1;
1261 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1262 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
1264 ve[0] = _limitField[nameOfGroup].v_x[0];
1269 ve[1] = _limitField[nameOfGroup].v_y[0];
1275 ve[2] = _limitField[nameOfGroup].v_z[0];
1280 double internal_energy=_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,_Uj[0]);
1281 double total_energy=internal_energy+ve2/2;
1284 _Jcb[0]=v2/(2*internal_energy);
1285 for(k=0; k<_Ndim;k++)
1286 _Jcb[1+k]=-v[k]/internal_energy;
1287 _Jcb[_nVar-1]=1/internal_energy;
1289 for(int l =1;l<1+_Ndim;l++){
1290 _Jcb[l*_nVar]=v2*ve[l-1]/(2*internal_energy);
1291 for(k=0; k<_Ndim;k++)
1292 _Jcb[l*_nVar+1+k]=-v[k]*ve[l-1]/internal_energy;
1293 _Jcb[l*_nVar+_nVar-1]=ve[l-1]/internal_energy;
1296 _Jcb[(_nVar-1)*_nVar]=v2*total_energy/(2*internal_energy);
1297 for(k=0; k<_Ndim;k++)
1298 _Jcb[(_nVar-1)*_nVar+1+k]=-v[k]*total_energy/internal_energy;
1299 _Jcb[(_nVar-1)*_nVar+_nVar-1]=total_energy/internal_energy;
1302 for(k=0;k<_nVar;k++)
1307 _Jcb[_nVar]=_limitField[nameOfGroup].v_x[0];//Kieu
1308 v2 +=(_limitField[nameOfGroup].v_x[0])*(_limitField[nameOfGroup].v_x[0]);
1311 _Jcb[2*_nVar]= _limitField[nameOfGroup].v_y[0];
1312 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
1314 _Jcb[3*_nVar]=_limitField[nameOfGroup].v_z[0];
1315 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
1318 _Jcb[(_nVar-1)*_nVar]=_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2;
1321 else if (_limitField[nameOfGroup].bcType==InletPressure && q_n<0){
1323 double v[_Ndim], v2=0;
1325 for(k=1; k<_nVar; k++)
1326 _idm[k] = _idm[k-1] + 1;
1327 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1329 for(k=0; k<_Ndim;k++){
1334 double rho_ext=_fluides[0]->getDensity(_limitField[nameOfGroup].p, _limitField[nameOfGroup].T);
1335 double rho_int = _externalStates[0];
1336 double density_ratio=rho_ext/rho_int;
1338 for(int l =1;l<1+_Ndim;l++){
1339 _Jcb[l*_nVar]=-density_ratio*v[l-1];
1340 _Jcb[l*_nVar+l]=density_ratio;
1343 _Jcb[(_nVar-1)*_nVar]=-v2*density_ratio;
1344 for(k=0; k<_Ndim;k++)
1345 _Jcb[(_nVar-1)*_nVar+1+k]=density_ratio*v[k];
1347 // not wall, not inlet, not inletPressure
1348 else if(_limitField[nameOfGroup].bcType==Outlet || (_limitField[nameOfGroup].bcType==InletPressure && q_n>=0))
1351 double v[_Ndim], v2=0;
1353 for(k=1; k<_nVar; k++)
1354 _idm[k] = _idm[k-1] + 1;
1355 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1357 for(k=0; k<_Ndim;k++){
1362 double rho_ext=_fluides[0]->getDensity(_limitField[nameOfGroup].p, _externalStates[_nVar-1]);
1363 double rho_int = _externalStates[0];
1364 double density_ratio=rho_ext/rho_int;
1365 double internal_energy=_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho_int);
1366 double total_energy=internal_energy+v2/2;
1369 _Jcb[0]=density_ratio*(1-v2/(2*internal_energy));
1370 for(k=0; k<_Ndim;k++)
1371 _Jcb[1+k]=density_ratio*v[k]/internal_energy;
1372 _Jcb[_nVar-1]=-density_ratio/internal_energy;
1374 for(int l =1;l<1+_Ndim;l++){
1375 _Jcb[l*_nVar]=density_ratio*v2*v[l-1]/(2*internal_energy);
1376 for(k=0; k<_Ndim;k++)
1377 _Jcb[l*_nVar+1+k]=density_ratio*v[k]*v[l-1]/internal_energy;
1378 _Jcb[l*_nVar+1+k]-=density_ratio;
1379 _Jcb[l*_nVar+_nVar-1]=-density_ratio*v[l-1]/internal_energy;
1382 _Jcb[(_nVar-1)*_nVar]=density_ratio*v2*total_energy/(2*internal_energy);
1383 for(k=0; k<_Ndim;k++)
1384 _Jcb[(_nVar-1)*_nVar+1+k]=density_ratio*v[k]*total_energy/internal_energy;
1385 _Jcb[(_nVar-1)*_nVar+_nVar-1]=density_ratio*(1-total_energy/internal_energy);
1389 double cd = 1,cn=0,p0, gamma;
1390 _idm[0] = j*_nVar;// Kieu
1391 for(k=1; k<_nVar;k++)
1392 _idm[k] = _idm[k-1] + 1;
1393 VecGetValues(_conservativeVars, _nVar, _idm, _phi);
1394 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
1396 // compute the common numerator and common denominator
1397 p0=_fluides[0]->constante("p0");
1398 gamma =_fluides[0]->constante("gamma");
1399 cn =_limitField[nameOfGroup].p +p0;
1400 cd = _phi[0]*_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho)-p0;
1404 for(k=1; k<_nVar-1;k++)
1405 v2+=_externalStates[k]*_externalStates[k];
1407 _JcbDiff[0] = cn*(_phi[_nVar-1] -v2 -p0)/cd;
1408 for(k=1; k<_nVar-1;k++)
1409 _JcbDiff[k]=cn*_phi[k]/cd;
1410 _JcbDiff[_nVar-1]= -cn*_phi[0]/cd;
1412 for(idim=0; idim<_Ndim;idim++)
1415 _JcbDiff[(1+idim)*_nVar]=-(v2*cn*_phi[idim+1])/(2*cd);
1416 //colonnes intermediaire
1417 for(jdim=0; jdim<_Ndim;jdim++)
1419 _JcbDiff[(1+idim)*_nVar + jdim + 1] =_externalStates[idim+1]*_phi[jdim+1];
1420 _JcbDiff[(1+idim)*_nVar + jdim + 1]*=cn/cd;
1422 //matrice identite*cn*(rhoe- p0)
1423 _JcbDiff[(1+idim)*_nVar + idim + 1] +=( cn*(_phi[0]*_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho)-p0))/cd;
1426 _JcbDiff[(1+idim)*_nVar + _nVar-1]=-_phi[idim+1]*cn/cd;
1429 _JcbDiff[_nVar*(_nVar-1)] = -(v2*_phi[_nVar -1]*cn)/(2*cd);
1430 for(int idim=0; idim<_Ndim;idim++)
1431 _JcbDiff[_nVar*(_nVar-1)+idim+1]=_externalStates[idim+1]*_phi[_nVar -1]*cn/cd;
1432 _JcbDiff[_nVar*_nVar -1] = -(v2/2+p0)*cn/cd;
1435 else if (_limitField[nameOfGroup].bcType!=Neumann)// not wall, not inlet, not outlet
1437 cout << "group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1438 *_runLogFile<<"group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1439 _runLogFile->close();
1440 throw CdmathException("SinglePhase::jacobian: This boundary condition is not treated");
1444 //calcule la jacobienne pour une CL de diffusion
1445 void SinglePhase::jacobianDiff(const int &j, string nameOfGroup)
1447 if(_verbose && _nbTimeStep%_freqSave ==0)
1448 cout<<"Jacobienne condition limite diffusion bord "<< nameOfGroup<<endl;
1451 for(k=0; k<_nVar*_nVar;k++)
1454 if (_limitField[nameOfGroup].bcType==Wall){
1455 double v[_Ndim], ve[_Ndim], v2, ve2;
1458 for(k=1; k<_nVar; k++)
1459 _idm[k] = _idm[k-1] + 1;
1460 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1461 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
1463 ve[0] = _limitField[nameOfGroup].v_x[0];
1468 ve[1] = _limitField[nameOfGroup].v_y[0];
1474 ve[2] = _limitField[nameOfGroup].v_z[0];
1480 double internal_energy=_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho);
1481 double total_energy=internal_energy+ve2/2;
1484 _JcbDiff[0]=v2/(2*internal_energy);
1485 for(k=0; k<_Ndim;k++)
1486 _JcbDiff[1+k]=-v[k]/internal_energy;
1487 _JcbDiff[_nVar-1]=1/internal_energy;
1489 for(int l =1;l<1+_Ndim;l++){
1490 _JcbDiff[l*_nVar]=v2*ve[l-1]/(2*internal_energy);
1491 for(k=0; k<_Ndim;k++)
1492 _JcbDiff[l*_nVar+1+k]=-v[k]*ve[l-1]/internal_energy;
1493 _JcbDiff[l*_nVar+_nVar-1]=ve[l-1]/internal_energy;
1496 _JcbDiff[(_nVar-1)*_nVar]=v2*total_energy/(2*internal_energy);
1497 for(k=0; k<_Ndim;k++)
1498 _JcbDiff[(_nVar-1)*_nVar+1+k]=-v[k]*total_energy/internal_energy;
1499 _JcbDiff[(_nVar-1)*_nVar+_nVar-1]=total_energy/internal_energy;
1501 else if (_limitField[nameOfGroup].bcType==Outlet || _limitField[nameOfGroup].bcType==Neumann
1502 ||_limitField[nameOfGroup].bcType==Inlet || _limitField[nameOfGroup].bcType==InletPressure)
1504 for(k=0;k<_nVar;k++)
1505 _JcbDiff[k*_nVar+k]=1;
1508 cout << "group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1509 *_runLogFile<<"group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1510 _runLogFile->close();
1511 throw CdmathException("SinglePhase::jacobianDiff: This boundary condition is not recognised");
1515 void SinglePhase::primToCons(const double *P, const int &i, double *W, const int &j){
1516 //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;
1518 double rho=_fluides[0]->getDensity(P[i*(_Ndim+2)], P[i*(_Ndim+2)+(_Ndim+1)]);
1519 W[j*(_Ndim+2)] = _porosityField(j)*rho;//phi*rho
1520 for(int k=0; k<_Ndim; k++)
1521 W[j*(_Ndim+2)+(k+1)] = W[j*(_Ndim+2)]*P[i*(_Ndim+2)+(k+1)];//phi*rho*u
1523 W[j*(_Ndim+2)+(_Ndim+1)] = W[j*(_Ndim+2)]*_fluides[0]->getInternalEnergy(P[i*(_Ndim+2)+ (_Ndim+1)],rho);//rho*e
1524 for(int k=0; k<_Ndim; k++)
1525 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
1528 void SinglePhase::primToConsJacobianMatrix(double *V)
1530 double pression=V[0];
1531 double temperature=V[_nVar-1];
1532 double vitesse[_Ndim];
1533 for(int idim=0;idim<_Ndim;idim++)
1534 vitesse[idim]=V[1+idim];
1536 for(int idim=0;idim<_Ndim;idim++)
1537 v2+=vitesse[idim]*vitesse[idim];
1539 double rho=_fluides[0]->getDensity(pression,temperature);
1540 double gamma=_fluides[0]->constante("gamma");
1541 double Pinf=_fluides[0]->constante("p0");
1542 double q=_fluides[0]->constante("q");
1543 double cv=_fluides[0]->constante("cv");
1545 for(int k=0;k<_nVar*_nVar; k++)
1546 _primToConsJacoMat[k]=0;
1548 if( !_useDellacherieEOS)
1550 StiffenedGas* fluide0=dynamic_cast<StiffenedGas*>(_fluides[0]);
1551 double e=fluide0->getInternalEnergy(temperature);
1554 _primToConsJacoMat[0]=1/((gamma-1)*(e-q));
1555 _primToConsJacoMat[_nVar-1]=-rho*cv/(e-q);
1557 for(int idim=0;idim<_Ndim;idim++)
1559 _primToConsJacoMat[_nVar+idim*_nVar]=vitesse[idim]/((gamma-1)*(e-q));
1560 _primToConsJacoMat[_nVar+idim*_nVar+1+idim]=rho;
1561 _primToConsJacoMat[_nVar+idim*_nVar+_nVar-1]=-rho*vitesse[idim]*cv/(e-q);
1563 _primToConsJacoMat[(_nVar-1)*_nVar]=E/((gamma-1)*(e-q));
1564 for(int idim=0;idim<_Ndim;idim++)
1565 _primToConsJacoMat[(_nVar-1)*_nVar+1+idim]=rho*vitesse[idim];
1566 _primToConsJacoMat[(_nVar-1)*_nVar+_nVar-1]=rho*cv*(1-E/(e-q));
1568 else if( _useDellacherieEOS)
1570 StiffenedGasDellacherie* fluide0=dynamic_cast<StiffenedGasDellacherie*>(_fluides[0]);
1571 double h=fluide0->getEnthalpy(temperature);
1573 double cp=_fluides[0]->constante("cp");
1575 _primToConsJacoMat[0]=gamma/((gamma-1)*(h-q));
1576 _primToConsJacoMat[_nVar-1]=-rho*cp/(h-q);
1578 for(int idim=0;idim<_Ndim;idim++)
1580 _primToConsJacoMat[_nVar+idim*_nVar]=gamma*vitesse[idim]/((gamma-1)*(h-q));
1581 _primToConsJacoMat[_nVar+idim*_nVar+1+idim]=rho;
1582 _primToConsJacoMat[_nVar+idim*_nVar+_nVar-1]=-rho*vitesse[idim]*cp/(h-q);
1584 _primToConsJacoMat[(_nVar-1)*_nVar]=gamma*H/((gamma-1)*(h-q))-1;
1585 for(int idim=0;idim<_Ndim;idim++)
1586 _primToConsJacoMat[(_nVar-1)*_nVar+1+idim]=rho*vitesse[idim];
1587 _primToConsJacoMat[(_nVar-1)*_nVar+_nVar-1]=rho*cp*(1-H/(h-q));
1591 *_runLogFile<<"SinglePhase::primToConsJacobianMatrix: eos should be StiffenedGas or StiffenedGasDellacherie"<<endl;
1592 _runLogFile->close();
1593 throw CdmathException("SinglePhase::primToConsJacobianMatrix: eos should be StiffenedGas or StiffenedGasDellacherie");
1596 if(_verbose && _nbTimeStep%_freqSave ==0)
1598 cout<<" SinglePhase::primToConsJacobianMatrix" << endl;
1599 displayVector(_Vi,_nVar," _Vi " );
1600 cout<<" Jacobienne primToCons: " << endl;
1601 displayMatrix(_primToConsJacoMat,_nVar," Jacobienne primToCons: ");
1605 void SinglePhase::consToPrim(const double *Wcons, double* Wprim,double porosity)
1608 for(int k=1;k<=_Ndim;k++)
1609 q_2 += Wcons[k]*Wcons[k];
1610 q_2 /= Wcons[0]; //phi rho u²
1611 double rhoe=(Wcons[(_Ndim+2)-1]-q_2/2)/porosity;
1612 double rho=Wcons[0]/porosity;
1613 Wprim[0] = _fluides[0]->getPressure(rhoe,rho);//pressure p
1615 cout << "pressure = "<< Wprim[0] << " < 0 " << endl;
1616 *_runLogFile<< "pressure = "<< Wprim[0] << " < 0 " << endl;
1617 _runLogFile->close();
1618 throw CdmathException("SinglePhase::consToPrim: negative pressure");
1620 for(int k=1;k<=_Ndim;k++)
1621 Wprim[k] = Wcons[k]/Wcons[0];//velocity u
1622 Wprim[(_Ndim+2)-1] = _fluides[0]->getTemperatureFromPressure(Wprim[0],Wcons[0]/porosity);
1624 if(_verbose && _nbTimeStep%_freqSave ==0)
1626 cout<<"ConsToPrim Vecteur conservatif"<<endl;
1627 for(int k=0;k<_nVar;k++)
1628 cout<<Wcons[k]<<endl;
1629 cout<<"ConsToPrim Vecteur primitif"<<endl;
1630 for(int k=0;k<_nVar;k++)
1631 cout<<Wprim[k]<<endl;
1635 void SinglePhase::entropicShift(double* n)//TO do: make sure _Vi and _Vj are well set
1637 /*Left and right values */
1638 double ul_n = 0, ul_2=0, ur_n=0, ur_2 = 0; //valeurs de vitesse normale et |u|² a droite et a gauche
1639 for(int i=0;i<_Ndim;i++)
1641 ul_n += _Vi[1+i]*n[i];
1642 ul_2 += _Vi[1+i]*_Vi[1+i];
1643 ur_n += _Vj[1+i]*n[i];
1644 ur_2 += _Vj[1+i]*_Vj[1+i];
1647 double cl = _fluides[0]->vitesseSonEnthalpie(_Vi[_Ndim+1]-ul_2/2);//vitesse du son a l'interface
1648 double cr = _fluides[0]->vitesseSonEnthalpie(_Vj[_Ndim+1]-ur_2/2);//vitesse du son a l'interface
1650 _entropicShift[0]=fabs(ul_n-cl - (ur_n-cr));
1651 _entropicShift[1]=fabs(ul_n - ur_n);
1652 _entropicShift[2]=fabs(ul_n+cl - (ur_n+cr));
1654 if(_verbose && _nbTimeStep%_freqSave ==0)
1656 cout<<"Entropic shift left eigenvalues: "<<endl;
1657 cout<<"("<< ul_n-cl<< ", " <<ul_n<<", "<<ul_n+cl << ")";
1659 cout<<"Entropic shift right eigenvalues: "<<endl;
1660 cout<<"("<< ur_n-cr<< ", " <<ur_n<<", "<<ur_n+cr << ")";
1662 cout<<"eigenvalue jumps "<<endl;
1663 cout<< _entropicShift[0] << ", " << _entropicShift[1] << ", "<< _entropicShift[2] <<endl;
1667 Vector SinglePhase::convectionFlux(Vector U,Vector V, Vector normale, double porosity){
1668 if(_verbose && _nbTimeStep%_freqSave ==0)
1670 cout<<"SinglePhase::convectionFlux start"<<endl;
1671 cout<<"Ucons"<<endl;
1673 cout<<"Vprim"<<endl;
1677 double phirho=U(0);//phi rho
1678 Vector phiq(_Ndim);//phi rho u
1679 for(int i=0;i<_Ndim;i++)
1682 double pression=V(0);
1683 Vector vitesse(_Ndim);
1684 for(int i=0;i<_Ndim;i++)
1686 double Temperature= V(1+_Ndim);
1688 double vitessen=vitesse*normale;
1689 double rho=phirho/porosity;
1690 double e_int=_fluides[0]->getInternalEnergy(Temperature,rho);
1693 F(0)=phirho*vitessen;
1694 for(int i=0;i<_Ndim;i++)
1695 F(1+i)=phirho*vitessen*vitesse(i)+pression*normale(i)*porosity;
1696 F(1+_Ndim)=phirho*(e_int+0.5*vitesse*vitesse+pression/rho)*vitessen;
1698 if(_verbose && _nbTimeStep%_freqSave ==0)
1700 cout<<"SinglePhase::convectionFlux end"<<endl;
1701 cout<<"Flux F(U,V)"<<endl;
1708 void SinglePhase::RoeMatrixConservativeVariables(double u_n, double H,Vector velocity, double k, double K)
1710 /******** Construction de la matrice de Roe *********/
1711 //premiere ligne (masse)
1713 for(int idim=0; idim<_Ndim;idim++)
1714 _Aroe[1+idim]=_vec_normal[idim];
1717 //lignes intermadiaires(qdm)
1718 for(int idim=0; idim<_Ndim;idim++)
1721 _Aroe[(1+idim)*_nVar]=K*_vec_normal[idim] - u_n*_Uroe[1+idim];
1722 //colonnes intermediaires
1723 for(int jdim=0; jdim<_Ndim;jdim++)
1724 _Aroe[(1+idim)*_nVar + jdim + 1] = _Uroe[1+idim]*_vec_normal[jdim]-k*_vec_normal[idim]*_Uroe[1+jdim];
1726 _Aroe[(1+idim)*_nVar + idim + 1] += u_n;
1728 _Aroe[(1+idim)*_nVar + _nVar-1]=k*_vec_normal[idim];
1731 //derniere ligne (energie)
1732 _Aroe[_nVar*(_nVar-1)] = (K - H)*u_n;
1733 for(int idim=0; idim<_Ndim;idim++)
1734 _Aroe[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] - k*u_n*_Uroe[idim+1];
1735 _Aroe[_nVar*_nVar -1] = (1 + k)*u_n;
1737 void SinglePhase::convectionMatrixPrimitiveVariables( double rho, double u_n, double H,Vector vitesse)
1739 //Not used. Suppress or use in alternative implicitation in primitive variable of the staggered-roe scheme
1740 //On remplit la matrice de Roe en variables primitives : F(V_L)-F(V_R)=Aroe (V_L-V_R)
1741 //EOS is more involved with primitive variables
1742 // call to getDensityDerivatives(double concentration, double pression, double temperature,double v2) needed
1743 _AroeImplicit[0*_nVar+0]=_drho_sur_dp*u_n;
1744 for(int i=0;i<_Ndim;i++)
1745 _AroeImplicit[0*_nVar+1+i]=rho*_vec_normal[i];
1746 _AroeImplicit[0*_nVar+1+_Ndim]=_drho_sur_dT*u_n;
1747 for(int i=0;i<_Ndim;i++)
1749 _AroeImplicit[(1+i)*_nVar+0]=_drho_sur_dp *u_n*vitesse[i]+_vec_normal[i];
1750 for(int j=0;j<_Ndim;j++)
1751 _AroeImplicit[(1+i)*_nVar+1+j]=rho*vitesse[i]*_vec_normal[j];
1752 _AroeImplicit[(1+i)*_nVar+1+i]+=rho*u_n;
1753 _AroeImplicit[(1+i)*_nVar+1+_Ndim]=_drho_sur_dT*u_n*vitesse[i];
1755 _AroeImplicit[(1+_Ndim)*_nVar+0]=(_drhoE_sur_dp+1)*u_n;
1756 for(int i=0;i<_Ndim;i++)
1757 _AroeImplicit[(1+_Ndim)*_nVar+1+i]=rho*(H*_vec_normal[i]+u_n*vitesse[i]);
1758 _AroeImplicit[(1+_Ndim)*_nVar+1+_Ndim]=_drhoE_sur_dT*u_n;
1760 void SinglePhase::staggeredRoeUpwindingMatrixConservativeVariables( double u_n, double H,Vector velocity, double k, double K)
1762 //Calcul de décentrement de type décalé pour formulation de Roe
1763 if(fabs(u_n)>_precision)
1765 //premiere ligne (masse)
1767 for(int idim=0; idim<_Ndim;idim++)
1768 _absAroe[1+idim]=_vec_normal[idim];
1769 _absAroe[_nVar-1]=0;
1771 //lignes intermadiaires(qdm)
1772 for(int idim=0; idim<_Ndim;idim++)
1775 _absAroe[(1+idim)*_nVar]=-K*_vec_normal[idim] - u_n*_Uroe[1+idim];
1776 //colonnes intermediaires
1777 for(int jdim=0; jdim<_Ndim;jdim++)
1778 _absAroe[(1+idim)*_nVar + jdim + 1] = _Uroe[1+idim]*_vec_normal[jdim]+k*_vec_normal[idim]*_Uroe[1+jdim];
1780 _absAroe[(1+idim)*_nVar + idim + 1] += u_n;
1782 _absAroe[(1+idim)*_nVar + _nVar-1]=-k*_vec_normal[idim];
1785 //derniere ligne (energie)
1786 _absAroe[_nVar*(_nVar-1)] = (-K - H)*u_n;
1787 for(int idim=0; idim<_Ndim;idim++)
1788 _absAroe[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] + k*u_n*_Uroe[idim+1];
1789 _absAroe[_nVar*_nVar -1] = (1 - k)*u_n;
1797 for(int i=0; i<_nVar*_nVar;i++)
1798 _absAroe[i] *= signu;
1800 else//umn=0 ->centered scheme
1802 for(int i=0; i<_nVar*_nVar;i++)
1806 void SinglePhase::staggeredRoeUpwindingMatrixPrimitiveVariables(double rho, double u_n,double H, Vector vitesse)
1808 //Not used. Suppress or use in alternative implicitation in primitive variable of the staggered-roe scheme
1809 //Calcul de décentrement de type décalé pour formulation Roe
1810 _AroeImplicit[0*_nVar+0]=_drho_sur_dp*u_n;
1811 for(int i=0;i<_Ndim;i++)
1812 _AroeImplicit[0*_nVar+1+i]=rho*_vec_normal[i];
1813 _AroeImplicit[0*_nVar+1+_Ndim]=_drho_sur_dT*u_n;
1814 for(int i=0;i<_Ndim;i++)
1816 _AroeImplicit[(1+i)*_nVar+0]=_drho_sur_dp *u_n*vitesse[i]-_vec_normal[i];
1817 for(int j=0;j<_Ndim;j++)
1818 _AroeImplicit[(1+i)*_nVar+1+j]=rho*vitesse[i]*_vec_normal[j];
1819 _AroeImplicit[(1+i)*_nVar+1+i]+=rho*u_n;
1820 _AroeImplicit[(1+i)*_nVar+1+_Ndim]=_drho_sur_dT*u_n*vitesse[i];
1822 _AroeImplicit[(1+_Ndim)*_nVar+0]=(_drhoE_sur_dp+1)*u_n;
1823 for(int i=0;i<_Ndim;i++)
1824 _AroeImplicit[(1+_Ndim)*_nVar+1+i]=rho*(H*_vec_normal[i]+u_n*vitesse[i]);
1825 _AroeImplicit[(1+_Ndim)*_nVar+1+_Ndim]=_drhoE_sur_dT*u_n;
1828 Vector SinglePhase::staggeredVFFCFlux()
1830 if(_verbose && _nbTimeStep%_freqSave ==0)
1831 cout<<"SinglePhase::staggeredVFFCFlux() start"<<endl;
1833 if(_spaceScheme!=staggered || _nonLinearFormulation!=VFFC)
1835 *_runLogFile<< "SinglePhase::staggeredVFFCFlux: staggeredVFFCFlux method should be called only for VFFC formulation and staggered upwinding, pressure = "<< endl;
1836 _runLogFile->close();
1837 throw CdmathException("SinglePhase::staggeredVFFCFlux: staggeredVFFCFlux method should be called only for VFFC formulation and staggered upwinding");
1839 else//_spaceScheme==staggered && _nonLinearFormulation==VFFC
1843 double uijn=0, phiqn=0, uin=0, ujn=0;
1844 for(int idim=0;idim<_Ndim;idim++)
1846 uijn+=_vec_normal[idim]*_Uroe[1+idim];//URoe = rho, u, H
1847 uin +=_vec_normal[idim]*_Ui[1+idim];
1848 ujn +=_vec_normal[idim]*_Uj[1+idim];
1851 if( (uin>0 && ujn >0) || (uin>=0 && ujn <=0 && uijn>0) ) // formerly (uijn>_precision)
1853 for(int idim=0;idim<_Ndim;idim++)
1854 phiqn+=_vec_normal[idim]*_Ui[1+idim];//phi rho u n
1856 for(int idim=0;idim<_Ndim;idim++)
1857 Fij(1+idim)=phiqn*_Vi[1+idim]+_Vj[0]*_vec_normal[idim]*_porosityj;
1858 Fij(_nVar-1)=phiqn/_Ui[0]*(_Ui[_nVar-1]+_Vj[0]*sqrt(_porosityj/_porosityi));
1860 else if( (uin<0 && ujn <0) || (uin>=0 && ujn <=0 && uijn<0) ) // formerly (uijn<-_precision)
1862 for(int idim=0;idim<_Ndim;idim++)
1863 phiqn+=_vec_normal[idim]*_Uj[1+idim];//phi rho u n
1865 for(int idim=0;idim<_Ndim;idim++)
1866 Fij(1+idim)=phiqn*_Vj[1+idim]+_Vi[0]*_vec_normal[idim]*_porosityi;
1867 Fij(_nVar-1)=phiqn/_Uj[0]*(_Uj[_nVar-1]+_Vi[0]*sqrt(_porosityi/_porosityj));
1869 else//case (uin<=0 && ujn >=0) or (uin>=0 && ujn <=0 && uijn==0), apply centered scheme
1871 Vector Ui(_nVar), Uj(_nVar), Vi(_nVar), Vj(_nVar), Fi(_nVar), Fj(_nVar);
1872 Vector normale(_Ndim);
1873 for(int i1=0;i1<_Ndim;i1++)
1874 normale(i1)=_vec_normal[i1];
1875 for(int i1=0;i1<_nVar;i1++)
1882 Fi=convectionFlux(Ui,Vi,normale,_porosityi);
1883 Fj=convectionFlux(Uj,Vj,normale,_porosityj);
1884 Fij=(Fi+Fj)/2;//+_maxvploc*(Ui-Uj)/2;
1886 if(_verbose && _nbTimeStep%_freqSave ==0)
1888 cout<<"SinglePhase::staggeredVFFCFlux() endf uijn="<<uijn<<endl;
1895 void SinglePhase::staggeredVFFCMatricesConservativeVariables(double un)//vitesse normale de Roe en entrée
1897 if(_verbose && _nbTimeStep%_freqSave ==0)
1898 cout<<"SinglePhase::staggeredVFFCMatrices()"<<endl;
1900 if(_spaceScheme!=staggered || _nonLinearFormulation!=VFFC)
1902 *_runLogFile<< "SinglePhase::staggeredVFFCMatrices: staggeredVFFCMatrices method should be called only for VFFC formulation and staggered upwinding"<< endl;
1903 _runLogFile->close();
1904 throw CdmathException("SinglePhase::staggeredVFFCMatrices: staggeredVFFCMatrices method should be called only for VFFC formulation and staggered upwinding");
1906 else//_spaceScheme==staggered && _nonLinearFormulation==VFFC
1908 double ui_n=0, ui_2=0, uj_n=0, uj_2=0;//vitesse normale et carré du module
1909 double H;//enthalpie totale (expression particulière)
1910 consToPrim(_Ui,_Vi,_porosityi);
1911 consToPrim(_Uj,_Vj,_porosityj);
1912 for(int i=0;i<_Ndim;i++)
1914 ui_2 += _Vi[1+i]*_Vi[1+i];
1915 ui_n += _Vi[1+i]*_vec_normal[i];
1916 uj_2 += _Vj[1+i]*_Vj[1+i];
1917 uj_n += _Vj[1+i]*_vec_normal[i];
1920 double rhoi,pj, Ei, rhoj;
1921 double cj, Kj, kj;//dérivées de la pression
1922 rhoi=_Ui[0]/_porosityi;
1923 Ei= _Ui[_Ndim+1]/(rhoi*_porosityi);
1925 rhoj=_Uj[0]/_porosityj;
1927 cj = _fluides[0]->vitesseSonTemperature(_Vj[_Ndim+1],rhoj);
1928 kj = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
1929 Kj = uj_2*kj/2; //g-1/2 *|u|²
1932 double ci, Ki, ki;//dérivées de la pression
1933 Ej= _Uj[_Ndim+1]/rhoj;
1936 ci = _fluides[0]->vitesseSonTemperature(_Vi[_Ndim+1],rhoi);
1937 ki = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
1938 Ki = ui_2*ki/2; //g-1/2 *|u|²
1942 /***********Calcul des valeurs propres ********/
1943 vector<complex<double> > vp_dist(3,0);
1944 vp_dist[0]=ui_n-cj;vp_dist[1]=ui_n;vp_dist[2]=ui_n+cj;
1946 _maxvploc=fabs(ui_n)+cj;
1947 if(_maxvploc>_maxvp)
1950 if(_verbose && _nbTimeStep%_freqSave ==0)
1951 cout<<"Valeurs propres "<<ui_n-cj<<" , "<<ui_n<<" , "<<ui_n+cj<<endl;
1953 /******** Construction de la matrice A^+ *********/
1954 //premiere ligne (masse)
1956 for(int idim=0; idim<_Ndim;idim++)
1957 _AroePlus[1+idim]=_vec_normal[idim];
1958 _AroePlus[_nVar-1]=0;
1960 //lignes intermadiaires(qdm)
1961 for(int idim=0; idim<_Ndim;idim++)
1964 _AroePlus[(1+idim)*_nVar]=- ui_n*_Vi[1+idim];
1965 //colonnes intermediaires
1966 for(int jdim=0; jdim<_Ndim;jdim++)
1967 _AroePlus[(1+idim)*_nVar + jdim + 1] = _Vi[1+idim]*_vec_normal[jdim];
1969 _AroePlus[(1+idim)*_nVar + idim + 1] += ui_n;
1971 _AroePlus[(1+idim)*_nVar + _nVar-1]=0;
1974 //derniere ligne (energie)
1975 _AroePlus[_nVar*(_nVar-1)] = - H*ui_n;
1976 for(int idim=0; idim<_Ndim;idim++)
1977 _AroePlus[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] ;
1978 _AroePlus[_nVar*_nVar -1] = ui_n;
1980 /******** Construction de la matrice A^- *********/
1981 //premiere ligne (masse)
1983 for(int idim=0; idim<_Ndim;idim++)
1984 _AroeMinus[1+idim]=0;
1985 _AroeMinus[_nVar-1]=0;
1987 //lignes intermadiaires(qdm)
1988 for(int idim=0; idim<_Ndim;idim++)
1991 _AroeMinus[(1+idim)*_nVar]=Kj*_vec_normal[idim] ;
1992 //colonnes intermediaires
1993 for(int jdim=0; jdim<_Ndim;jdim++)
1994 _AroeMinus[(1+idim)*_nVar + jdim + 1] = -kj*_vec_normal[idim]*_Vj[1+jdim];
1996 _AroeMinus[(1+idim)*_nVar + idim + 1] += 0;
1998 _AroeMinus[(1+idim)*_nVar + _nVar-1]=kj*_vec_normal[idim];
2001 //derniere ligne (energie)
2002 _AroeMinus[_nVar*(_nVar-1)] = Kj *ui_n;
2003 for(int idim=0; idim<_Ndim;idim++)
2004 _AroeMinus[_nVar*(_nVar-1)+idim+1]= - kj*uj_n*_Vi[idim+1];
2005 _AroeMinus[_nVar*_nVar -1] = kj*ui_n;
2007 else if(un<-_precision)
2009 /***********Calcul des valeurs propres ********/
2010 vector<complex<double> > vp_dist(3,0);
2011 vp_dist[0]=uj_n-ci;vp_dist[1]=uj_n;vp_dist[2]=uj_n+ci;
2013 _maxvploc=fabs(uj_n)+ci;
2014 if(_maxvploc>_maxvp)
2017 if(_verbose && _nbTimeStep%_freqSave ==0)
2018 cout<<"Valeurs propres "<<uj_n-ci<<" , "<<uj_n<<" , "<<uj_n+ci<<endl;
2020 /******** Construction de la matrice A^+ *********/
2021 //premiere ligne (masse)
2023 for(int idim=0; idim<_Ndim;idim++)
2024 _AroePlus[1+idim]=0;
2025 _AroePlus[_nVar-1]=0;
2027 //lignes intermadiaires(qdm)
2028 for(int idim=0; idim<_Ndim;idim++)
2031 _AroePlus[(1+idim)*_nVar]=Ki*_vec_normal[idim] ;
2032 //colonnes intermediaires
2033 for(int jdim=0; jdim<_Ndim;jdim++)
2034 _AroePlus[(1+idim)*_nVar + jdim + 1] = -ki*_vec_normal[idim]*_Vi[1+jdim];
2036 _AroePlus[(1+idim)*_nVar + idim + 1] += 0;
2038 _AroePlus[(1+idim)*_nVar + _nVar-1]=ki*_vec_normal[idim];
2041 //derniere ligne (energie)
2042 _AroePlus[_nVar*(_nVar-1)] = Ki *uj_n;
2043 for(int idim=0; idim<_Ndim;idim++)
2044 _AroePlus[_nVar*(_nVar-1)+idim+1]= - ki*ui_n*_Vj[idim+1];
2045 _AroePlus[_nVar*_nVar -1] = ki*uj_n;
2047 /******** Construction de la matrice A^- *********/
2048 //premiere ligne (masse)
2050 for(int idim=0; idim<_Ndim;idim++)
2051 _AroeMinus[1+idim]=_vec_normal[idim];
2052 _AroeMinus[_nVar-1]=0;
2054 //lignes intermadiaires(qdm)
2055 for(int idim=0; idim<_Ndim;idim++)
2058 _AroeMinus[(1+idim)*_nVar]= - uj_n*_Vj[1+idim];
2059 //colonnes intermediaires
2060 for(int jdim=0; jdim<_Ndim;jdim++)
2061 _AroeMinus[(1+idim)*_nVar + jdim + 1] = _Vj[1+idim]*_vec_normal[jdim];
2063 _AroeMinus[(1+idim)*_nVar + idim + 1] += uj_n;
2065 _AroeMinus[(1+idim)*_nVar + _nVar-1]=0;
2068 //derniere ligne (energie)
2069 _AroeMinus[_nVar*(_nVar-1)] = - H*uj_n;
2070 for(int idim=0; idim<_Ndim;idim++)
2071 _AroeMinus[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] ;
2072 _AroeMinus[_nVar*_nVar -1] = uj_n;
2074 else//case nil velocity on the interface, apply centered scheme
2076 double u_n=0, u_2=0;//vitesse normale et carré du module
2077 for(int i=0;i<_Ndim;i++)
2079 u_2 += _Uroe[1+i]*_Uroe[1+i];
2080 u_n += _Uroe[1+i]*_vec_normal[i];
2082 Vector vitesse(_Ndim);
2083 for(int idim=0;idim<_Ndim;idim++)
2084 vitesse[idim]=_Uroe[1+idim];
2087 /***********Calcul des valeurs propres ********/
2089 c = _fluides[0]->vitesseSonEnthalpie(H-u_2/2);//vitesse du son a l'interface
2090 k = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
2091 K = u_2*k/2; //g-1/2 *|u|²
2093 _maxvploc=fabs(u_n)+c;
2094 if(_maxvploc>_maxvp)
2097 /******** Construction de la matrice A^+ *********/
2098 //premiere ligne (masse)
2100 for(int idim=0; idim<_Ndim;idim++)
2101 _AroePlus[1+idim]=0;
2102 _AroePlus[_nVar-1]=0;
2104 //lignes intermadiaires(qdm)
2105 for(int idim=0; idim<_Ndim;idim++)
2108 _AroePlus[(1+idim)*_nVar]=- ui_n*_Vi[1+idim];
2109 //colonnes intermediaires
2110 for(int jdim=0; jdim<_Ndim;jdim++)
2111 _AroePlus[(1+idim)*_nVar + jdim + 1] = _Vi[1+idim]*_vec_normal[jdim]-0.5*ki*_vec_normal[idim]*_Vi[1+jdim];
2113 _AroePlus[(1+idim)*_nVar + idim + 1] += 0.5*ui_n;
2115 _AroePlus[(1+idim)*_nVar + _nVar-1]=0.5*ki*_vec_normal[idim];
2118 //derniere ligne (energie)
2119 _AroePlus[_nVar*(_nVar-1)] = 0;
2120 for(int idim=0; idim<_Ndim;idim++)
2121 _AroePlus[_nVar*(_nVar-1)+idim+1]=0 ;
2122 _AroePlus[_nVar*_nVar -1] = 0;
2124 /******** Construction de la matrice A^- *********/
2125 //premiere ligne (masse)
2127 for(int idim=0; idim<_Ndim;idim++)
2128 _AroeMinus[1+idim]=0;
2129 _AroeMinus[_nVar-1]=0;
2131 //lignes intermadiaires(qdm)
2132 for(int idim=0; idim<_Ndim;idim++)
2135 _AroeMinus[(1+idim)*_nVar]=Kj*_vec_normal[idim] - uj_n*_Vj[1+idim];
2136 //colonnes intermediaires
2137 for(int jdim=0; jdim<_Ndim;jdim++)
2138 _AroeMinus[(1+idim)*_nVar + jdim + 1] = -0.5*kj*_vec_normal[idim]*_Vj[1+jdim];
2140 _AroeMinus[(1+idim)*_nVar + idim + 1] += 0.5*uj_n;
2142 _AroeMinus[(1+idim)*_nVar + _nVar-1]=0.5*kj*_vec_normal[idim];
2145 //derniere ligne (energie)
2146 _AroeMinus[_nVar*(_nVar-1)] = 0;
2147 for(int idim=0; idim<_Ndim;idim++)
2148 _AroeMinus[_nVar*(_nVar-1)+idim+1]= 0;
2149 _AroeMinus[_nVar*_nVar -1] = 0;
2152 if(_timeScheme==Implicit)
2153 for(int i=0; i<_nVar*_nVar;i++)
2155 _AroeMinusImplicit[i] = _AroeMinus[i];
2156 _AroePlusImplicit[i] = _AroePlus[i];
2159 /******** Construction de la matrices Aroe *********/
2161 //premiere ligne (masse)
2163 for(int idim=0; idim<_Ndim;idim++)
2164 _Aroe[1+idim]=_vec_normal[idim];
2167 //lignes intermadiaires(qdm)
2168 for(int idim=0; idim<_Ndim;idim++)
2171 _Aroe[(1+idim)*_nVar]=Ki*_vec_normal[idim] - uj_n*_Uj[1+idim];
2172 //colonnes intermediaires
2173 for(int jdim=0; jdim<_Ndim;jdim++)
2174 _Aroe[(1+idim)*_nVar + jdim + 1] = _Uj[1+idim]*_vec_normal[jdim]-ki*_vec_normal[idim]*_Ui[1+jdim];
2176 _Aroe[(1+idim)*_nVar + idim + 1] += uj_n;
2178 _Aroe[(1+idim)*_nVar + _nVar-1]=ki*_vec_normal[idim];
2181 //derniere ligne (energie)
2182 _Aroe[_nVar*(_nVar-1)] = (Ki - H)*uj_n;
2183 for(int idim=0; idim<_Ndim;idim++)
2184 _Aroe[_nVar*(_nVar-1)+idim+1]=H*_vec_normal[idim] - ki*ui_n*_Uj[idim+1];
2185 _Aroe[_nVar*_nVar -1] = (1 + ki)*uj_n;
2189 void SinglePhase::staggeredVFFCMatricesPrimitiveVariables(double un)//vitesse normale de Roe en entrée
2191 if(_verbose && _nbTimeStep%_freqSave ==0)
2192 cout<<"SinglePhase::staggeredVFFCMatricesPrimitiveVariables()"<<endl;
2194 if(_spaceScheme!=staggered || _nonLinearFormulation!=VFFC)
2196 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: staggeredVFFCMatricesPrimitiveVariables method should be called only for VFFC formulation and staggered upwinding" << endl;
2197 _runLogFile->close();
2198 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: staggeredVFFCMatricesPrimitiveVariables method should be called only for VFFC formulation and staggered upwinding");
2200 else//_spaceScheme==staggered && _nonLinearFormulation==VFFC
2202 double ui_n=0., ui_2=0., uj_n=0., uj_2=0.;//vitesse normale et carré du module
2203 double H;//enthalpie totale (expression particulière)
2204 consToPrim(_Ui,_Vi,_porosityi);
2205 consToPrim(_Uj,_Vj,_porosityj);
2207 for(int i=0;i<_Ndim;i++)
2209 ui_2 += _Vi[1+i]*_Vi[1+i];
2210 ui_n += _Vi[1+i]*_vec_normal[i];
2211 uj_2 += _Vj[1+i]*_Vj[1+i];
2212 uj_n += _Vj[1+i]*_vec_normal[i];
2215 if(_verbose && _nbTimeStep%_freqSave ==0){
2216 cout <<"SinglePhase::staggeredVFFCMatricesPrimitiveVariables " << endl;
2217 cout<<"Vecteur primitif _Vi" << endl;
2218 for(int i=0;i<_nVar;i++)
2221 cout<<"Vecteur primitif _Vj" << endl;
2222 for(int i=0;i<_nVar;i++)
2227 double gamma=_fluides[0]->constante("gamma");
2228 double q=_fluides[0]->constante("q");
2230 if(fabs(un)>_precision)//non zero velocity on the interface
2232 if( !_useDellacherieEOS)
2234 StiffenedGas* fluide0=dynamic_cast<StiffenedGas*>(_fluides[0]);
2235 double cv=fluide0->constante("cv");
2239 double rhoi,rhoj,pj, Ei, ei;
2240 double cj;//vitesse du son pour calcul valeurs propres
2241 rhoi=_Ui[0]/_porosityi;
2242 Ei= _Ui[_Ndim+1]/(rhoi*_porosityi);
2245 rhoj=_Uj[0]/_porosityj;
2246 cj = _fluides[0]->vitesseSonTemperature(_Vj[_Ndim+1],rhoj);
2248 /***********Calcul des valeurs propres ********/
2249 vector<complex<double> > vp_dist(3,0);
2250 vp_dist[0]=ui_n-cj;vp_dist[1]=ui_n;vp_dist[2]=ui_n+cj;
2252 _maxvploc=fabs(ui_n)+cj;
2253 if(_maxvploc>_maxvp)
2256 if(_verbose && _nbTimeStep%_freqSave ==0)
2257 cout<<"Valeurs propres "<<ui_n-cj<<" , "<<ui_n<<" , "<<ui_n+cj<<endl;
2259 /******** Construction de la matrice A^+ *********/
2260 //premiere ligne (masse)
2261 _AroePlusImplicit[0]=ui_n/((gamma-1)*(ei-q));
2262 for(int idim=0; idim<_Ndim;idim++)
2263 _AroePlusImplicit[1+idim]=rhoi*_vec_normal[idim];
2264 _AroePlusImplicit[_nVar-1]=-rhoi*ui_n*cv/(ei-q);
2266 //lignes intermadiaires(qdm)
2267 for(int idim=0; idim<_Ndim;idim++)
2270 _AroePlusImplicit[(1+idim)*_nVar]=ui_n/((gamma-1)*(ei-q))*_Vi[1+idim];
2271 //colonnes intermediaires
2272 for(int jdim=0; jdim<_Ndim;jdim++)
2273 _AroePlusImplicit[(1+idim)*_nVar + jdim + 1] = rhoi*_Vi[1+idim]*_vec_normal[jdim];
2275 _AroePlusImplicit[(1+idim)*_nVar + idim + 1] += rhoi*ui_n;
2277 _AroePlusImplicit[(1+idim)*_nVar + _nVar-1]=-rhoi*ui_n*cv/(ei-q)*_Vi[1+idim];
2280 //derniere ligne (energie)
2281 _AroePlusImplicit[_nVar*(_nVar-1)] = Ei*ui_n/((gamma-1)*(ei-q));
2282 for(int idim=0; idim<_Ndim;idim++)
2283 _AroePlusImplicit[_nVar*(_nVar-1)+idim+1]=(rhoi*Ei+pj)*_vec_normal[idim]+rhoi*ui_n*_Vi[1+idim];
2284 _AroePlusImplicit[_nVar*_nVar -1] = rhoi*ui_n*(1-Ei/(ei-q))*cv;
2286 /******** Construction de la matrice A^- *********/
2287 //premiere ligne (masse)
2288 _AroeMinusImplicit[0]=0;
2289 for(int idim=0; idim<_Ndim;idim++)
2290 _AroeMinusImplicit[1+idim]=0;
2291 _AroeMinusImplicit[_nVar-1]=0;
2293 //lignes intermadiaires(qdm)
2294 for(int idim=0; idim<_Ndim;idim++)
2297 _AroeMinusImplicit[(1+idim)*_nVar]=_vec_normal[idim] ;
2298 //colonnes intermediaires
2299 for(int jdim=0; jdim<_Ndim;jdim++)
2300 _AroeMinusImplicit[(1+idim)*_nVar + jdim + 1] = 0;
2302 _AroeMinusImplicit[(1+idim)*_nVar + idim + 1] += 0;
2304 _AroeMinusImplicit[(1+idim)*_nVar + _nVar-1]=0;
2307 //derniere ligne (energie)
2308 _AroeMinusImplicit[_nVar*(_nVar-1)] = ui_n;
2309 for(int idim=0; idim<_Ndim;idim++)
2310 _AroeMinusImplicit[_nVar*(_nVar-1)+idim+1]= 0;
2311 _AroeMinusImplicit[_nVar*_nVar -1] = 0;
2313 else if(un<-_precision)
2315 double pi, Ej, rhoi, rhoj, ej;
2316 double ci;//vitesse du son pour calcul valeurs propres
2317 rhoj=_Uj[0]/_porosityj;
2318 Ej= _Uj[_Ndim+1]/rhoj;
2321 rhoi=_Ui[0]/_porosityi;
2322 ci = _fluides[0]->vitesseSonTemperature(_Vi[_Ndim+1],rhoi);
2324 /***********Calcul des valeurs propres ********/
2325 vector<complex<double> > vp_dist(3,0);
2326 vp_dist[0]=uj_n-ci;vp_dist[1]=uj_n;vp_dist[2]=uj_n+ci;
2328 _maxvploc=fabs(uj_n)+ci;
2329 if(_maxvploc>_maxvp)
2332 if(_verbose && _nbTimeStep%_freqSave ==0)
2333 cout<<"Valeurs propres "<<uj_n-ci<<" , "<<uj_n<<" , "<<uj_n+ci<<endl;
2335 /******** Construction de la matrice A^+ *********/
2336 //premiere ligne (masse)
2337 _AroePlusImplicit[0]=0;
2338 for(int idim=0; idim<_Ndim;idim++)
2339 _AroePlusImplicit[1+idim]=0;
2340 _AroePlusImplicit[_nVar-1]=0;
2342 //lignes intermadiaires(qdm)
2343 for(int idim=0; idim<_Ndim;idim++)
2346 _AroePlusImplicit[(1+idim)*_nVar]=0;
2347 //colonnes intermediaires
2348 for(int jdim=0; jdim<_Ndim;jdim++)
2349 _AroePlusImplicit[(1+idim)*_nVar + jdim + 1] = 0;
2351 _AroePlusImplicit[(1+idim)*_nVar + idim + 1] += 0;
2353 _AroePlusImplicit[(1+idim)*_nVar + _nVar-1]=0;
2356 //derniere ligne (energie)
2357 _AroePlusImplicit[_nVar*(_nVar-1)] = uj_n;
2358 for(int idim=0; idim<_Ndim;idim++)
2359 _AroePlusImplicit[_nVar*(_nVar-1)+idim+1]= 0;
2360 _AroePlusImplicit[_nVar*_nVar -1] = 0;
2362 /******** Construction de la matrice A^- *********/
2363 //premiere ligne (masse)
2364 _AroeMinusImplicit[0]=uj_n/((gamma-1)*(ej-q));
2365 for(int idim=0; idim<_Ndim;idim++)
2366 _AroeMinusImplicit[1+idim]=rhoj*_vec_normal[idim];
2367 _AroeMinusImplicit[_nVar-1]=-rhoj*uj_n*cv/(ej-q);
2369 //lignes intermadiaires(qdm)
2370 for(int idim=0; idim<_Ndim;idim++)
2373 _AroeMinusImplicit[(1+idim)*_nVar]= uj_n/((gamma-1)*(ej-q))*_Vj[1+idim];
2374 //colonnes intermediaires
2375 for(int jdim=0; jdim<_Ndim;jdim++)
2376 _AroeMinusImplicit[(1+idim)*_nVar + jdim + 1] = rhoj*_Vj[1+idim]*_vec_normal[jdim];
2378 _AroeMinusImplicit[(1+idim)*_nVar + idim + 1] += rhoj*uj_n;
2380 _AroeMinusImplicit[(1+idim)*_nVar + _nVar-1]=-rhoj*uj_n*cv/(ej-q)*_Vj[1+idim];
2383 //derniere ligne (energie)
2384 _AroeMinusImplicit[_nVar*(_nVar-1)] = Ej*uj_n/((gamma-1)*(ej-q));
2385 for(int idim=0; idim<_Ndim;idim++)
2386 _AroeMinusImplicit[_nVar*(_nVar-1)+idim+1]=(rhoj*Ej+pi)*_vec_normal[idim]+rhoj*uj_n*_Vj[1+idim];
2387 _AroeMinusImplicit[_nVar*_nVar -1] = rhoj*uj_n*(1-Ej/(ej-q))*cv;
2391 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: velocity un should be non zero" << endl;
2392 _runLogFile->close();
2393 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: velocity un should be non zero");
2396 else if(_useDellacherieEOS )
2398 StiffenedGasDellacherie* fluide0=dynamic_cast<StiffenedGasDellacherie*>(_fluides[0]);
2399 double cp=fluide0->constante("cp");
2403 double rhoi,rhoj,pj, Ei, hi, Hi;
2404 double cj;//vitesse du son pour calcul valeurs propres
2405 rhoi=_Ui[0]/_porosityi;
2406 Ei= _Ui[_Ndim+1]/(rhoi*_porosityi);
2410 rhoj=_Uj[0]/_porosityj;
2411 cj = _fluides[0]->vitesseSonTemperature(_Vj[_Ndim+1],rhoj);
2413 /***********Calcul des valeurs propres ********/
2414 vector<complex<double> > vp_dist(3,0);
2415 vp_dist[0]=ui_n-cj;vp_dist[1]=ui_n;vp_dist[2]=ui_n+cj;
2417 _maxvploc=fabs(ui_n)+cj;
2418 if(_maxvploc>_maxvp)
2421 if(_verbose && _nbTimeStep%_freqSave ==0)
2422 cout<<"Valeurs propres "<<ui_n-cj<<" , "<<ui_n<<" , "<<ui_n+cj<<endl;
2424 /******** Construction de la matrice A^+ *********/
2425 //premiere ligne (masse)
2426 _AroePlusImplicit[0]=ui_n*gamma/((gamma-1)*(hi-q));
2427 for(int idim=0; idim<_Ndim;idim++)
2428 _AroePlusImplicit[1+idim]=rhoi*_vec_normal[idim];
2429 _AroePlusImplicit[_nVar-1]=-rhoi*ui_n*cp/(hi-q);
2431 //lignes intermadiaires(qdm)
2432 for(int idim=0; idim<_Ndim;idim++)
2435 _AroePlusImplicit[(1+idim)*_nVar]=ui_n*gamma/((gamma-1)*(hi-q))*_Vi[1+idim];
2436 //colonnes intermediaires
2437 for(int jdim=0; jdim<_Ndim;jdim++)
2438 _AroePlusImplicit[(1+idim)*_nVar + jdim + 1] = rhoi*_Vi[1+idim]*_vec_normal[jdim];
2440 _AroePlusImplicit[(1+idim)*_nVar + idim + 1] += rhoi*ui_n;
2442 _AroePlusImplicit[(1+idim)*_nVar + _nVar-1]=-rhoi*ui_n*cp/(hi-q)*_Vi[1+idim];
2445 //derniere ligne (energie)
2446 _AroePlusImplicit[_nVar*(_nVar-1)] = ui_n*(Hi*gamma/((gamma-1)*(hi-q))-1);
2447 for(int idim=0; idim<_Ndim;idim++)
2448 _AroePlusImplicit[_nVar*(_nVar-1)+idim+1]=(rhoi*Ei+pj)*_vec_normal[idim]+rhoi*ui_n*_Vi[1+idim];
2449 _AroePlusImplicit[_nVar*_nVar -1] = rhoi*ui_n*(1-Hi/(hi-q))*cp;
2451 /******** Construction de la matrice A^- *********/
2452 //premiere ligne (masse)
2453 _AroeMinusImplicit[0]=0;
2454 for(int idim=0; idim<_Ndim;idim++)
2455 _AroeMinusImplicit[1+idim]=0;
2456 _AroeMinusImplicit[_nVar-1]=0;
2458 //lignes intermadiaires(qdm)
2459 for(int idim=0; idim<_Ndim;idim++)
2462 _AroeMinusImplicit[(1+idim)*_nVar]=_vec_normal[idim] ;
2463 //colonnes intermediaires
2464 for(int jdim=0; jdim<_Ndim;jdim++)
2465 _AroeMinusImplicit[(1+idim)*_nVar + jdim + 1] = 0;
2467 _AroeMinusImplicit[(1+idim)*_nVar + idim + 1] += 0;
2469 _AroeMinusImplicit[(1+idim)*_nVar + _nVar-1]=0;
2472 //derniere ligne (energie)
2473 _AroeMinusImplicit[_nVar*(_nVar-1)] = ui_n;
2474 for(int idim=0; idim<_Ndim;idim++)
2475 _AroeMinusImplicit[_nVar*(_nVar-1)+idim+1]= 0;
2476 _AroeMinusImplicit[_nVar*_nVar -1] = 0;
2478 else if(un<-_precision)
2480 double pi, Ej, rhoi,rhoj, Hj, hj;
2481 double ci;//vitesse du son pour calcul valeurs propres
2482 rhoj=_Uj[0]/_porosityj;
2483 Ej= _Uj[_Ndim+1]/rhoj;
2487 rhoi=_Ui[0]/_porosityi;
2488 ci = _fluides[0]->vitesseSonTemperature(_Vi[_Ndim+1],rhoi);
2490 /***********Calcul des valeurs propres ********/
2491 vector<complex<double> > vp_dist(3,0);
2492 vp_dist[0]=uj_n-ci;vp_dist[1]=uj_n;vp_dist[2]=uj_n+ci;
2494 _maxvploc=fabs(uj_n)+ci;
2495 if(_maxvploc>_maxvp)
2498 if(_verbose && _nbTimeStep%_freqSave ==0)
2499 cout<<"Valeurs propres "<<uj_n-ci<<" , "<<uj_n<<" , "<<uj_n+ci<<endl;
2501 /******** Construction de la matrice A^+ *********/
2502 //premiere ligne (masse)
2503 _AroePlusImplicit[0]=0;
2504 for(int idim=0; idim<_Ndim;idim++)
2505 _AroePlusImplicit[1+idim]=0;
2506 _AroePlusImplicit[_nVar-1]=0;
2508 //lignes intermadiaires(qdm)
2509 for(int idim=0; idim<_Ndim;idim++)
2512 _AroePlusImplicit[(1+idim)*_nVar]=0;
2513 //colonnes intermediaires
2514 for(int jdim=0; jdim<_Ndim;jdim++)
2515 _AroePlusImplicit[(1+idim)*_nVar + jdim + 1] = 0;
2517 _AroePlusImplicit[(1+idim)*_nVar + idim + 1] += 0;
2519 _AroePlusImplicit[(1+idim)*_nVar + _nVar-1]=0;
2522 //derniere ligne (energie)
2523 _AroePlusImplicit[_nVar*(_nVar-1)] = uj_n;
2524 for(int idim=0; idim<_Ndim;idim++)
2525 _AroePlusImplicit[_nVar*(_nVar-1)+idim+1]= 0;
2526 _AroePlusImplicit[_nVar*_nVar -1] = 0;
2528 /******** Construction de la matrice A^- *********/
2529 //premiere ligne (masse)
2530 _AroeMinusImplicit[0]=uj_n*gamma/((gamma-1)*(hj-q));
2531 for(int idim=0; idim<_Ndim;idim++)
2532 _AroeMinusImplicit[1+idim]=rhoj*_vec_normal[idim];
2533 _AroeMinusImplicit[_nVar-1]=-rhoj*uj_n*cp/(hj-q);
2535 //lignes intermadiaires(qdm)
2536 for(int idim=0; idim<_Ndim;idim++)
2539 _AroeMinusImplicit[(1+idim)*_nVar]= uj_n*gamma/((gamma-1)*(hj-q))*_Vj[1+idim];
2540 //colonnes intermediaires
2541 for(int jdim=0; jdim<_Ndim;jdim++)
2542 _AroeMinusImplicit[(1+idim)*_nVar + jdim + 1] = rhoj*_Vj[1+idim]*_vec_normal[jdim];
2544 _AroeMinusImplicit[(1+idim)*_nVar + idim + 1] += rhoj*uj_n;
2546 _AroeMinusImplicit[(1+idim)*_nVar + _nVar-1]=-rhoj*uj_n*cp/(hj-q)*_Vj[1+idim];
2549 //derniere ligne (energie)
2550 _AroeMinusImplicit[_nVar*(_nVar-1)] = uj_n*(Hj*gamma/((gamma-1)*(hj-q))-1);
2551 for(int idim=0; idim<_Ndim;idim++)
2552 _AroeMinusImplicit[_nVar*(_nVar-1)+idim+1]=(rhoj*Ej+pi)*_vec_normal[idim]+rhoj*uj_n*_Vj[1+idim];
2553 _AroeMinusImplicit[_nVar*_nVar -1] = rhoj*uj_n*(1-Hj/(hj-q))*cp;
2557 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: velocity un should be non zero" << endl;
2558 _runLogFile->close();
2559 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: velocity un should be non zero");
2564 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie" << endl;
2565 _runLogFile->close();
2566 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie");
2569 else//case nil velocity on the interface, apply centered scheme
2571 primToConsJacobianMatrix(_Vj);
2572 Polynoms::matrixProduct(_AroeMinus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroeMinusImplicit);
2573 primToConsJacobianMatrix(_Vi);
2574 Polynoms::matrixProduct(_AroePlus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroePlusImplicit);
2578 void SinglePhase::applyVFRoeLowMachCorrections(bool isBord, string groupname)
2580 if(_nonLinearFormulation!=VFRoe)
2582 *_runLogFile<< "SinglePhase::applyVFRoeLowMachCorrections: applyVFRoeLowMachCorrections method should be called only for VFRoe formulation" << endl;
2583 _runLogFile->close();
2584 throw CdmathException("SinglePhase::applyVFRoeLowMachCorrections: applyVFRoeLowMachCorrections method should be called only for VFRoe formulation");
2586 else//_nonLinearFormulation==VFRoe
2588 if(_spaceScheme==lowMach){
2590 for(int i=0;i<_Ndim;i++)
2591 u_2 += _Uroe[1+i]*_Uroe[1+i];
2592 double c = _maxvploc;//vitesse du son a l'interface
2593 double M=sqrt(u_2)/c;//Mach number
2594 _Vij[0]=M*_Vij[0]+(1-M)*(_Vi[0]+_Vj[0])/2;
2596 else if(_spaceScheme==pressureCorrection)
2597 {//order 1 : no correction, oarder 2 : correction everywhere, order 3 : correction only inside, orders 4 and 5 : special correction at boundaries
2598 if(_pressureCorrectionOrder==2 || (!isBord && _pressureCorrectionOrder==3) || (!isBord && _pressureCorrectionOrder==4) || (!isBord && _pressureCorrectionOrder==5) )
2600 double norm_uij=0, uij_n=0, ui_n=0, uj_n=0;
2601 for(int i=0;i<_Ndim;i++)
2603 norm_uij += _Uroe[1+i]*_Uroe[1+i];
2604 uij_n += _Uroe[1+i]*_vec_normal[i];
2605 ui_n += _Vi[1+i]*_vec_normal[i];
2606 uj_n += _Vj[1+i]*_vec_normal[i];
2608 norm_uij=sqrt(norm_uij);
2609 if(norm_uij>_precision)//avoid division by zero
2610 _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;
2612 _Vij[0]=(_Vi[0]+_Vj[0])/2 - _Uroe[0]*norm_uij*(uj_n-ui_n)/4;
2614 else if(_pressureCorrectionOrder==4 && isBord)
2616 else if(_pressureCorrectionOrder==5 && isBord)
2618 double g_n=0;//scalar product of gravity and normal vector
2619 for(int i=0;i<_Ndim;i++)
2620 g_n += _GravityField3d[i]*_vec_normal[i];
2621 _Vij[0]=_Vi[0]- _Ui[0]*g_n/_inv_dxi/2;
2624 else if(_spaceScheme==staggered)
2627 for(int i=0;i<_Ndim;i++)
2628 uij_n += _Uroe[1+i]*_vec_normal[i];
2630 if(uij_n>_precision){
2632 for(int i=0;i<_Ndim;i++)
2634 _Vij[_nVar-1]=_Vi[_nVar-1];
2636 else if(uij_n<-_precision){
2638 for(int i=0;i<_Ndim;i++)
2640 _Vij[_nVar-1]=_Vj[_nVar-1];
2643 _Vij[0]=(_Vi[0]+_Vi[0])/2;
2644 for(int i=0;i<_Ndim;i++)
2645 _Vij[1+i]=(_Vj[1+i]+_Vj[1+i])/2;
2646 _Vij[_nVar-1]=(_Vj[_nVar-1]+_Vj[_nVar-1])/2;
2649 primToCons(_Vij,0,_Uij,0);
2653 void SinglePhase::testConservation()
2655 double SUM, DELTA, x;
2657 for(int i=0; i<_nVar; i++)
2661 cout << "Masse totale (kg): ";
2665 cout << "Energie totale (J): ";
2667 cout << "Quantite de mouvement totale (kg.m.s^-1): ";
2673 for(int j=0; j<_Nmailles; j++)
2675 if(!_usePrimitiveVarsInNewton)
2676 VecGetValues(_conservativeVars, 1, &I, &x);//on recupere la valeur du champ
2678 VecGetValues(_primitiveVars, 1, &I, &x);//on recupere la valeur du champ
2679 SUM += x*_mesh.getCell(j).getMeasure();
2680 VecGetValues(_newtonVariation, 1, &I, &x);//on recupere la variation du champ
2681 DELTA += x*_mesh.getCell(j).getMeasure();
2684 if(fabs(SUM)>_precision)
2685 cout << SUM << ", variation relative: " << fabs(DELTA /SUM) << endl;
2687 cout << " a une somme quasi nulle, variation absolue: " << fabs(DELTA) << endl;
2691 void SinglePhase::getDensityDerivatives( double pressure, double temperature, double v2)
2693 double rho=_fluides[0]->getDensity(pressure,temperature);
2694 double gamma=_fluides[0]->constante("gamma");
2695 double q=_fluides[0]->constante("q");
2697 if( !_useDellacherieEOS)
2699 StiffenedGas* fluide0=dynamic_cast<StiffenedGas*>(_fluides[0]);
2700 double e = fluide0->getInternalEnergy(temperature);
2701 double cv=fluide0->constante("cv");
2704 _drho_sur_dp=1/((gamma-1)*(e-q));
2705 _drho_sur_dT=-rho*cv/(e-q);
2706 _drhoE_sur_dp=E/((gamma-1)*(e-q));
2707 _drhoE_sur_dT=rho*cv*(1-E/(e-q));
2709 else if(_useDellacherieEOS )
2711 StiffenedGasDellacherie* fluide0=dynamic_cast<StiffenedGasDellacherie*>(_fluides[0]);
2712 double h=fluide0->getEnthalpy(temperature);
2714 double cp=fluide0->constante("cp");
2716 _drho_sur_dp=gamma/((gamma-1)*(h-q));
2717 _drho_sur_dT=-rho*cp/(h-q);
2718 _drhoE_sur_dp=gamma*H/((gamma-1)*(h-q))-1;
2719 _drhoE_sur_dT=rho*cp*(1-H/(h-q));
2723 *_runLogFile<< "SinglePhase::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie" << endl;
2724 _runLogFile->close();
2725 throw CdmathException("SinglePhase::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie");
2728 if(_verbose && _nbTimeStep%_freqSave ==0)
2730 cout<<"_drho_sur_dp= "<<_drho_sur_dp<<", _drho_sur_dT= "<<_drho_sur_dT<<endl;
2731 cout<<"_drhoE_sur_dp= "<<_drhoE_sur_dp<<", _drhoE_sur_dT= "<<_drhoE_sur_dT<<endl;
2734 void SinglePhase::save(){
2735 PetscPrintf(PETSC_COMM_WORLD,"Saving numerical results at time step number %d \n\n", _nbTimeStep);
2736 *_runLogFile<< "Saving numerical results at time step number "<< _nbTimeStep << endl<<endl;
2738 string prim(_path+"/SinglePhasePrim_");///Results
2739 string cons(_path+"/SinglePhaseCons_");
2740 string allFields(_path+"/");
2743 allFields+=_fileName;
2746 for (long i = 0; i < _Nmailles; i++){
2747 // j = 0 : pressure; j = _nVar - 1: temperature; j = 1,..,_nVar-2: velocity
2748 for (int j = 0; j < _nVar; j++){
2750 VecGetValues(_primitiveVars,1,&Ii,&_VV(i,j));
2753 if(_saveConservativeField){
2754 for (long i = 0; i < _Nmailles; i++){
2755 // j = 0 : density; j = _nVar - 1 : energy j = 1,..,_nVar-2: momentum
2756 for (int j = 0; j < _nVar; j++){
2758 VecGetValues(_conservativeVars,1,&Ii,&_UU(i,j));
2761 _UU.setTime(_time,_nbTimeStep);
2763 _VV.setTime(_time,_nbTimeStep);
2765 // create mesh and component info
2766 if (_nbTimeStep ==0 || _restartWithNewFileName){
2767 string prim_suppress ="rm -rf "+prim+"_*";
2768 string cons_suppress ="rm -rf "+cons+"_*";
2770 system(prim_suppress.c_str());//Nettoyage des précédents calculs identiques
2771 system(cons_suppress.c_str());//Nettoyage des précédents calculs identiques
2773 if(_saveConservativeField){
2774 _UU.setInfoOnComponent(0,"Density_(kg/m^3)");
2775 _UU.setInfoOnComponent(1,"Momentum_x");// (kg/m^2/s)
2777 _UU.setInfoOnComponent(2,"Momentum_y");// (kg/m^2/s)
2779 _UU.setInfoOnComponent(3,"Momentum_z");// (kg/m^2/s)
2781 _UU.setInfoOnComponent(_nVar-1,"Energy_(J/m^3)");
2796 _VV.setInfoOnComponent(0,"Pressure_(Pa)");
2797 _VV.setInfoOnComponent(1,"Velocity_x_(m/s)");
2799 _VV.setInfoOnComponent(2,"Velocity_y_(m/s)");
2801 _VV.setInfoOnComponent(3,"Velocity_z_(m/s)");
2802 _VV.setInfoOnComponent(_nVar-1,"Temperature_(K)");
2818 // do not create mesh
2823 _VV.writeVTK(prim,false);
2826 _VV.writeMED(prim,false);
2832 if(_saveConservativeField){
2836 _UU.writeVTK(cons,false);
2839 _UU.writeMED(cons,false);
2847 if(_saveVelocity || _saveAllFields){
2848 for (long i = 0; i < _Nmailles; i++){
2849 // j = 0 : pressure; j = _nVar - 1: temperature; j = 1,..,_nVar-2: velocity
2850 for (int j = 0; j < _Ndim; j++)//On récupère les composantes de vitesse
2852 int Ii = i*_nVar +1+j;
2853 VecGetValues(_primitiveVars,1,&Ii,&_Vitesse(i,j));
2855 for (int j = _Ndim; j < 3; j++)//On met à zero les composantes de vitesse si la dimension est <3
2858 _Vitesse.setTime(_time,_nbTimeStep);
2859 if (_nbTimeStep ==0 || _restartWithNewFileName){
2860 _Vitesse.setInfoOnComponent(0,"Velocity_x_(m/s)");
2861 _Vitesse.setInfoOnComponent(1,"Velocity_y_(m/s)");
2862 _Vitesse.setInfoOnComponent(2,"Velocity_z_(m/s)");
2867 _Vitesse.writeVTK(prim+"_Velocity");
2870 _Vitesse.writeMED(prim+"_Velocity");
2873 _Vitesse.writeCSV(prim+"_Velocity");
2881 _Vitesse.writeVTK(prim+"_Velocity",false);
2884 _Vitesse.writeMED(prim+"_Velocity",false);
2887 _Vitesse.writeCSV(prim+"_Velocity");
2895 double p,T,rho, h, vx,vy,vz,v2;
2897 for (long i = 0; i < _Nmailles; i++){
2899 VecGetValues(_conservativeVars,1,&Ii,&rho);
2901 VecGetValues(_primitiveVars,1,&Ii,&p);
2902 Ii = i*_nVar +_nVar-1;
2903 VecGetValues(_primitiveVars,1,&Ii,&T);
2905 VecGetValues(_primitiveVars,1,&Ii,&vx);
2909 VecGetValues(_primitiveVars,1,&Ii,&vy);
2912 VecGetValues(_primitiveVars,1,&Ii,&vz);
2916 h = _fluides[0]->getEnthalpy(T,rho);
2934 _MachNumber(i)=sqrt(v2)/_fluides[0]->vitesseSonEnthalpie(h);
2936 _Enthalpy.setTime(_time,_nbTimeStep);
2937 _Density.setTime(_time,_nbTimeStep);
2938 _Pressure.setTime(_time,_nbTimeStep);
2939 _Temperature.setTime(_time,_nbTimeStep);
2940 _MachNumber.setTime(_time,_nbTimeStep);
2941 _VitesseX.setTime(_time,_nbTimeStep);
2944 _VitesseY.setTime(_time,_nbTimeStep);
2946 _VitesseZ.setTime(_time,_nbTimeStep);
2948 if (_nbTimeStep ==0 || _restartWithNewFileName){
2952 _Enthalpy.writeVTK(allFields+"_Enthalpy");
2953 _Density.writeVTK(allFields+"_Density");
2954 _Pressure.writeVTK(allFields+"_Pressure");
2955 _Temperature.writeVTK(allFields+"_Temperature");
2956 _MachNumber.writeVTK(allFields+"_MachNumber");
2957 _VitesseX.writeVTK(allFields+"_VelocityX");
2960 _VitesseY.writeVTK(allFields+"_VelocityY");
2962 _VitesseZ.writeVTK(allFields+"_VelocityZ");
2966 _Enthalpy.writeMED(allFields+"_Enthalpy");
2967 _Density.writeMED(allFields+"_Density");
2968 _Pressure.writeMED(allFields+"_Pressure");
2969 _Temperature.writeMED(allFields+"_Temperature");
2970 _MachNumber.writeMED(allFields+"_MachNumber");
2971 _VitesseX.writeMED(allFields+"_VelocityX");
2974 _VitesseY.writeMED(allFields+"_VelocityY");
2976 _VitesseZ.writeMED(allFields+"_VelocityZ");
2980 _Enthalpy.writeCSV(allFields+"_Enthalpy");
2981 _Density.writeCSV(allFields+"_Density");
2982 _Pressure.writeCSV(allFields+"_Pressure");
2983 _Temperature.writeCSV(allFields+"_Temperature");
2984 _MachNumber.writeCSV(allFields+"_MachNumber");
2985 _VitesseX.writeCSV(allFields+"_VelocityX");
2988 _VitesseY.writeCSV(allFields+"_VelocityY");
2990 _VitesseZ.writeCSV(allFields+"_VelocityZ");
2999 _Enthalpy.writeVTK(allFields+"_Enthalpy",false);
3000 _Density.writeVTK(allFields+"_Density",false);
3001 _Pressure.writeVTK(allFields+"_Pressure",false);
3002 _Temperature.writeVTK(allFields+"_Temperature",false);
3003 _MachNumber.writeVTK(allFields+"_MachNumber",false);
3004 _VitesseX.writeVTK(allFields+"_VelocityX",false);
3007 _VitesseY.writeVTK(allFields+"_VelocityY",false);
3009 _VitesseZ.writeVTK(allFields+"_VelocityZ",false);
3013 _Enthalpy.writeMED(allFields+"_Enthalpy",false);
3014 _Density.writeMED(allFields+"_Density",false);
3015 _Pressure.writeMED(allFields+"_Pressure",false);
3016 _Temperature.writeMED(allFields+"_Temperature",false);
3017 _MachNumber.writeMED(allFields+"_MachNumber",false);
3018 _VitesseX.writeMED(allFields+"_VelocityX",false);
3021 _VitesseY.writeMED(allFields+"_VelocityY",false);
3023 _VitesseZ.writeMED(allFields+"_VelocityZ",false);
3027 _Enthalpy.writeCSV(allFields+"_Enthalpy");
3028 _Density.writeCSV(allFields+"_Density");
3029 _Pressure.writeCSV(allFields+"_Pressure");
3030 _Temperature.writeCSV(allFields+"_Temperature");
3031 _MachNumber.writeCSV(allFields+"_MachNumber");
3032 _VitesseX.writeCSV(allFields+"_VelocityX");
3035 _VitesseY.writeCSV(allFields+"_VelocityY");
3037 _VitesseZ.writeCSV(allFields+"_VelocityZ");
3062 if(_saveConservativeField){
3077 if(_saveVelocity || _saveAllFields){
3081 _Vitesse.writeVTK(prim+"_Velocity");
3084 _Vitesse.writeMED(prim+"_Velocity");
3087 _Vitesse.writeCSV(prim+"_Velocity");
3093 if (_nbTimeStep ==0 || _restartWithNewFileName){ // delete mesh in memory
3094 _VV.deleteMEDCouplingMesh();
3095 _UU.deleteMEDCouplingMesh();
3097 if (_restartWithNewFileName)
3098 _restartWithNewFileName=false;
3101 Field& SinglePhase::getPressureField()
3103 if(!_initializedMemory)
3104 throw CdmathException("SinglePhase::getPressureField, Call initialize first");
3108 _Pressure=Field("Pressure",CELLS,_mesh,1);
3110 for (long i = 0; i < _Nmailles; i++){
3112 VecGetValues(_primitiveVars,1,&Ii,&_Pressure(i));
3114 _Pressure.setTime(_time,_nbTimeStep);
3119 Field& SinglePhase::getTemperatureField()
3121 if(!_initializedMemory)
3122 throw CdmathException("SinglePhase::getTemperatureField, Call initialize first");
3126 _Temperature=Field("Temperature",CELLS,_mesh,1);
3128 for (long i = 0; i < _Nmailles; i++){
3129 Ii = i*_nVar +_nVar-1;
3130 VecGetValues(_primitiveVars,1,&Ii,&_Temperature(i));
3132 _Temperature.setTime(_time,_nbTimeStep);
3134 return _Temperature;
3137 Field& SinglePhase::getVelocityField()
3139 if(!_initializedMemory)
3140 throw CdmathException("SinglePhase::getVelocityField, Call initialize first");
3142 if(!_saveAllFields )
3144 _Vitesse=Field("Vitesse",CELLS,_mesh,3);
3146 for (long i = 0; i < _Nmailles; i++)
3148 for (int j = 0; j < _Ndim; j++)//On récupère les composantes de vitesse
3150 int Ii = i*_nVar +1+j;
3151 VecGetValues(_primitiveVars,1,&Ii,&_Vitesse(i,j));
3153 for (int j = _Ndim; j < 3; j++)//On met à zero les composantes de vitesse si la dimension est <3
3156 _Vitesse.setTime(_time,_nbTimeStep);
3157 _Vitesse.setInfoOnComponent(0,"Velocity_x_(m/s)");
3158 _Vitesse.setInfoOnComponent(1,"Velocity_y_(m/s)");
3159 _Vitesse.setInfoOnComponent(2,"Velocity_z_(m/s)");
3165 Field& SinglePhase::getMachNumberField()
3167 if(!_initializedMemory)
3168 throw CdmathException("SinglePhase::getMachNumberField, Call initialize first");
3170 if(!_saveAllFields )
3172 _MachNumber=Field("Mach number",CELLS,_mesh,1);
3174 double p,T,rho,h, temp, u2=0;
3175 for (long i = 0; i < _Nmailles; i++){
3177 VecGetValues(_primitiveVars,1,&Ii,&p);
3178 Ii = i*_nVar +_nVar-1;
3179 VecGetValues(_primitiveVars,1,&Ii,&T);
3181 for (int j = 0; j < _Ndim; j++)//On récupère les composantes de vitesse
3183 int Ii = i*_nVar +1+j;
3184 VecGetValues(_primitiveVars,1,&Ii,&temp);
3188 rho=_fluides[0]->getDensity(p,T);
3189 h =_fluides[0]->getEnthalpy(T,rho);
3190 _MachNumber[i] =sqrt(u2)/_fluides[0]->vitesseSonEnthalpie(h);
3191 //cout<<"u="<<sqrt(u2)<<", c= "<<_fluides[0]->vitesseSonEnthalpie(h)<<", MachNumberField[i] = "<<MachNumberField[i] <<endl;
3193 _MachNumber.setTime(_time,_nbTimeStep);
3195 //cout<<", MachNumberField = "<<MachNumberField <<endl;
3200 Field& SinglePhase::getVelocityXField()
3202 if(!_initializedMemory)
3203 throw CdmathException("SinglePhase::getVelocityXField, Call initialize first");
3205 if(!_saveAllFields )
3207 _VitesseX=Field("Velocity X",CELLS,_mesh,1);
3209 for (long i = 0; i < _Nmailles; i++)
3211 int Ii = i*_nVar +1;
3212 VecGetValues(_primitiveVars,1,&Ii,&_VitesseX(i));
3214 _VitesseX.setTime(_time,_nbTimeStep);
3215 _VitesseX.setInfoOnComponent(0,"Velocity_x_(m/s)");
3221 Field& SinglePhase::getVelocityYField()
3223 if(!_initializedMemory)
3224 throw CdmathException("SinglePhase::getVelocityYField, Call initialize first");
3227 throw CdmathException("SinglePhase::getVelocityYField() error : dimension should be at least 2");
3229 if(!_saveAllFields )
3231 _VitesseY=Field("Velocity Y",CELLS,_mesh,1);
3233 for (long i = 0; i < _Nmailles; i++)
3235 int Ii = i*_nVar +2;
3236 VecGetValues(_primitiveVars,1,&Ii,&_VitesseY(i));
3238 _VitesseY.setTime(_time,_nbTimeStep);
3239 _VitesseY.setInfoOnComponent(0,"Velocity_y_(m/s)");
3245 Field& SinglePhase::getVelocityZField()
3247 if(!_initializedMemory)
3248 throw CdmathException("SinglePhase::getVelocityZField, Call initialize first");
3251 throw CdmathException("SinglePhase::getvelocityZField() error : dimension should be 3");
3253 if(!_saveAllFields )
3255 _VitesseZ=Field("Velocity Z",CELLS,_mesh,1);
3257 for (long i = 0; i < _Nmailles; i++)
3259 int Ii = i*_nVar +3;
3260 VecGetValues(_primitiveVars,1,&Ii,&_VitesseZ(i));
3262 _VitesseZ.setTime(_time,_nbTimeStep);
3263 _VitesseZ.setInfoOnComponent(0,"Velocity_z_(m/s)");
3269 Field& SinglePhase::getDensityField()
3271 if(!_initializedMemory)
3272 throw CdmathException("SinglePhase::getDensityField, Call initialize first");
3274 if(!_saveAllFields )
3276 _Density=Field("Density",CELLS,_mesh,1);
3278 for (long i = 0; i < _Nmailles; i++){
3280 VecGetValues(_conservativeVars,1,&Ii,&_Density(i));
3282 _Density.setTime(_time,_nbTimeStep);
3287 Field& SinglePhase::getMomentumField()//not yet managed by parameter _saveAllFields
3289 if(!_initializedMemory)
3290 throw CdmathException("SinglePhase::getMomentumField, Call initialize first");
3292 _Momentum=Field("Momentum",CELLS,_mesh,_Ndim);
3294 for (long i = 0; i < _Nmailles; i++)
3295 for (int j = 0; j < _Ndim; j++)//On récupère les composantes de qdm
3297 int Ii = i*_nVar +1+j;
3298 VecGetValues(_conservativeVars,1,&Ii,&_Momentum(i,j));
3300 _Momentum.setTime(_time,_nbTimeStep);
3305 Field& SinglePhase::getTotalEnergyField()//not yet managed by parameter _saveAllFields
3307 if(!_initializedMemory)
3308 throw CdmathException("SinglePhase::getTotalEnergyField, Call initialize first");
3310 _TotalEnergy=Field("TotalEnergy",CELLS,_mesh,1);
3312 for (long i = 0; i < _Nmailles; i++){
3313 Ii = i*_nVar +_nVar-1;
3314 VecGetValues(_conservativeVars,1,&Ii,&_TotalEnergy(i));
3316 _TotalEnergy.setTime(_time,_nbTimeStep);
3318 return _TotalEnergy;
3321 Field& SinglePhase::getEnthalpyField()
3323 if(!_initializedMemory)
3324 throw CdmathException("SinglePhase::getEnthalpyField, Call initialize first");
3326 if(!_saveAllFields )
3328 _Enthalpy=Field("Enthalpy",CELLS,_mesh,1);
3331 for (long i = 0; i < _Nmailles; i++){
3333 VecGetValues(_primitiveVars,1,&Ii,&p);
3334 Ii = i*_nVar +_nVar-1;
3335 VecGetValues(_primitiveVars,1,&Ii,&T);
3337 rho=_fluides[0]->getDensity(p,T);
3338 _Enthalpy(i)=_fluides[0]->getEnthalpy(T,rho);
3340 _Enthalpy.setTime(_time,_nbTimeStep);
3346 vector<string> SinglePhase::getOutputFieldsNames()
3348 vector<string> result(8);
3350 result[0]="Pressure";
3351 result[1]="Velocity";
3352 result[2]="Temperature";
3353 result[3]="Density";
3354 result[4]="Momentum";
3355 result[5]="TotalEnergy";
3356 result[6]="Enthalpy";
3357 result[7]="VelocityX";
3362 Field& SinglePhase::getOutputField(const string& nameField )
3364 if(nameField=="pressure" || nameField=="Pressure" || nameField=="PRESSURE" || nameField=="PRESSION" || nameField=="Pression" || nameField=="pression" )
3365 return getPressureField();
3366 else if(nameField=="velocity" || nameField=="Velocity" || nameField=="VELOCITY" || nameField=="Vitesse" || nameField=="VITESSE" || nameField=="vitesse" )
3367 return getVelocityField();
3368 else if(nameField=="velocityX" || nameField=="VelocityX" || nameField=="VELOCITYX" || nameField=="VitesseX" || nameField=="VITESSEX" || nameField=="vitesseX" )
3369 return getVelocityXField();
3370 else if(nameField=="velocityY" || nameField=="VelocityY" || nameField=="VELOCITYY" || nameField=="VitesseY" || nameField=="VITESSEY" || nameField=="vitesseY" )
3371 return getVelocityYField();
3372 else if(nameField=="velocityZ" || nameField=="VelocityZ" || nameField=="VELOCITYZ" || nameField=="VitesseZ" || nameField=="VITESSEZ" || nameField=="vitesseZ" )
3373 return getVelocityZField();
3374 else if(nameField=="temperature" || nameField=="Temperature" || nameField=="TEMPERATURE" || nameField=="temperature" )
3375 return getTemperatureField();
3376 else if(nameField=="density" || nameField=="Density" || nameField=="DENSITY" || nameField=="Densite" || nameField=="DENSITE" || nameField=="densite" )
3377 return getDensityField();
3378 else if(nameField=="momentum" || nameField=="Momentum" || nameField=="MOMENTUM" || nameField=="Qdm" || nameField=="QDM" || nameField=="qdm" )
3379 return getMomentumField();
3380 else if(nameField=="enthalpy" || nameField=="Enthalpy" || nameField=="ENTHALPY" || nameField=="Enthalpie" || nameField=="ENTHALPIE" || nameField=="enthalpie" )
3381 return getEnthalpyField();
3382 else if(nameField=="totalenergy" || nameField=="TotalEnergy" || nameField=="TOTALENERGY" || nameField=="ENERGIETOTALE" || nameField=="EnergieTotale" || nameField=="energietotale" )
3383 return getTotalEnergyField();
3386 cout<<"Error : Field name "<< nameField << " does not exist, call getOutputFieldsNames first to check" << endl;
3387 throw CdmathException("SinglePhase::getOutputField error : Unknown Field name");