TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Domaine_VEF.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 <Connectivite_som_elem.h>
17#include <Check_espace_virtuel.h>
18#include <MD_Vector_composite.h>
19#include <VEF_discretisation.h>
20#include <EcrFicPartageBin.h>
21#include <Static_Int_Lists.h>
22#include <MD_Vector_tools.h>
23#include <Domaine_Cl_VEF.h>
24#include <Quadrangle_VEF.h>
25#include <Octree_Double.h>
26#include <Hexaedre_VEF.h>
27#include <Domaine_VEF.h>
28#include <EFichierBin.h>
29#include <Quadri_VEF.h>
30#include <Periodique.h>
31#include <TRUSTLists.h>
32#include <Periodique.h>
33#include <Rectangle.h>
34#include <Tetra_VEF.h>
35#include <Conds_lim.h>
36#include <Tetraedre.h>
37#include <ArrOfBit.h>
38#include <Hexaedre.h>
39#include <Hexa_VEF.h>
40#include <Triangle.h>
41#include <Tri_VEF.h>
42#include <Domaine.h>
43#include <Debog.h>
44
45Implemente_instanciable(Domaine_VEF, "Domaine_VEF", Domaine_VF);
46
47Sortie& Domaine_VEF::ecrit(Sortie& os) const
48{
50 os << "____ h_carre " << finl;
51 os << h_carre << finl;
52 os << "____ type_elem_ " << finl;
53 os << type_elem_.valeur() << finl;
54 os << "____ nb_elem_std_ " << finl;
55 os << nb_elem_std_ << finl;
56 os << "____ volumes_entrelaces_ " << finl;
57 volumes_entrelaces_.ecrit(os);
58 os << "____ face_normales_ " << finl;
59 face_normales_.ecrit(os);
60 os << "____ facette_normales_ " << finl;
61 facette_normales_.ecrit(os);
62 os << "____ nb_faces_std_ " << finl;
63 os << nb_faces_std_ << finl;
64 os << "____ rang_elem_non_std_ " << finl;
65 rang_elem_non_std_.ecrit(os);
66 return os;
67}
68
70{
72
73 os << h_carre << finl;
74 os << type_elem_.valeur() << finl;
75 os << nb_elem_std_ << finl;
76 os << volumes_entrelaces_ << finl;
77 os << face_normales_ << finl;
78 os << facette_normales_ << finl;
79 os << xp_ << finl;
80 os << xv_ << finl;
81 os << nb_faces_std_ << finl;
82 os << rang_elem_non_std_ << finl;
83 return os;
84}
85
87{
89 is >> h_carre;
90
91 /* read type_elem */
92 {
93 Nom type;
94 is >> type;
95 if (type == "Tri_VEF")
96 type_elem_ = Tri_VEF();
97 else if (type == "Tetra_VEF")
98 type_elem_ = Tetra_VEF();
99 else if (type == "Quadri_VEF")
100 type_elem_ = Quadri_VEF();
101 else if (type == "Hexa_VEF")
102 type_elem_ = Hexa_VEF();
103 else
104 {
105 Cerr << type << " is not an Elem_VEF!" << finl;
107 }
108 }
109
110 is >> nb_elem_std_;
112 is >> face_normales_;
113 is >> facette_normales_;
114 is >> xp_;
115 is >> xv_;
116 is >> nb_faces_std_;
117 is >> rang_elem_non_std_;
118 return is;
119}
120
121void exemple_champ_non_homogene(const Domaine_VEF& domaine_VEF, DoubleTab& tab)
122{
123 const DoubleTab& xp = domaine_VEF.xp();
124 const Domaine& domaine=domaine_VEF.domaine();
125 const DoubleTab& coord=domaine.coord_sommets();
126 const DoubleTab& xa=domaine_VEF.xa();
127 const ArrOfInt& renum_arete_perio=domaine_VEF.get_renum_arete_perio();
128 // Check array xa of edge coordinates
129 if (xa.size_array()) Debog::verifier("xa=",xa);
130 int nb_elem=domaine.nb_elem();
131 int nb_elem_tot=domaine.nb_elem_tot();
132 int nb_som=domaine.nb_som();
133 int nb_som_tot=domaine.nb_som_tot();
134 int nb_aretes=domaine.nb_aretes();
135 for (int I=0 ; I<nb_elem; I++)
136 {
137 tab(I)=(1.1+xp(I,0))*(1.1+2*xp(I,1));
138 if (Objet_U::dimension==3) tab(I)*=(1.1+3*xp(I,2));
139 }
140 for (int I=0; I<nb_som; I++)
141 {
142 tab(nb_elem_tot+I)=(1.1+coord(I,0))*(1.1+2*coord(I,1));
143 if (Objet_U::dimension==3) tab(nb_elem_tot+I)*=(1.1+3*coord(I,2));
144 // Apply periodicity:
145 tab(nb_elem_tot+I)=tab(nb_elem_tot+domaine.get_renum_som_perio(I));
146 }
147
148#ifndef NDEBUG
149 const IntVect& ok_arete = domaine_VEF.get_ok_arete();
150#endif
151 for (int I=0; I<nb_aretes; I++)
152 {
153 tab(nb_elem_tot+nb_som_tot+I)=(1.1+xa(I,0))*(1.1+2*xa(I,1))*(1.1+3*xa(I,2));
154 // Apply periodicity:
155 tab(nb_elem_tot+nb_som_tot+I)=tab[nb_elem_tot+nb_som_tot+renum_arete_perio[I]];
156 // Check ok_arete in passing
157 assert(ok_arete(I)==ok_arete(renum_arete_perio[I]));
158 }
160}
161
162void Domaine_VEF::swap(int fac1, int fac2, int nb_som_faces)
163{
164
165}
166
168{
169 Domaine& domaine_geom = domaine();
170 typer_elem(domaine_geom);
171 Elem_geom_base& elem_geom = domaine_geom.type_elem().valeur();
173
174 // Correction of the face_voisins array:
175 // After Domaine_VF::discretiser(), neighbor elements 0 and 1 of a face
176 // are the same on all processors that own the face.
177 // If the face is virtual and one of its two neighbor elements is
178 // unknown (not in the ghost layer), the neighbor element
179 // is -1. This can be neighbor 0 or neighbor 1.
180 // Correct virtual faces so that if a neighbor element is unknown,
181 // it is neighbor1. Neighbor0 is therefore always valid.
182 {
183 IntTab& face_vois = face_voisins();
184 const int debut = nb_faces();
185 const int fin = nb_faces_tot();
186 for (int i = debut; i < fin; i++)
187 {
188 if (face_voisins(i, 0) == -1)
189 {
190 face_vois(i, 0) = face_vois(i, 1);
191 face_vois(i, 1) = -1;
192 }
193 }
194 }
195
196 // Check coherence between the geometric element and
197 //the discretisation element
198
199 if (sub_type(Tri_VEF, type_elem_.valeur()))
200 {
201 if (!sub_type(Triangle, elem_geom))
202 {
203 Cerr << " The geometric element type " << elem_geom.que_suis_je() << " is incorrect" << finl;
204 Cerr << " Only the Triangle type is compatible with VEF discretization in 2D" << finl;
205 Cerr << " The domain must be triangulated when using the internal mesher";
206 Cerr << " using the instruction: Trianguler nom_dom" << finl;
207 exit();
208 }
209 }
210 else if (sub_type(Tetra_VEF, type_elem_.valeur()))
211 {
212 if (!sub_type(Tetraedre, elem_geom))
213 {
214 Cerr << " The geometric element type " << elem_geom.que_suis_je() << " is incorrect" << finl;
215 Cerr << " Only the Tetraedre type is compatible with VEF discretization in 3D" << finl;
216 Cerr << " The domain must be tetrahedralized when using the internal mesher";
217 Cerr << " using the instruction: Tetraedriser nom_dom" << finl;
218 exit();
219 }
220 }
221
222 else if (sub_type(Quadri_VEF, type_elem_.valeur()))
223 {
224
225 if (!sub_type(Quadrangle_VEF, elem_geom))
226 {
227 Cerr << " The geometric element type " << elem_geom.que_suis_je() << " is incorrect" << finl;
228 exit();
229 }
230 }
231 else if (sub_type(Hexa_VEF, type_elem_.valeur()))
232 {
233
234 if (!sub_type(Hexaedre_VEF, elem_geom))
235 {
236 Cerr << " The geometric element type " << elem_geom.que_suis_je() << " is incorrect" << finl;
237 exit();
238 }
239 }
240
241 // Fill the face_normales_ array;
242 // Note: the face_voisins array is not exactly a distributed array.
243 // A face does not have its two neighbors in the same order on all
244 // processors that own the face.
245 // Therefore the face normal can change direction from one processor
246 // to another, including for joint faces.
247 {
248 const int n = nb_faces();
249 face_normales_.resize(n, dimension);
250 creer_tableau_faces(face_normales_, RESIZE_OPTIONS::NOCOPY_NOINIT);
251 const IntTab& face_som = face_sommets();
252 const IntTab& face_vois = face_voisins();
253 const IntTab& elem_face = elem_faces();
254 type_elem_->creer_face_normales(face_normales_, face_som, face_vois, elem_face, domaine_geom);
255 }
256
257 // Compute facette_normales_
258 type_elem_->creer_facette_normales(*this, rang_elem_non_std());
259
261 Cerr << "Informations of the Domaine VEF of the domain " << domaine().le_nom() << " : " << finl;
262
264
265 domaine().creer_tableau_sommets(volumes_som_, RESIZE_OPTIONS::NOCOPY_NOINIT);
266
267 double coeff=1./3.;
268 if (dimension==3)
269 coeff=1./4.;
270
271 const IntTab& elements = domaine().les_elems();
272 const int nb_som_elem = elements.dimension(1);
273 // Loop over all elements because contributions are added to joint vertices:
274 const int n = nb_elem_tot();
275 // The virtual space of volumes is needed
276 const DoubleVect& volume_elem = volumes();
277 assert_espace_virtuel_vect(volume_elem);
278
279 // Zero out the entire array because += is done on virtual items
280 // (otherwise uninitialized memory is accessed)
281 operator_egal(volumes_som_, 0., VECT_ALL_ITEMS);
282 for(int k=0; k<n; k++)
283 {
284 double volume = coeff * volume_elem(k);
285 for(int isom=0; isom<nb_som_elem; isom++)
286 {
287 int som = elements(k, isom);
288 volumes_som_(som)+=volume;
289 }
290 }
291 volumes_som_.echange_espace_virtuel();
292}
293
295{
296 // Retrieve discretisation parameters
297 alphaE = discr.get_alphaE();
298 alphaS = discr.get_alphaS();
299 alphaA = discr.get_alphaA();
300 alphaRT = discr.get_alphaRT();
301 P1Bulle = discr.get_P1Bulle();
302 modif_div_face_dirichlet= discr.get_modif_div_face_dirichlet();
303 cl_pression_sommet_faible = discr.get_cl_pression_sommet_faible();
304
305
306 if (alphaA)
308
309 // Build the descriptor for p1bulle arrays
310 {
311 MD_Vector_composite md_p1b;
312 if (alphaE)
313 {
314 const MD_Vector& md = domaine().md_vector_elements();
315 md_p1b.add_part(md, 0, "P0");
316 }
317 if (alphaS)
318 {
319 const MD_Vector& md = domaine().md_vector_sommets();
320 md_p1b.add_part(md, 0, "P1");
321 }
322 if (alphaA)
323 {
324 const MD_Vector& md = md_vector_aretes();
325 md_p1b.add_part(md, 0, "Pa");
326 }
327 md_vector_p1b_.copy(md_p1b);
328 }
329 Cerr << "the Domaine_VEF has been filled successfully" << finl;
330}
331
332/*
333 static int arete(const IntTab& som_aretes,
334 const IntTab& aretes_som,
335 int S1, int S2, const Domaine& dom)
336 {
337 //Cout << "S1,S2 = " << S1 << " " << S2 << finl;
338 for(int i=0; i<nb_max_aretes_som; i++)
339 {
340 const int& a=som_aretes(S1,i);
341 if( (dom.get_renum_som_perio(aretes_som(a,0))==S2)
342 ||
343 (dom.get_renum_som_perio(aretes_som(a,1))==S2) )
344 return a;
345 }
346 {
347 Cerr << "arete pas Trouvee!!" << finl;
348 Cout << "S1,S2 = " << S1 << " " << S2 << finl;
349 Cout << "som_aretes " << som_aretes << finl;
350 Cout << "aretes_som " << aretes_som << finl;
351 Process::exit();
352 }
353 return -1;
354 } */
355
356static int next(int S,
357 const ArrOfInt& contenu)
358{
359 int nb_som=contenu.size_array();
360 int i=S+1;
361 while(i<nb_som)
362 if(contenu[i]==1)
363 return i;
364 else i++;
365 i=0;
366 while(i<S)
367 if(contenu[i]==1)
368 return i;
369 else i++;
370 return -1;
371}
372
374{
375 const Domaine& dom = domaine();
376
377 // Create real edges (geometric information built and stored in the domain)
380
381 // Compute edge gravity centers xa_ stored in Domaine_VF
382 const IntTab& aretes_som = domaine().aretes_som();
383 const int nb_aretes = aretes_som.dimension(0);
384 const DoubleTab& coord = dom.les_sommets();
385 const int dim = coord.dimension(1);
386 xa_.resize(0, dim);
387 creer_tableau_aretes(xa_, RESIZE_OPTIONS::NOCOPY_NOINIT);
388 for (int i = 0; i < nb_aretes; i++)
389 {
390 const int s0 = aretes_som(i, 0);
391 const int s1 = aretes_som(i, 1);
392 for (int j = 0; j < dim; j++)
393 xa_(i, j) = (coord(s0, j) + coord(s1, j)) * 0.5;
394 }
395 xa_.echange_espace_virtuel();
396
397 const IntTab& elem_aretes = domaine().elem_aretes();
398
399 // Compute edge volumes
400 // Create an array initialised to zero:
401 creer_tableau_aretes(volumes_aretes);
402
403 const int nbr_elem = domaine().nb_elem();
404 const int nb_aretes_elem = elem_aretes.dimension(1);
405 // factor 6 for edge volume computation, is this correct for elements other than tetra?
406 assert(nb_aretes_elem == 6);
407 // Alternative approach: compute contributions to edges from real elements,
408 // then sum contributions of shared edges:
409 for (int elem = 0; elem < nbr_elem; elem++)
410 {
411 double vol = volumes(elem) / 6.0;
412 for(int j = 0; j < nb_aretes_elem; j++)
413 {
414 int arete = elem_aretes(elem, j);
415 volumes_aretes[arete] += vol;
416 }
417 }
418 // Sum joint edge contributions and exchange virtual spaces
420}
421
423{
424 Cerr << "Build array ok_arete..." << finl;
425 const Domaine& dom=domaine();
426 const IntTab& aretes_som=domaine().aretes_som();
427 const int nb_som_reel=nb_som();
428
429 // Vertex-to-edge connectivity (for each vertex, list of adjacent edges)
430 // B.M.: replacing IntTab(n, 64) with a Static_Int_List, reusing
431 // the connectivity computation method... more memory efficient!
432 // som_aretes contains a modified connectivity for periodic vertices
433 // (edges are always attached to get_renum_som_perio() vertex,
434 // opposite periodic edges are replaced by a fictitious edge [nb_som_reel,nb_som_reel],
435 // and opposite periodic vertices are not attached to any edge)
436 const int nb_aretes = aretes_som.dimension(0);
437 Static_Int_Lists som_aretes;
438 {
439 // Create an edge array where vertices are replaced by their periodic counterpart
440 // and without the opposite periodic edges
441 IntTab aretes_som2;
442 aretes_som2.copy(aretes_som, RESIZE_OPTIONS::NOCOPY_NOINIT);
443
444 for (int i = 0; i < nb_aretes; i++)
445 {
446 if (renum_arete_perio[i] == i)
447 {
448 aretes_som2(i, 0) = dom.get_renum_som_perio(aretes_som(i,0));
449 aretes_som2(i, 1) = dom.get_renum_som_perio(aretes_som(i,1));
450 }
451 else
452 {
453 // opposite periodic edge, not retained; create a fictitious edge for
454 // construire_connectivite_som_elem: vertex with index nb_som_reel
455 // will be connected to all suppressed periodic edges
456 aretes_som2(i, 0) = nb_som_reel;
457 aretes_som2(i, 1) = nb_som_reel;
458 }
459 }
460 // Add one extra vertex (the fictitious vertex connected to suppressed edges)
461 construire_connectivite_som_elem(nb_som_reel+1, aretes_som2, som_aretes, 0 /* do not include virtual items */);
462 }
463
464 // Create and initialise array contenu, initialised to zero by default
465 ArrOfInt contenu(nb_som_reel);
466
467 // Parallel initialisation: contenu is set to 2
468 // for shared vertices received from another processor
469 {
470 ArrOfBit flags;
472 for (int i = 0; i < nb_som_reel; i++)
473 {
474 if (!flags[i])
475 {
476 // This vertex is received from another processor
477 const int i2 = dom.get_renum_som_perio(i);
478 contenu[i] = 2;
479 if (i2 != i)
480 contenu[i2] = 2;
481 }
482 }
483 }
484
485 // Estimate the number of superfluous edges to find on the domain
486 // by counting real non-periodic vertices whose contenu equals 0
487 int nombre_aretes_superflues_prevues_sur_le_dom=0;
488 for (int i=0; i<nb_som_reel; i++)
489 if (i==dom.get_renum_som_perio(i) && contenu[i]==0)
490 nombre_aretes_superflues_prevues_sur_le_dom++;
491
492 ok_arete = -1;
493
494 // Loop while there are vertices with contenu == 0
495 while (min_array(contenu)==0)
496 {
497 // Find the first vertex with contenu == 0 by looping over edges
498 int Aroot=-1,Sroot=-1;
499 int S0,S1;
500 do
501 {
502 while (ok_arete(++Aroot)==0) {};
503 S0=dom.get_renum_som_perio(aretes_som(Aroot,0));
504 S1=dom.get_renum_som_perio(aretes_som(Aroot,1));
505 }
506 while (Aroot<nb_aretes && contenu[S0]!=0 && contenu[S1]!=0);
507
508 assert(Aroot<nb_aretes);
509
510 Aroot=renum_arete_perio[Aroot];
511
512 ok_arete(Aroot)=0; // lockee
513 if (!contenu[S0])
514 {
515 contenu[S0]=1;
516 Sroot=S0;
517 }
518 else if (!contenu[S1])
519 {
520 contenu[S1]=1;
521 Sroot=S1;
522 }
523
524 // Loop over vertices
525 do
526 {
527 const int nb_aretes_voisines = som_aretes.get_list_size(Sroot);
528 for(int i=0; i<nb_aretes_voisines; i++)
529 {
530 int A=renum_arete_perio[som_aretes(Sroot,i)];
531 if(ok_arete(A)==-1)
532 {
533 int S=dom.get_renum_som_perio(aretes_som(A,0));
534 if(S==Sroot)
535 {
536 S=dom.get_renum_som_perio(aretes_som(A,1));
537 }
538 if(!contenu[S])
539 {
540 ok_arete(A)=0; // lockee
541 contenu[S]=1;
542 }
543 else
544 {
545 ok_arete(A)=1; // libre
546 }
547 }
548 }
549 contenu[Sroot]=2;
550 }
551 while((Sroot=next(Sroot, contenu))!=-1);
552
553 // Correction of ok_arete and contenu arrays for periodicity
554 for(int i=0; i<nb_aretes; i++)
555 ok_arete(i)=ok_arete[renum_arete_perio[i]];
556 for(int i=0; i<nb_som_reel; i++)
557 contenu[i]=contenu[dom.get_renum_som_perio(i)];
558 }
559
560 // Update virtual parts of the ok_arete array
561 ok_arete.echange_espace_virtuel();
562
563 // Check superfluous edges
564 verifie_ok_arete(nombre_aretes_superflues_prevues_sur_le_dom);
565
566 // Write superfluous edges to file nom_du_cas.ok_arete to be read next time
567 Nom fichier(nom_du_cas());
568 fichier+="_";
569 fichier+=domaine().le_nom()+".ok_arete";
570
571 Cerr << "Writing file " << fichier << finl;
572 EcrFicPartageBin fic_ok_arete_;
573 if (!fic_ok_arete_.ouvrir(fichier,ios::out))
574 {
575 Cerr << "Error: cannot open file " << fichier << " for writing." << finl;
576 exit();
577 }
578
579 ArrOfBit marqueurs_aretes;
580 const MD_Vector& md_aretes = md_vector_aretes();
581 md_aretes->get_sequential_items_flags(marqueurs_aretes);
582 const trustIdType nb_aretes_seq = md_aretes->nb_items_seq_tot();
583
585 fic_ok_arete_ << nb_aretes_seq << finl;
586
587 // Each processor writes its non-shared edges:
588 const int n = marqueurs_aretes.size_array();
589 for (int i = 0; i < n; i++)
590 {
591 if (marqueurs_aretes[i])
592 fic_ok_arete_ << xa_(i,0) << tspace << xa_(i,1) << tspace << xa_(i,2) << tspace << ok_arete(i) << finl;
593 }
594 fic_ok_arete_.syncfile();
595 fic_ok_arete_.close();
596}
597
599{
600 Cerr << "Build array renum_arete_perio..." << finl;
601 const IntTab& aretes_som=domaine().aretes_som();
602 const int nb_aretes_tot = static_cast<int>(domaine().nb_aretes_tot()); // domain is already discretised, so already split, so we're just working with a small part
603 const Domaine& dom=domaine();
604
605 // Initialise renum_arete_perio
606 renum_arete_perio.resize_array(nb_aretes_tot);
607 for (int i=0; i<nb_aretes_tot; i++)
608 renum_arete_perio[i]=i;
609
610 const IntTab& elem_aretes=domaine().elem_aretes();
611 ArrOfInt aretes1(6);
612 ArrOfInt aretes2(6);
613 // First step: make all periodic edges linked together point to the same edge
614 for (auto& itr : conds_lim)
615 {
616 //for cl
617
618 const Cond_lim_base& cl = itr.valeur();
619 if (sub_type(Periodique, cl))
620 {
621 //if Perio
622 const Periodique& la_cl_perio = ref_cast(Periodique,cl);
623 const Front_VF& le_bord = ref_cast(Front_VF,cl.frontiere_dis());
624
625 int nf_bord_tot = le_bord.nb_faces_tot();
626 IntVect fait(nf_bord_tot);
627 fait = 0;
628 for(int ind_face=0; ind_face<nf_bord_tot; ind_face++)
629 if(!fait(ind_face))
630 {
631 int face=le_bord.num_face(ind_face);
632 int ind_faassociee=la_cl_perio.face_associee(ind_face);
633 int face_assciee=le_bord.num_face(ind_faassociee);
634 fait(ind_faassociee)=fait(ind_face)=1;
635
636 int elem1 = face_voisins_(face,0);
637 int elem2 = face_voisins_(face,1);
638
639 for(int j=0; j<6; j++)
640 {
641 aretes1[j]=elem_aretes(elem1,j);
642 aretes2[j]=elem_aretes(elem2,j);
643 }
644
645 for(int j1=0; j1<6; j1++)
646 {
647 int ar1=aretes1[j1];
648 int& ar1_perio = renum_arete_perio[ar1];
649 // Check that the edge belongs to the face (ok==2)
650 int som11=aretes_som(ar1, 0);
651 int som12=aretes_som(ar1, 1);
652 int ok=0;
653 int nbf = domaine().type_elem()->nb_som_face();
654 const IntTab& sommet = face_sommets();
655 for (int k=0; k<nbf; k++)
656 if (sommet(face,k)==som11 || sommet(face,k)==som12) ok++;
657 assert(ok>0);
658 if (ok==2)
659 {
660 int s11=dom.get_renum_som_perio(som11);
661 int s12=dom.get_renum_som_perio(som12);
662 for(int j2=0; j2<6; j2++)
663 {
664 int ar2=aretes2[j2];
665 int& ar2_perio = renum_arete_perio[ar2];
666 int som21=aretes_som(ar2, 0);
667 int som22=aretes_som(ar2, 1);
668 ok=0;
669 // Check that the edge belongs to face_assciee (ok==2)
670 for (int k=0; k<nbf; k++)
671 if (sommet(face_assciee,k)==som21 || sommet(face_assciee,k)==som22) ok++;
672 assert(ok>0);
673 if (ok==2)
674 {
675 int s21=dom.get_renum_som_perio(som21);
676 int s22=dom.get_renum_som_perio(som22);
677 assert(ar1!=ar2);
678 //The edges are therefore periodic if we enter the "if"
679 if ( ( (s21==s11)||(s22==s11) ) && ( (s22==s12)||(s21==s12) ) )
680 {
681 // Criterion I: choose the periodic edge based on a geometric criterion
682 int dir_perio = la_cl_perio.direction_periodicite();
683 int arete_perio = (xa(ar1_perio,dir_perio)<=xa(ar2_perio,dir_perio)) ? ar1_perio : ar2_perio;
684 /*
685 // Criterion II: choose the periodic edge based on periodic vertices
686 int arete_perio;
687 if (som11!=s11 && som12!=s12) // Vertices of edge 1 are periodic
688 arete_perio = ar2_perio;
689 else if (som21!=s21 && som22!=s22) // Vertices of edge 2 are periodic
690 arete_perio = ar1_perio;
691 else
692 {
693 Cerr << "Cas non prevu." << finl;
694 exit();
695 } */
696 ar2_perio = arete_perio;
697 ar1_perio = arete_perio;
698 volumes_aretes(ar2)+=volumes_aretes(ar1);
699 volumes_aretes(ar1)+=volumes_aretes(ar2);
700 }//end if "s21==s11"
701 }
702 }//end for "j2"
703 }
704 }//end if "renum_arete_perio(aretes1)" and end for "j1"
705 }//end if "fait"
706 }//end if Perio
707 }// end for cl
708
709 // Second step: make all periodic edges linked together point to the same edge
710 for (int i = 0; i < nb_aretes_tot; i++)
711 {
712 int j = renum_arete_perio[i];
713 // Traverse linked edges for this chain:
714 while (j != renum_arete_perio[j])
715 j = renum_arete_perio[j];
716 renum_arete_perio[i] = j;
717 }
718
719 if (Debog::active())
720 {
721 IntVect tmp;
722 creer_tableau_aretes(tmp, RESIZE_OPTIONS::NOCOPY_NOINIT);
723 const int n = tmp.size_array();
724 for (int i=0; i<n; i++)
725 tmp[i] = renum_arete_perio[i];
726 Debog::verifier_indices_items("renum_arete_perio",tmp.get_md_vector(),tmp);
727 }
728}
729
730void Domaine_VEF::verifie_ok_arete(int nombre_aretes_superflues_prevues_sur_le_dom) const
731{
732 Cerr << "Check array ok_arete..." << finl;
733 // Algorithm to verify the superfluous edge array
734 // ok_arete(i)==0 : edge i is superfluous
735 // ok_arete(i)==2 : edge i is necessary
736 // ...
737 // contenu must contain only 2, meaning all vertices have been analysed.
738 const Domaine& dom=domaine();
739 const int nb_som_reel=nb_som();
740 const IntTab& aretes_som=domaine().aretes_som();
741 int nb_aretes_pour_verbose=60; // for verbose output
742 ArrOfInt sommet_relie_arete_superflue(nb_som_reel);
743 sommet_relie_arete_superflue=0;
744 for (int i=0; i<nb_som_reel; i++) // If i is a periodic vertex:
745 if (dom.get_renum_som_perio(i)!=i) // it suffices to verify on vertex dom.get_renum_som_perio(i)
746 sommet_relie_arete_superflue[i]=1; // so we skip i
747
748 double nombre_aretes_reelles_superflues=0;
749 // Traverse all edges but only consider real vertices
750 int nb_aretes_tot=domaine().nb_aretes_tot();
751 int nb_aretes_reelles=domaine().nb_aretes();
752 for (int i=0; i<nb_aretes_tot; i++)
753 {
754 if (!ok_arete(i)) // arete superflue
755 {
756 int S0=aretes_som(i,0);
757 if (S0<nb_som_reel)
758 {
759 sommet_relie_arete_superflue[S0]=1;
760 sommet_relie_arete_superflue[dom.get_renum_som_perio(S0)]=1;
761 }
762 int S1=aretes_som(i,1);
763 if (S1<nb_som_reel)
764 {
765 sommet_relie_arete_superflue[S1]=1;
766 sommet_relie_arete_superflue[dom.get_renum_som_perio(S1)]=1;
767 }
768 if (renum_arete_perio[i]==i) // Count periodic edges only once
769 {
770 if (nb_aretes_tot<nb_aretes_pour_verbose)
771 {
772 if (renum_arete_perio[i]==i) Cerr << "[" << Process::me() << "] Arete " << i << " superflue non perio: " << S0 << " " << S1 << finl;
773 else Cerr << "[" << Process::me() << "] Arete " << i << " superflue perio: " << S0 << " " << S1 << " Periodique avec " << renum_arete_perio[i] << finl;
774 }
775 int aretes_superflues_communes=1;
776 // If the superfluous edge is shared, account for it
777 for (int j=0; j<dom.faces_joint().size(); j++)
778 {
779 int nb_aretes_sur_le_joint = dom.faces_joint()(j).joint_item(JOINT_ITEM::ARETE).items_communs().size_array();
780 for (int k=0; k<nb_aretes_sur_le_joint; k++)
781 if (dom.faces_joint()(j).joint_item(JOINT_ITEM::ARETE).items_communs()[k]==i) aretes_superflues_communes++;
782 }
783 // Count real superfluous edges
784 if (i<nb_aretes_reelles)
785 nombre_aretes_reelles_superflues+=1./aretes_superflues_communes;
786 }
787 }
788 }
789
790 if (nb_som_reel > 0 && min_array(sommet_relie_arete_superflue)==0)
791 {
792 Cerr << finl << "[" << Process::me() << "] There is at least one vertex not linked to a redundant edge:" << finl;
793 for (int i=0; i<sommet_relie_arete_superflue.size_array(); i++)
794 if (sommet_relie_arete_superflue[i]==0) Cerr << "Vertex " << i << finl;
796 }
797 Cerr << "[" << Process::me() << "] Verification that each non-periodic vertex is linked to at least one redundant edge: OK!" << finl;
798 // Count the total number of vertices accounting for periodicity and shared vertices
799 double nb_sommets_non_periodiques=0;
800 for (int i=0; i<nb_som_reel; i++)
801 if (dom.get_renum_som_perio(i)==i) // Non-periodic vertex
802 {
803 int sommets_communs=1;
804 // Account for shared vertices
805 for (int j=0; j<dom.faces_joint().size(); j++)
806 for (int k=0; k<dom.faces_joint()(j).joint_item(JOINT_ITEM::SOMMET).items_communs().size_array(); k++)
807 if (dom.faces_joint()(j).joint_item(JOINT_ITEM::SOMMET).items_communs()[k]==i) sommets_communs++;
808 nb_sommets_non_periodiques+=1./sommets_communs;
809 }
810 double total_nombre_aretes_superflues = mp_sum(nombre_aretes_reelles_superflues);
811 double somme_nombre_aretes_superflues_prevues_par_domaine = mp_sum_as_double(nombre_aretes_superflues_prevues_sur_le_dom);
812 double total_nb_sommets_non_periodiques = mp_sum(nb_sommets_non_periodiques);
813
814
815 // Cerr << "Nombre de sommets non periodiques = " << total_nb_sommets_non_periodiques << finl;
816 // Cerr << "Nombre de sommets periodiques = " << nb_som_reel-total_nb_sommets_non_periodiques << finl;
817 //int nb_aretes_periodiques=0;
818 //int nb_aretes_perio_superflues=0;
819 for (int i=0; i<nb_aretes_tot; i++)
820 {
821 if (renum_arete_perio[i]!=i)
822 {
823 //nb_aretes_periodiques++;
824 assert(ok_arete(i)==ok_arete(renum_arete_perio[i]));
825 //if (!ok_arete(i)) nb_aretes_perio_superflues++;
826 }
827 }
828 // Cerr << "Number of non-periodic edges = " << nb_aretes_tot-nb_aretes_periodiques << finl;
829 // Cerr << "Number of periodic edges = " << nb_aretes_periodiques << finl;
830
831 // Cerr << "Number of redundant edges = " << total_nombre_aretes_superflues << finl;
832 // Cerr << "Number of periodic redundant edges = " << nb_aretes_perio_superflues << finl;
833 // Cerr << "Number of non-redundant periodic edges = " << nb_aretes_periodiques-nb_aretes_perio_superflues << finl;
834
835 if (Process::is_sequential()) // Limited to sequential because there is an issue with computing total_nombre_aretes_superflues (common items for edges are not yet built!)
836 if (!est_egal(somme_nombre_aretes_superflues_prevues_par_domaine,total_nombre_aretes_superflues) && je_suis_maitre())
837 {
838 Cerr << "The sum of redundant edges predicted per domain is not equal to the number of redundant edges found on the domain." << finl;
839 Cerr << somme_nombre_aretes_superflues_prevues_par_domaine << " != " << total_nombre_aretes_superflues << finl;
841 }
842 Cerr << "Total number of redundant edges: " << somme_nombre_aretes_superflues_prevues_par_domaine << finl;
843 Cerr << "Total number of non-periodic vertices = " << total_nb_sommets_non_periodiques << finl;
844 Cerr << "Verifying equality between total number of redundant edges and total number of vertices: ";
845 // Verify that the number of redundant edges equals the number of vertices
846 if (!est_egal(somme_nombre_aretes_superflues_prevues_par_domaine,total_nb_sommets_non_periodiques) && je_suis_maitre())
847 {
848 Cerr << "Mismatch. Failure of the redundant edge search algorithm." << finl;
850 }
851 Cerr << "OK!" << finl << "Redundant edge verification correct." << finl;
852}
853
854// Return value:
855// 1: ok
856// 0: file does not exist
857// -1: file exists but wrong number of edges
859{
860 Nom fichier(nom_du_cas());
861 fichier+="_";
862 fichier+=domaine().le_nom()+".ok_arete";
863
864 Cerr << "Trying to read file " << fichier << " (edges to remove from the set of degrees of freedom)" << finl;
865 EFichierBin fic_ok_arete_;
866 // Read ok_arete from file for sequential-parallel comparison
867 if (!fic_ok_arete_.ouvrir(fichier,ios::out))
868 {
869 Cerr << "File " << fichier << " does not exist." << finl;
870 return 0;
871 }
872
873 int n;
874 fic_ok_arete_ >> n;
875 if (n != md_vector_aretes()->nb_items_seq_tot())
876 {
877 Cerr << "File " << fichier << " is not compatible with the current mesh." << finl;
878 return 0;
879 }
880
881 Octree_Double octree;
882 octree.build_nodes(xa_, 1 /* include virtual nodes */);
883 const double eps = precision_geom;
884 ArrOfInt liste_aretes;
885
886
887 IntVect marqueurs;
888 creer_tableau_aretes(marqueurs); // initialised to zero by default
889
890 for (int i = 0; i < n; i++)
891 {
892 double x, y, z;
893 int flag;
894 fic_ok_arete_ >> x >> y >> z >> flag;
895 octree.search_elements_box(x-eps, y-eps, z-eps, x+eps, y+eps, z+eps, liste_aretes);
896 octree.search_nodes_close_to(x, y, z, xa_, liste_aretes, eps);
897 const int m = liste_aretes.size_array();
898 if (m > 1)
899 {
900 Cerr << "File " << fichier << " is not compatible with the current mesh." << finl;
901 return 0;
902 }
903 if (m == 1)
904 {
905 const int arete = liste_aretes[0];
906 ok_arete[arete] = flag;
907 marqueurs[arete]++;
908 }
909 else
910 {
911 // Normal in parallel: not all edges are available on all processors...
912 }
913 }
914
915 // Each edge must have been found exactly once:
916 if (max_array(marqueurs) > 1 || min_array(marqueurs) < 1)
917 {
918 Cerr << "File " << fichier << " is not compatible with the current mesh." << finl;
919 return 0;
920 }
921 else
922 Cerr << "File " << fichier << " is OK." << finl;
923 fic_ok_arete_.close();
924 assert_espace_virtuel_vect(ok_arete);
925
926 return 1;
927}
928
929void Domaine_VEF::creer_tableau_p1bulle(Array_base& x, RESIZE_OPTIONS opt) const
930{
931 const MD_Vector& md = md_vector_p1b();
933}
934
936{
937 const int nbe = nb_elem();
938 // Compute h_carre
939 h_carre = 1.e30;
940 h_carre_.resize(nbe);
941 // Compute face surfaces
942 const int nb_faces_elem = domaine().nb_faces_elem();
943 CDoubleArrView face_surfaces_v = face_surfaces().view_ro();
944 CDoubleArrView volumes_v = volumes().view_ro();
945 CIntTabView elem_faces_v = elem_faces().view_ro();
946 DoubleArrView h_carre_v = h_carre_.view_rw();
947 Kokkos::parallel_reduce(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nbe),
948 KOKKOS_LAMBDA(const int num_elem, double& h_carre_local)
949 {
950 double surf_max = 0;
951 for (int i = 0; i < nb_faces_elem; i++)
952 {
953 double surf = face_surfaces_v(elem_faces_v(num_elem, i));
954 surf_max = (surf > surf_max) ? surf : surf_max;
955 }
956 double vol = volumes_v(num_elem) / surf_max;
957 vol *= vol;
958 h_carre_v(num_elem) = vol;
959 if (vol < h_carre_local) h_carre_local = vol;
960 }, Kokkos::Min<double>(h_carre));
961 end_gpu_timer(__KERNEL_NAME__);
962 h_carre = mp_min(h_carre);
963 Cerr << "Lowest cell size h=(Volume/max(Surface))= " << sqrt(h_carre) << finl;
964 double moyenne = 0.;
965 Kokkos::parallel_reduce(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nbe),
966 KOKKOS_LAMBDA(const int i, double& sum)
967 {
968 sum += h_carre_v(i);
969 }, moyenne);
970 end_gpu_timer(__KERNEL_NAME__);
971 moyenne = mp_sum(moyenne);
972 double h_carre_moyen = moyenne / mp_sum((double) nbe);
973 Cerr << "Average cell size <h>= " << sqrt(h_carre_moyen) << finl;
974 if (h_carre * 1e6 < h_carre_moyen)
975 Cerr << "Warning, a cell size is more than 1000 times smaller than the average cell size of the domain. Check your mesh." << finl;
976 Cerr << "==============================================" << finl;
977}
978
980{
981 // Cerr << "face normals " << face_normales() << finl;
982 // Compute interlaced volumes;
983
984 // For a dynamic domain, the array may or may not already have the correct structure.
985 // If not deformable, this function should not be called twice.
986 assert(domaine().deformable() || !(volumes_entrelaces_.get_md_vector()));
987 if (!(volumes_entrelaces_.get_md_vector() == md_vector_faces()))
988 {
989 volumes_entrelaces_.reset();
990 creer_tableau_faces(volumes_entrelaces_, RESIZE_OPTIONS::NOCOPY_NOINIT);
991 }
992 int nb_faces_elem = domaine().nb_faces_elem();
993 int num_face;
994 int nmax = premiere_face_int();
995 const double facteur = 1. / nb_faces_elem;
996 for (num_face = 0; num_face < nmax; num_face++)
997 {
998 int elem1 = face_voisins_(num_face, 0);
999 volumes_entrelaces_[num_face] = volumes(elem1) * facteur;
1000 }
1001 nmax = nb_faces();
1002 for (; num_face < nmax; num_face++)
1003 {
1004 int elem1 = face_voisins_(num_face, 0);
1005 int elem2 = face_voisins_(num_face, 1);
1006 volumes_entrelaces_[num_face] = (volumes(elem1) + volumes(elem2)) * facteur;
1007 }
1008 volumes_entrelaces_.echange_espace_virtuel();
1009}
1010
1012{
1013 Journal() << "Domaine_VEF::Modifier_pour_Cl" << finl;
1014 for (auto &itr : conds_lim)
1015 {
1016 const Cond_lim_base& cl = itr.valeur();
1017 if (sub_type(Periodique, cl))
1018 {
1019 const Periodique& la_cl_period = ref_cast(Periodique, cl);
1020 int nb_faces_elem = domaine().nb_faces_elem();
1021 const Front_VF& la_front_dis = ref_cast(Front_VF, cl.frontiere_dis());
1022 // Modification of arrays face_voisins_, face_normales_, volumes_entrelaces_
1023 // Orient certain normals so that normals at periodic faces point
1024 // from face_voisins(face,0) to face_voisins(face,1),
1025 // consistent with internal faces
1026 ToDo_Kokkos("critical");
1027 for (int ind_face = 0; ind_face < la_front_dis.nb_faces_tot(); ind_face++)
1028 {
1029 int face = la_front_dis.num_face(ind_face);
1030 if ((face_voisins_(face, 0) == -1) || (face_voisins_(face, 1) == -1))
1031 {
1032 int faassociee = la_front_dis.num_face(la_cl_period.face_associee(ind_face));
1033 int elem1 = face_voisins_(face, 0);
1034 int elem2 = face_voisins_(faassociee, 0);
1035 double vol = (volumes(elem1) + volumes(elem2)) / nb_faces_elem;
1036 volumes_entrelaces_[face] = vol;
1037 volumes_entrelaces_[faassociee] = vol;
1038 face_voisins_(face, 1) = elem2;
1039 face_voisins_(faassociee, 0) = elem1;
1040 face_voisins_(faassociee, 1) = elem2;
1041 double psc = 0;
1042 for (int k = 0; k < dimension; k++)
1043 psc += face_normales_(face, k) * (xv_(face, k) - xp_(face_voisins_(face, 0), k));
1044
1045 if (psc < 0)
1046 for (int k = 0; k < dimension; k++)
1047 face_normales_(face, k) *= -1;
1048
1049 for (int k = 0; k < dimension; k++)
1050 face_normales_(faassociee, k) = face_normales_(face, k);
1051 }
1052 }
1053 }
1054 }
1055
1056 // PQ: 10/10/05: periodic faces having double contribution,
1057 // marquer_faces_double_contrib is called in this method
1058 // to be able to use conds_lim.
1060 // Build array num_fac_loc_
1062
1063 static DoubleVect* ptr=0;
1064 if(ptr!=&volumes_som_)
1065 {
1066 const Domaine& dom=domaine();
1067 const int ns = nb_som();
1068 CIntArrView renum_som_perio = dom.get_renum_som_perio().view_ro();
1069 DoubleArrView volumes_som = volumes_som_.view_rw();
1070 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, ns), KOKKOS_LAMBDA(const int i)
1071 {
1072 int j = renum_som_perio(i);
1073 if (i != j)
1074 Kokkos::atomic_add(&volumes_som(j), volumes_som(i));
1075 });
1076 end_gpu_timer(__KERNEL_NAME__);
1077 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, ns), KOKKOS_LAMBDA(const int i)
1078 {
1079 int j = renum_som_perio(i);
1080 if (i != j)
1081 volumes_som(i) = volumes_som(j);
1082 });
1083 end_gpu_timer(__KERNEL_NAME__);
1084 volumes_som_.echange_espace_virtuel();
1085 ptr = &volumes_som_;
1086 }
1087
1088 // Check array renum_som_perio
1089 if (Debog::active())
1090 {
1091 IntVect tmp;
1092 const Domaine& dom = domaine();
1093 dom.creer_tableau_sommets(tmp, RESIZE_OPTIONS::NOCOPY_NOINIT);
1094 const int n = tmp.size_array();
1095 for (int i=0; i<n; i++)
1096 tmp[i] = dom.get_renum_som_perio(i);
1097 Debog::verifier_indices_items("renum_som_perio",tmp.get_md_vector(),tmp);
1098 }
1099
1100 if(get_alphaA())
1101 {
1102 // Build renum_arete_perio
1104
1105 // Create a distributed array for ok_arete
1106 creer_tableau_aretes(ok_arete, RESIZE_OPTIONS::NOCOPY_NOINIT);
1107
1108 // If P1, find superfluous edges:
1109 if (get_alphaS())
1110 {
1111 // Try to read a .ok_arete file from a previous calculation
1112 // If it does not exist or is inconsistent with the mesh, rebuild ok_arete
1113 if (!lecture_ok_arete())
1115 }
1116 else
1117 {
1118 // All edges are necessary if no P1 support
1119 ok_arete=1;
1120 }
1121 Debog::verifier_getref("ok_arete", ok_arete, ok_arete);
1122
1123 //Debog::verifier("ok_arete (identical only if ok_arete re-read from the .ok_arete file):",ok_arete);
1124 }// end if 3D
1125}
1126
1127void Domaine_VEF::typer_elem(Domaine& domaine_geom)
1128{
1129 const Elem_geom_base& elem_geom = domaine_geom.type_elem().valeur();
1130 if (sub_type(Rectangle, elem_geom))
1131 domaine_geom.typer("Quadrangle");
1132 else if (sub_type(Hexaedre, elem_geom))
1133 domaine_geom.typer("Hexaedre_VEF");
1134
1135 const Nom& type_elem_geom = domaine_geom.type_elem()->que_suis_je();
1136
1137 if (Motcle(type_elem_geom) != "Segment")
1138 {
1139 Nom type;
1140 if (type_elem_geom == "Triangle")
1141 type = "Tri_VEF";
1142 else if (type_elem_geom == "Tetraedre")
1143 type = "Tetra_VEF";
1144 else if (type_elem_geom == "Quadrangle")
1145 type = "Quadri_VEF";
1146 else if (type_elem_geom == "Hexaedre_VEF")
1147 type = "Hexa_VEF";
1148 else
1149 {
1150 Cerr << "typing problem in Elem_VEF::typer" << finl;
1151 Process::exit();
1152 }
1153 type_elem_.typer(type);
1154 }
1155}
1156
1158{
1159 // Build if size is zero
1160 // or if the mesh is deformable
1161 if (vecteur_face_facette_.size() == 0 || domaine().deformable())
1162 {
1163 // Size 8*n*4*3*2=192n
1164 const int nfa7 = type_elem().nb_facette();
1165 const int nb_poly_tot = nb_elem_tot();
1166 vecteur_face_facette_.resize(nb_poly_tot, nfa7, dimension, 2);
1167 const IntTab& KEL = type_elem().KEL();
1168 const IntTab& les_Polys = domaine().les_elems();
1169 const DoubleTab& coord = domaine().coord_sommets();
1170 const DoubleTab& xg = xp();
1171 int nb_som_facette=dimension;
1172 for (int poly = 0; poly < nb_poly_tot; poly++)
1173 {
1174 // Loop over facets of the non-standard polyhedron:
1175 for (int fa7 = 0; fa7 < nfa7; fa7++)
1176 {
1177 int num1 = elem_faces(poly, KEL(0, fa7));
1178 int num2 = elem_faces(poly, KEL(1, fa7));
1179
1180 // Compute rx0 and rx1:
1181 for (int i = 0; i < dimension; i++)
1182 {
1183 // Compute the i-th coordinate of the fa7 center
1184 double coord_centre_fa7 = xg(poly, i);
1185 for (int num_som_fa7 = 0; num_som_fa7 < nb_som_facette - 1; num_som_fa7++)
1186 {
1187 int isom_loc = KEL(num_som_fa7 + 2, fa7);
1188 int isom_glob = les_Polys(poly, isom_loc);
1189 coord_centre_fa7 += coord(isom_glob, i);
1190 }
1191 coord_centre_fa7 /= nb_som_facette;
1192 // End compute i-th coordinate of fa7 center
1193 vecteur_face_facette_(poly,fa7,i,0) = coord_centre_fa7 - xv_(num1,i);
1194 vecteur_face_facette_(poly,fa7,i,1) = coord_centre_fa7 - xv_(num2,i);
1195 }
1196 // End of rx0 and rx1 computation
1197 }
1198 }
1199 Cerr << "Build of vecteur_face_facette() size:" << vecteur_face_facette_.size_array() << finl;
1200 }
1201 return vecteur_face_facette_;
1202}
int_t size_array() const
Returns the size of the array in bits.
Definition ArrOfBit.h:45
Empty class used as a base for all the arrays.
Definition Array_base.h:41
class Cond_lim_base Base class for the hierarchy of classes that represent the different boundary con...
virtual Frontiere_dis_base & frontiere_dis()
Returns the discretized boundary to which the boundary conditions apply.
class Conds_lim This class represents a vector of boundary conditions.
Definition Conds_lim.h:32
static void verifier_indices_items(const char *const msg, const MD_Vector &, const IntVect &)
Tests the content of the vector v assuming it contains item indices associated with the descriptor md...
Definition Debog.cpp:58
static void verifier_getref(const char *const msg, double val, double &refval)
like verifier(), but, in "read&compare" mode, put the reference value found in the file in the ref va...
Definition Debog.cpp:74
static int active()
Returns 1 if we are in Debog mode, 0 otherwise.
Definition Debog.cpp:66
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
int_t nb_aretes_tot() const
returns the total number of edges (real+virtual).
Definition Domaine.h:145
virtual const MD_Vector & md_vector_sommets() const
Definition Domaine.h:369
void creer_aretes()
Definition Domaine.cpp:2118
const IntTab_t & aretes_som() const
returns the connectivity array edges/vertices.
Definition Domaine.h:156
DoubleTab_t & les_sommets()
Definition Domaine.h:113
int_t get_renum_som_perio(int_t i) const
Definition Domaine.h:281
IntTab_t & les_elems()
Definition Domaine.h:129
int_t nb_elem() const
Definition Domaine.h:131
int nb_faces_elem(int=0) const
Returns the number of faces of type i of the geometric elements that make up the domain.
Definition Domaine.h:484
int_t nb_aretes() const
Returns the number of real edges.
Definition Domaine.h:143
void typer(const Nom &)
Sets the element type of the domain using the name passed as parameter.
Definition Domaine.h:457
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
virtual void creer_tableau_sommets(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Creates an array with one "row" per mesh vertex.
Definition Domaine.cpp:999
virtual const MD_Vector & md_vector_elements() const
Returns the parallel descriptor of element arrays of the domain.
Definition Domaine.cpp:859
int_t elem_aretes(int_t i, int j) const
returns the number of the j-th edge of the i-th element.
Definition Domaine.h:154
Joints_t & faces_joint()
Definition Domaine.h:265
class Domaine_VEF
Definition Domaine_VEF.h:53
virtual void creer_tableau_p1bulle(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
void verifie_ok_arete(int) const
void construire_ok_arete()
const IntVect & get_ok_arete() const
Definition Domaine_VEF.h:98
IntVect & rang_elem_non_std()
Definition Domaine_VEF.h:85
void modifier_pour_Cl(const Conds_lim &) override
void swap(int, int, int)
DoubleTab & vecteur_face_facette()
void calculer_volumes_entrelaces()
void calculer_h_carre()
void typer_elem(Domaine &) override
const Elem_VEF_base & type_elem() const
Definition Domaine_VEF.h:74
int lecture_ok_arete()
int get_alphaA() const
Definition Domaine_VEF.h:93
const ArrOfInt & get_renum_arete_perio() const
Definition Domaine_VEF.h:97
virtual void discretiser_suite(const VEF_discretisation &)
void discretiser_arete()
virtual const MD_Vector & md_vector_p1b() const
int get_alphaS() const
Definition Domaine_VEF.h:92
void construire_renum_arete_perio(const Conds_lim &)
void discretiser() override
class Domaine_VF
Definition Domaine_VF.h:44
IntVect rang_elem_non_std_
Definition Domaine_VF.h:252
void creer_tableau_aretes(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
int nb_faces() const
Returns the total number of faces.
Definition Domaine_VF.h:471
DoubleTab xp_
Definition Domaine_VF.h:218
IntTab & face_sommets() override
Returns the face/vertex connectivity array.
Definition Domaine_VF.h:590
DoubleVect volumes_entrelaces_
Definition Domaine_VF.h:210
const MD_Vector & md_vector_faces() const
Definition Domaine_VF.h:158
const MD_Vector & md_vector_aretes() const
Definition Domaine_VF.h:160
DoubleTab xa_
Definition Domaine_VF.h:225
int nb_faces_tot() const
Returns the total number of faces.
Definition Domaine_VF.h:481
double xa(int num_arete, int k) const
Definition Domaine_VF.h:78
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
DoubleTab xv_
Definition Domaine_VF.h:219
int nb_elem_std_
Definition Domaine_VF.h:250
int nb_faces_std_
Definition Domaine_VF.h:251
DoubleTab & xa()
Definition Domaine_VF.h:97
void discretiser() override
Generates the faces and builds the boundaries.
IntTab & elem_faces()
Returns the element/face connectivity array.
Definition Domaine_VF.h:550
IntTab face_voisins_
Definition Domaine_VF.h:216
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
DoubleVect & volumes()
Definition Domaine_VF.h:119
DoubleTab face_normales_
Definition Domaine_VF.h:212
void construire_num_fac_loc()
int premiere_face_int() const
A face is internal if and only if it separates two elements.
Definition Domaine_VF.h:463
MD_Vector md_vector_aretes_
Definition Domaine_VF.h:233
DoubleTab & xp()
Definition Domaine_VF.h:95
IntTab & face_voisins() override
Returns the face-element connectivity array; see above.
Definition Domaine_VF.h:426
void marquer_faces_double_contrib(const Conds_lim &)
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
int nb_elem_tot() const
const Domaine & domaine() const
Reading from a file of objects written in binary format.
Definition EFichierBin.h:30
Writing to a shared file. This class derives from Ecr_Fic_Par, using binary output.
int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out) override
Opens the file with the given mode and prot parameters. These parameters are the parameters of the st...
Sortie & syncfile() override
Triggers writing to disk of the data accumulated on the different processors since the last call to s...
const IntTab & KEL() const
virtual int nb_facette() const =0
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::in)
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Front_VF
Definition Front_VF.h:36
int nb_faces_tot() const
Definition Front_VF.h:58
int num_face(const int) const
Definition Front_VF.h:68
int get_sequential_items_flags(ArrOfBit &flags, int line_size=1) const
virtual trustIdType nb_items_seq_tot() const
Metadata for a distributed composite vector.
void add_part(const MD_Vector &part, int shape=0, Nom name="")
Append the "part" descriptor to the composite vector.
static void creer_tableau_distribue(const MD_Vector &, Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Transforms v into a parallel array having the structure md.
static void echange_espace_virtuel(IntVect &, Operations_echange opt=ECHANGE_EV, IsExchangeBlocking is_exchange_blocking=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
: This class is an OWN_PTR but the pointed object is shared among multiple
Definition MD_Vector.h:48
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
static double precision_geom
Definition Objet_U.h:81
static const Nom & nom_du_cas()
Returns a constant reference to the case name. This method is static.
Definition Objet_U.cpp:145
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
static int_t search_nodes_close_to(double x, double y, double z, const DoubleTab_t &coords, ArrOfInt_t &node_list, double epsilon)
Non-member method. Searches among the vertices in node_list for those within a distance.
void build_nodes(const DoubleTab_t &coords, const bool include_virtual, const double epsilon=0.)
builds an octree containing the points with coordinates coords.
int_t search_elements_box(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, ArrOfInt_t &elements) const
searches for all elements or points potentially having a non-empty intersection with the given box.
class Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
int direction_periodicite() const
static double mp_min(double)
Definition Process.cpp:391
static Sortie & Journal(int message_level=0)
Returns a static Sortie object used as an event journal.
Definition Process.cpp:592
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
Definition Process.cpp:145
static double mp_sum_as_double(int v)
Definition Process.h:97
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
Definition Process.cpp:122
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
static bool is_sequential()
Definition Process.cpp:113
Base class for output streams.
Definition Sortie.h:52
int_t get_list_size(int_t i_liste) const
Returns the number of elements in list i.
_SIZE_ size_array() const
void copy(const TRUSTTab &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:622
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
Definition TRUSTTab.h:261
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
int get_modif_div_face_dirichlet() const
int get_cl_pression_sommet_faible() const