TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Domaine_DG.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Domaine_Cl_DG.h>
17#include <Domaine_DG.h>
18#include <Option_DG.h>
19#include <Poly_geom_base.h>
20#include <Array_tools.h>
21#include <TRUSTLists.h>
22#include <TRUSTList.h>
23#include <Domaine.h>
24#include <Hexa_poly.h>
25#include <Tri_poly.h>
26#include <Hexaedre.h>
27#include <Triangle.h>
28#include <Tetraedre.h>
29#include <Rectangle.h>
30#include <Quadri_poly.h>
31#include <Tetra_poly.h>
32#include <EChaine.h>
33#include <Interprete_bloc.h>
34#include <Quadrature_base.h>
35#include <Quadrature_Ord1_Polygone.h>
36#include <Quadrature_Ord3_Polygone.h>
37#include <Quadrature_Ord5_Polygone.h>
38#include <BasisFunction.h>
39#include <Champ_Elem_DG.h>
40
41Implemente_instanciable(Domaine_DG, "Domaine_DG", Domaine_Poly_base);
42
44
46
47
48/*! @brief Compute mesh parameters, allocate quadratures and link them to the domain
49 *
50 * The function use Domaine_Poly_base::discretiser() that builds every geometric connectivities that are not in the mesh file
51 */
53{
56
58
61 quad1_ = std::make_shared<Quadrature_Ord1_Polygone>(*this);
62 quad3_ = std::make_shared<Quadrature_Ord3_Polygone>(*this);
63 quad5_ = std::make_shared<Quadrature_Ord5_Polygone>(*this);
64
65 int nelem_tot = nb_elem_tot();
66 const int nb_faces_max = elem_faces_.dimension(1);
67
68 stencil_sorted_.resize(nelem_tot, nb_faces_max+1);
69 stencil_sorted_ = -1;
70
71 int elem1, elem2, size_stencil, face;
72
73 std::vector<int> elem_stencil;
74
75 for (int nelem = 0 ; nelem < nelem_tot ; nelem++)
76 {
77 elem_stencil.clear();
78 elem_stencil.push_back(nelem);
79 for (int num_face = 0 ; num_face < nb_faces_max; num_face++)
80 {
81 if ( elem_faces(nelem,num_face) < 0 ) break;
82
83 face = elem_faces(nelem,num_face);
84 elem1 = face_voisins(face, 0);
85 elem2 = face_voisins(face, 1);
86
87 if (elem1 != nelem && elem1 != -1)
88 elem_stencil.push_back(elem1);
89 else if (elem2 != -1 && elem2 != nelem)
90 elem_stencil.push_back(elem2);
91 }
92 std::sort(elem_stencil.begin(), elem_stencil.end());
93
94 size_stencil = (int)elem_stencil.size();
95 for (int k = 0; k < size_stencil; k++)
96 stencil_sorted_(nelem,k) = elem_stencil[k];
97 }
98}
99/*! @brief Set the global default order
100 *
101 * @param order : order to specify
102 */
103void Domaine_DG::set_default_order(int order) //TODO DG adapt the default order for P1 P2...
104{
105 order_quad_=order;
106}
107
108/*! @brief New feature in Trust, not yet available in DG, ask Elie
109 *
110 */
112{
113 //TODO DG
114}
115
116/*! @brief Compute positions of the quadrature points
117 *
118 * For now it uses the default quadrature order and compute positions for every cells
119 *
120 * @param positions coordinates of the quadrature points
121 */
122void Domaine_DG::get_position(DoubleTab& positions) const
123{
124 //TODO Kokkos DG
125 const Quadrature_base& quad = get_quadrature(5);
126 positions = quad.get_integ_points();
127}
128
129/*! @brief Give an IntTab that contains the number of integration points for each cell
130 *
131 * @param nb_integ_points : nb_integ_points[i] give the number of integration points for cell i
132 *
133 */
134void Domaine_DG::get_nb_integ_points(IntTab& nb_integ_points) const
135{
136 const Quadrature_base& quad = get_quadrature(5);
137 nb_integ_points = quad.get_tab_nb_pts_integ();
138// nb_integ_points.ref(tab_pts_integ);
139}
140
142{
143 const Quadrature_base& quad = get_quadrature(5);
144 return quad.nb_pts_integ_max();
145}
146
147/*! @brief Create the indirection that give for each cell, the index number of the first integration point
148 *
149 * @param ind_integ_points : ind_integ_points[i] give the index of the first integration point associated with cell i
150 */
151void Domaine_DG::get_ind_integ_points(IntTab& ind_integ_points) const
152{
153 const Quadrature_base& quad = get_quadrature(5);
154 ind_integ_points = quad.get_ind_pts_integ();
155// ind_integ_points.ref(ind_pts_integ);
156}
157
159{
160 BasisFunction_Key key {order}; //possibility to add other key later
161 auto it = bfunc_maps_.find(key);
162 if (it == bfunc_maps_.end())
163 {
164 // Lazy build so we only compute mass/transition matrices once per unique configuration
165 auto tk = std::make_shared<BasisFunction>();
166 tk->initialize(*this, order, gram_schmidt_);
167 it = bfunc_maps_.emplace(key, std::move(tk)).first;
168 }
169 return *it->second;
170}
171
172/*! @brief Compute L_1 norm
173 *
174 */
175double Domaine_DG::compute_L1_norm(const DoubleVect& val_source, const bool basis_function, const int order) const
176{
177 //In case of Champ_Fonc_Quad, the values are on the quadrature point
178 const Quadrature_base& quad = get_quadrature(5);
179 int nb_pts_integ_max = quad.nb_pts_integ_max();
180 int nelem = nb_elem();
181
182 DoubleTab val_elem(nb_pts_integ_max);
183 double sum = 0.;
184
185 if (basis_function)
186 {
187 //In case of Champ_Inc_Elem, the values are the coefficient of the basis function
188 const BasisFunction& bfunc = get_basisFunction(order);
189 const int nb_bfunc = bfunc.nb_bfunc();
190 DoubleTab fbase(nb_bfunc, nb_pts_integ_max);
191
192 for (int i = 0; i < nelem; i++)
193 {
194 bfunc.eval_bfunc(quad, i, fbase);
195 for (int k = 0; k < quad.nb_pts_integ(i) ; k++)
196 {
197 for (int l =0; l<nb_bfunc; l++)
198 val_elem(k) += val_source(i*nb_bfunc+l)*fbase(l,k);
199
200 val_elem(k) = std::fabs(val_elem(k));
201 }
202 sum += quad.compute_integral_on_elem(i, val_elem);
203 }
204 }
205 else
206 {
207 for (int i = 0; i < nelem; i++)
208 {
209 for (int k = 0; k < quad.nb_pts_integ(i) ; k++)
210 val_elem(k) = std::fabs(val_source(i*nb_pts_integ_max+k));
211 sum += quad.compute_integral_on_elem(i, val_elem);
212 }
213 }
214
215 return sum;
216}
217/*! @brief Compute L_2 norm
218 *
219 */
220double Domaine_DG::compute_L2_norm(const DoubleVect& val_source, const bool basis_function, const int order) const
221{
222 //In case of Champ_Fonc_Quad, the values are on the quadrature point
223 const Quadrature_base& quad = get_quadrature(5);
224 int nb_pts_integ_max = quad.nb_pts_integ_max();
225 int nelem = nb_elem();
226
227 DoubleTab val_elem(nb_pts_integ_max);
228 double sum = 0.;
229 if (basis_function)
230 {
231 //In case of Champ_Inc_Elem, the values are the coefficient of the basis function
232 const BasisFunction& bfunc = get_basisFunction(order);
233 const int nb_bfunc = bfunc.nb_bfunc();
234 DoubleTab fbase(nb_bfunc, nb_pts_integ_max);
235
236 for (int i = 0; i < nelem; i++)
237 {
238 bfunc.eval_bfunc(quad, i, fbase);
239 for (int k = 0; k < quad.nb_pts_integ(i) ; k++)
240 {
241 for (int l =0; l<nb_bfunc; l++)
242 val_elem(k) += val_source(i*nb_bfunc+l)*fbase(l,k);
243
244 val_elem(k) = val_elem(k)*val_elem(k);
245 }
246 sum += quad.compute_integral_on_elem(i, val_elem);
247 }
248 }
249 else
250 {
251 for (int i = 0; i < nelem; i++)
252 {
253 for (int k = 0; k < quad.nb_pts_integ(i) ; k++)
254 val_elem(k) = val_source(i*nb_pts_integ_max+k)*val_source(i*nb_pts_integ_max+k);
255 sum += quad.compute_integral_on_elem(i, val_elem);
256 }
257 }
258
259 return sum;
260}
261/*! @brief Compute average
262 *
263 */
264void Domaine_DG::compute_average(const DoubleVect& val_source, double& sum, double& volume, const bool basis_function, const int order) const
265{
266 //In case of Champ_Fonc_Quad, the values are on the quadrature point
267 const Quadrature_base& quad = get_quadrature(5);
268 int nb_pts_integ_max = quad.nb_pts_integ_max();
269 int nelem = nb_elem();
270
271 DoubleTab val_elem(nb_pts_integ_max);
272
273 if (basis_function)
274 {
275 //In case of Champ_Inc_Elem, the values are the coefficient of the basis function
276 const BasisFunction& bfunc = get_basisFunction(order);
277 const int nb_bfunc = bfunc.nb_bfunc();
278 DoubleTab fbase(nb_bfunc, nb_pts_integ_max);
279
280 for (int i = 0; i < nelem; i++)
281 {
282 val_elem = 0.;
283 bfunc.eval_bfunc(quad, i, fbase);
284 for (int k = 0; k < quad.nb_pts_integ(i) ; k++)
285 {
286 for (int l =0; l<nb_bfunc; l++)
287 val_elem(k) += val_source(i*nb_bfunc+l)*fbase(l,k);
288 }
289 sum += quad.compute_integral_on_elem(i, val_elem);
290 volume += volumes(i);
291 }
292 }
293 else
294 {
295 for (int i = 0; i < nelem; i++)
296 {
297
298 for (int k = 0; k < quad.nb_pts_integ(i) ; k++)
299 val_elem(k) = val_source(i*nb_pts_integ_max+k);
300 sum += quad.compute_integral_on_elem(i, val_elem);
301 volume += volumes(i);
302 }
303 }
304}
305/*! @brief Compute average with porosity
306 *
307 */
308void Domaine_DG::compute_average_porosity(const DoubleVect& val_source, const DoubleVect& porosity, double& sum, double& volume, const bool basis_function, const int order) const
309{
310 //In case of Champ_Fonc_Quad, the values are on the quadrature point
311 const Quadrature_base& quad = get_quadrature(5);
312 int nb_pts_integ_max = quad.nb_pts_integ_max();
313 int nelem = nb_elem();
314
315 DoubleTab val_elem(nb_pts_integ_max);
316 if (basis_function)
317 {
318 //In case of Champ_Inc_Elem, the values are the coefficient of the basis function
319 const BasisFunction& bfunc = get_basisFunction(order);
320 const int nb_bfunc = bfunc.nb_bfunc();
321 DoubleTab fbase(nb_bfunc, nb_pts_integ_max);
322
323 for (int i = 0; i < nelem; i++)
324 {
325 val_elem = 0.;
326 bfunc.eval_bfunc(quad, i, fbase);
327 for (int k = 0; k < quad.nb_pts_integ(i) ; k++)
328 {
329 for (int l =0; l<nb_bfunc; l++)
330 val_elem(k) += val_source(i*nb_bfunc+l)*fbase(l,k);
331 val_elem(k) *= porosity(i);
332 }
333 sum += quad.compute_integral_on_elem(i, val_elem);
334 volume += volumes(i)*porosity(i);
335 }
336 }
337 else
338 {
339 for (int i = 0; i < nelem; i++)
340 {
341
342 for (int k = 0; k < quad.nb_pts_integ(i) ; k++)
343 val_elem(k) = val_source(i*nb_pts_integ_max+k)*porosity(i);
344 sum += quad.compute_integral_on_elem(i, val_elem);
345 volume += volumes(i)*porosity(i);
346 }
347 }
348}
349/*! @brief Compute geometric quantities used for the computation
350 * TODO :: Put this in the Domain_Poly_base and delete h_carre
351 */
353{
354 int nb_elem_tot = this->nb_elem_tot();
355 DoubleTab& xs = domaine().les_sommets(); // facets barycentre
356 const IntTab& vert_elems = domaine().les_elems();
357 const IntTab& elem_faces=this->elem_faces();
358 const IntTab& face_som=this->face_sommets();
359 dia_.resize(nb_elem_tot); ///< Array of the diameter for each cell
360 per_.resize(nb_elem_tot); ///< Perimeter of each cell
361 rho_.resize(nb_elem_tot); ///< Diameter of the largest incircle for each cell
362 sig_.resize(nb_elem_tot); ///< Aspect ratio of each cell
363
364 for (int e = 0; e < nb_elem_tot; e++)
365 {
366 int nsom = nfaces_elem_(e);
367 if (nsom==3)
368 {
369 dia_(e) = 1 / (2 * volumes(e));
370 int nb_elem_face = 3; // nb_elem_faces(e)
371 for (int i_f = 0; i_f < nb_elem_face; i_f++)
372 {
373 int f = elem_faces(e, i_f);
374 double sur_f = face_surfaces(f);
375 dia_(e) *= sur_f;
376 per_(e) += sur_f; //
377 }
378 rho_(e) = 4. * volumes(e) / per_(e);
379 sig_(e) = dia_(e) / rho_(e);
380 }
381 else
382 {
383 per_(e)=0;
384 double h_e=0;
385 for (int f = 0; f < nsom; f++) // local index of facet
386 {
387 int f_e = elem_faces(e,f);
388 int s1 = face_som(f_e,0);
389 int s2 = face_som(f_e,1);
390// double x1= xs(s1,0);
391// double y2=xs(s2,1);
392// double x2=xs(s2,0);
393// double y1=xs(s1,1);
394// double prod=x1*y2-x2*y1;
395// std::cout<< "Les sommets sont ("<<x1<<","<<y1<<") et (" <<x2<<","<<y2<<") et prod : "<<prod<<std::endl ;
396 per_(e)+= std::sqrt((xs(s1,0) - xs(s2,0)) * (xs(s1,0) - xs(s2,0)) + (xs(s1,1) - xs(s2,1)) * (xs(s1,1) - xs(s2,1)));
397
398 // calcul of h
399 for (int loc_vert2 = f+1; loc_vert2 < nsom; loc_vert2++) // That's tricky: we use the bijection between vertices and faces to loop over the vertices simultaneously.
400 h_e=std::max(h_e,std::sqrt((xs(vert_elems(e, f),0) - xs(vert_elems(e, loc_vert2),0)) * (xs(vert_elems(e, f),0) - xs(vert_elems(e, loc_vert2),0)) + (xs(vert_elems(e, f),1) - xs(vert_elems(e, loc_vert2),1)) * (xs(vert_elems(e, f),1) - xs(vert_elems(e, loc_vert2),1)))); // max between the distance of each vertices
401 }
402 rho_(e)=2.*(volumes(e)/per_(e));
403 dia_(e)=h_e;
404 sig_(e)=h_e/rho_(e);
405 }
406 }
407}
408
409/*! @brief Should disappear, as well as h_carre, as we have dia_, this come with a refactoring of Domaine_Poly_base
410 *
411 */
413{
414 h_carre=0;
415 for (int e = 0; e < this->nb_elem(); e++)
416 {
417 h_carre=std::max(h_carre,dia_(e)*dia_(e));
418 }
420
421 // Calcul de h_carre
422 //h_carre = 1;
423 if (h_carre_.size()) return; // deja fait
424 int nb_elem_tot = this->nb_elem_tot();
425 h_carre_.resize(nb_elem_tot);
427// h_carre = 1.;
428}
429
430/*! @brief Create an array that store the number of faces per element
431 *
432 * If the mesh is only composed with the same type of element, return yes.
433 */
435{
436 nfaces_elem_.resize(nb_elem_tot());
437 bool only_tri_quad=true;
438 const IntTab& elem_face = elem_faces();
439 int nb_f_elem_max=elem_face.dimension(1);
440
441 if (Objet_U::dimension == 2)
442 {
443 for (int e = 0; e < nb_elem_tot(); e++)
444 {
445 if ((nb_f_elem_max == 3) || (elem_face(e, 3) == -1))
446 {
447 nfaces_elem_(e) = 3; // triangles
448 }
449 else if ((nb_f_elem_max == 4) || (elem_face(e, 4) == -1))
450 {
451 nfaces_elem_(e) = 4; // quads
452 }
453 else
454 {
455 int i_f = 5;
456 for (; i_f < nb_f_elem_max; i_f++)
457 {
458 if (elem_face(e, i_f) == -1)
459 {
460 nfaces_elem_(e) = i_f; // polys
461 break;
462 }
463 }
464 if (i_f == nb_f_elem_max)
465 nfaces_elem_(e) = i_f; // full poly
466 }
467 }
468 }
469 else
470 {
471 Process::exit("3D not implemented yet");
472 }
473 return only_tri_quad;
474}
Manages the local polynomial basis functions for Discontinuous Galerkin elements.
void eval_bfunc(const Quadrature_base &quad, const int &nelem, DoubleTab &fbasis) const
Evaluates all basis functions at the element quadrature points.
const int & nb_bfunc() const
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
std::shared_ptr< Quadrature_base > quad3_
Definition Domaine_DG.h:71
IntTab nfaces_elem_
Definition Domaine_DG.h:79
DoubleTab rho_
Definition Domaine_DG.h:77
std::shared_ptr< Quadrature_base > quad1_
Definition Domaine_DG.h:70
DoubleTab per_
Definition Domaine_DG.h:76
void init_equiv() const override
New feature in Trust, not yet available in DG, ask Elie.
bool build_nfaces_elem_()
Create an array that store the number of faces per element.
void get_ind_integ_points(IntTab &ind_integ_points) const override
Create the indirection that give for each cell, the index number of the first integration point.
int get_max_nb_integ_points() const override
DoubleTab sig_
Definition Domaine_DG.h:78
void discretiser() override
Compute mesh parameters, allocate quadratures and link them to the domain.
double compute_L1_norm(const DoubleVect &val_source, const bool basis_function, const int order) const override
Compute L_1 norm.
std::map< BasisFunction_Key, std::shared_ptr< BasisFunction > > bfunc_maps_
Definition Domaine_DG.h:97
bool gram_schmidt_
Definition Domaine_DG.h:81
void set_default_order(int order)
Set the global default order.
void get_nb_integ_points(IntTab &nb_integ_points) const override
Give an IntTab that contains the number of integration points for each cell.
void calculer_h_carre() override
Should disappear, as well as h_carre, as we have dia_, this come with a refactoring of Domaine_Poly_b...
void compute_mesh_param()
Compute geometric quantities used for the computation TODO :: Put this in the Domain_Poly_base and de...
std::shared_ptr< Quadrature_base > quad5_
Definition Domaine_DG.h:72
double compute_L2_norm(const DoubleVect &val_source, const bool basis_function, const int order) const override
Compute L_2 norm.
Stencil stencil_sorted_
Definition Domaine_DG.h:83
int order_quad_
Definition Domaine_DG.h:80
void compute_average(const DoubleVect &val_source, double &sum, double &average, const bool basis_function, const int order) const override
Compute average.
const Quadrature_base & get_quadrature() const
Definition Domaine_DG.h:117
void get_position(DoubleTab &positions) const override
Compute positions of the quadrature points.
void compute_average_porosity(const DoubleVect &val_source, const DoubleVect &porosity, double &sum, double &average, const bool basis_function, const int order) const override
Compute average with porosity.
const BasisFunction & get_basisFunction(int order) const
DoubleTab dia_
Definition Domaine_DG.h:74
class Domaine_Poly_base
void discretiser() override
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
IntTab & face_sommets() override
renvoie le tableau de connectivite faces/sommets.
Definition Domaine_VF.h:591
IntTab & elem_faces()
renvoie le tableau de connectivite element/faces
Definition Domaine_VF.h:551
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
IntTab elem_faces_
Definition Domaine_VF.h:222
DoubleVect & volumes()
Definition Domaine_VF.h:119
IntTab & face_voisins() override
renvoie le tableaux des volumes des connectivites face elements cf au dessus.
Definition Domaine_VF.h:426
int nb_elem_tot() const
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
static int dimension
Definition Objet_U.h:99
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static int GRAM_SCHMIDT
Definition Option_DG.h:42
static double mp_max(double)
Definition Process.cpp:376
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
int nb_pts_integ(int e) const
const DoubleTab & get_integ_points() const
int nb_pts_integ_max() const
const IntTab & get_tab_nb_pts_integ() const
double compute_integral_on_elem(int num_elem, Parser_U &parser) const
const IntTab & get_ind_pts_integ() const
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133