2 * SinglePhaseStaggered.cxx
5 #include "SinglePhaseStaggered.hxx"
10 computeVelocityMCells(const Field& velocity,
11 Field& velocityMCells)
13 Mesh myMesh=velocity.getMesh();
14 int nbCells=myMesh.getNumberOfCells();
16 for(int i=0;i<nbCells;i++)
18 std::vector< int > facesId=myMesh.getCell(i).getFacesId();
19 velocityMCells(i)=(velocity(facesId[0])+velocity(facesId[1]))/2.;
23 SinglePhaseStaggered::SinglePhaseStaggered(phaseType fluid, pressureEstimate pEstimate, int dim, bool useDellacherieEOS){
27 _dragCoeffs=vector<double>(1,0);
29 _useDellacherieEOS=useDellacherieEOS;
31 if(pEstimate==around1bar300K){//EOS at 1 bar and 300K
33 cout<<"Fluid is air around 1 bar and 300 K (27°C)"<<endl;
34 *_runLogFile<<"Fluid is air around 1 bar and 300 K (27°C)"<<endl;
35 _fluides[0] = new StiffenedGas(1.4,743,300,2.22e5); //ideal gas law for nitrogen at pressure 1 bar and temperature 27°C, e=2.22e5, c_v=743
38 cout<<"Fluid is water around 1 bar and 300 K (27°C)"<<endl;
39 *_runLogFile<<"Fluid is water around 1 bar and 300 K (27°C)"<<endl;
40 _fluides[0] = new StiffenedGas(996,1e5,300,1.12e5,1501,4130); //stiffened gas law for water at pressure 1 bar and temperature 27°C, e=1.12e5, c_v=4130
43 else{//EOS at 155 bars and 618K
45 cout<<"Fluid is Gas around saturation point 155 bars and 618 K (345°C)"<<endl;
46 *_runLogFile<<"Fluid is Gas around saturation point 155 bars and 618 K (345°C)"<<endl;
47 _fluides[0] = new StiffenedGas(102,1.55e7,618,2.44e6, 433,3633); //stiffened gas law for Gas at pressure 155 bar and temperature 345°C
49 else{//To do : change to normal regime: 155 bars and 573K
50 cout<<"Fluid is water around saturation point 155 bars and 618 K (345°C)"<<endl;
51 *_runLogFile<<"Fluid is water around saturation point 155 bars and 618 K (345°C)"<<endl;
52 if(_useDellacherieEOS)
53 _fluides[0]= new StiffenedGasDellacherie(2.35,1e9,-1.167e6,1816); //stiffened gas law for water from S. Dellacherie
55 _fluides[0]= new StiffenedGas(594.,1.55e7,618.,1.6e6, 621.,3100.); //stiffened gas law for water at pressure 155 bar, and temperature 345°C
59 void SinglePhaseStaggered::initialize(){
60 cout<<"Initialising the Navier-Stokes model"<<endl;
61 *_runLogFile<<"Initialising the Navier-Stokes model"<<endl;
63 _Uroe = new double[_nVar];
64 _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
65 for(int i=0; i<_Ndim; i++)
66 _gravite[i+1]=_GravityField3d[i];
68 _GravityImplicitationMatrix = new PetscScalar[_nVar*_nVar];
70 _Vitesse=Field("Velocity",CELLS,_mesh,3);//Forcement en dimension 3 pour le posttraitement des lignes de courant
72 if(_entropicCorrection)
73 _entropicShift=vector<double>(3,0);//at most 3 distinct eigenvalues
75 ProblemFluid::initialize();
78 bool SinglePhaseStaggered::iterateTimeStep(bool &converged)
80 if(_timeScheme == Explicit || !_usePrimitiveVarsInNewton)
81 ProblemFluid::iterateTimeStep(converged);
86 if(_NEWTON_its>0){//Pas besoin de computeTimeStep à la première iteration de Newton
88 computeTimeStep(stop);
90 if(stop){//Le compute time step ne s'est pas bien passé
91 cout<<"ComputeTimeStep failed"<<endl;
96 computeNewtonVariation();
98 //converged=convergence des iterations
99 if(_timeScheme == Explicit)
101 else{//Implicit scheme
103 KSPGetIterationNumber(_ksp, &_PetscIts);
104 if( _MaxIterLinearSolver < _PetscIts)//save the maximum number of iterations needed during the newton scheme
105 _MaxIterLinearSolver = _PetscIts;
106 if(_PetscIts>=_maxPetscIts)//solving the linear system failed
108 cout<<"Systeme lineaire : pas de convergence de Petsc. Itérations maximales "<<_maxPetscIts<<" atteintes"<<endl;
109 *_runLogFile<<"Systeme lineaire : pas de convergence de Petsc. Itérations maximales "<<_maxPetscIts<<" atteintes"<<endl;
113 else{//solving the linear system succeeded
114 //Calcul de la variation relative Uk+1-Uk
118 for(int j=1; j<=_Nmailles; j++)
120 for(int k=0; k<_nVar; k++)
123 VecGetValues(_newtonVariation, 1, &I, &dx);
124 VecGetValues(_primitiveVars, 1, &I, &x);
125 if (fabs(x)*fabs(x)< _precision)
127 if(_erreur_rel < fabs(dx))
128 _erreur_rel = fabs(dx);
130 else if(_erreur_rel < fabs(dx/x))
131 _erreur_rel = fabs(dx/x);
135 converged = _erreur_rel <= _precision_Newton;
138 double relaxation=1;//Vk+1=Vk+relaxation*deltaV
140 VecAXPY(_primitiveVars, relaxation, _newtonVariation);
142 //mise a jour du champ primitif
143 updateConservatives();
145 if(_nbPhases==2 && fabs(_err_press_max) > _precision)//la pression n'a pu être calculée en diphasique à partir des variables conservatives
147 cout<<"Warning consToPrim: nbiter max atteint, erreur relative pression= "<<_err_press_max<<" precision= " <<_precision<<endl;
148 *_runLogFile<<"Warning consToPrim: nbiter max atteint, erreur relative pression= "<<_err_press_max<<" precision= " <<_precision<<endl;
154 cout<<"Vecteur Vkp1-Vk "<<endl;
155 VecView(_newtonVariation, PETSC_VIEWER_STDOUT_SELF);
156 cout << "Nouvel etat courant Vk de l'iteration Newton: " << endl;
157 VecView(_primitiveVars, PETSC_VIEWER_STDOUT_SELF);
160 if(_nbPhases==2 && _nbTimeStep%_freqSave ==0){
161 if(_minm1<-_precision || _minm2<-_precision)
163 cout<<"!!!!!!!!! WARNING masse partielle negative sur " << _nbMaillesNeg << " faces, min m1= "<< _minm1 << " , minm2= "<< _minm2<< " precision "<<_precision<<endl;
164 *_runLogFile<<"!!!!!!!!! WARNING masse partielle negative sur " << _nbMaillesNeg << " faces, min m1= "<< _minm1 << " , minm2= "<< _minm2<< " precision "<<_precision<<endl;
168 cout << "!!!!!!!!!!!!!!!!!!!!!!!! Complex eigenvalues on " << _nbVpCplx << " cells, max imag= " << _part_imag_max << endl;
169 *_runLogFile << "!!!!!!!!!!!!!!!!!!!!!!!! Complex eigenvalues on " << _nbVpCplx << " cells, max imag= " << _part_imag_max << endl;
181 void SinglePhaseStaggered::computeNewtonVariation()
183 if(!_usePrimitiveVarsInNewton)
184 ProblemFluid::computeNewtonVariation();
189 cout<<"Vecteur courant Vk "<<endl;
190 VecView(_primitiveVars,PETSC_VIEWER_STDOUT_SELF);
192 cout << "Matrice du système linéaire avant contribution delta t" << endl;
193 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
195 cout << "Second membre du système linéaire avant contribution delta t" << endl;
196 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
199 if(_timeScheme == Explicit)
201 VecCopy(_b,_newtonVariation);
202 VecScale(_newtonVariation, _dt);
203 if(_verbose && _nbTimeStep%_freqSave ==0)
205 cout<<"Vecteur _newtonVariation =_b*dt"<<endl;
206 VecView(_newtonVariation,PETSC_VIEWER_STDOUT_SELF);
212 MatAssemblyBegin(_A, MAT_FINAL_ASSEMBLY);
214 VecAXPY(_b, 1/_dt, _old);
215 VecAXPY(_b, -1/_dt, _conservativeVars);
217 for(int imaille = 0; imaille<_Nmailles; imaille++){
218 _idm[0] = _nVar*imaille;
219 for(int k=1; k<_nVar; k++)
220 _idm[k] = _idm[k-1] + 1;
221 VecGetValues(_primitiveVars, _nVar, _idm, _Vi);
222 primToConsJacobianMatrix(_Vi);
223 for(int k=0; k<_nVar*_nVar; k++)
224 _primToConsJacoMat[k]*=1/_dt;
225 MatSetValuesBlocked(_A, 1, &imaille, 1, &imaille, _primToConsJacoMat, ADD_VALUES);
227 MatAssemblyEnd(_A, MAT_FINAL_ASSEMBLY);
229 #if PETSC_VERSION_GREATER_3_5
230 KSPSetOperators(_ksp, _A, _A);
232 KSPSetOperators(_ksp, _A, _A,SAME_NONZERO_PATTERN);
237 cout << "Matrice du système linéaire" << endl;
238 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
240 cout << "Second membre du système linéaire" << endl;
241 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
246 KSPSetComputeEigenvalues(_ksp,PETSC_TRUE);
249 KSPSolve(_ksp, _b, _newtonVariation);
253 computeScaling(_maxvp);
255 VecAssemblyBegin(_vecScaling);
256 VecAssemblyBegin(_invVecScaling);
257 for(int imaille = 0; imaille<_Nmailles; imaille++)
260 VecSetValuesBlocked(_vecScaling,1 , &indice, _blockDiag, INSERT_VALUES);
261 VecSetValuesBlocked(_invVecScaling,1,&indice,_invBlockDiag, INSERT_VALUES);
263 VecAssemblyEnd(_vecScaling);
264 VecAssemblyEnd(_invVecScaling);
268 cout << "Matrice avant le preconditionneur des vecteurs propres " << endl;
269 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
271 cout << "Second membre avant le preconditionneur des vecteurs propres " << endl;
272 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
275 MatDiagonalScale(_A,_vecScaling,_invVecScaling);
278 cout << "Matrice apres le preconditionneur des vecteurs propres " << endl;
279 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
282 VecCopy(_b,_bScaling);
283 VecPointwiseMult(_b,_vecScaling,_bScaling);
286 cout << "Produit du second membre par le preconditionneur bloc diagonal a gauche" << endl;
287 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
291 KSPSolve(_ksp,_b, _bScaling);
292 VecPointwiseMult(_newtonVariation,_invVecScaling,_bScaling);
296 cout << "solution du systeme lineaire local:" << endl;
297 VecView(_newtonVariation, PETSC_VIEWER_STDOUT_SELF);
303 void SinglePhaseStaggered::convectionState( const long &i, const long &j, const bool &IsBord){
306 for(int k=1; k<_nVar; k++)
307 _idm[k] = _idm[k-1] + 1;
308 VecGetValues(_conservativeVars, _nVar, _idm, _Ui);
311 for(int k=1; k<_nVar; k++)
312 _idm[k] = _idm[k-1] + 1;
314 VecGetValues(_Uext, _nVar, _idm, _Uj);
316 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
317 if(_verbose && _nbTimeStep%_freqSave ==0)
319 cout<<"Convection Left state cell " << i<< ": "<<endl;
320 for(int k =0; k<_nVar; k++)
322 cout<<"Convection Right state cell " << j<< ": "<<endl;
323 for(int k =0; k<_nVar; k++)
326 if(_Ui[0]<0||_Uj[0]<0)
328 cout<<"!!!!!!!!!!!!!!!!!!!!!!!!densite negative, arret de calcul!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
329 *_runLogFile<<"!!!!!!!!!!!!!!!!!!!!!!!!densite negative, arret de calcul!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
330 _runLogFile->close();
331 throw CdmathException("densite negative, arret de calcul");
333 PetscScalar ri, rj, xi, xj, pi, pj;
335 ri = sqrt(_Ui[0]);//racine carre de phi_i rho_i
337 _Uroe[0] = ri*rj; //moyenne geometrique des densites
338 if(_verbose && _nbTimeStep%_freqSave ==0)
339 cout << "Densité moyenne Roe gauche " << i << ": " << ri*ri << ", droite " << j << ": " << rj*rj << "->" << _Uroe[0] << endl;
340 for(int k=0;k<_Ndim;k++){
343 _Uroe[1+k] = (xi/ri + xj/rj)/(ri + rj);
344 //"moyenne" des vitesses
345 if(_verbose && _nbTimeStep%_freqSave ==0)
346 cout << "Vitesse de Roe composante "<< k<<" gauche " << i << ": " << xi/(ri*ri) << ", droite " << j << ": " << xj/(rj*rj) << "->" << _Uroe[k+1] << endl;
348 // H = (rho E + p)/rho
349 xi = _Ui[_nVar-1];//phi rho E
351 Ii = i*_nVar; // correct Kieu
352 VecGetValues(_primitiveVars, 1, &Ii, &pi);// _primitiveVars pour p
356 for(int k=1;k<=_Ndim;k++)
357 q_2 += _Uj[k]*_Uj[k];
358 q_2 /= _Uj[0]; //phi rho u²
359 pj = _fluides[0]->getPressure((_Uj[(_Ndim+2)-1]-q_2/2)/_porosityj,_Uj[0]/_porosityj);
363 Ii = j*_nVar; // correct Kieu
364 VecGetValues(_primitiveVars, 1, &Ii, &pj);
366 xi = (xi + pi)/(ri*ri);
367 xj = (xj + pj)/(rj*rj);
368 _Uroe[_nVar-1] = (ri*xi + rj*xj)/(ri + rj);
369 //on se donne l enthalpie ici
370 if(_verbose && _nbTimeStep%_freqSave ==0)
371 cout << "Enthalpie totale de Roe H gauche " << i << ": " << xi << ", droite " << j << ": " << xj << "->" << _Uroe[_nVar-1] << endl;
373 if(_verbose && _nbTimeStep%_freqSave ==0)
375 cout<<"Convection interfacial state"<<endl;
376 for(int k=0;k<_nVar;k++)
377 cout<< _Uroe[k]<<" , "<<endl;
381 void SinglePhaseStaggered::setBoundaryState(string nameOfGroup, const int &j,double *normale){
383 double v2=0, q_n=0;//q_n=quantité de mouvement normale à la face frontière;
385 for(k=1; k<_nVar; k++)
386 _idm[k] = _idm[k-1] + 1;
388 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);//On initialise l'état fantôme avec l'état interne
389 for(k=0; k<_Ndim; k++)
390 q_n+=_externalStates[(k+1)]*normale[k];
392 double porosityj=_porosityField(j);
394 if(_verbose && _nbTimeStep%_freqSave ==0)
396 cout << "setBoundaryState for group "<< nameOfGroup << ", inner cell j= "<<j<< " face unit normal vector "<<endl;
397 for(k=0; k<_Ndim; k++){
398 cout<<normale[k]<<", ";
403 if (_limitField[nameOfGroup].bcType==Wall){
404 //Pour la convection, inversion du sens de la vitesse normale
405 for(k=0; k<_Ndim; k++)
406 _externalStates[(k+1)]-= 2*q_n*normale[k];
409 for(k=1; k<_nVar; k++)
410 _idm[k] = _idm[k-1] + 1;
412 VecAssemblyBegin(_Uext);
413 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
414 VecAssemblyEnd(_Uext);
416 //Pour la diffusion, paroi à vitesse et temperature imposees
418 for(k=1; k<_nVar; k++)
419 _idm[k] = _idm[k-1] + 1;
420 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
421 double pression=_externalStates[0];
422 double T=_limitField[nameOfGroup].T;
423 double rho=_fluides[0]->getDensity(pression,T);
425 _externalStates[0]=porosityj*rho;
426 _externalStates[1]=_externalStates[0]*_limitField[nameOfGroup].v_x[0];
427 v2 +=_limitField[nameOfGroup].v_x[0]*_limitField[nameOfGroup].v_x[0];
430 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
431 _externalStates[2]=_externalStates[0]*_limitField[nameOfGroup].v_y[0];
434 _externalStates[3]=_externalStates[0]*_limitField[nameOfGroup].v_z[0];
435 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
438 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2);
440 for(k=1; k<_nVar; k++)
441 _idm[k] = _idm[k-1] + 1;
442 VecAssemblyBegin(_Uextdiff);
443 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
444 VecAssemblyEnd(_Uextdiff);
446 else if (_limitField[nameOfGroup].bcType==Neumann){
448 for(k=1; k<_nVar; k++)
449 _idm[k] = _idm[k-1] + 1;
451 VecAssemblyBegin(_Uext);
452 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
453 VecAssemblyEnd(_Uext);
455 VecAssemblyBegin(_Uextdiff);
456 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
457 VecAssemblyEnd(_Uextdiff);
459 else if (_limitField[nameOfGroup].bcType==Inlet){
462 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
463 double pression=_externalStates[0];
464 double T=_limitField[nameOfGroup].T;
465 double rho=_fluides[0]->getDensity(pression,T);
467 _externalStates[0]=porosityj*rho;
468 _externalStates[1]=_externalStates[0]*(_limitField[nameOfGroup].v_x[0]);
469 v2 +=(_limitField[nameOfGroup].v_x[0])*(_limitField[nameOfGroup].v_x[0]);
472 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
473 _externalStates[2]=_externalStates[0]*_limitField[nameOfGroup].v_y[0];
476 _externalStates[3]=_externalStates[0]*_limitField[nameOfGroup].v_z[0];
477 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
480 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2);
482 else if(_nbTimeStep%_freqSave ==0)
483 cout<< "Warning : fluid going out through inlet boundary "<<nameOfGroup<<". Applying Neumann boundary condition"<<endl;
486 for(k=1; k<_nVar; k++)
487 _idm[k] = _idm[k-1] + 1;
488 VecAssemblyBegin(_Uext);
489 VecAssemblyBegin(_Uextdiff);
490 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
491 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
492 VecAssemblyEnd(_Uext);
493 VecAssemblyEnd(_Uextdiff);
495 else if (_limitField[nameOfGroup].bcType==InletPressure){
497 //Computation of the hydrostatic contribution : scalar product between gravity vector and position vector
498 Cell Cj=_mesh.getCell(j);
499 double hydroPress=Cj.x()*_GravityField3d[0];
501 hydroPress+=Cj.y()*_GravityField3d[1];
503 hydroPress+=Cj.z()*_GravityField3d[2];
505 hydroPress*=_externalStates[0]/porosityj;//multiplication by rho the total density
507 //Building the external state
508 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
510 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress,_limitField[nameOfGroup].T);
513 if(_nbTimeStep%_freqSave ==0)
514 cout<< "Warning : fluid going out through inletPressure boundary "<<nameOfGroup<<". Applying Neumann boundary condition for velocity and temperature"<<endl;
515 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress, _externalStates[_nVar-1]);
518 for(k=0; k<_Ndim; k++)
520 v2+=_externalStates[(k+1)]*_externalStates[(k+1)];
521 _externalStates[(k+1)]*=_externalStates[0] ;
523 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy( _externalStates[_nVar-1],_externalStates[0]) + v2/2);
527 for(k=1; k<_nVar; k++)
528 _idm[k] = _idm[k-1] + 1;
529 VecAssemblyBegin(_Uext);
530 VecAssemblyBegin(_Uextdiff);
531 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
532 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
533 VecAssemblyEnd(_Uext);
534 VecAssemblyEnd(_Uextdiff);
536 else if (_limitField[nameOfGroup].bcType==Outlet){
537 if(q_n<=0 && _nbTimeStep%_freqSave ==0)
538 cout<< "Warning : fluid going in through outlet boundary "<<nameOfGroup<<". Applying Neumann boundary condition for velocity and temperature"<<endl;
540 //Computation of the hydrostatic contribution : scalar product between gravity vector and position vector
541 Cell Cj=_mesh.getCell(j);
542 double hydroPress=Cj.x()*_GravityField3d[0];
544 hydroPress+=Cj.y()*_GravityField3d[1];
546 hydroPress+=Cj.z()*_GravityField3d[2];
548 hydroPress*=_externalStates[0]/porosityj;//multiplication by rho the total density
550 if(_verbose && _nbTimeStep%_freqSave ==0)
552 cout<<"Cond lim outlet densite= "<<_externalStates[0]<<" gravite= "<<_GravityField3d[0]<<" Cj.x()= "<<Cj.x()<<endl;
553 cout<<"Cond lim outlet pression ref= "<<_limitField[nameOfGroup].p<<" pression hydro= "<<hydroPress<<" total= "<<_limitField[nameOfGroup].p+hydroPress<<endl;
555 //Building the external state
556 _idm[0] = _nVar*j;// Kieu
557 for(k=1; k<_nVar; k++)
558 _idm[k] = _idm[k-1] + 1;
559 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
561 _externalStates[0]=porosityj*_fluides[0]->getDensity(_limitField[nameOfGroup].p+hydroPress, _externalStates[_nVar-1]);
562 for(k=0; k<_Ndim; k++)
564 v2+=_externalStates[(k+1)]*_externalStates[(k+1)];
565 _externalStates[(k+1)]*=_externalStates[0] ;
567 _externalStates[_nVar-1] = _externalStates[0]*(_fluides[0]->getInternalEnergy( _externalStates[_nVar-1],_externalStates[0]) + v2/2);
569 for(k=1; k<_nVar; k++)
570 _idm[k] = _idm[k-1] + 1;
571 VecAssemblyBegin(_Uext);
572 VecAssemblyBegin(_Uextdiff);
573 VecSetValues(_Uext, _nVar, _idm, _externalStates, INSERT_VALUES);
574 VecSetValues(_Uextdiff, _nVar, _idm, _externalStates, INSERT_VALUES);
575 VecAssemblyEnd(_Uext);
576 VecAssemblyEnd(_Uextdiff);
578 cout<<"Boundary condition not set for boundary named "<<nameOfGroup<<endl;
579 cout<<"Accepted boundary condition are Neumann, Wall, Inlet, and Outlet"<<endl;
580 *_runLogFile<<"Boundary condition not set for boundary named. Accepted boundary condition are Neumann, Wall, Inlet, and Outlet"<<endl;
581 _runLogFile->close();
582 throw CdmathException("Unknown boundary condition");
586 void SinglePhaseStaggered::convectionMatrices()
588 //entree: URoe = rho, u, H
589 //sortie: matrices Roe+ et Roe-
591 if(_verbose && _nbTimeStep%_freqSave ==0)
592 cout<<"SinglePhaseStaggered::convectionMatrices()"<<endl;
594 double u_n=0, u_2=0;//vitesse normale et carré du module
596 for(int i=0;i<_Ndim;i++)
598 u_2 += _Uroe[1+i]*_Uroe[1+i];
599 u_n += _Uroe[1+i]*_vec_normal[i];
602 vector<complex<double> > vp_dist(3,0);
604 if(_spaceScheme==staggered && _nonLinearFormulation==VFFC)//special case
606 staggeredVFFCMatricesConservativeVariables(u_n);//Computation of classical upwinding matrices
607 if(_timeScheme==Implicit && _usePrimitiveVarsInNewton)//For use in implicit matrix
608 staggeredVFFCMatricesPrimitiveVariables(u_n);
612 Vector vitesse(_Ndim);
613 for(int idim=0;idim<_Ndim;idim++)
614 vitesse[idim]=_Uroe[1+idim];
617 /***********Calcul des valeurs propres ********/
619 c = _fluides[0]->vitesseSonEnthalpie(H-u_2/2);//vitesse du son a l'interface
620 k = _fluides[0]->constante("gamma") - 1;//A generaliser pour porosite et stephane gas law
621 K = u_2*k/2; //g-1/2 *|u|²
623 vp_dist[0]=u_n-c;vp_dist[1]=u_n;vp_dist[2]=u_n+c;
625 _maxvploc=fabs(u_n)+c;
629 if(_verbose && _nbTimeStep%_freqSave ==0)
630 cout<<"SinglePhaseStaggered::convectionMatrices Eigenvalues "<<u_n-c<<" , "<<u_n<<" , "<<u_n+c<<endl;
632 RoeMatrixConservativeVariables( u_n, H,vitesse,k,K);
634 /******** Construction des matrices de decentrement ********/
635 if( _spaceScheme ==centered){
636 if(_entropicCorrection)
638 *_runLogFile<<"SinglePhaseStaggered::convectionMatrices: entropy scheme not available for centered scheme"<<endl;
639 _runLogFile->close();
640 throw CdmathException("SinglePhaseStaggered::convectionMatrices: entropy scheme not available for centered scheme");
643 for(int i=0; i<_nVar*_nVar;i++)
646 else if(_spaceScheme == upwind || _spaceScheme ==pressureCorrection || _spaceScheme ==lowMach){
647 if(_entropicCorrection)
648 entropicShift(_vec_normal);
650 _entropicShift=vector<double>(3,0);//at most 3 distinct eigenvalues
652 vector< complex< double > > y (3,0);
654 for( int i=0 ; i<3 ; i++)
655 y[i] = Poly.abs_generalise(vp_dist[i])+_entropicShift[i];
656 Poly.abs_par_interp_directe(3,vp_dist, _Aroe, _nVar,_precision, _absAroe,y);
658 if( _spaceScheme ==pressureCorrection)
659 for( int i=0 ; i<_Ndim ; i++)
660 for( int j=0 ; j<_Ndim ; j++)
661 _absAroe[(1+i)*_nVar+1+j]-=(vp_dist[2].real()-vp_dist[0].real())/2*_vec_normal[i]*_vec_normal[j];
662 else if( _spaceScheme ==lowMach){
663 double M=sqrt(u_2)/c;
664 for( int i=0 ; i<_Ndim ; i++)
665 for( int j=0 ; j<_Ndim ; j++)
666 _absAroe[(1+i)*_nVar+1+j]-=(1-M)*(vp_dist[2].real()-vp_dist[0].real())/2*_vec_normal[i]*_vec_normal[j];
669 else if( _spaceScheme ==staggered ){
670 if(_entropicCorrection)//To do: study entropic correction for staggered
672 *_runLogFile<<"SinglePhaseStaggered::convectionMatrices: entropy scheme not available for staggered scheme"<<endl;
673 _runLogFile->close();
674 throw CdmathException("SinglePhaseStaggered::convectionMatrices: entropy scheme not available for staggered scheme");
677 staggeredRoeUpwindingMatrixConservativeVariables( u_n, H, vitesse, k, K);
681 *_runLogFile<<"SinglePhaseStaggered::convectionMatrices: scheme not treated"<<endl;
682 _runLogFile->close();
683 throw CdmathException("SinglePhaseStaggered::convectionMatrices: scheme not treated");
686 for(int i=0; i<_nVar*_nVar;i++)
688 _AroeMinus[i] = (_Aroe[i]-_absAroe[i])/2;
689 _AroePlus[i] = (_Aroe[i]+_absAroe[i])/2;
691 if(_timeScheme==Implicit)
693 if(_usePrimitiveVarsInNewton)//Implicitation using primitive variables
695 _Vij[0]=_fluides[0]->getPressureFromEnthalpy(_Uroe[_nVar-1]-u_2/2, _Uroe[0]);//pressure
696 _Vij[_nVar-1]=_fluides[0]->getTemperatureFromPressure( _Vij[0], _Uroe[0]);//Temperature
697 for(int idim=0;idim<_Ndim; idim++)
698 _Vij[1+idim]=_Uroe[1+idim];
699 primToConsJacobianMatrix(_Vij);
701 Poly.matrixProduct(_AroeMinus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroeMinusImplicit);
702 Poly.matrixProduct(_AroePlus, _nVar, _nVar, _primToConsJacoMat, _nVar, _nVar, _AroePlusImplicit);
705 for(int i=0; i<_nVar*_nVar;i++)
707 _AroeMinusImplicit[i] = _AroeMinus[i];
708 _AroePlusImplicit[i] = _AroePlus[i];
711 if(_verbose && _nbTimeStep%_freqSave ==0)
713 displayMatrix(_Aroe, _nVar,"Matrice de Roe");
714 displayMatrix(_absAroe, _nVar,"Valeur absolue matrice de Roe");
715 displayMatrix(_AroeMinus, _nVar,"Matrice _AroeMinus");
716 displayMatrix(_AroePlus, _nVar,"Matrice _AroePlus");
720 if(_verbose && _nbTimeStep%_freqSave ==0 && _timeScheme==Implicit)
722 displayMatrix(_AroeMinusImplicit, _nVar,"Matrice _AroeMinusImplicit");
723 displayMatrix(_AroePlusImplicit, _nVar,"Matrice _AroePlusImplicit");
726 /*********Calcul de la matrice signe pour VFFC, VFRoe et décentrement des termes source*****/
727 if(_entropicCorrection)
729 InvMatriceRoe( vp_dist);
731 Poly.matrixProduct(_absAroe, _nVar, _nVar, _invAroe, _nVar, _nVar, _signAroe);
733 else if (_spaceScheme==upwind || (_spaceScheme ==pressureCorrection ) || (_spaceScheme ==lowMach ))//upwind sans entropic
734 SigneMatriceRoe( vp_dist);
735 else if (_spaceScheme==centered)//centre sans entropic
736 for(int i=0; i<_nVar*_nVar;i++)
738 else if( _spaceScheme ==staggered )//à tester
747 for(int i=0; i<_nVar*_nVar;i++)
749 _signAroe[0] = signu;
750 for(int i=1; i<_nVar-1;i++)
751 _signAroe[i*_nVar+i] = -signu;
752 _signAroe[_nVar*(_nVar-1)+_nVar-1] = signu;
756 *_runLogFile<<"SinglePhaseStaggered::convectionMatrices: well balanced option not treated"<<endl;
757 _runLogFile->close();
758 throw CdmathException("SinglePhaseStaggered::convectionMatrices: well balanced option not treated");
761 void SinglePhaseStaggered::computeScaling(double maxvp)
765 for(int q=1; q<_nVar-1; q++)
767 _blockDiag[q]=1./maxvp;//
768 _invBlockDiag[q]= maxvp;//1.;//
770 _blockDiag[_nVar - 1]=(_fluides[0]->constante("gamma")-1)/(maxvp*maxvp);//1
771 _invBlockDiag[_nVar - 1]= 1./_blockDiag[_nVar - 1] ;// 1.;//
775 void SinglePhaseStaggered::sourceVector(PetscScalar * Si, PetscScalar * Ui, PetscScalar * Vi, int i)
777 double phirho=Ui[0], T=Vi[_nVar-1];
779 for(int k=0; k<_Ndim; k++)
780 norm_u+=Vi[1+k]*Vi[1+k];
783 Si[0]=_heatPowerField(i)/_latentHeat;
786 for(int k=1; k<_nVar-1; k++)
787 Si[k] =(_gravite[k]-_dragCoeffs[0]*norm_u*Vi[1+k])*phirho;
789 Si[_nVar-1]=_heatPowerField(i);
791 for(int k=0; k<_Ndim; k++)
792 Si[_nVar-1] +=(_GravityField3d[k]-_dragCoeffs[0]*norm_u*Vi[1+k])*Vi[1+k]*phirho;
794 if(_timeScheme==Implicit)
796 for(int k=0; k<_nVar*_nVar;k++)
797 _GravityImplicitationMatrix[k] = 0;
798 if(!_usePrimitiveVarsInNewton)
799 for(int k=0; k<_nVar;k++)
800 _GravityImplicitationMatrix[k*_nVar]=-_gravite[k];
803 double pression=Vi[0];
804 getDensityDerivatives( pression, T, norm_u*norm_u);
805 for(int k=0; k<_nVar;k++)
807 _GravityImplicitationMatrix[k*_nVar+0] =-_gravite[k]*_drho_sur_dp;
808 _GravityImplicitationMatrix[k*_nVar+_nVar-1]=-_gravite[k]*_drho_sur_dT;
812 if(_verbose && _nbTimeStep%_freqSave ==0)
814 cout<<"SinglePhaseStaggered::sourceVector"<<endl;
816 for(int k=0;k<_nVar;k++)
820 for(int k=0;k<_nVar;k++)
824 for(int k=0;k<_nVar;k++)
827 if(_timeScheme==Implicit)
828 displayMatrix(_GravityImplicitationMatrix, _nVar, "Gravity implicitation matrix");
832 void SinglePhaseStaggered::pressureLossVector(PetscScalar * pressureLoss, double K, PetscScalar * Ui, PetscScalar * Vi, PetscScalar * Uj, PetscScalar * Vj)
834 double norm_u=0, u_n=0, rho;
835 for(int i=0;i<_Ndim;i++)
836 u_n += _Uroe[1+i]*_vec_normal[i];
840 for(int i=0;i<_Ndim;i++)
841 norm_u += Vi[1+i]*Vi[1+i];
844 for(int i=0;i<_Ndim;i++)
845 pressureLoss[1+i]=-1/2*K*rho*norm_u*Vi[1+i];
848 for(int i=0;i<_Ndim;i++)
849 norm_u += Vj[1+i]*Vj[1+i];
852 for(int i=0;i<_Ndim;i++)
853 pressureLoss[1+i]=-1/2*K*rho*norm_u*Vj[1+i];
855 pressureLoss[_nVar-1]=-1/2*K*rho*norm_u*norm_u*norm_u;
857 if(_verbose && _nbTimeStep%_freqSave ==0)
859 cout<<"SinglePhaseStaggered::pressureLossVector K= "<<K<<endl;
861 for(int k=0;k<_nVar;k++)
865 for(int k=0;k<_nVar;k++)
869 for(int k=0;k<_nVar;k++)
873 for(int k=0;k<_nVar;k++)
876 cout<<"pressureLoss="<<endl;
877 for(int k=0;k<_nVar;k++)
878 cout<<pressureLoss[k]<<", ";
883 void SinglePhaseStaggered::porosityGradientSourceVector()
885 double u_ni=0, u_nj=0, rhoi,rhoj, pi=_Vi[0], pj=_Vj[0],pij;
886 for(int i=0;i<_Ndim;i++) {
887 u_ni += _Vi[1+i]*_vec_normal[i];
888 u_nj += _Vj[1+i]*_vec_normal[i];
890 _porosityGradientSourceVector[0]=0;
891 rhoj=_Uj[0]/_porosityj;
892 rhoi=_Ui[0]/_porosityi;
893 pij=(pi+pj)/2+rhoi*rhoj/2/(rhoi+rhoj)*(u_ni-u_nj)*(u_ni-u_nj);
894 for(int i=0;i<_Ndim;i++)
895 _porosityGradientSourceVector[1+i]=pij*(_porosityi-_porosityj)*2/(1/_inv_dxi+1/_inv_dxj);
896 _porosityGradientSourceVector[_nVar-1]=0;
899 void SinglePhaseStaggered::jacobian(const int &j, string nameOfGroup,double * normale)
901 if(_verbose && _nbTimeStep%_freqSave ==0)
902 cout<<"Jacobienne condition limite convection bord "<< nameOfGroup<<endl;
905 for(k=0; k<_nVar*_nVar;k++)
906 _Jcb[k] = 0;//No implicitation at this stage
909 for(k=1; k<_nVar; k++)
910 _idm[k] = _idm[k-1] + 1;
911 VecGetValues(_conservativeVars, _nVar, _idm, _externalStates);
912 double q_n=0;//quantité de mouvement normale à la paroi
913 for(k=0; k<_Ndim; k++)
914 q_n+=_externalStates[(k+1)]*normale[k];
916 // loop of boundary types
917 if (_limitField[nameOfGroup].bcType==Wall)
919 for(k=0; k<_nVar;k++)
920 _Jcb[k*_nVar + k] = 1;
921 for(k=1; k<_nVar-1;k++)
922 for(int l=1; l<_nVar-1;l++)
923 _Jcb[k*_nVar + l] -= 2*normale[k-1]*normale[l-1];
925 else if (_limitField[nameOfGroup].bcType==Inlet)
929 double v[_Ndim], ve[_Ndim], v2, ve2;
932 for(k=1; k<_nVar; k++)
933 _idm[k] = _idm[k-1] + 1;
934 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
935 VecGetValues(_conservativeVars, _nVar, _idm, _Uj);
937 ve[0] = _limitField[nameOfGroup].v_x[0];
942 ve[1] = _limitField[nameOfGroup].v_y[0];
948 ve[2] = _limitField[nameOfGroup].v_z[0];
953 double internal_energy=_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,_Uj[0]);
954 double total_energy=internal_energy+ve2/2;
957 _Jcb[0]=v2/(2*internal_energy);
958 for(k=0; k<_Ndim;k++)
959 _Jcb[1+k]=-v[k]/internal_energy;
960 _Jcb[_nVar-1]=1/internal_energy;
962 for(int l =1;l<1+_Ndim;l++){
963 _Jcb[l*_nVar]=v2*ve[l-1]/(2*internal_energy);
964 for(k=0; k<_Ndim;k++)
965 _Jcb[l*_nVar+1+k]=-v[k]*ve[l-1]/internal_energy;
966 _Jcb[l*_nVar+_nVar-1]=ve[l-1]/internal_energy;
969 _Jcb[(_nVar-1)*_nVar]=v2*total_energy/(2*internal_energy);
970 for(k=0; k<_Ndim;k++)
971 _Jcb[(_nVar-1)*_nVar+1+k]=-v[k]*total_energy/internal_energy;
972 _Jcb[(_nVar-1)*_nVar+_nVar-1]=total_energy/internal_energy;
980 _Jcb[_nVar]=_limitField[nameOfGroup].v_x[0];//Kieu
981 v2 +=(_limitField[nameOfGroup].v_x[0])*(_limitField[nameOfGroup].v_x[0]);
984 _Jcb[2*_nVar]= _limitField[nameOfGroup].v_y[0];
985 v2 +=_limitField[nameOfGroup].v_y[0]*_limitField[nameOfGroup].v_y[0];
987 _Jcb[3*_nVar]=_limitField[nameOfGroup].v_z[0];
988 v2 +=_limitField[nameOfGroup].v_z[0]*_limitField[nameOfGroup].v_z[0];
991 _Jcb[(_nVar-1)*_nVar]=_fluides[0]->getInternalEnergy(_limitField[nameOfGroup].T,rho) + v2/2;
994 else if (_limitField[nameOfGroup].bcType==InletPressure && q_n<0){
996 double v[_Ndim], v2=0;
998 for(k=1; k<_nVar; k++)
999 _idm[k] = _idm[k-1] + 1;
1000 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1002 for(k=0; k<_Ndim;k++){
1007 double rho_ext=_fluides[0]->getDensity(_limitField[nameOfGroup].p, _limitField[nameOfGroup].T);
1008 double rho_int = _externalStates[0];
1009 double density_ratio=rho_ext/rho_int;
1011 for(int l =1;l<1+_Ndim;l++){
1012 _Jcb[l*_nVar]=-density_ratio*v[l-1];
1013 _Jcb[l*_nVar+l]=density_ratio;
1016 _Jcb[(_nVar-1)*_nVar]=-v2*density_ratio;
1017 for(k=0; k<_Ndim;k++)
1018 _Jcb[(_nVar-1)*_nVar+1+k]=density_ratio*v[k];
1020 // not wall, not inlet, not inletPressure
1021 else if(_limitField[nameOfGroup].bcType==Outlet || (_limitField[nameOfGroup].bcType==InletPressure && q_n>=0))
1024 double v[_Ndim], v2=0;
1026 for(k=1; k<_nVar; k++)
1027 _idm[k] = _idm[k-1] + 1;
1028 VecGetValues(_primitiveVars, _nVar, _idm, _Vj);
1030 for(k=0; k<_Ndim;k++){
1035 double rho_ext=_fluides[0]->getDensity(_limitField[nameOfGroup].p, _externalStates[_nVar-1]);
1036 double rho_int = _externalStates[0];
1037 double density_ratio=rho_ext/rho_int;
1038 double internal_energy=_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho_int);
1039 double total_energy=internal_energy+v2/2;
1042 _Jcb[0]=density_ratio*(1-v2/(2*internal_energy));
1043 for(k=0; k<_Ndim;k++)
1044 _Jcb[1+k]=density_ratio*v[k]/internal_energy;
1045 _Jcb[_nVar-1]=-density_ratio/internal_energy;
1047 for(int l =1;l<1+_Ndim;l++){
1048 _Jcb[l*_nVar]=density_ratio*v2*v[l-1]/(2*internal_energy);
1049 for(k=0; k<_Ndim;k++)
1050 _Jcb[l*_nVar+1+k]=density_ratio*v[k]*v[l-1]/internal_energy;
1051 _Jcb[l*_nVar+1+k]-=density_ratio;
1052 _Jcb[l*_nVar+_nVar-1]=-density_ratio*v[l-1]/internal_energy;
1055 _Jcb[(_nVar-1)*_nVar]=density_ratio*v2*total_energy/(2*internal_energy);
1056 for(k=0; k<_Ndim;k++)
1057 _Jcb[(_nVar-1)*_nVar+1+k]=density_ratio*v[k]*total_energy/internal_energy;
1058 _Jcb[(_nVar-1)*_nVar+_nVar-1]=density_ratio*(1-total_energy/internal_energy);
1062 double cd = 1,cn=0,p0, gamma;
1063 _idm[0] = j*_nVar;// Kieu
1064 for(k=1; k<_nVar;k++)
1065 _idm[k] = _idm[k-1] + 1;
1066 VecGetValues(_conservativeVars, _nVar, _idm, _phi);
1067 VecGetValues(_primitiveVars, _nVar, _idm, _externalStates);
1069 // compute the common numerator and common denominator
1070 p0=_fluides[0]->constante("p0");
1071 gamma =_fluides[0]->constante("gamma");
1072 cn =_limitField[nameOfGroup].p +p0;
1073 cd = _phi[0]*_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho)-p0;
1077 for(k=1; k<_nVar-1;k++)
1078 v2+=_externalStates[k]*_externalStates[k];
1080 _JcbDiff[0] = cn*(_phi[_nVar-1] -v2 -p0)/cd;
1081 for(k=1; k<_nVar-1;k++)
1082 _JcbDiff[k]=cn*_phi[k]/cd;
1083 _JcbDiff[_nVar-1]= -cn*_phi[0]/cd;
1085 for(idim=0; idim<_Ndim;idim++)
1088 _JcbDiff[(1+idim)*_nVar]=-(v2*cn*_phi[idim+1])/(2*cd);
1089 //colonnes intermediaire
1090 for(jdim=0; jdim<_Ndim;jdim++)
1092 _JcbDiff[(1+idim)*_nVar + jdim + 1] =_externalStates[idim+1]*_phi[jdim+1];
1093 _JcbDiff[(1+idim)*_nVar + jdim + 1]*=cn/cd;
1095 //matrice identite*cn*(rhoe- p0)
1096 _JcbDiff[(1+idim)*_nVar + idim + 1] +=( cn*(_phi[0]*_fluides[0]->getInternalEnergy(_externalStates[_nVar-1],rho)-p0))/cd;
1099 _JcbDiff[(1+idim)*_nVar + _nVar-1]=-_phi[idim+1]*cn/cd;
1102 _JcbDiff[_nVar*(_nVar-1)] = -(v2*_phi[_nVar -1]*cn)/(2*cd);
1103 for(int idim=0; idim<_Ndim;idim++)
1104 _JcbDiff[_nVar*(_nVar-1)+idim+1]=_externalStates[idim+1]*_phi[_nVar -1]*cn/cd;
1105 _JcbDiff[_nVar*_nVar -1] = -(v2/2+p0)*cn/cd;
1108 else if (_limitField[nameOfGroup].bcType!=Neumann)// not wall, not inlet, not outlet
1110 cout << "group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1111 *_runLogFile<<"group named "<<nameOfGroup << " : unknown boundary condition" << endl;
1112 _runLogFile->close();
1113 throw CdmathException("SinglePhaseStaggered::jacobian: This boundary condition is not treated");
1118 Vector SinglePhaseStaggered::convectionFlux(Vector U,Vector V, Vector normale, double porosity){
1119 if(_verbose && _nbTimeStep%_freqSave ==0)
1121 cout<<"SinglePhaseStaggered::convectionFlux start"<<endl;
1122 cout<<"Ucons"<<endl;
1124 cout<<"Vprim"<<endl;
1128 double phirho=U(0);//phi rho
1129 Vector phiq(_Ndim);//phi rho u
1130 for(int i=0;i<_Ndim;i++)
1133 double pression=V(0);
1134 Vector vitesse(_Ndim);
1135 for(int i=0;i<_Ndim;i++)
1137 double Temperature= V(1+_Ndim);
1139 double vitessen=vitesse*normale;
1140 double rho=phirho/porosity;
1141 double e_int=_fluides[0]->getInternalEnergy(Temperature,rho);
1144 F(0)=phirho*vitessen;
1145 for(int i=0;i<_Ndim;i++)
1146 F(1+i)=phirho*vitessen*vitesse(i)+pression*normale(i)*porosity;
1147 F(1+_Ndim)=phirho*(e_int+0.5*vitesse*vitesse+pression/rho)*vitessen;
1149 if(_verbose && _nbTimeStep%_freqSave ==0)
1151 cout<<"SinglePhaseStaggered::convectionFlux end"<<endl;
1152 cout<<"Flux F(U,V)"<<endl;
1159 void SinglePhaseStaggered::convectionMatrixPrimitiveVariables( double rho, double u_n, double H,Vector vitesse)
1161 //Not used. Suppress or use in alternative implicitation in primitive variable of the staggered-roe scheme
1162 //On remplit la matrice de Roe en variables primitives : F(V_L)-F(V_R)=Aroe (V_L-V_R)
1163 //EOS is more involved with primitive variables
1164 // call to getDensityDerivatives(double concentration, double pression, double temperature,double v2) needed
1165 _AroeImplicit[0*_nVar+0]=_drho_sur_dp*u_n;
1166 for(int i=0;i<_Ndim;i++)
1167 _AroeImplicit[0*_nVar+1+i]=rho*_vec_normal[i];
1168 _AroeImplicit[0*_nVar+1+_Ndim]=_drho_sur_dT*u_n;
1169 for(int i=0;i<_Ndim;i++)
1171 _AroeImplicit[(1+i)*_nVar+0]=_drho_sur_dp *u_n*vitesse[i]+_vec_normal[i];
1172 for(int j=0;j<_Ndim;j++)
1173 _AroeImplicit[(1+i)*_nVar+1+j]=rho*vitesse[i]*_vec_normal[j];
1174 _AroeImplicit[(1+i)*_nVar+1+i]+=rho*u_n;
1175 _AroeImplicit[(1+i)*_nVar+1+_Ndim]=_drho_sur_dT*u_n*vitesse[i];
1177 _AroeImplicit[(1+_Ndim)*_nVar+0]=(_drhoE_sur_dp+1)*u_n;
1178 for(int i=0;i<_Ndim;i++)
1179 _AroeImplicit[(1+_Ndim)*_nVar+1+i]=rho*(H*_vec_normal[i]+u_n*vitesse[i]);
1180 _AroeImplicit[(1+_Ndim)*_nVar+1+_Ndim]=_drhoE_sur_dT*u_n;
1183 void SinglePhaseStaggered::getDensityDerivatives( double pressure, double temperature, double v2)
1185 double rho=_fluides[0]->getDensity(pressure,temperature);
1186 double gamma=_fluides[0]->constante("gamma");
1187 double q=_fluides[0]->constante("q");
1189 if( !_useDellacherieEOS)
1191 StiffenedGas* fluide0=dynamic_cast<StiffenedGas*>(_fluides[0]);
1192 double e = fluide0->getInternalEnergy(temperature);
1193 double cv=fluide0->constante("cv");
1196 _drho_sur_dp=1/((gamma-1)*(e-q));
1197 _drho_sur_dT=-rho*cv/(e-q);
1198 _drhoE_sur_dp=E/((gamma-1)*(e-q));
1199 _drhoE_sur_dT=rho*cv*(1-E/(e-q));
1201 else if(_useDellacherieEOS )
1203 StiffenedGasDellacherie* fluide0=dynamic_cast<StiffenedGasDellacherie*>(_fluides[0]);
1204 double h=fluide0->getEnthalpy(temperature);
1206 double cp=fluide0->constante("cp");
1208 _drho_sur_dp=gamma/((gamma-1)*(h-q));
1209 _drho_sur_dT=-rho*cp/(h-q);
1210 _drhoE_sur_dp=gamma*H/((gamma-1)*(h-q))-1;
1211 _drhoE_sur_dT=rho*cp*(1-H/(h-q));
1215 *_runLogFile<< "SinglePhaseStaggered::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie" << endl;
1216 _runLogFile->close();
1217 throw CdmathException("SinglePhaseStaggered::staggeredVFFCMatricesPrimitiveVariables: eos should be StiffenedGas or StiffenedGasDellacherie");
1220 if(_verbose && _nbTimeStep%_freqSave ==0)
1222 cout<<"_drho_sur_dp= "<<_drho_sur_dp<<", _drho_sur_dT= "<<_drho_sur_dT<<endl;
1223 cout<<"_drhoE_sur_dp= "<<_drhoE_sur_dp<<", _drhoE_sur_dT= "<<_drhoE_sur_dT<<endl;
1226 void SinglePhaseStaggered::save(){
1227 string prim(_path+"/SinglePhaseStaggeredPrim_");///Results
1228 string cons(_path+"/SinglePhaseStaggeredCons_");
1233 for (long i = 0; i < _Nmailles; i++){
1234 // j = 0 : pressure; j = _nVar - 1: temperature; j = 1,..,_nVar-2: velocity
1235 for (int j = 0; j < _nVar; j++){
1237 VecGetValues(_primitiveVars,1,&Ii,&_VV(i,j));
1240 if(_saveConservativeField){
1241 for (long i = 0; i < _Nmailles; i++){
1242 // j = 0 : density; j = _nVar - 1 : energy j = 1,..,_nVar-2: momentum
1243 for (int j = 0; j < _nVar; j++){
1245 VecGetValues(_conservativeVars,1,&Ii,&_UU(i,j));
1248 _UU.setTime(_time,_nbTimeStep);
1250 _VV.setTime(_time,_nbTimeStep);
1252 // create mesh and component info
1253 if (_nbTimeStep ==0){
1254 string prim_suppress ="rm -rf "+prim+"_*";
1255 string cons_suppress ="rm -rf "+cons+"_*";
1257 system(prim_suppress.c_str());//Nettoyage des précédents calculs identiques
1258 system(cons_suppress.c_str());//Nettoyage des précédents calculs identiques
1260 if(_saveConservativeField){
1261 _UU.setInfoOnComponent(0,"Density_(kg/m^3)");
1262 _UU.setInfoOnComponent(1,"Momentum_x");// (kg/m^2/s)
1264 _UU.setInfoOnComponent(2,"Momentum_y");// (kg/m^2/s)
1266 _UU.setInfoOnComponent(3,"Momentum_z");// (kg/m^2/s)
1268 _UU.setInfoOnComponent(_nVar-1,"Energy_(J/m^3)");
1283 _VV.setInfoOnComponent(0,"Pressure_(Pa)");
1284 _VV.setInfoOnComponent(1,"Velocity_x_(m/s)");
1286 _VV.setInfoOnComponent(2,"Velocity_y_(m/s)");
1288 _VV.setInfoOnComponent(3,"Velocity_z_(m/s)");
1289 _VV.setInfoOnComponent(_nVar-1,"Temperature_(K)");
1304 // do not create mesh
1309 _VV.writeVTK(prim,false);
1312 _VV.writeMED(prim,false);
1318 if(_saveConservativeField){
1322 _UU.writeVTK(cons,false);
1325 _UU.writeMED(cons,false);
1334 for (long i = 0; i < _Nmailles; i++){
1335 // j = 0 : pressure; j = _nVar - 1: temperature; j = 1,..,_nVar-2: velocity
1336 for (int j = 0; j < _Ndim; j++)//On récupère les composantes de vitesse
1338 int Ii = i*_nVar +1+j;
1339 VecGetValues(_primitiveVars,1,&Ii,&_Vitesse(i,j));
1341 for (int j = _Ndim; j < 3; j++)//On met à zero les composantes de vitesse si la dimension est <3
1344 _Vitesse.setTime(_time,_nbTimeStep);
1345 if (_nbTimeStep ==0){
1346 _Vitesse.setInfoOnComponent(0,"Velocity_x_(m/s)");
1347 _Vitesse.setInfoOnComponent(1,"Velocity_y_(m/s)");
1348 _Vitesse.setInfoOnComponent(2,"Velocity_z_(m/s)");
1353 _Vitesse.writeVTK(prim+"_Velocity");
1356 _Vitesse.writeMED(prim+"_Velocity");
1359 _Vitesse.writeCSV(prim+"_Velocity");
1367 _Vitesse.writeVTK(prim+"_Velocity",false);
1370 _Vitesse.writeMED(prim+"_Velocity",false);
1373 _Vitesse.writeCSV(prim+"_Velocity");
1396 if(_saveConservativeField){
1415 _Vitesse.writeVTK(prim+"_Velocity");
1418 _Vitesse.writeMED(prim+"_Velocity");
1421 _Vitesse.writeCSV(prim+"_Velocity");