1 #include "ProblemFluid.hxx"
7 ProblemFluid::ProblemFluid(void){
12 _porosityFieldSet=false;
13 _pressureLossFieldSet=false;
14 _sectionFieldSet=false;
15 _GravityField3d=vector<double>(3,0);
16 _gravityReferencePoint=vector<double>(3,0);
17 _Uroe=NULL;_Udiff=NULL;_temp=NULL;_l=NULL;_vec_normal=NULL;;
20 _saveConservativeField=false;
21 _usePrimitiveVarsInNewton=false;
22 _saveInterfacialField=false;
23 _err_press_max=0; _part_imag_max=0; _nbMaillesNeg=0; _nbVpCplx=0;_minm1=1e30;_minm2=1e30;//Pour affichage paramètres diphasiques dans IterateTimeStep
25 _entropicCorrection=false;
26 _pressureCorrectionOrder=2;
27 _nonLinearFormulation=Roe;
32 SpaceScheme ProblemFluid::getSpaceScheme() const
36 void ProblemFluid::setNumericalScheme(SpaceScheme spaceScheme, TimeScheme timeScheme)
38 if( _nbTimeStep>0 && timeScheme!=_timeScheme)//This is a change of time scheme during a simulation
39 _restartWithNewTimeScheme=true;
40 _timeScheme = timeScheme;
41 _spaceScheme = spaceScheme;
44 void ProblemFluid::initialize()
47 *_runLogFile<<"ProblemFluid::initialize() set initial data first"<<endl;
49 throw CdmathException("ProblemFluid::initialize() set initial data first");
51 cout << "Number of Phases = " << _nbPhases << " mesh dimension = "<<_Ndim<<" number of variables = "<<_nVar<<endl;
52 *_runLogFile << "Number of Phases = " << _nbPhases << " spaceDim= "<<_Ndim<<" number of variables= "<<_nVar<<endl;
54 /********* local arrays ****************/
55 _AroePlus = new PetscScalar[_nVar*_nVar];
56 _Diffusion = new PetscScalar[_nVar*_nVar];
57 _AroeMinus = new PetscScalar[_nVar*_nVar];
58 _Aroe = new PetscScalar[_nVar*_nVar];
59 _absAroe = new PetscScalar[_nVar*_nVar];
60 _signAroe = new PetscScalar[_nVar*_nVar];
61 _invAroe = new PetscScalar[_nVar*_nVar];
62 _AroeImplicit = new PetscScalar[_nVar*_nVar];
63 _AroeMinusImplicit = new PetscScalar[_nVar*_nVar];
64 _AroePlusImplicit = new PetscScalar[_nVar*_nVar];
65 _absAroeImplicit = new PetscScalar[_nVar*_nVar];
66 _primToConsJacoMat = new PetscScalar[_nVar*_nVar];
67 _phi = new PetscScalar[_nVar];
68 _Jcb = new PetscScalar[_nVar*_nVar];
69 _JcbDiff = new PetscScalar[_nVar*_nVar];
70 _a = new PetscScalar[_nVar*_nVar];
71 _externalStates = new PetscScalar[_nVar];
72 _Ui = new PetscScalar[_nVar];
73 _Uj = new PetscScalar[_nVar];
74 _Vi = new PetscScalar[_nVar];
75 _Vj = new PetscScalar[_nVar];
76 _Uij = new PetscScalar[_nVar];//used for VFRoe scheme
77 _Vij = new PetscScalar[_nVar];//used for VFRoe scheme
78 _Si = new PetscScalar[_nVar];
79 _Sj = new PetscScalar[_nVar];
80 _pressureLossVector= new PetscScalar[_nVar];
81 _porosityGradientSourceVector= new PetscScalar[_nVar];
83 _l = new double[_nVar];
84 _r = new double[_nVar];
85 _Udiff = new double[_nVar];
86 _temp = new double[_nVar*_nVar];
88 _idm = new int[_nVar];
89 _idn = new int[_nVar];
90 _vec_normal = new double[_Ndim];
92 for(int k=0;k<_nVar*_nVar;k++)
97 for(int k=0; k<_nVar; k++){
102 /**************** Field creation *********************/
103 if(!_heatPowerFieldSet){
104 _heatPowerField=Field("Heat Power",CELLS,_mesh,1);
105 for(int i =0; i<_Nmailles; i++)
106 _heatPowerField(i) = _heatSource;
109 _dp_over_dt=Field("dP/dt",CELLS,_mesh,1);
110 if(!_porosityFieldSet){
111 _porosityField=Field("Porosity field",CELLS,_mesh,1);
112 for(int i =0; i<_Nmailles; i++)
113 _porosityField(i) = 1;
114 _porosityFieldSet=true;
117 //conservative field used only for saving results
118 _UU=Field ("Conservative vec", CELLS, _mesh, _nVar);
119 if(_saveInterfacialField && _nonLinearFormulation==VFRoe)
121 _UUstar=Field ("Interfacial U", CELLS, _mesh, _nVar);
122 _VVstar=Field ("Interfacial V", CELLS, _mesh, _nVar);
125 //Construction des champs primitifs et conservatifs initiaux comme avant dans ParaFlow
126 double * initialFieldPrim = new double[_nVar*_Nmailles];
127 for(int i =0; i<_Nmailles;i++)
128 for(int j =0; j<_nVar;j++)
129 initialFieldPrim[i*_nVar+j]=_VV(i,j);
130 double *initialFieldCons = new double[_nVar*_Nmailles];
131 for(int i=0; i<_Nmailles; i++)
132 primToCons(initialFieldPrim, i, initialFieldCons, i);
133 for(int i =0; i<_Nmailles;i++)
134 for(int j =0; j<_nVar;j++)
135 _UU(i,j)=initialFieldCons[i*_nVar+j];
137 /**********Petsc structures: ****************/
139 //creation de la matrice
140 if(_timeScheme == Implicit)
141 MatCreateSeqBAIJ(PETSC_COMM_SELF, _nVar, _nVar*_Nmailles, _nVar*_Nmailles, (1+_neibMaxNb), PETSC_NULL, &_A);
143 //creation des vecteurs
144 VecCreateSeq(PETSC_COMM_SELF, _nVar, &_Uext);
145 VecCreateSeq(PETSC_COMM_SELF, _nVar, &_Vext);
146 VecCreateSeq(PETSC_COMM_SELF, _nVar, &_Uextdiff);
147 // VecCreateSeq(PETSC_COMM_SELF, _nVar*_Nmailles, &_conservativeVars);
148 VecCreate(PETSC_COMM_SELF, &_conservativeVars);
149 VecSetSizes(_conservativeVars,PETSC_DECIDE,_nVar*_Nmailles);
150 VecSetBlockSize(_conservativeVars,_nVar);
151 VecSetFromOptions(_conservativeVars);
152 VecDuplicate(_conservativeVars, &_old);
153 VecDuplicate(_conservativeVars, &_newtonVariation);
154 VecDuplicate(_conservativeVars, &_b);
155 VecDuplicate(_conservativeVars, &_primitiveVars);
159 VecDuplicate(_conservativeVars, &_vecScaling);
160 VecDuplicate(_conservativeVars, &_invVecScaling);
161 VecDuplicate(_conservativeVars, &_bScaling);
163 _blockDiag = new PetscScalar[_nVar];
164 _invBlockDiag = new PetscScalar[_nVar];
168 int *indices = new int[_Nmailles];
169 for(int i=0; i<_Nmailles; i++)
171 VecSetValuesBlocked(_conservativeVars, _Nmailles, indices, initialFieldCons, INSERT_VALUES);
172 VecAssemblyBegin(_conservativeVars);
173 VecAssemblyEnd(_conservativeVars);
174 VecCopy(_conservativeVars, _old);
175 VecAssemblyBegin(_old);
176 VecAssemblyEnd(_old);
177 VecSetValuesBlocked(_primitiveVars, _Nmailles, indices, initialFieldPrim, INSERT_VALUES);
178 VecAssemblyBegin(_primitiveVars);
179 VecAssemblyEnd(_primitiveVars);
182 cout << "Variables primitives initiales : " << endl;
183 VecView(_primitiveVars, PETSC_VIEWER_STDOUT_WORLD);
185 cout<<"Variables conservatives initiales : "<<endl;
186 VecView(_conservativeVars, PETSC_VIEWER_STDOUT_SELF);
189 delete[] initialFieldPrim;
190 delete[] initialFieldCons;
194 KSPCreate(PETSC_COMM_SELF, &_ksp);
195 KSPSetType(_ksp, _ksptype);
196 // if(_ksptype == KSPGMRES) KSPGMRESSetRestart(_ksp,10000);
197 KSPSetTolerances(_ksp,_precision,_precision,PETSC_DEFAULT,_maxPetscIts);
198 KSPGetPC(_ksp, &_pc);
199 PCSetType(_pc, _pctype);
201 _initializedMemory=true;
202 save();//save initial data
205 bool ProblemFluid::initTimeStep(double dt){
207 return _dt>0;//No need to call MatShift as the linear system matrix is filled at each Newton iteration (unlike linear problem)
210 bool ProblemFluid::iterateTimeStep(bool &converged)
214 if(_NEWTON_its>0){//Pas besoin de computeTimeStep à la première iteration de Newton
216 computeTimeStep(stop);//This compute timestep is just to update the linear system. The time step was imposed befor starting the Newton iterations
218 if(stop){//Le compute time step ne s'est pas bien passé
219 cout<<"ComputeTimeStep failed"<<endl;
224 computeNewtonVariation();
226 //converged=convergence des iterations
227 if(_timeScheme == Explicit)
229 else{//Implicit scheme
231 KSPGetIterationNumber(_ksp, &_PetscIts);
232 if( _MaxIterLinearSolver < _PetscIts)//save the maximum number of iterations needed during the newton scheme
233 _MaxIterLinearSolver = _PetscIts;
235 KSPConvergedReason reason;
236 KSPGetConvergedReason(_ksp,&reason);
238 if(reason<0)//solving the linear system failed
240 cout<<"Systeme lineaire : pas de convergence de Petsc. Raison PETSC numéro "<<reason<<endl;
241 cout<<"Nombre d'itérations effectuées "<< _PetscIts<<" nombre maximal Itérations autorisées "<<_maxPetscIts<<endl;
242 *_runLogFile<<"Systeme lineaire : pas de convergence de Petsc. Raison PETSC numéro "<<reason<<endl;
243 *_runLogFile<<"Nombre d'itérations effectuées "<< _PetscIts<<" nombre maximal Itérations autorisées "<<_maxPetscIts<<endl;
247 else{//solving the linear system succeeded
248 //Calcul de la variation relative Uk+1-Uk
252 for(int j=1; j<=_Nmailles; j++)
254 for(int k=0; k<_nVar; k++)
257 VecGetValues(_newtonVariation, 1, &I, &dx);
258 VecGetValues(_conservativeVars, 1, &I, &x);
259 if (fabs(x)*fabs(x)< _precision)
261 if(_erreur_rel < fabs(dx))
262 _erreur_rel = fabs(dx);
264 else if(_erreur_rel < fabs(dx/x))
265 _erreur_rel = fabs(dx/x);
269 converged = _erreur_rel <= _precision_Newton;
272 double relaxation=1;//Uk+1=Uk+relaxation*deltaU
274 VecAXPY(_conservativeVars, relaxation, _newtonVariation);
276 //mise a jour du champ primitif
279 if(_nbPhases==2 && fabs(_err_press_max) > _precision)//la pression n'a pu être calculée en diphasique à partir des variables conservatives
281 cout<<"Warning consToPrim: nbiter max atteint, erreur relative pression= "<<_err_press_max<<" precision= " <<_precision<<endl;
282 *_runLogFile<<"Warning consToPrim: nbiter max atteint, erreur relative pression= "<<_err_press_max<<" precision= " <<_precision<<endl;
288 cout<<"Vecteur Ukp1-Uk "<<endl;
289 VecView(_newtonVariation, PETSC_VIEWER_STDOUT_SELF);
290 cout << "Nouvel etat courant Uk de l'iteration Newton: " << endl;
291 VecView(_conservativeVars, PETSC_VIEWER_STDOUT_SELF);
294 if(_nbPhases==2 && _nbTimeStep%_freqSave ==0){
295 if(_minm1<-_precision || _minm2<-_precision)
297 cout<<"!!!!!!!!! WARNING masse partielle negative sur " << _nbMaillesNeg << " faces, min m1= "<< _minm1 << " , minm2= "<< _minm2<< " precision "<<_precision<<endl;
298 *_runLogFile<<"!!!!!!!!! WARNING masse partielle negative sur " << _nbMaillesNeg << " faces, min m1= "<< _minm1 << " , minm2= "<< _minm2<< " precision "<<_precision<<endl;
302 cout << "!!!!!!!!!!!!!!!!!!!!!!!! Complex eigenvalues on " << _nbVpCplx << " cells, max imag= " << _part_imag_max << endl;
303 *_runLogFile << "!!!!!!!!!!!!!!!!!!!!!!!! Complex eigenvalues on " << _nbVpCplx << " cells, max imag= " << _part_imag_max << endl;
315 double ProblemFluid::computeTimeStep(bool & stop){
318 if(_restartWithNewTimeScheme)//This is a change of time scheme during a simulation
320 if(_timeScheme == Implicit)
321 MatCreateSeqBAIJ(PETSC_COMM_SELF, _nVar, _nVar*_Nmailles, _nVar*_Nmailles, (1+_neibMaxNb), PETSC_NULL, &_A);
324 _restartWithNewTimeScheme=false;
326 if(_timeScheme == Implicit)
329 VecAssemblyBegin(_b);
330 VecAssemblyBegin(_conservativeVars);
331 std::vector< int > idCells;
332 PetscInt idm, idn, size = 1;
334 long nbFaces = _mesh.getNumberOfFaces();
339 for (int j=0; j<nbFaces;j++){
340 Fj = _mesh.getFace(j);
341 _isBoundary=Fj.isBorder();
342 idCells = Fj.getCellsId();
344 // If Fj is on the boundary
347 for(int k=0;k<Fj.getNumberOfCells();k++)//there will be at most two neighours in the case of an inner wall
349 // compute the normal vector corresponding to face j : from Ctemp1 outward
350 Ctemp1 = _mesh.getCell(idCells[k]);//origin of the normal vector
352 for(int l=0; l<Ctemp1.getNumberOfFaces(); l++)
353 {//we look for l the index of the face Fj for the cell Ctemp1
354 if (j == Ctemp1.getFacesId()[l])
356 for (int idim = 0; idim < _Ndim; ++idim)
357 _vec_normal[idim] = Ctemp1.getNormalVector(l,idim);
361 }else{ // _Ndim = 1, build normal vector (bug cdmath)
362 if(!_sectionFieldSet)
364 if (Fj.x()<Ctemp1.x())
377 if(_verbose && _nbTimeStep%_freqSave ==0)
379 cout << "face numero " << j << " cellule frontiere " << idCells[k] << " ; vecteur normal=(";
380 for(int p=0; p<_Ndim; p++)
381 cout << _vec_normal[p] << ",";
384 nameOfGroup = Fj.getGroupName();
385 _porosityi=_porosityField(idCells[k]);
386 _porosityj=_porosityi;
387 setBoundaryState(nameOfGroup,idCells[k],_vec_normal);
388 convectionState(idCells[k],0,true);
389 convectionMatrices();
390 diffusionStateAndMatrices(idCells[k], 0, true);
393 _inv_dxi = Fj.getMeasure()/Ctemp1.getMeasure();
395 _inv_dxi = 1/Ctemp1.getMeasure();
397 addConvectionToSecondMember(idCells[k],-1,true,nameOfGroup);
398 addDiffusionToSecondMember(idCells[k],-1,true);
399 addSourceTermToSecondMember(idCells[k],(_mesh.getCell(idCells[k])).getNumberOfFaces(),-1, -1,true,j,_inv_dxi*Ctemp1.getMeasure());
401 if(_timeScheme == Implicit){
402 for(int l=0; l<_nVar*_nVar;l++){
403 _AroeMinusImplicit[l] *= _inv_dxi;
404 _Diffusion[l] *=_inv_dxi*_inv_dxi;
407 jacobian(idCells[k],nameOfGroup,_vec_normal);
408 jacobianDiff(idCells[k],nameOfGroup);
409 if(_verbose && _nbTimeStep%_freqSave ==0){
410 cout << "Matrice Jacobienne CL convection:" << endl;
411 for(int p=0; p<_nVar; p++){
412 for(int q=0; q<_nVar; q++)
413 cout << _Jcb[p*_nVar+q] << "\t";
417 cout << "Matrice Jacobienne CL diffusion:" << endl;
418 for(int p=0; p<_nVar; p++){
419 for(int q=0; q<_nVar; q++)
420 cout << _JcbDiff[p*_nVar+q] << "\t";
426 //calcul et insertion de A^-*Jcb
427 Polynoms::matrixProduct(_AroeMinusImplicit, _nVar, _nVar, _Jcb, _nVar, _nVar, _a);
428 MatSetValuesBlocked(_A, size, &idm, size, &idm, _a, ADD_VALUES);
431 displayMatrix(_a, _nVar, "produit A^-*Jcb pour CL");
434 for(int k=0; k<_nVar*_nVar;k++){
435 _AroeMinusImplicit[k] *= -1;
437 MatSetValuesBlocked(_A, size, &idm, size, &idm, _AroeMinusImplicit, ADD_VALUES);
439 displayMatrix(_AroeMinusImplicit, _nVar,"-_AroeMinusImplicit: ");
441 //calcul et insertion de D*JcbDiff
442 Polynoms::matrixProduct(_Diffusion, _nVar, _nVar, _JcbDiff, _nVar, _nVar, _a);
443 MatSetValuesBlocked(_A, size, &idm, size, &idm, _a, ADD_VALUES);
444 for(int k=0; k<_nVar*_nVar;k++)
446 MatSetValuesBlocked(_A, size, &idm, size, &idm, _Diffusion, ADD_VALUES);
449 } else if (Fj.getNumberOfCells()==2 ){ // Fj is inside the domain and has two neighours (no junction)
450 // compute the normal vector corresponding to face j : from Ctemp1 to Ctemp2
451 Ctemp1 = _mesh.getCell(idCells[0]);//origin of the normal vector
452 Ctemp2 = _mesh.getCell(idCells[1]);
454 for(int l=0; l<Ctemp1.getNumberOfFaces(); l++){//we look for l the index of the face Fj for the cell Ctemp1
455 if (j == Ctemp1.getFacesId()[l]){
456 for (int idim = 0; idim < _Ndim; ++idim)
457 _vec_normal[idim] = Ctemp1.getNormalVector(l,idim);
461 }else{ // _Ndim = 1, build normal vector (bug cdmath)
462 if(!_sectionFieldSet)
464 if (Fj.x()<Ctemp1.x())
471 if(idCells[0]>idCells[1])
477 if(_verbose && _nbTimeStep%_freqSave ==0)
479 cout << "face numero " << j << " cellule gauche " << idCells[0] << " cellule droite " << idCells[1];
480 cout<<" Normal vector= ";
481 for (int idim = 0; idim < _Ndim; ++idim)
482 cout<<_vec_normal[idim]<<", ";
485 _porosityi=_porosityField(idCells[0]);
486 _porosityj=_porosityField(idCells[1]);
487 convectionState(idCells[0],idCells[1],false);
488 convectionMatrices();
489 diffusionStateAndMatrices(idCells[0], idCells[1], false);
491 // compute 1/dxi and 1/dxj
494 _inv_dxi = Fj.getMeasure()/Ctemp1.getMeasure();
495 _inv_dxj = Fj.getMeasure()/Ctemp2.getMeasure();
499 _inv_dxi = 1/Ctemp1.getMeasure();
500 _inv_dxj = 1/Ctemp2.getMeasure();
503 addConvectionToSecondMember( idCells[0],idCells[1], false);
504 addDiffusionToSecondMember( idCells[0],idCells[1], false);
505 addSourceTermToSecondMember(idCells[0], Ctemp1.getNumberOfFaces(),idCells[1], _mesh.getCell(idCells[1]).getNumberOfFaces(),false,j,_inv_dxi*Ctemp1.getMeasure());
507 if(_timeScheme == Implicit){
508 for(int k=0; k<_nVar*_nVar;k++)
510 _AroeMinusImplicit[k] *= _inv_dxi;
511 _Diffusion[k] *=_inv_dxi*2/(1/_inv_dxi+1/_inv_dxj);
515 //cout<<"idm= "<<idm<<"idn= "<<idn<<"nbvoismax= "<<_neibMaxNb<<endl;
516 MatSetValuesBlocked(_A, size, &idm, size, &idn, _AroeMinusImplicit, ADD_VALUES);
517 MatSetValuesBlocked(_A, size, &idm, size, &idn, _Diffusion, ADD_VALUES);
520 displayMatrix(_AroeMinusImplicit, _nVar, "+_AroeMinusImplicit: ");
521 displayMatrix(_Diffusion, _nVar, "+_Diffusion: ");
523 for(int k=0;k<_nVar*_nVar;k++){
524 _AroeMinusImplicit[k] *= -1;
527 MatSetValuesBlocked(_A, size, &idm, size, &idm, _AroeMinusImplicit, ADD_VALUES);
528 MatSetValuesBlocked(_A, size, &idm, size, &idm, _Diffusion, ADD_VALUES);
530 displayMatrix(_AroeMinusImplicit, _nVar, "-_AroeMinusImplicit: ");
531 displayMatrix(_Diffusion, _nVar, "-_Diffusion: ");
533 for(int k=0; k<_nVar*_nVar;k++)
535 _AroePlusImplicit[k] *= _inv_dxj;
536 _Diffusion[k] *=_inv_dxj/_inv_dxi;
538 MatSetValuesBlocked(_A, size, &idn, size, &idn, _AroePlusImplicit, ADD_VALUES);
539 MatSetValuesBlocked(_A, size, &idn, size, &idn, _Diffusion, ADD_VALUES);
541 displayMatrix(_AroePlusImplicit, _nVar, "+_AroePlusImplicit: ");
543 for(int k=0;k<_nVar*_nVar;k++){
544 _AroePlusImplicit[k] *= -1;
547 MatSetValuesBlocked(_A, size, &idn, size, &idm, _AroePlusImplicit, ADD_VALUES);
548 MatSetValuesBlocked(_A, size, &idn, size, &idm, _Diffusion, ADD_VALUES);
551 displayMatrix(_AroePlusImplicit, _nVar, "-_AroePlusImplicit: ");
554 else if( Fj.getNumberOfCells()>2 && _Ndim==1 ){//inner face with more than two neighbours
555 if(_verbose && _nbTimeStep%_freqSave ==0)
556 cout<<"lattice mesh junction at face "<<j<<" nbvoismax= "<<_neibMaxNb<<endl;
557 *_runLogFile<<"Warning: treatment of a junction node"<<endl;
559 if(!_sectionFieldSet)
561 _runLogFile->close();
562 throw CdmathException("ProblemFluid::ComputeTimeStep(): pipe network requires section field");
564 int largestSectionCellIndex=0;
565 for(int i=1;i<Fj.getNumberOfCells();i++){
566 if(_sectionField(idCells[i])>_sectionField(idCells[largestSectionCellIndex]))
567 largestSectionCellIndex=i;
569 idm = idCells[largestSectionCellIndex];
570 Ctemp1 = _mesh.getCell(idm);//origin of the normal vector
571 _porosityi=_porosityField(idm);
573 if (j==15)// bug cdmath (Fj.x() > _mesh.getCell(idm).x())
577 if(_verbose && _nbTimeStep%_freqSave ==0)
579 cout<<"Cell with largest section has index "<< largestSectionCellIndex <<" and number "<<idm<<endl;
580 cout << " ; vecteur normal=(";
581 for(int p=0; p<_Ndim; p++)
582 cout << _vec_normal[p] << ",";
585 for(int i=0;i<Fj.getNumberOfCells();i++){
586 if(i != largestSectionCellIndex){
588 Ctemp2 = _mesh.getCell(idn);
589 _porosityj=_porosityField(idn);
590 convectionState(idm,idn,false);
591 convectionMatrices();
592 diffusionStateAndMatrices(idm, idn,false);
594 if(_verbose && _nbTimeStep%_freqSave ==0)
595 cout<<"Neighbour index "<<i<<" cell number "<< idn<<endl;
597 _inv_dxi = _sectionField(idn)/_sectionField(idm)/Ctemp1.getMeasure();
598 _inv_dxj = 1/Ctemp2.getMeasure();
600 addConvectionToSecondMember(idm,idn, false);
601 _inv_dxi = sqrt(_sectionField(idn)/_sectionField(idm))/Ctemp1.getMeasure();
602 addDiffusionToSecondMember(idm,idn, false);
603 _inv_dxi = _sectionField(idn)/_sectionField(idm)/Ctemp1.getMeasure();
604 addSourceTermToSecondMember(idm, Ctemp1.getNumberOfFaces()*(Fj.getNumberOfCells()-1),idn, Ctemp2.getNumberOfFaces(),false,j,_inv_dxi*Ctemp1.getMeasure());
606 if(_timeScheme == Implicit){
607 for(int k=0; k<_nVar*_nVar;k++)
609 _AroeMinusImplicit[k] *= _inv_dxi;
610 _Diffusion[k] *=_inv_dxi*2/(1/_inv_dxi+1/_inv_dxj);//use sqrt as above
612 MatSetValuesBlocked(_A, size, &idm, size, &idn, _AroeMinusImplicit, ADD_VALUES);
613 MatSetValuesBlocked(_A, size, &idm, size, &idn, _Diffusion, ADD_VALUES);
616 displayMatrix(_AroeMinusImplicit, _nVar, "+_AroeMinusImplicit: ");
617 displayMatrix(_Diffusion, _nVar, "+_Diffusion: ");
619 for(int k=0;k<_nVar*_nVar;k++){
620 _AroeMinusImplicit[k] *= -1;
623 MatSetValuesBlocked(_A, size, &idm, size, &idm, _AroeMinusImplicit, ADD_VALUES);
624 MatSetValuesBlocked(_A, size, &idm, size, &idm, _Diffusion, ADD_VALUES);
626 displayMatrix(_AroeMinusImplicit, _nVar, "-_AroeMinusImplicit: ");
627 displayMatrix(_Diffusion, _nVar, "-_Diffusion: ");
629 for(int k=0; k<_nVar*_nVar;k++)
631 _AroePlusImplicit[k] *= _inv_dxj;
632 _Diffusion[k] *=_inv_dxj/_inv_dxi;//use sqrt as above
634 MatSetValuesBlocked(_A, size, &idn, size, &idn, _AroePlusImplicit, ADD_VALUES);
635 MatSetValuesBlocked(_A, size, &idn, size, &idn, _Diffusion, ADD_VALUES);
637 displayMatrix(_AroePlusImplicit, _nVar, "+_AroePlusImplicit: ");
639 for(int k=0;k<_nVar*_nVar;k++){
640 _AroePlusImplicit[k] *= -1;
643 MatSetValuesBlocked(_A, size, &idn, size, &idm, _AroePlusImplicit, ADD_VALUES);
644 MatSetValuesBlocked(_A, size, &idn, size, &idm, _Diffusion, ADD_VALUES);
647 displayMatrix(_AroePlusImplicit, _nVar, "-_AroePlusImplicit: ");
654 cout<< "Face j="<<j<< " is not a boundary face and has "<<Fj.getNumberOfCells()<< " neighbour cells"<<endl;
655 _runLogFile->close();
656 throw CdmathException("ProblemFluid::ComputeTimeStep(): incompatible number of cells around a face");
660 VecAssemblyEnd(_conservativeVars);
663 if(_timeScheme == Implicit){
664 for(int imaille = 0; imaille<_Nmailles; imaille++)
665 MatSetValuesBlocked(_A, size, &imaille, size, &imaille, _GravityImplicitationMatrix, ADD_VALUES);
667 if(_verbose && _nbTimeStep%_freqSave ==0)
668 displayMatrix(_GravityImplicitationMatrix,_nVar,"Gravity matrix:");
670 MatAssemblyBegin(_A, MAT_FINAL_ASSEMBLY);
671 MatAssemblyEnd(_A, MAT_FINAL_ASSEMBLY);
672 if(_verbose && _nbTimeStep%_freqSave ==0){
673 cout << "Fin ProblemFluid.cxx : matrice implicite"<<endl;
674 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
682 if(_nbTimeStep+1<_cfl)
683 return (_nbTimeStep+1)*_minl/_maxvp;
686 return _cfl*_minl/_maxvp;
689 void ProblemFluid::computeNewtonVariation()
693 cout<<"Vecteur courant Uk "<<endl;
694 VecView(_conservativeVars,PETSC_VIEWER_STDOUT_SELF);
697 if(_timeScheme == Explicit)
699 VecCopy(_b,_newtonVariation);
700 VecScale(_newtonVariation, _dt);
701 if(_verbose && _nbTimeStep%_freqSave ==0)
703 cout<<"Vecteur _newtonVariation =_b*dt"<<endl;
704 VecView(_newtonVariation,PETSC_VIEWER_STDOUT_SELF);
712 cout << "Matrice du système linéaire avant contribution delta t" << endl;
713 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
715 cout << "Second membre du système linéaire avant contribution delta t" << endl;
716 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
719 MatAssemblyBegin(_A, MAT_FINAL_ASSEMBLY);
720 MatAssemblyEnd(_A, MAT_FINAL_ASSEMBLY);
722 VecAXPY(_b, 1/_dt, _old);
723 VecAXPY(_b, -1/_dt, _conservativeVars);
726 #if PETSC_VERSION_GREATER_3_5
727 KSPSetOperators(_ksp, _A, _A);
729 KSPSetOperators(_ksp, _A, _A,SAME_NONZERO_PATTERN);
734 cout << "Matrice du système linéaire après contribution delta t" << endl;
735 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
737 cout << "Second membre du système linéaire après contribution delta t" << endl;
738 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
743 KSPSetComputeEigenvalues(_ksp,PETSC_TRUE);
746 KSPSolve(_ksp, _b, _newtonVariation);
750 computeScaling(_maxvp);
752 VecAssemblyBegin(_vecScaling);
753 VecAssemblyBegin(_invVecScaling);
754 for(int imaille = 0; imaille<_Nmailles; imaille++)
757 VecSetValuesBlocked(_vecScaling,1 , &indice, _blockDiag, INSERT_VALUES);
758 VecSetValuesBlocked(_invVecScaling,1,&indice,_invBlockDiag, INSERT_VALUES);
760 VecAssemblyEnd(_vecScaling);
761 VecAssemblyEnd(_invVecScaling);
765 cout << "Matrice avant le preconditionneur des vecteurs propres " << endl;
766 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
768 cout << "Second membre avant le preconditionneur des vecteurs propres " << endl;
769 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
772 MatDiagonalScale(_A,_vecScaling,_invVecScaling);
775 cout << "Matrice apres le preconditionneur des vecteurs propres " << endl;
776 MatView(_A,PETSC_VIEWER_STDOUT_SELF);
779 VecCopy(_b,_bScaling);
780 VecPointwiseMult(_b,_vecScaling,_bScaling);
783 cout << "Produit du second membre par le preconditionneur bloc diagonal a gauche" << endl;
784 VecView(_b, PETSC_VIEWER_STDOUT_SELF);
788 KSPSolve(_ksp,_b, _bScaling);
789 VecPointwiseMult(_newtonVariation,_invVecScaling,_bScaling);
793 cout << "solution du systeme lineaire local:" << endl;
794 VecView(_newtonVariation, PETSC_VIEWER_STDOUT_SELF);
800 void ProblemFluid::validateTimeStep()
804 cout<<" Vecteur Un"<<endl;
805 VecView(_old, PETSC_VIEWER_STDOUT_WORLD);
806 cout<<" Vecteur Un+1"<<endl;
807 VecView(_conservativeVars, PETSC_VIEWER_STDOUT_WORLD);
809 VecAXPY(_old, -1, _conservativeVars);//old contient old-courant
811 //Calcul de la variation Un+1-Un
816 for(int j=1; j<=_Nmailles; j++)
818 for(int k=0; k<_nVar; k++)
821 VecGetValues(_old, 1, &I, &dx);
822 VecGetValues(_conservativeVars, 1, &I, &x);
823 if (fabs(x)< _precision)
825 if(_erreur_rel < fabs(dx))
826 _erreur_rel = fabs(dx);
828 else if(_erreur_rel < fabs(dx/x))
829 _erreur_rel = fabs(dx/x);
833 _isStationary =_erreur_rel <_precision;
835 VecCopy(_conservativeVars, _old);
837 if(_verbose && _nbTimeStep%_freqSave ==0){
838 if(!_usePrimitiveVarsInNewton)
840 cout <<"Valeur propre locale max: " << _maxvp << endl;
843 if(_nbPhases==2 && _nbTimeStep%_freqSave ==0){
844 //Find minimum and maximum void fractions
845 double alphamin=1e30;
846 double alphamax=-1e30;
847 double T, Tmax=-1e30;
850 for(int j=0; j<_Nmailles; j++)
852 VecGetValues(_primitiveVars, 1, &I, &x);//extract void fraction
858 VecGetValues(_primitiveVars, 1, &J, &T);//extract void fraction
863 cout<<"Alpha min = " << alphamin << ", Alpha max = " << alphamax<<", Tmax= "<<Tmax<<" K"<<endl;
865 *_runLogFile<<"Alpha min = " << alphamin << " Alpha max = " << alphamax<<", Tmax= "<<Tmax<<" K"<<endl;
870 if (_nbTimeStep%_freqSave ==0 || _isStationary || _time>=_timeMax || _nbTimeStep>=_maxNbOfTimeStep)
874 void ProblemFluid::abortTimeStep(){
878 void ProblemFluid::addConvectionToSecondMember
880 const int &j, bool isBord, string groupname
883 if(_verbose && _nbTimeStep%_freqSave ==0)
884 cout<<"ProblemFluid::addConvectionToSecondMember start"<<endl;
886 //extraction des valeurs
887 for(int k=0; k<_nVar; k++)
888 _idm[k] = _nVar*i + k;
889 VecGetValues(_conservativeVars, _nVar, _idm, _Ui);
890 VecGetValues(_primitiveVars, _nVar, _idm, _Vi);
893 for(int k=0; k<_nVar; k++)
894 _idn[k] = _nVar*j + k;
895 VecGetValues(_conservativeVars, _nVar, _idn, _Uj);
896 VecGetValues(_primitiveVars, _nVar, _idn, _Vj);
899 for(int k=0; k<_nVar; k++)
901 VecGetValues(_Uext, _nVar, _idn, _Uj);
902 consToPrim(_Uj, _Vj,_porosityj);
907 if(_verbose && _nbTimeStep%_freqSave ==0)
909 cout << "addConvectionToSecondMember : état i= " << i << ", _Ui=" << endl;
910 for(int q=0; q<_nVar; q++)
911 cout << _Ui[q] << endl;
913 cout << "addConvectionToSecondMember : état j= " << j << ", _Uj=" << endl;
914 for(int q=0; q<_nVar; q++)
915 cout << _Uj[q] << endl;
918 if(_nonLinearFormulation!=reducedRoe){//VFRoe, Roe or VFFC
919 Vector Ui(_nVar), Uj(_nVar), Vi(_nVar), Vj(_nVar), Fi(_nVar), Fj(_nVar),Fij(_nVar);
920 for(int i1=0;i1<_nVar;i1++)
927 Vector normale(_Ndim);
928 for(int i1=0;i1<_Ndim;i1++)
929 normale(i1)=_vec_normal[i1];
931 Matrix signAroe(_nVar);
932 for(int i1=0;i1<_nVar;i1++)
933 for(int i2=0;i2<_nVar;i2++)
934 signAroe(i1,i2)=_signAroe[i1*_nVar+i2];
936 Matrix absAroe(_nVar);
937 for(int i1=0;i1<_nVar;i1++)
938 for(int i2=0;i2<_nVar;i2++)
939 absAroe(i1,i2)=_absAroe[i1*_nVar+i2];
941 if(_nonLinearFormulation==VFRoe)//VFRoe
943 Vector Uij(_nVar),Vij(_nVar);
944 double porosityij=sqrt(_porosityi*_porosityj);
946 Uij=(Ui+Uj)/2+signAroe*(Ui-Uj)/2;
948 for(int i1=0;i1<_nVar;i1++)
951 consToPrim(_Uij, _Vij,porosityij);
953 applyVFRoeLowMachCorrections(isBord, groupname);
955 for(int i1=0;i1<_nVar;i1++)
961 Fij=convectionFlux(Uij,Vij,normale,porosityij);
963 if(_verbose && _nbTimeStep%_freqSave ==0)
965 cout<<"Etat interfacial conservatif "<<i<<", "<<j<< endl;
967 cout<<"Etat interfacial primitif "<<i<<", "<<j<< endl;
973 if(_spaceScheme==staggered && _nonLinearFormulation==VFFC)//special case
974 Fij=staggeredVFFCFlux();
977 Fi=convectionFlux(Ui,Vi,normale,_porosityi);
978 Fj=convectionFlux(Uj,Vj,normale,_porosityj);
979 if(_nonLinearFormulation==VFFC)//VFFC
980 Fij=(Fi+Fj)/2+signAroe*(Fi-Fj)/2;
981 else if(_nonLinearFormulation==Roe)//Roe
982 Fij=(Fi+Fj)/2+absAroe*(Ui-Uj)/2;
984 if(_verbose && _nbTimeStep%_freqSave ==0)
986 cout<<"Flux cellule "<<i<<" = "<< endl;
988 cout<<"Flux cellule "<<j<<" = "<< endl;
993 for(int i1=0;i1<_nVar;i1++)
994 _phi[i1]=-Fij(i1)*_inv_dxi;
995 VecSetValuesBlocked(_b, 1, _idm, _phi, ADD_VALUES);
996 if(_verbose && _nbTimeStep%_freqSave ==0)
998 cout << "Ajout convection au 2nd membre pour les etats " << i << "," << j << endl;
999 cout<<"Flux interfacial "<<i<<", "<<j<< endl;
1001 cout << "Contribution convection à " << i << ", -Fij(i1)*_inv_dxi= "<<endl;
1002 for(int q=0; q<_nVar; q++)
1003 cout << _phi[q] << endl;
1007 for(int i1=0;i1<_nVar;i1++)
1008 _phi[i1]*=-_inv_dxj/_inv_dxi;
1009 VecSetValuesBlocked(_b, 1, _idn, _phi, ADD_VALUES);
1010 if(_verbose && _nbTimeStep%_freqSave ==0)
1012 cout << "Contribution convection à " << j << ", Fij(i1)*_inv_dxj= "<<endl;
1013 for(int q=0; q<_nVar; q++)
1014 cout << _phi[q] << endl;
1018 }else //_nonLinearFormulation==reducedRoe)
1020 for(int k=0; k<_nVar; k++)
1021 _temp[k]=(_Ui[k] - _Uj[k])*_inv_dxi;//(Ui-Uj)*_inv_dxi
1022 Polynoms::matrixProdVec(_AroeMinus, _nVar, _nVar, _temp, _phi);//phi=A^-(U_i-U_j)/dx
1023 VecSetValuesBlocked(_b, 1, _idm, _phi, ADD_VALUES);
1025 if(_verbose && _nbTimeStep%_freqSave ==0)
1027 cout << "Ajout convection au 2nd membre pour les etats " << i << "," << j << endl;
1028 cout << "(Ui - Uj)*_inv_dxi= "<<endl;;
1029 for(int q=0; q<_nVar; q++)
1030 cout << _temp[q] << endl;
1032 cout << "Contribution convection à " << i << ", A^-*(Ui - Uj)*_inv_dxi= "<<endl;
1033 for(int q=0; q<_nVar; q++)
1034 cout << _phi[q] << endl;
1040 for(int k=0; k<_nVar; k++)
1041 _temp[k]*=_inv_dxj/_inv_dxi;//(Ui-Uj)*_inv_dxj
1042 Polynoms::matrixProdVec(_AroePlus, _nVar, _nVar, _temp, _phi);//phi=A^+(U_i-U_j)/dx
1043 VecSetValuesBlocked(_b, 1, _idn, _phi, ADD_VALUES);
1045 if(_verbose && _nbTimeStep%_freqSave ==0)
1047 cout << "Contribution convection à " << j << ", A^+*(Ui - Uj)*_inv_dxi= "<<endl;
1048 for(int q=0; q<_nVar; q++)
1049 cout << _phi[q] << endl;
1054 if(_verbose && _nbTimeStep%_freqSave ==0)
1056 cout<<"ProblemFluid::addConvectionToSecondMember end : matrices de décentrement cellules i= " << i << ", et j= " << j<< "):"<<endl;
1057 displayMatrix(_absAroe, _nVar,"Valeur absolue matrice de Roe");
1058 displayMatrix(_AroeMinus, _nVar,"Matrice _AroeMinus");
1059 displayMatrix(_AroePlus, _nVar,"Matrice _AroePlus");
1060 displayMatrix(_signAroe, _nVar,"Signe de la matrice de Roe");
1064 void ProblemFluid::addSourceTermToSecondMember
1065 ( const int i, int nbVoisinsi,
1066 const int j, int nbVoisinsj,
1067 bool isBord, int ij, double mesureFace)//To do : generalise to unstructured meshes
1069 if(_verbose && _nbTimeStep%_freqSave ==0)
1070 cout<<"ProblemFluid::addSourceTerm cell i= "<<i<< " cell j= "<< j<< " isbord "<<isBord<<endl;
1073 for(int k=1; k<_nVar;k++)
1074 _idm[k] = _idm[k-1] + 1;
1075 VecGetValues(_conservativeVars, _nVar, _idm, _Ui);
1076 VecGetValues(_primitiveVars, _nVar, _idm, _Vi);
1077 sourceVector(_Si,_Ui,_Vi,i);
1079 if (_verbose && _nbTimeStep%_freqSave ==0)
1081 cout << "Terme source S(Ui), i= " << i<<endl;
1082 for(int q=0; q<_nVar; q++)
1083 cout << _Si[q] << endl;
1087 for(int k=0; k<_nVar; k++)
1088 _idn[k] = _nVar*j + k;
1089 VecGetValues(_conservativeVars, _nVar, _idn, _Uj);
1090 VecGetValues(_primitiveVars, _nVar, _idn, _Vj);
1091 sourceVector(_Sj,_Uj,_Vj,j);
1094 for(int k=0; k<_nVar; k++)
1096 VecGetValues(_Uext, _nVar, _idn, _Uj);
1097 consToPrim(_Uj, _Vj,_porosityj);
1098 sourceVector(_Sj,_Uj,_Vj,i);
1100 if (_verbose && _nbTimeStep%_freqSave ==0)
1103 cout << "Terme source S(Uj), j= " << j<<endl;
1105 cout << "Terme source S(Uj), cellule fantôme "<<endl;
1106 for(int q=0; q<_nVar; q++)
1107 cout << _Sj[q] << endl;
1111 //Compute pressure loss vector
1113 if(_pressureLossFieldSet){
1114 K=_pressureLossField(ij);
1115 pressureLossVector(_pressureLossVector, K,_Ui, _Vi, _Uj, _Vj);
1119 for(int k=0; k<_nVar;k++)
1120 _pressureLossVector[k]=0;
1122 if (_verbose && _nbTimeStep%_freqSave ==0)
1124 cout<<"interface i= "<<i<<", j= "<<j<<", ij="<<ij<<", K="<<K<<endl;
1125 for(int k=0; k<_nVar;k++)
1126 cout<< _pressureLossVector[k]<<", ";
1129 //Contribution of the porosityField gradient:
1131 porosityGradientSourceVector();
1133 for(int k=0; k<_nVar;k++)
1134 _porosityGradientSourceVector[k]=0;
1137 if (_verbose && _nbTimeStep%_freqSave ==0)
1140 cout<<"interface i= "<<i<<", j= "<<j<<", ij="<<ij<<", dxi= "<<1/_inv_dxi<<", dxj= "<<1/_inv_dxj<<endl;
1142 cout<<"interface frontière i= "<<i<<", ij="<<ij<<", dxi= "<<1/_inv_dxi<<endl;
1143 cout<<"Gradient de porosite à l'interface"<<endl;
1144 for(int k=0; k<_nVar;k++)
1145 cout<< _porosityGradientSourceVector[k]<<", ";
1150 if(_wellBalancedCorrection){
1151 for(int k=0; k<_nVar;k++)
1152 _phi[k]=(_Si[k]+_Sj[k])/2+_pressureLossVector[k]+_porosityGradientSourceVector[k];
1153 Polynoms::matrixProdVec(_signAroe, _nVar, _nVar, _phi, _l);
1154 for(int k=0; k<_nVar;k++){
1155 _Si[k]=(_phi[k]-_l[k])*mesureFace/_perimeters(i);///nbVoisinsi;
1156 _Sj[k]=(_phi[k]+_l[k])*mesureFace/_perimeters(j);///nbVoisinsj;
1158 if (_verbose && _nbTimeStep%_freqSave ==0)
1160 cout << "Contribution au terme source Si de la cellule i= " << i<<" venant (après décentrement) de la face (i,j), j="<<j<<endl;
1161 for(int q=0; q<_nVar; q++)
1162 cout << _Si[q] << endl;
1163 cout << "Contribution au terme source Sj de la cellule j= " << j<<" venant (après décentrement) de la face (i,j), i="<<i<<endl;
1164 for(int q=0; q<_nVar; q++)
1165 cout << _Sj[q] << endl;
1167 cout<<"ratio surface sur volume i = "<<mesureFace/_perimeters(i)<<" perimeter = "<< _perimeters(i)<<endl;
1168 cout<<"ratio surface sur volume j = "<<mesureFace/_perimeters(j)<<" perimeter = "<< _perimeters(j)<<endl;
1173 for(int k=0; k<_nVar;k++){
1174 _Si[k]=_Si[k]/nbVoisinsi+_pressureLossVector[k]/2+_porosityGradientSourceVector[k]/2;//mesureFace/_perimeters(i)
1175 _Sj[k]=_Sj[k]/nbVoisinsj+_pressureLossVector[k]/2+_porosityGradientSourceVector[k]/2;//mesureFace/_perimeters(j)
1177 if (_verbose && _nbTimeStep%_freqSave ==0)
1179 cout << "Contribution au terme source Si de la cellule i = " << i<<" venant de la face (i,j), j="<<j<<endl;
1180 for(int q=0; q<_nVar; q++)
1181 cout << _Si[q] << endl;
1182 cout << "Contribution au terme source Sj de la cellule j = " << j<<" venant de la face (i,j), i="<<i <<endl;
1183 for(int q=0; q<_nVar; q++)
1184 cout << _Sj[q] << endl;
1189 VecSetValuesBlocked(_b, 1, _idn, _Sj, ADD_VALUES);
1191 if(_wellBalancedCorrection){
1192 for(int k=0; k<_nVar;k++)
1193 _phi[k]=(_Si[k]+_Sj[k])/2+_pressureLossVector[k]+_porosityGradientSourceVector[k];
1194 Polynoms::matrixProdVec(_signAroe, _nVar, _nVar, _phi, _l);
1195 for(int k=0; k<_nVar;k++)
1196 _Si[k]=(_phi[k]-_l[k])*mesureFace/_perimeters(i);///nbVoisinsi;
1197 if (_verbose && _nbTimeStep%_freqSave ==0)
1199 cout << "Contribution au terme source Si de la cellule i= " << i<<" venant (après décentrement) de la face (i,bord)"<<endl;
1200 for(int q=0; q<_nVar; q++)
1201 cout << _Si[q] << endl;
1202 cout<<"ratio surface sur volume i ="<<mesureFace/_perimeters(i)<<" perimeter = "<< _perimeters(i)<<endl;
1208 for(int k=0; k<_nVar;k++)
1209 _Si[k]=_Si[k]/nbVoisinsi+_pressureLossVector[k]/2+_porosityGradientSourceVector[k]/2;//mesureFace/_perimeters(i);//
1210 if (_verbose && _nbTimeStep%_freqSave ==0)
1212 cout << "Contribution au terme source Si de la cellule i = " << i<<" venant de la face (i,bord) "<<endl;
1213 for(int q=0; q<_nVar; q++)
1214 cout << _Si[q] << endl;
1220 VecSetValuesBlocked(_b, 1, _idm, _Si, ADD_VALUES);
1222 if(_verbose && _nbTimeStep%_freqSave ==0 && _wellBalancedCorrection)
1223 displayMatrix( _signAroe,_nVar,"Signe matrice de Roe");
1226 void ProblemFluid::updatePrimitives()
1228 VecAssemblyBegin(_primitiveVars);
1229 for(int i=1; i<=_Nmailles; i++)
1231 _idm[0] = _nVar*( (i-1));
1232 for(int k=1; k<_nVar; k++)
1233 _idm[k] = _idm[k-1] + 1;
1235 VecGetValues(_conservativeVars, _nVar, _idm, _Ui);
1236 consToPrim(_Ui,_Vi,_porosityField(i-1));
1237 if(_verbose && _nbTimeStep%_freqSave ==0)
1239 cout << "ProblemFluid::updatePrimitives() cell " << i-1 << endl;
1241 for(int q=0; q<_nVar; q++)
1242 cout << _Ui[q] << "\t";
1245 for(int q=0; q<_nVar; q++)
1246 cout << _Vi[q] << "\t";
1250 if(_nbPhases==2 && _Psat>-1e30){//Cas simulation flashing
1252 VecGetValues(_primitiveVars, 1, _idm+1, &pressure);
1253 _dp_over_dt(i-1)=(_Vi[1]-pressure)/_dt;//pn+1-pn
1256 VecSetValuesBlocked(_primitiveVars, 1, _idm, _Vi, INSERT_VALUES);
1258 VecAssemblyEnd(_primitiveVars);
1262 cout << "Nouvelles variables primitives : " << endl;
1263 VecView(_primitiveVars, PETSC_VIEWER_STDOUT_WORLD);
1268 void ProblemFluid::updateConservatives()
1270 VecAssemblyBegin(_conservativeVars);
1271 for(int i=1; i<=_Nmailles; i++)
1273 _idm[0] = _nVar*( (i-1));
1274 for(int k=1; k<_nVar; k++)
1275 _idm[k] = _idm[k-1] + 1;
1277 VecGetValues(_primitiveVars, _nVar, _idm, _Vi);
1279 primToCons(_Vi,0,_Ui,0);
1281 VecSetValuesBlocked(_conservativeVars, 1, _idm, _Ui, INSERT_VALUES);
1283 if(_verbose && _nbTimeStep%_freqSave ==0)
1285 cout << "ProblemFluid::updateConservatives() cell " << i-1 << endl;
1287 for(int q=0; q<_nVar; q++)
1288 cout << _Vi[q] << "\t";
1291 for(int q=0; q<_nVar; q++)
1292 cout << _Ui[q] << "\t";
1296 VecAssemblyEnd(_conservativeVars);
1300 cout << "Nouvelles variables conservatives : " << endl;
1301 VecView(_conservativeVars, PETSC_VIEWER_STDOUT_WORLD);
1306 vector< complex<double> > ProblemFluid::getRacines(vector< double > pol_car){
1307 int degre_polynom = pol_car.size()-1;
1309 vector< complex< double > > valeurs_propres (degre_polynom);
1310 vector< double > zeror(degre_polynom);
1311 vector< double > zeroi(degre_polynom);
1312 for(int j=0; j<(degre_polynom+1)/2; j++){//coefficients in order of decreasing powers for rpoly
1314 pol_car[j] =pol_car[degre_polynom-j];
1315 pol_car[degre_polynom-j]=tmp;
1318 //Calcul des racines du polynome
1319 roots_polynoms roots;
1320 int size_vp = roots.rpoly(&pol_car[0],degre_polynom,&zeror[0],&zeroi[0]);
1322 //On ordonne les valeurs propres
1323 if(zeror[1]<zeror[0])
1333 if(size_vp == degre_polynom) {
1334 for(int ct =0; ct<degre_polynom; ct++)
1335 valeurs_propres[ct] = complex<double> (zeror[ct],zeroi[ct]); //vp non triviales
1338 cout << " Pb, found only " << size_vp << " eigenvalues over " << degre_polynom << endl;
1339 *_runLogFile << " Pb, found only " << size_vp << " eigenvalues over " << degre_polynom << endl;
1340 cout<<"Coefficients polynome caracteristique: "<<endl;
1341 for(int ct =0; ct<degre_polynom+1; ct++)
1342 cout<<pol_car[ct]<< " , " <<endl;
1344 *_runLogFile<<"getRacines computation failed"<<endl;
1345 _runLogFile->close();
1346 throw CdmathException("getRacines computation failed");
1349 return valeurs_propres;
1352 void ProblemFluid::AbsMatriceRoe(vector< complex<double> > valeurs_propres_dist)
1354 int nbVp_dist=valeurs_propres_dist.size();
1355 vector< complex< double > > y (nbVp_dist,0);
1356 for( int i=0 ; i<nbVp_dist ; i++)
1357 y[i] = Polynoms::abs_generalise(valeurs_propres_dist[i]);
1358 Polynoms::abs_par_interp_directe(nbVp_dist,valeurs_propres_dist, _Aroe, _nVar,_precision, _absAroe,y);
1359 if(_verbose && (_nbTimeStep-1)%_freqSave ==0)
1361 cout<< endl<<"ProblemFluid::AbsMatriceRoe: Valeurs propres :" << nbVp_dist<<endl;
1362 for(int ct =0; ct<nbVp_dist; ct++)
1363 cout<< "("<<valeurs_propres_dist[ct].real()<< ", " <<valeurs_propres_dist[ct].imag() <<") ";
1365 cout<<"ProblemFluid::AbsMatriceRoe: Valeurs à atteindre pour l'interpolation"<<endl;
1366 for(int ct =0; ct<nbVp_dist; ct++)
1367 cout<< "("<<y[ct].real()<< ", " <<y[ct].imag() <<") ";
1369 displayMatrix(_absAroe,_nVar,"Valeur absolue de la matrice de Roe");
1373 void ProblemFluid::SigneMatriceRoe(vector< complex<double> > valeurs_propres_dist)
1375 int nbVp_dist=valeurs_propres_dist.size();
1376 vector< complex< double > > y (nbVp_dist,0);
1377 for( int i=0 ; i<nbVp_dist ; i++)
1379 if(valeurs_propres_dist[i].real()>0)
1381 else if(valeurs_propres_dist[i].real()<0)
1387 Polynoms::abs_par_interp_directe(nbVp_dist,valeurs_propres_dist, _Aroe, _nVar,_precision, _signAroe,y);
1388 if(_verbose && (_nbTimeStep-1)%_freqSave ==0)
1390 cout<< endl<<"ProblemFluid::SigneMatriceRoe: Valeurs propres :" << nbVp_dist<<endl;
1391 for(int ct =0; ct<nbVp_dist; ct++)
1392 cout<< "("<<valeurs_propres_dist[ct].real()<< ", " <<valeurs_propres_dist[ct].imag() <<") ";
1394 cout<<"ProblemFluid::SigneMatriceRoe: Valeurs à atteindre pour l'interpolation"<<endl;
1395 for(int ct =0; ct<nbVp_dist; ct++)
1396 cout<< "("<<y[ct].real()<< ", " <<y[ct].imag() <<") ";
1398 displayMatrix(_signAroe,_nVar,"Signe matrice de Roe");
1401 void ProblemFluid::InvMatriceRoe(vector< complex<double> > valeurs_propres_dist)
1403 int nbVp_dist=valeurs_propres_dist.size();
1404 vector< complex< double > > y (nbVp_dist,0);
1406 for( int i=0 ; i<nbVp_dist ; i++)
1408 if(Polynoms::module(valeurs_propres_dist[i])>_precision)
1409 y[i] = 1./valeurs_propres_dist[i];
1411 y[i] = 1./_precision;
1413 Polynoms::abs_par_interp_directe(nbVp_dist,valeurs_propres_dist, _Aroe, _nVar,_precision, _invAroe,y);
1414 if(_verbose && (_nbTimeStep-1)%_freqSave ==0)
1416 cout<< endl<<"ProblemFluid::InvMatriceRoe : Valeurs propres :" << nbVp_dist<<endl;
1417 for(int ct =0; ct<nbVp_dist; ct++)
1418 cout<< "("<<valeurs_propres_dist[ct].real()<< ", " <<valeurs_propres_dist[ct].imag() <<") ";
1420 cout<<"ProblemFluid::InvMatriceRoe : Valeurs à atteindre pour l'interpolation"<<endl;
1421 for(int ct =0; ct<nbVp_dist; ct++)
1422 cout<< "("<<y[ct].real()<< ", " <<y[ct].imag() <<") ";
1424 displayMatrix(_invAroe,_nVar,"Inverse matrice de Roe");
1428 Field ProblemFluid::getConservativeField() const
1430 if(!_initializedMemory)
1432 _runLogFile->close();
1433 throw CdmathException("ProblemFluid::getConservativeField call initialize() first");
1438 Field ProblemFluid::getPrimitiveField() const
1440 if(!_initializedMemory)
1442 _runLogFile->close();
1443 throw CdmathException("ProblemFluid::getPrimitiveField call initialize() first");
1448 void ProblemFluid::terminate(){
1451 delete[] _Diffusion;
1452 delete[] _GravityImplicitationMatrix;
1453 delete[] _AroeMinus;
1458 delete[] _AroeImplicit;
1459 delete[] _AroeMinusImplicit;
1460 delete[] _AroePlusImplicit;
1461 delete[] _absAroeImplicit;
1466 delete[] _primToConsJacoMat;
1473 delete[] _externalStates;
1476 delete[] _vec_normal;
1481 if(_nonLinearFormulation==VFRoe){
1487 delete[] _pressureLossVector;
1488 delete[] _porosityGradientSourceVector;
1491 delete[] _blockDiag;
1492 delete[] _invBlockDiag;
1494 VecDestroy(&_vecScaling);
1495 VecDestroy(&_invVecScaling);
1496 VecDestroy(&_bScaling);
1499 VecDestroy(&_conservativeVars);
1500 VecDestroy(&_newtonVariation);
1502 VecDestroy(&_primitiveVars);
1505 VecDestroy(&_Uextdiff);
1509 for(int i=0;i<_nbPhases;i++)