TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Op_Div_VEFP1B_Elem.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 <Dirichlet_entree_fluide_leaves.h>
17#include <Check_espace_virtuel.h>
18#include <Op_Div_VEFP1B_Elem.h>
19#include <Dirichlet_homogene.h>
20#include <Schema_Temps_base.h>
21#include <Porosites_champ.h>
22#include <Neumann_val_ext.h>
23#include <Domaine_Cl_VEF.h>
24#include <communications.h>
25#include <EcrFicPartage.h>
26#include <Probleme_base.h>
27#include <VerifierCoin.h>
28#include <Domaine_VEF.h>
29#include <Periodique.h>
30#include <Dirichlet.h>
31#include <Symetrie.h>
32#include <Domaine.h>
33#include <SChaine.h>
34#include <Neumann.h>
35#include <Debog.h>
36#include <Device.h>
37
38Implemente_instanciable(Op_Div_VEFP1B_Elem, "Op_Div_VEFPreP1B_P1NC|Op_Div_VEF_P1NC", Operateur_Div_base);
39
40Sortie& Op_Div_VEFP1B_Elem::printOn(Sortie& s) const { return s << que_suis_je() ; }
41
42Entree& Op_Div_VEFP1B_Elem::readOn(Entree& is) { return is; }
43
44static int chercher_arete(int elem, int somi, int somj, const IntTab& elem_aretes, const IntTab& aretes_som)
45{
46 if (somi > somj)
47 {
48 int k = somi;
49 somi = somj;
50 somj = k;
51 }
52 for (int i_arete = 0; i_arete < 6; i_arete++)
53 {
54 int arete = elem_aretes(elem, i_arete);
55 int som1 = aretes_som(arete, 0);
56 if (somi == som1)
57 {
58 int som2 = aretes_som(arete, 1);
59 if (somj == som2)
60 return arete;
61 }
62 }
63 return -1;
64}
65
66static int verifier(const Op_Div_VEFP1B_Elem& op, int& init, const Domaine_VEF& domaine_VEF, const DoubleTab& vit, DoubleTab& div)
67{
68 init = 1;
69 DoubleTab v(vit);
70 v = 1;
71 DoubleTab r(div);
72 r = 0;
73 op.ajouter(v, r);
74 Cerr << "div(1,..,1) = " << r << finl;
75 Debog::verifier("div(1,..,1) =", r);
76 const DoubleTab& xv = domaine_VEF.xv();
77 v = xv;
78 {
79 for (int i = 0; i < v.dimension(0); i++)
80 v(i, 1) = 0;
81 }
82 r = 0;
83 op.ajouter(v, r);
84 Cerr << "div(x,0) = " << r << finl;
85 Debog::verifier("div(x,0) =", r);
86 return 1;
87}
88
89void Op_Div_VEFP1B_Elem::associer(const Domaine_dis_base& domaine_dis, const Domaine_Cl_dis_base& domaine_Cl_dis, const Champ_Inc_base&)
90{
91 le_dom_vef = ref_cast(Domaine_VEF, domaine_dis);
92 la_zcl_vef = ref_cast(Domaine_Cl_VEF, domaine_Cl_dis);
93}
94
95DoubleTab& Op_Div_VEFP1B_Elem::ajouter_elem(const DoubleTab& vit, DoubleTab& div) const
96{
97 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_vef.valeur());
98 assert(domaine_VEF.get_alphaE());
99 const Domaine& domaine = domaine_VEF.domaine();
100 const DoubleTab& face_normales = domaine_VEF.face_normales();
101 const IntTab& elem_faces = domaine_VEF.elem_faces();
102 const IntTab& face_voisins = domaine_VEF.face_voisins();
103 int nfe = domaine.nb_faces_elem();
104 int nb_elem = domaine.nb_elem();
105 int dim = Objet_U::dimension; // Objet_U::dimension can not be read from Kernel.
106
107 CIntTabView elem_faces_v = elem_faces.view_ro();
108 DoubleTabView div_v = div.view_rw(); // read-write
109 if (getenv("TRUST_USE_RANDOM_ACCESS")!=nullptr)
110 {
111 // Random access
112 RandomAccessView<int, 2> face_voisins_v = face_voisins.view_ro();
113 RandomAccessView<double, 2> face_normales_v = face_normales.view_ro();
114 RandomAccessView<double, 2> vit_v = vit.view_ro();
115 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem, KOKKOS_LAMBDA(
116 const int elem)
117 {
118 double pscf = 0;
119 for (int indice = 0; indice < nfe; indice++)
120 {
121 int face = elem_faces_v(elem, indice);
122 int signe = elem == face_voisins_v(face, 0) ? 1 : -1;
123 for (int comp = 0; comp < dim; comp++)
124 pscf += signe * vit_v(face, comp) * face_normales_v(face, comp);
125 }
126 div_v(elem, 0) += pscf;
127 });
128 }
129 else
130 {
131 CIntTabView face_voisins_v = face_voisins.view_ro();
132 CDoubleTabView face_normales_v = face_normales.view_ro();
133 CDoubleTabView vit_v = vit.view_ro();
134 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem, KOKKOS_LAMBDA(
135 const int elem)
136 {
137 double pscf = 0;
138 for (int indice = 0; indice < nfe; indice++)
139 {
140 int face = elem_faces_v(elem, indice);
141 int signe = elem == face_voisins_v(face, 0) ? 1 : -1;
142 for (int comp = 0; comp < dim; comp++)
143 pscf += signe * vit_v(face, comp) * face_normales_v(face, comp);
144 }
145 div_v(elem, 0) += pscf;
146 });
147 }
148 end_gpu_timer(__KERNEL_NAME__);
149 assert_invalide_items_non_calcules(div);
150 return div;
151}
152
153int find_cl_face(const Domaine& domaine, const int face)
154{
155 int i;
156 const int nb_cl = domaine.nb_front_Cl();
157 for (i = 0; i < nb_cl; i++)
158 {
159 const Frontiere& fr = domaine.frontiere(i);
160 const int debut = fr.num_premiere_face();
161 if (face >= debut && face < debut + fr.nb_faces())
162 return i;
163 const ArrOfInt& faces_virt = fr.get_faces_virt();
164 const int nb_faces_virt = faces_virt.size_array();
165 for (int j = 0; j < nb_faces_virt; j++)
166 if (face == faces_virt[j])
167 return i;
168 }
169 return -1;
170}
171
172// Passage int -> int car plantage au run avec nvc++ avec type long
173KOKKOS_FUNCTION
174double calculer_coef_som(int type_elem, int dimension, int& nb_face_diri, int* indice_diri)
175{
176 if (type_elem == 0)
177 {
178 nb_face_diri = 0;
179 double coeff_som = 1. / (dimension * (dimension + 1));
180 return coeff_som;
181 }
182 else
183 {
184 if (dimension == 2)
185 {
186 switch(type_elem)
187 {
188 case 1:
189 nb_face_diri = 1;
190 indice_diri[0] = 2;
191 break;
192 case 2:
193 nb_face_diri = 1;
194 indice_diri[0] = 1;
195 break;
196 case 4:
197 nb_face_diri = 1;
198 indice_diri[0] = 0;
199 break;
200 case 3:
201 nb_face_diri = 2;
202 indice_diri[0] = 1;
203 indice_diri[1] = 2;
204 break;
205 case 5:
206 nb_face_diri = 2;
207 indice_diri[0] = 0;
208 indice_diri[1] = 2;
209 break;
210 case 6:
211 nb_face_diri = 2;
212 indice_diri[0] = 0;
213 indice_diri[1] = 1;
214 break;
215 default:
216 //abort();
217 break;
218 }
219 }
220 else if (dimension == 3)
221 {
222 switch(type_elem)
223 {
224 case 1:
225 nb_face_diri = 1;
226 indice_diri[0] = 3;
227 break;
228 case 2:
229 nb_face_diri = 1;
230 indice_diri[0] = 2;
231 break;
232 case 3:
233 nb_face_diri = 2;
234 indice_diri[0] = 3;
235 indice_diri[1] = 2;
236 break;
237 case 4:
238 nb_face_diri = 1;
239 indice_diri[0] = 1;
240 break;
241 case 5:
242 nb_face_diri = 2;
243 indice_diri[0] = 1;
244 indice_diri[1] = 3;
245 break;
246 case 6:
247 nb_face_diri = 2;
248 indice_diri[0] = 1;
249 indice_diri[1] = 2;
250 break;
251 case 7:
252 nb_face_diri = 3;
253 indice_diri[0] = 1;
254 indice_diri[1] = 2;
255 indice_diri[2] = 3;
256 break;
257 case 8:
258 nb_face_diri = 1;
259 indice_diri[0] = 0;
260 break;
261 case 9:
262 nb_face_diri = 2;
263 indice_diri[0] = 0;
264 indice_diri[1] = 3;
265 break;
266 case 10:
267 nb_face_diri = 2;
268 indice_diri[0] = 0;
269 indice_diri[1] = 2;
270 break;
271 case 11:
272 nb_face_diri = 3;
273 indice_diri[0] = 0;
274 indice_diri[1] = 2;
275 indice_diri[2] = 3;
276 break;
277 case 12:
278 nb_face_diri = 2;
279 indice_diri[0] = 0;
280 indice_diri[1] = 1;
281 break;
282 case 13:
283 nb_face_diri = 3;
284 indice_diri[0] = 0;
285 indice_diri[1] = 1;
286 indice_diri[2] = 3;
287 break;
288 case 14:
289 nb_face_diri = 3;
290 indice_diri[0] = 0;
291 indice_diri[1] = 1;
292 indice_diri[2] = 2;
293 break;
294 default:
295#ifndef TRUST_USE_GPU
296 abort();
297#endif
298 break;
299 }
300 }
301 else
302 {
303#ifndef TRUST_USE_GPU
304 abort();
305#endif
306 }
307 }
308 double coeff_som = 1. / (dimension * (dimension + 1 - nb_face_diri));
309 return coeff_som;
310}
311
312DoubleTab& Op_Div_VEFP1B_Elem::ajouter_som(const DoubleTab& tab_vit, DoubleTab& tab_div, DoubleTab& tab_flux_b) const
313{
314 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_vef.valeur());
315 assert(domaine_VEF.get_alphaS());
316 const Domaine& domaine = domaine_VEF.domaine();
317 int nfe = domaine.nb_faces_elem();
318 int nb_elem_tot = domaine.nb_elem_tot();
319 int nps = domaine_VEF.numero_premier_sommet();
320
321 // Initialisation tableaux constants
322 if (!som_initialized_)
323 {
324 som_initialized_ = true;
325 const IntTab& som_elem = domaine.les_elems();
326 som_.resize(nb_elem_tot, nfe);
327 nb_degres_liberte_.resize(domaine_VEF.domaine().nb_som_tot());
328 nb_degres_liberte_ = -1;
329 for (int elem = 0; elem < nb_elem_tot; elem++)
330 for (int indice = 0; indice < nfe; indice++)
331 {
332 int som = nps + domaine.get_renum_som_perio(som_elem(elem, indice));
333 nb_degres_liberte_(som - nps)++;
334 som_(elem, indice) = som;
335 }
336 corrige_sommets_sans_degre_liberte_ = (mp_min_vect(nb_degres_liberte_) == 0);
337 }
338
339 int dim = Objet_U::dimension;
340 int modif_traitement_diri = domaine_VEF.get_modif_div_face_dirichlet();
341 const Domaine_Cl_VEF& zcl = ref_cast(Domaine_Cl_VEF, la_zcl_vef.valeur());
342
343 CDoubleTabView face_normales = domaine_VEF.face_normales().view_ro();
344 CDoubleTabView vit = tab_vit.view_ro();
345 CIntArrView rang_elem_non_std = domaine_VEF.rang_elem_non_std().view_ro();
346 CIntArrView type_elem_Cl = zcl.type_elem_Cl().view_ro();
347 CIntTabView elem_faces = domaine_VEF.elem_faces().view_ro();
348 CIntTabView face_voisins = domaine_VEF.face_voisins().view_ro();
349 CIntTabView som_v = som_.view_ro();
350 DoubleArrView div = static_cast<DoubleVect&>(tab_div).view_rw();
351 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
352 range_1D(0, nb_elem_tot),
353 KOKKOS_LAMBDA (const int elem)
354 {
355 double sigma[3];
356 for (int comp = 0; comp < dim; comp++)
357 {
358 double s = 0;
359 for (int indice = 0; indice < nfe; indice++)
360 {
361 int face = elem_faces(elem, indice);
362 s += vit(face, comp);
363 }
364 sigma[comp] = s;
365 }
366
367 double coeff_som = 1. / (dim * (dim + 1));
368 if (modif_traitement_diri)
369 {
370 int indice_diri[4];
371 int nb_face_diri = 0;
372 int rang_elem = (int)rang_elem_non_std(elem);
373 int type_elem = rang_elem < 0 ? 0 : (int)type_elem_Cl(rang_elem);
374 coeff_som = calculer_coef_som(type_elem, dim, nb_face_diri, indice_diri);
375 // on retire la contribution des faces dirichlets
376 for (int fdiri = 0; fdiri < nb_face_diri; fdiri++)
377 {
378 int indice = indice_diri[fdiri];
379 int face = elem_faces(elem,indice);
380 for (int comp = 0; comp < dim; comp++)
381 sigma[comp] -= vit(face,comp);
382 }
383 }
384
385 for (int indice = 0; indice < nfe; indice++)
386 {
387 int face = elem_faces(elem,indice);
388 double psc = 0;
389 for (int comp = 0; comp < dim; comp++)
390 psc += sigma[comp] * face_normales(face,comp);
391
392 int som = som_v(elem,indice);
393 int signe = (elem != face_voisins(face,0) ? -1 : 1);
394 Kokkos::atomic_add(&div(som), signe * coeff_som * psc);
395 }
396 });
397 end_gpu_timer(__KERNEL_NAME__);
398
399 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
400 const Conds_lim& les_cl = domaine_Cl_VEF.les_conditions_limites();
401 int nb_bords = les_cl.size();
402 int nb_comp = Objet_U::dimension;
403
404 IntArrView nb_degres_liberte = nb_degres_liberte_.view_rw();
405 DoubleTabView flux_b = tab_flux_b.view_wo();
406
407 for (int n_bord = 0; n_bord < nb_bords; n_bord++)
408 {
409 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
410 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
411 CIntArrView num_face = le_bord.num_face().view_ro();
412 int nb_faces_bord = le_bord.nb_faces();
413 int nb_faces_bord_tot = le_bord.nb_faces_tot();
414 assert(le_bord.nb_faces() == domaine_VEF.domaine().frontiere(n_bord).nb_faces());
415 if (!sub_type(Periodique, la_cl.valeur()))
416 {
417 int libre = 1;
418 if (sub_type(Dirichlet,la_cl.valeur()) || sub_type(Dirichlet_homogene, la_cl.valeur()) || sub_type(Dirichlet_entree_fluide, la_cl.valeur()) || sub_type(Symetrie, la_cl.valeur()))
419 libre = 0;
420
421 CIntTabView face_sommets = domaine_VEF.face_sommets().view_ro();
422 CIntArrView renum_som_perio = domaine.get_renum_som_perio().view_ro();
423
424 // On boucle sur les faces de bord reelles et virtuelles
425 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
426 range_1D(0, nb_faces_bord_tot), KOKKOS_LAMBDA(
427 const int ind_face)
428 {
429 int face = num_face(ind_face);
430 double flux = 0.;
431 for (int comp = 0; comp < nb_comp; comp++)
432 flux += vit(face, comp) * face_normales(face, comp);
433 if (ind_face < nb_faces_bord)
434 flux_b(face, 0) = flux;
435 flux *= 1. / nb_comp;
436 for (int indice = 0; indice < (nfe - 1); indice++)
437 {
438 int som = renum_som_perio(face_sommets(face, indice));
439 Kokkos::atomic_add(&div(nps + som), flux);
440 if (libre)
441 Kokkos::atomic_add(&nb_degres_liberte(som), 1);
442 }
443 });
444 end_gpu_timer(__KERNEL_NAME__);
445 }
446 else
447 {
448 const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
449 CIntArrView face_associee = la_cl_perio.face_associee().view_ro();
450 // On boucle sur les faces de bord reelles et virtuelles
451 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
452 range_1D(0, nb_faces_bord_tot), KOKKOS_LAMBDA(
453 const int ind_face)
454 {
455 int face = num_face(ind_face);
456 int face_perio = num_face(face_associee(ind_face));
457 double flux = 0.;
458 double flux_perio = 0.;
459 for (int comp = 0; comp < nb_comp; comp++)
460 {
461 flux += vit(face, comp) * face_normales(face, comp);
462 flux_perio += vit(face_perio, comp) * face_normales(face_perio, comp);
463 }
464 if (ind_face < (nb_faces_bord / 2))
465 {
466 flux_b(face, 0) = -flux;
467 flux_b(face_perio, 0) = flux_perio;
468 }
469 });
470 end_gpu_timer(__KERNEL_NAME__);
471 }
472 }
473 return tab_div;
474}
475
476DoubleTab& Op_Div_VEFP1B_Elem::ajouter_aretes(const DoubleTab& vit, DoubleTab& div) const
477{
478 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_vef.valeur());
479 assert(domaine_VEF.get_alphaA());
480 const Domaine& domaine = domaine_VEF.domaine();
481 const DoubleTab& face_normales = domaine_VEF.face_normales();
482 const IntTab& som_elem = domaine.les_elems();
483 const IntTab& elem_faces = domaine_VEF.elem_faces();
484 const IntTab& face_voisins = domaine_VEF.face_voisins();
485 const ArrOfInt& renum_arete_perio = domaine_VEF.get_renum_arete_perio();
486 const ArrOfInt& ok_arete = domaine_VEF.get_ok_arete();
487 int npa = domaine_VEF.numero_premiere_arete();
488 int nb_elem_tot = domaine.nb_elem_tot();
489 int elem, comp;
490
491 const IntTab& aretes_som = domaine_VEF.domaine().aretes_som();
492 const IntTab& elem_aretes = domaine_VEF.domaine().elem_aretes();
493 for (elem = 0; elem < nb_elem_tot; elem++)
494 {
495 for (int isom = 0; isom < 3; isom++)
496 {
497 int somi = som_elem(elem, isom);
498 int facei = elem_faces(elem, isom);
499 double signei = 1.;
500 if (face_voisins(facei, 0) != elem)
501 signei = -1.;
502 for (int jsom = isom + 1; jsom < 4; jsom++)
503 {
504 int somj = som_elem(elem, jsom);
505 int facej = elem_faces(elem, jsom);
506 double signej = 1.;
507 if (face_voisins(facej, 0) != elem)
508 signej = -1.;
509 int arete = renum_arete_perio[chercher_arete(elem, somi, somj, elem_aretes, aretes_som)];
510 if (ok_arete[arete])
511 {
512 int niinij = 0;
513 for (int ksom = 0; ksom < 4; ksom++)
514 {
515 if ((ksom == isom) || (ksom == jsom))
516 {
517 if (niinij == ksom)
518 niinij++;
519 double psc = 0;
520 for (comp = 0; comp < 3; comp++)
521 psc += (signei * face_normales(facei, comp) + signej * face_normales(facej, comp)) * vit(elem_faces(elem, ksom), comp);
522 div(npa + arete) -= 1. / 15. * psc;
523 }
524 else
525 {
526 if (niinij == ksom)
527 niinij++;
528 while ((niinij == jsom) || (niinij == isom))
529 niinij++;
530 assert(niinij < 4);
531 assert(niinij != isom);
532 assert(niinij != jsom);
533 assert(niinij != ksom);
534 int facek = elem_faces(elem, niinij);
535 double signek = 1.;
536 if (face_voisins(facek, 0) != elem)
537 signek = -1.;
538 double psc = 0;
539 for (comp = 0; comp < 3; comp++)
540 psc += signek * face_normales(facek, comp) * vit(elem_faces(elem, ksom), comp);
541 div(npa + arete) -= 2. / 15. * psc;
542 niinij = ksom;
543 }
544 }
545 }
546 }
547 }
548 }
549 return div;
550}
551
552DoubleTab& Op_Div_VEFP1B_Elem::ajouter(const DoubleTab& tab_velocity_tab, DoubleTab& tab_div) const
553{
554 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_vef.valeur());
555 const Domaine_Cl_VEF& domaine_Cl_VEF = la_zcl_vef.valeur();
556 // Quelques verifications:
557 // L'espace virtuel de velocity_tab doit etre a jour (Le test est fait si check_enabled==1)
558 assert_espace_virtuel_vect(tab_velocity_tab);
559 // On s'en fiche de l'espace virtuel de div a l'entree, mais on fait += dessus.
560 assert_invalide_items_non_calcules(tab_div, 0.);
561
562#ifndef NDEBUG
563 // On s'assure que la periodicite est respectee sur velocity_tab (Voir FA814)
564 int nb_comp = tab_velocity_tab.dimension(1);
565 for (int n_bord = 0; n_bord < domaine_VEF.nb_front_Cl(); n_bord++)
566 {
567 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
568 if (sub_type(Periodique, la_cl.valeur()))
569 {
570 const Periodique& la_cl_perio = ref_cast(Periodique, la_cl.valeur());
571 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
572 int nb_faces_bord = le_bord.nb_faces();
573 CIntArrView face_associee = la_cl_perio.face_associee().view_ro();
574 CIntArrView num_face = le_bord.num_face().view_ro();
575 CDoubleTabView velocity_tab = tab_velocity_tab.view_ro();
576 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), Kokkos::RangePolicy<>(0, nb_faces_bord), KOKKOS_LAMBDA(const int ind_face)
577 {
578 int ind_face_associee = face_associee(ind_face);
579 int face = num_face(ind_face);
580 int face_ass = num_face(ind_face_associee);
581 // PL : test a 1.e-4 car certains cas ne respectent pas strictement (lente derive?)
582 for (int comp = 0; comp < nb_comp; comp++)
583 if (!est_egal(velocity_tab(face, comp), velocity_tab(face_ass, comp), 1.e-4))
584 {
585#ifndef TRUST_USE_GPU
586 Cerr << "vit1(" << face << "," << comp << ")=" << velocity_tab(face, comp) << finl;
587 Cerr << "vit2(" << face_ass << "," << comp << ")=" << velocity_tab(face_ass, comp) << finl;
588 Cerr << "Delta=" << velocity_tab(face, comp) - velocity_tab(face_ass, comp) << finl;
589 Cerr << "Periodic boundary condition is not correct in Op_Div_VEFP1B_Elem::ajouter" << finl;
590 Cerr << "Contact TRUST support." << finl;
591#endif
592 Process::Kokkos_exit("Error in Op_Div_VEFP1B_Elem::ajouter.");
593 }
594 }); // for face
595 end_gpu_timer(__KERNEL_NAME__);
596 } // sub_type Perio
597 }
598#endif
599 const DoubleVect& porosite_face = equation().milieu().porosite_face();
600 DoubleTab phi_vitesse_face_;
601 const DoubleTab& vit = modif_par_porosite_si_flag(tab_velocity_tab, phi_vitesse_face_, 1, porosite_face);
602
603 DoubleTab& flux_b = flux_bords_;
604 flux_b.resize(domaine_VEF.nb_faces_bord(), 1);
605 flux_b = 0.;
606
607 static int init = 1;
608 if (!init)
609 ::verifier(*this, init, domaine_VEF, vit, tab_div);
610 if (domaine_VEF.get_alphaE())
611 ajouter_elem(vit, tab_div);
612 if (domaine_VEF.get_alphaS())
613 ajouter_som(vit, tab_div, flux_b);
614 if (domaine_VEF.get_alphaA())
615 ajouter_aretes(vit, tab_div);
616
617 // correction de de div u si pression sommet imposee de maniere forte
618 if ((domaine_VEF.get_alphaS()) && ((domaine_VEF.get_cl_pression_sommet_faible() == 0)))
619 {
620 const Conds_lim& les_cl = domaine_Cl_VEF.les_conditions_limites();
621 int nps = domaine_VEF.numero_premier_sommet();
622 for (const auto &itr : les_cl)
623 {
624 const Cond_lim& la_cl = itr;
625 if (sub_type(Neumann,la_cl.valeur()) || sub_type(Neumann_val_ext, la_cl.valeur()))
626 {
627 const Front_VF& la_front_dis = ref_cast(Front_VF, la_cl->frontiere_dis());
628 int nb_faces = la_front_dis.nb_faces_tot();
629 int nsf = 0;
630 if (nb_faces != 0)
631 nsf = domaine_VEF.face_sommets().dimension(1);
632 CIntArrView num_face = la_front_dis.num_face().view_ro();
633 CIntTabView faces_sommets = domaine_VEF.face_sommets().view_ro();
634 DoubleArrView div = static_cast<DoubleVect&>(tab_div).view_wo();
635 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
636 range_1D(0, nb_faces), KOKKOS_LAMBDA(
637 const int ind_face)
638 {
639 int face = num_face(ind_face);
640 for (int som = 0; som < nsf; som++)
641 {
642 int som1 = faces_sommets(face, som);
643 div(nps + som1) = 0.;
644 }
645 });
646 end_gpu_timer(__KERNEL_NAME__);
647 }
648 }
649 }
650 if (domaine_VEF.get_alphaS() && corrige_sommets_sans_degre_liberte_)
652 //Optimisation, pas necessaire:
653 //tab_div.echange_espace_virtuel();
654 return tab_div;
655}
656
657#ifdef VersionP1
658double tiers=1./3.;
659const IntTab& aretes_som=domaine_VEF.domaine().aretes_som();
660const IntTab& elem_aretes=domaine_VEF.domaine().elem_aretes();
661ArrOfDouble gradK(3);
662for(int isom=0; isom<3; isom++)
663 {
664 int somi = som_elem(elem,isom);
665 int facei = elem_faces(elem,isom);
666 double signei=1.;
667 if (face_voisins(facei,0) != elem)
668 signei=-1.;
669 for(int jsom=isom+1; jsom<4; jsom++)
670 {
671 int somj = som_elem(elem,jsom);
672 int facej = elem_faces(elem,jsom);
673 double signej=1.;
674 if (face_voisins(facej,0) != elem)
675 signej=-1.;
676 int arete = chercher_arete(elem, somi, somj,
677 elem_aretes, aretes_som);
678 for(comp=0; comp<dimension; comp++)
679 gradK(comp) = (signei*face_normales(facei,comp)+
680 signej*face_normales(facej,comp));
681 psc=0;
682 for(comp=0; comp<dimension; comp++)
683 psc+=tiers*(
684 -signei*face_normales(facei,comp)*vit(facei,comp)
685 -signej*face_normales(facej,comp)*vit(facej,comp)
686 +.5*gradK(comp)*sigma[comp]);
687 div(npa+arete)-=psc;
688 }
689 }
690#else
691#endif
692
693// Divise par le volume
694void Op_Div_VEFP1B_Elem::volumique_P0(DoubleTab& tab_div) const
695{
696 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
697 int nb_elem = domaine_VEF.domaine().nb_elem_tot();
698 CDoubleArrView vol = domaine_VEF.volumes().view_ro();
699 DoubleArrView div = static_cast<DoubleVect&>(tab_div).view_rw();
700 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem, KOKKOS_LAMBDA(const int i) { div(i) /= vol(i); });
701 end_gpu_timer(__KERNEL_NAME__);
702}
703
704void Op_Div_VEFP1B_Elem::volumique(DoubleTab& tab_div) const
705{
706 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_vef.valeur());
707 int n = 0;
708 if (domaine_VEF.get_alphaE())
709 {
710 volumique_P0(tab_div);
711 n += domaine_VEF.nb_elem_tot();
712 }
713 if (domaine_VEF.get_alphaS())
714 {
715 int size_tot = domaine_VEF.volume_aux_sommets().size_totale();
716 CDoubleArrView vol = domaine_VEF.volume_aux_sommets().view_ro();
717 DoubleArrView div = static_cast<DoubleVect&>(tab_div).view_rw();
718 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), size_tot, KOKKOS_LAMBDA(const int i) { div(n + i) /= vol(i); });
719 end_gpu_timer(__KERNEL_NAME__);
720 n += domaine_VEF.nb_som_tot();
721 }
722 if (domaine_VEF.get_alphaA())
723 {
724 const DoubleVect& vol = domaine_VEF.get_volumes_aretes();
725 int size_tot = vol.size_totale();
726 ToDo_Kokkos("critical");
727 for (int i = 0; i < size_tot; i++)
728 tab_div(n + i) /= vol(i);
729 }
730}
731
733{
734 // On annulle la divergence aux sommets sans degre de liberte
735 // (sommet uniquement commun a des faces avec des CL Diriclet)
736 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_vef.valeur());
737 const Domaine& domaine = domaine_VEF.domaine();
738 const IntTab& elem_faces = domaine_VEF.elem_faces();
739 const IntTab& face_voisins = domaine_VEF.face_voisins();
740 const int nse = domaine.nb_som_elem();
741 int nb_faces_tot = domaine_VEF.nb_faces_tot();
742
743 Sortie& journal = Process::Journal();
744 int afficher_message = 0;
745 int nb_som = domaine.nb_som();
746
747 int ecrire_decoupage_som = 0;
748 int decoupage_som = 0;
749 // On n'ecrit qu'une seule fois le fichier decoupage_som
750 // et uniquement en sequentiel
751 if ((Process::is_sequential()) && equation().schema_temps().nb_pas_dt() == 0)
752 decoupage_som = 1;
753
754 SChaine decoup_som;
755 decoup_som << "1" << finl;
756 decoup_som << Objet_U::dimension << " " << nb_som << finl;
757 ArrOfInt somm(dimension + 2);
758 for (int k = 0; k < nb_som; k++)
759 {
760 int sommet = domaine.get_renum_som_perio(k);
761 if (nb_degres_liberte_(sommet) != 0)
762 continue;
763 if (!afficher_message)
764 {
765 afficher_message = 1;
766 Cerr << finl << "Problem with the mesh used for the VEF P1Bulle discretization." << finl;
767 journal << "List of nodes with no degrees of freedom :" << finl;
768 }
769 const double x = domaine.coord(sommet, 0);
770 const double y = domaine.coord(sommet, 1);
771 const double z = (Objet_U::dimension == 3) ? domaine.coord(sommet, 2) : 0.;
772
773 journal << "Error node " << sommet << " ( " << x << " " << y << " " << z << " )\n";
774 // On affiche la liste des indices d'elements reels et virtuels qui contiennent
775 // ce sommet. On affiche la lettre "v" pour les elements virtuels.
776 journal << "Elements ";
777 const int nb_elem_tot = domaine.nb_elem_tot();
778 const int nb_elem = domaine.nb_elem();
779 const IntTab& som_elem = domaine.les_elems();
780 for (int elem = 0; elem < nb_elem_tot; elem++)
781 for (int som = 0; som < nse; som++)
782 if (som_elem(elem, som) == sommet)
783 {
784 journal << elem << ((elem >= nb_elem) ? "v " : " ");
785
786 // Ecriture dans le fichier decoupage_som
787 int face_opp = elem_faces(elem, som);
788 int elem_opp;
789 somm = -1;
790 somm(0) = sommet;
791
792 int elem1 = face_voisins(face_opp, 0);
793 int elem2 = face_voisins(face_opp, 1);
794
795 if (elem1 == elem)
796 elem_opp = elem2;
797 else
798 elem_opp = elem1;
799
800 int i = 2;
801 for (int som1 = 0; som1 < nse; som1++) // on parcourt les sommets de elem_opp
802 {
803 int ok = 1;
804 for (int som2 = 0; som2 < nse; som2++) // on parcourt les sommets de elem
805 if (som_elem(elem, som2) == som_elem(elem_opp, som1))
806 ok = 0;
807 if (ok)
808 somm(1) = som_elem(elem_opp, som1);
809 else
810 {
811 somm(i) = som_elem(elem_opp, som1); // sommets de la face commune
812 i++;
813 }
814 }
815 if (decoupage_som)
816 {
817 ecrire_decoupage_som = 1;
818 for (int j = 0; j < dimension + 2; j++)
819 decoup_som << somm(j) << " ";
820 decoup_som << elem << " " << elem_opp << finl;
821 }
822 }
823 journal << "\n";
824 // On affiche la liste des faces qui contiennent ce sommet.
825 // Pour les faces de bord, on affiche la condlim,
826 // pour les faces virtuelles, la lettre "v"
827 journal << "\nFaces ";
828 const int nb_faces = domaine_VEF.nb_faces();
829 const int nb_som_face = domaine_VEF.face_sommets().dimension(1);
830 for (int face = 0; face < nb_faces_tot; face++)
831 {
832 for (int som = 0; som < nb_som_face; som++)
833 {
834 if (domaine_VEF.face_sommets(face, som) == sommet)
835 {
836 journal << face;
837 if (face >= nb_faces) // Face virtuelle
838 journal << "v";
839 const int cl = find_cl_face(domaine, face);
840 // Face de bord reelle:
841 if (cl >= 0)
842 {
843 const Nom& nom_bord = domaine.frontiere(cl).le_nom();
844 journal << "(boundary=" << nom_bord << ")";
845 }
846 journal << " ";
847 }
848 }
849 }
850 journal << finl;
851 }
852
853 if (ecrire_decoupage_som)
854 {
855 decoup_som << "-1";
856 SFichier fic(Objet_U::nom_du_cas() + ".decoupage_som");
857 fic << decoup_som.get_str() << finl;
858 fic.close();
859
860 }
861 if (afficher_message)
862 {
863 Nom nom_fichier(nom_du_cas());
864 Cerr << "Look at the .log file of processor " << Process::me() << " to know which nodes" << finl;
865 Cerr << "do not have enough degrees of freedom. You can also visualize" << finl;
866 Cerr << "your mesh to identify which elements have a problem and" << finl;
867 Cerr << "remesh your domain close to these nodes so that these have" << finl;
868 Cerr << "at least a degree of freedom." << finl;
869 Cerr << "The VEF P1Bulle discretization is not compatible with this type" << finl;
870 Cerr << "of mesh and boundary conditions used (Dirichlet, Symmetry ,...)" << finl << finl;
871 Cerr << "Other possibility, in your data file:" << finl;
872 if (dimension == 2)
873 Cerr << "If you have used \"Trianguler\", substituted by \"Trianguler_H\"." << finl << finl;
874 if (dimension == 3)
875 Cerr << "If you have used \"Tetraedriser\", substituted by \"Tetraedriser_homogene\" or \"Tetraedriser_par_prisme\"." << finl << finl;
876 Cerr << "Or insert the line:" << finl;
877 Cerr << "VerifierCoin " << domaine.le_nom() << " { [Read_file " << nom_fichier << ".decoupage_som] }" << finl;
878 Cerr << "after the mesh is finished to be read and built." << finl;
880 Cerr << "and BEFORE the keyword \"Decouper\" during the partition of the mesh." << finl;
881 else
882 Cerr << "and BEFORE the keyword \"Discretiser\"." << finl;
883 Cerr << "A few cells will be divided into 3 (2D) or 4 (3D)." << finl;
884 Cerr << finl;
886 }
887}
888
890{
891 const int impr_bord = (le_dom_vef->domaine().bords_a_imprimer().est_vide() ? 0 : 1);
893 double temps = sch.temps_courant();
894
895 int nb_compo = flux_bords_.dimension(1);
896 // On parcours les frontieres pour sommer les flux par frontiere dans le tableau flux_bord
897 DoubleVect bilan(nb_compo);
898 bilan = 0;
899 int nb_cl = le_dom_vef->nb_front_Cl();
900 // flux_bords contains the sum of flux on each boundary:
901 DoubleTrav tab_flux_bords(3, nb_cl, nb_compo);
902 for (int num_cl = 0; num_cl < nb_cl; num_cl++)
903 {
904 const Cond_lim& la_cl = la_zcl_vef->les_conditions_limites(num_cl);
905 const Front_VF& frontiere_dis = ref_cast(Front_VF, la_cl->frontiere_dis());
906 int ndeb = frontiere_dis.num_premiere_face();
907 int nfin = ndeb + frontiere_dis.nb_faces();
908 int perio = (sub_type(Periodique,la_cl.valeur()) ? 1 : 0);
909 for (int face = ndeb; face < nfin; face++)
910 for (int k = 0; k < nb_compo; k++)
911 {
912 tab_flux_bords(0, num_cl, k) += flux_bords_(face, k);
913 if (perio)
914 {
915 if (face < (ndeb + frontiere_dis.nb_faces() / 2))
916 tab_flux_bords(1, num_cl, k) += flux_bords_(face, k);
917 else
918 tab_flux_bords(2, num_cl, k) += flux_bords_(face, k);
919 }
920 }
921 }
922 // Sum on all CPUs:
923 mp_sum_for_each_item(tab_flux_bords);
924
925 // Print
926 if (je_suis_maitre())
927 {
928 ouvrir_fichier(Flux_div, "", 1);
929 Flux_div.add_col(temps);
930 for (int num_cl = 0; num_cl < nb_cl; num_cl++)
931 {
932 const Cond_lim& la_cl = la_zcl_vef->les_conditions_limites(num_cl);
933 int perio = (sub_type(Periodique,la_cl.valeur()) ? 1 : 0);
934 for (int k = 0; k < nb_compo; k++)
935 {
936 if (perio)
937 {
938 Flux_div.add_col(tab_flux_bords(1, num_cl, k));
939 Flux_div.add_col(tab_flux_bords(2, num_cl, k));
940 }
941 else
942 Flux_div.add_col(tab_flux_bords(0, num_cl, k));
943 bilan(k) += tab_flux_bords(0, num_cl, k);
944 }
945 }
946
947 for (int k = 0; k < nb_compo; k++)
948 Flux_div.add_col(bilan(k));
949 Flux_div << finl;
950 }
951
952 const LIST(Nom) &Liste_bords_a_imprimer = le_dom_vef->domaine().bords_a_imprimer();
953 if (!Liste_bords_a_imprimer.est_vide())
954 {
955 EcrFicPartage Flux_face;
956 ouvrir_fichier_partage(Flux_face, "", impr_bord);
957 for (int num_cl = 0; num_cl < nb_cl; num_cl++)
958 {
959 const Frontiere_dis_base& la_fr = la_zcl_vef->les_conditions_limites(num_cl)->frontiere_dis();
960 const Cond_lim& la_cl = la_zcl_vef->les_conditions_limites(num_cl);
961 const Front_VF& frontiere_dis = ref_cast(Front_VF, la_cl->frontiere_dis());
962 int ndeb = frontiere_dis.num_premiere_face();
963 int nfin = ndeb + frontiere_dis.nb_faces();
964 if (le_dom_vef->domaine().bords_a_imprimer().contient(la_fr.le_nom()))
965 {
966 Flux_face << "# Flux par face sur " << la_fr.le_nom() << " au temps " << temps << " : " << finl;
967 for (int face = ndeb; face < nfin; face++)
968 {
969 if (dimension == 2)
970 Flux_face << "# Face a x= " << le_dom_vef->xv(face, 0) << " y= " << le_dom_vef->xv(face, 1) << " flux=";
971 else if (dimension == 3)
972 Flux_face << "# Face a x= " << le_dom_vef->xv(face, 0) << " y= " << le_dom_vef->xv(face, 1) << " z= " << le_dom_vef->xv(face, 2) << " flux=";
973 for (int k = 0; k < nb_compo; k++)
974 Flux_face << " " << flux_bords_(face, k);
975 Flux_face << finl;
976 }
977 Flux_face.syncfile();
978 }
979 }
980 }
981 return 1;
982}
Classe Champ_Inc_base.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
classe Dirichlet_entree_fluide Cette classe represente une condition aux limite imposant une grandeur
Classe Dirichlet_homogene Cette classe est la classe de base de la hierarchie des conditions aux limi...
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
int_t nb_elem_tot() const
Definition Domaine.h:132
const IntTab_t & aretes_som() const
renvoie le tableau de connectivite aretes/sommets.
Definition Domaine.h:156
const Frontiere_t & frontiere(int i) const
Definition Domaine.h:539
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
Definition Domaine.h:484
int_t elem_aretes(int_t i, int j) const
renvoie le numero de la jeme arete du ieme element.
Definition Domaine.h:154
int_t nb_som_tot() const
Renvoie le nombre total de sommets du domaine i.e. le nombre de sommets reels et virtuels sur le proc...
Definition Domaine.h:123
int type_elem_Cl(int i) const
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VEF
Definition Domaine_VEF.h:54
int numero_premiere_arete() const
const IntVect & get_ok_arete() const
Definition Domaine_VEF.h:99
IntVect & rang_elem_non_std()
Definition Domaine_VEF.h:86
int numero_premier_sommet() const
const DoubleVect & get_volumes_aretes() const
int get_modif_div_face_dirichlet() const
Definition Domaine_VEF.h:96
int get_cl_pression_sommet_faible() const
Definition Domaine_VEF.h:97
int get_alphaA() const
Definition Domaine_VEF.h:94
const ArrOfInt & get_renum_arete_perio() const
Definition Domaine_VEF.h:98
const DoubleVect & volume_aux_sommets() const
Definition Domaine_VEF.h:90
int get_alphaS() const
Definition Domaine_VEF.h:93
int get_alphaE() const
Definition Domaine_VEF.h:92
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
int nb_faces_tot() const
renvoie le nombre total de faces.
Definition Domaine_VF.h:481
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
double volumes(int i) const
Definition Domaine_VF.h:113
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
Definition Domaine_VF.h:583
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
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
int nb_faces_bord() const
renvoie le nombre de faces sur lesquelles sont appliquees les conditions limites :
Definition Domaine_VF.h:513
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
int nb_elem_tot() const
int nb_front_Cl() const
const Domaine & domaine() const
int nb_som_tot() const
Sortie & syncfile() override
Provoque l'ecriture sur disque des donnees accumulees sur les differents processeurs depuis le dernie...
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Milieu_base & milieu() const =0
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
int nb_faces_tot() const
Definition Front_VF.h:58
int num_face(const int) const
Definition Front_VF.h:68
const ArrOfInt_t & get_faces_virt() const
Definition Frontiere.h:69
int_t num_premiere_face() const
Definition Frontiere.h:67
int_t nb_faces() const
Renvoie le nombre de faces de la frontiere.
Definition Frontiere.h:59
classe Frontiere_dis_base Classe representant une frontiere discretisee.
const Nom & le_nom() const override
Renvoie le nom de la frontiere geometrique.
DoubleVect & porosite_face()
Definition Milieu_base.h:62
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
Classe Neumann_val_ext Cette classe est la classe de base de la hierarchie des conditions.
Classe Neumann Cette classe est la classe de base de la hierarchie des conditions aux limites de type...
Definition Neumann.h:31
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const Nom & le_nom() const override
Renvoie *this;.
Definition Nom.cpp:563
static int dimension
Definition Objet_U.h:99
friend class Sortie
Definition Objet_U.h:75
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
static const Nom & nom_du_cas()
Renvoie une reference constante vers le nom du cas.
Definition Objet_U.cpp:146
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
class Op_Div_VEFP1B_Elem
void volumique(DoubleTab &) const override
int impr(Sortie &os) const override
DOES NOTHING - to override in derived classes.
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
public_for_cuda void volumique_P0(DoubleTab &) const
DoubleTab & ajouter_aretes(const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter_elem(const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter_som(const DoubleTab &, DoubleTab &, DoubleTab &) const
void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &, const Champ_Inc_base &) override
Classe Operateur_Div_base Cette classe est la base de la hierarchie des operateurs representant.
DoubleTab flux_bords_
void ouvrir_fichier_partage(EcrFicPartage &, const Nom &, const int flag=1) const
Ouverture/creation d'un fichier d'impression d'un operateur A surcharger dans les classes derivees.
void ouvrir_fichier(SFichier &os, const Nom &, const int flag=1) const
Ouverture/creation d'un fichier d'impression d'un operateur A surcharger dans les classes derivees.
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
static KOKKOS_INLINE_FUNCTION void Kokkos_exit(const char *)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.h:173
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:193
static bool is_parallel()
Definition Process.cpp:110
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
Definition Process.cpp:588
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
static bool is_sequential()
Definition Process.cpp:115
Cette classe derivee de Sortie empile ce qu'on lui envoie dans une chaine de caracteres.
Definition SChaine.h:26
const char * get_str() const
returns a copy of the string stored by the SChaine
Definition SChaine.cpp:72
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
class Schema_Temps_base
double temps_courant() const
Renvoie le temps courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
Definition Symetrie.h:37
_SIZE_ size_array() const
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_wo()
Definition TRUSTTab.h:276
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
Definition TRUSTTab.h:261
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_rw()
Definition TRUSTTab.h:291
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61