1 //============================================================================
2 // Author : Anouar MEKKAS
4 // Description : Equation de transport lineaire 2D non structure
5 //============================================================================
26 void conditions_initiales(Field& yField)
31 Mesh myMesh=yField.getMesh();
32 int nbCells=myMesh.getNumberOfCells();
33 for (int j=0 ; j<nbCells ; j++)
35 double x = myMesh.getCell(j).x() ;
36 double y = myMesh.getCell(j).y() ;
37 double valX=(x-xcentre)*(x-xcentre);
38 double valY=(y-ycentre)*(y-ycentre);
39 double val=sqrt(valX+valY);
47 void sigma_flux(const parameters & p, const Field& yField, const IntTab indexFacesPerio, double& dt, Field& SumFlux)
50 Mesh myMesh=yField.getMesh();
51 int nbCells=myMesh.getNumberOfCells();
52 double normU=sqrt(p.VitesseX*p.VitesseX+p.VitesseY*p.VitesseY);
53 for (int j=0 ; j<nbCells ; j++)
55 Cell Cj=myMesh.getCell(j);
56 int nbFace=Cj.getNumberOfFaces();
58 double minlengthFk=1.E30;
60 int cellCourante,cellAutre;
61 for (int k=0 ; k<nbFace ; k++)
63 int indexFace=Cj.getFacesId()[k];
64 Face Fk=myMesh.getFace(indexFace);
65 double NormalX=Cj.getNormalVector(k,0);
66 double NormalY=Cj.getNormalVector(k,1);
67 double LengthFk = Fk.getMeasure();
68 double UN=p.VitesseX*NormalX+p.VitesseY*NormalY;
70 minlengthFk=min(minlengthFk,LengthFk/fabs(UN));
71 minlengthFk=min(minlengthFk,LengthFk/fabs(p.VitesseX));
72 minlengthFk=min(minlengthFk,LengthFk/fabs(p.VitesseY));
80 int indexC1=Fk.getCellsId()[0];
81 int indexC2=Fk.getCellsId()[1];
82 /* hypothese: La cellule d'index indexC1 est la cellule courante index j */
85 /* hypothese verifie */
88 } else if ( indexC2 == j )
90 /* hypothese non verifie */
94 // definir la cellule gauche et droite par le prduit vitesse * normale sortante
95 // si u*n>0 : rien a faire sinon inverser la gauche et la droite
97 conc=yField(cellCourante);
99 conc=yField(cellAutre);
102 /* conditions aux limites neumann homogene */
103 if (Fk.getGroupName().compare("GAUCHE")==0 || Fk.getGroupName().compare("DROITE")==0)
106 conc=yField(cellCourante);
110 /* conditions aux limites periodiques */
111 if (Fk.getGroupName().compare("BAS")==0 || Fk.getGroupName().compare("HAUT")==0)
113 int indexFP=indexFacesPerio[indexFace];
114 /* une autre manière de recuperer l'index de la face periodique */
115 //int indexFP=M.getIndexFacePeriodic(indexFace);
116 Face Fp=myMesh.getFace(indexFP);
117 int indexCp=Fp.getCellsId()[0];
119 conc=yField(cellCourante);
121 conc=yField(indexCp);
124 SumF=SumF+UN*LengthFk*conc;
126 dt=p.cfl*minlengthFk/normU;
127 SumFlux(j)=dt*SumF/Cj.getMeasure();
131 void EquationTransport2D(int &iter, double tmin, double & tmax,
132 const parameters & p, Field & yField)
136 * MED output of the initial condition at t=0 and iter = 0
139 const Mesh& myMesh = yField.getMesh();
141 yField.setTime(time,iter);
142 yField.writeMED(p.outFile,true);
143 yField.writeVTK(p.outFile);
144 yField.writeCSV(p.outFile);
145 /* --------------------------------------------- */
148 cout << "Resolution of the transport equation with an UPWIND scheme…" << endl;
151 IntTab indexFacesPerio=myMesh.getIndexFacePeriodic();
152 while (iter<ntmax && time <= tmax )
154 Field SumFlux("Fluxes sum",CELLS,myMesh,1) ;
155 sigma_flux(p,yField,indexFacesPerio,dt,SumFlux);
156 cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
158 /* Advancing time step */
163 // Output every freq iterations
164 if (iter % p.freqSortie==0)
166 yField.setTime(time,iter);
167 yField.writeVTK(p.outFile,false);
168 yField.writeCSV(p.outFile);
172 cout << "MED post-treatment of the solution at T=" << time << endl;
173 yField.setTime(time,iter);
174 yField.writeMED(p.outFile,false);
175 yField.writeCSV(p.outFile);
178 cout << "End of EquationTransport2D." << endl;
181 void compute_onepass(double tmin, double tmax, const Mesh & M, const parameters & p)
185 /* Initial conditions */
186 cout << "Construction of initial condition…" << endl;
187 Field f("Y field",CELLS,M,1) ;
188 conditions_initiales(f);
190 EquationTransport2D(iter, tmin, tmax, p, f);
193 void compute_twopass(double tmin, double tmax, const Mesh & M, const parameters & p)
197 double tstep = 0.5 * (tmin + tmax);
199 /* Initial conditions */
200 cout << "Construction of initial condition…" << endl;
201 Field f("Y field",CELLS,M,1) ;
202 conditions_initiales(f);
204 q.outFile = p.outFile + "_A";
205 EquationTransport2D(iter, tmin, tstep, q, f);
207 Field f2(q.outFile, CELLS, "Y field", iter, 0);
209 q.outFile = p.outFile + "_B";
210 EquationTransport2D(iter, tstep, tmax, q, f2);
216 cout << "Resolution of the 2D transport equation:" << endl;
217 cout << "- DOMAIN: SQUARE" << endl;
218 cout << "- MESH: TRIANGULAR, GENERATED WITH SALOME" << endl;
219 cout << "- PERIODIC BC ON TOP AND BOTTOM" << endl;
220 cout << "- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT" << endl;
222 // donnees du probleme
232 cout << "Construction of Cartesian mesh…" << endl;
233 Mesh M("../../tests/ressources/meshSquare.med");
238 compute_onepass(tmin, tmax, M, p);
239 compute_twopass(tmin, tmax, M, p);
240 cout << "CDMATH calculation done." << endl;