TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Sous_Domaine.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 <LecFicDistribue.h>
17#include <communications.h>
18#include <Synonyme_info.h>
19#include <Sous_Domaine.h>
20#include <Interprete.h>
21#include <Polynome.h>
22#include <Parser_U.h>
23#include <ParserView.h>
24#include <Domaine.h>
25
26Implemente_instanciable_32_64(Sous_Domaine_32_64,"Sous_Domaine",Objet_U);
27Add_synonym(Sous_Domaine, "Sous_Zone");
28// XD sous_zone objet_u sous_zone BRACE It is an object type describing a domain sub-set. NL2 A Sous_Zone (Sub-area)
29// XD_CONT type object must be associated with a Domaine type object. The Read (Lire) interpretor is used to define the
30// XD_CONT items comprising the sub-area. NL2 Caution: The Domain type object nom_domaine must have been meshed (and
31// XD_CONT triangulated or tetrahedralised in VEF) prior to carrying out the Associate (Associer) nom_sous_zone
32// XD_CONT nom_domaine instruction; this instruction must always be preceded by the read instruction.
33// XD attr restriction ref_sous_zone restriction OPT The elements of the sub-area nom_sous_zone must be included into
34// XD_CONT the other sub-area named nom_sous_zone2. This keyword should be used first in the Read keyword.
35// XD attr rectangle bloc_origine_cotes rectangle OPT The sub-area will include all the domain elements whose centre of
36// XD_CONT gravity is within the Rectangle (in dimension 2).
37// XD attr segment bloc_origine_cotes segment OPT not_set
38// XD attr boite bloc_origine_cotes box OPT The sub-area will include all the domain elements whose centre of gravity is
39// XD_CONT within the Box (in dimension 3).
40// XD attr liste listentier liste OPT The sub-area will include n domain items, numbers No. 1 No. i No. n.
41// XD attr fichier chaine filename OPT The sub-area is read into the file filename.
42// XD attr intervalle deuxentiers intervalle OPT The sub-area will include domain items whose number is between n1 and
43// XD_CONT n2 (where n1<=n2).
44// XD attr polynomes bloc_lecture polynomes OPT A REPRENDRE
45// XD attr couronne bloc_couronne couronne OPT In 2D case, to create a couronne.
46// XD attr tube bloc_tube tube OPT In 3D case, to create a tube.
47// XD attr fonction_sous_zone chaine fonction_sous_domaine OPT Keyword to build a sub-area with the the elements
48// XD_CONT included into the area defined by fonction>0.
49// XD attr union ref_sous_zone union_with OPT The elements of the sub-area nom_sous_zone3 will be added to the sub-area
50// XD_CONT nom_sous_zone. This keyword should be used last in the Read keyword.
51// XD ref domaine domaine
52
53// XD bloc_origine_cotes objet_lecture nul NO_BRACE Class to create a rectangle (or a box).
54// XD attr name chaine(into=["Origine"]) name REQ Keyword to define the origin of the rectangle (or the box).
55// XD attr origin listf origine REQ Coordinates of the origin of the rectangle (or the box).
56// XD attr name2 chaine(into=["Cotes"]) name2 REQ Keyword to define the length along the axes.
57// XD attr cotes listf cotes REQ Length along the axes.
58
59// XD bloc_couronne objet_lecture nul NO_BRACE Class to create a couronne (2D).
60// XD attr name chaine(into=["Origine"]) name REQ Keyword to define the center of the circle.
61// XD attr origin listf origine REQ Center of the circle.
62// XD attr name3 chaine(into=["ri"]) name3 REQ Keyword to define the interior radius.
63// XD attr ri floattant ri REQ Interior radius.
64// XD attr name4 chaine(into=["re"]) name4 REQ Keyword to define the exterior radius.
65// XD attr re floattant re REQ Exterior radius.
66
67// XD bloc_tube objet_lecture nul NO_BRACE Class to create a tube (3D).
68// XD attr name chaine(into=["Origine"]) name REQ Keyword to define the center of the tube.
69// XD attr origin listf origine REQ Center of the tube.
70// XD attr name2 chaine(into=["dir"]) name2 REQ Keyword to define the direction of the main axis.
71// XD attr direction chaine(into=["X","Y","Z"]) direction REQ direction of the main axis X, Y or Z
72// XD attr name3 chaine(into=["ri"]) name3 REQ Keyword to define the interior radius.
73// XD attr ri floattant ri REQ Interior radius.
74// XD attr name4 chaine(into=["re"]) name4 REQ Keyword to define the exterior radius.
75// XD attr re floattant re REQ Exterior radius.
76// XD attr name5 chaine(into=["hauteur"]) name5 REQ Keyword to define the heigth of the tube.
77// XD attr h floattant h REQ Heigth of the tube.
78
79
80/*! @brief Ecrit la liste des polyedres de la sous-domaine sur un flot de sortie.
81 *
82 * Format:
83 * Liste n1 n2 .. Ni
84 *
85 * @param (Sortie& os) un flot de sortie
86 * @return (Sortie&) le flot de sortie modifie
87 */
88template <typename _SIZE_>
90{
91 os << "{" << finl;
92 os << "Liste" << finl;
93 os << les_elems_;
94 os << "}" << finl;
95 return os;
96}
97
98
99/*! @brief Lit les specifications d'un sous-domaine dans le jeu de donnee a partir d'un flot d'entree.
100 *
101 * Format:
102 * { Rectangle Origine x0 y0 Cotes lx ly } en dimension 2
103 * { Boite Origine x0 y0 z0 Cotes lx ly lz} en dimension 3
104 * ou
105 * { Liste n n1 ni nn }
106 * ou
107 * { Intervalle n1 n2 }
108 * ou
109 * { Polynomes {bloc_lecture_poly1 et bloc_lecture_poly_i
110 * et bloc_lecture_poly_n}
111 * }
112 *
113 * @param (Entree& is) un flot d'entree
114 * @return (Entree&) le flot d'entree modifie
115 * @throws accolade ouvrante attendue
116 * @throws mot clef non reconnu
117 * @throws mot clef "et" ou "}" attendu
118 * @throws En dimension 2, il faut utiliser Rectangle
119 * @throws mot clef "Origine" attendu
120 * @throws mot clef "Cotes" attendu
121 * @throws En dimension 3, il faut utiliser Boite
122 * @throws Erreur TRUST (mot clef reconnu non prevu)
123 * @throws accolade fermante attendue
124 */
125template <typename _SIZE_>
127{
128 build(is);
129 return is;
130}
131
132template <typename _SIZE_>
134{
135 Motcles les_mots(13);
136 {
137 les_mots[0] = "Liste";
138 les_mots[1] = "Polynomes";
139 les_mots[2] = "Boite";
140 les_mots[3] = "Rectangle";
141 les_mots[4] = "Intervalle";
142 les_mots[5] = "Fichier";
143 les_mots[6] = "Plaque";
144 les_mots[7] = "Segment";
145 les_mots[8] = "Couronne";
146 les_mots[9] = "Tube";
147 les_mots[10]= "Tube_Hexagonal";
148 les_mots[11]= "fonction_sous_zone";
149 les_mots[12]= "fonction_sous_domaine";
150 }
151
152 if (!le_dom_)
153 {
154 Cerr << "You have not associated one of the objects of type Sous_Domaine " << finl;
155 Cerr << "to the object of type Domain " << finl;
157 }
158
159 const Domaine_t& ledomaine=le_dom_.valeur();
160 const Domaine_t& dom=ledomaine;
161 ArrOfInt_t les_polys_possibles_;
162
163 Motcle motlu;
164 is >> motlu;
165 if(motlu != Motcle("{"))
166 {
167 Cerr << "We expected a { to the reading of the subarea" << finl;
168 Cerr << "instead of " << motlu << finl;
170 }
171 is >> motlu;
172
173 using Int_tArrView = View<int_t, 1>; // ToDo report in ViewTypes.h
174 using CInt_tArrView = ConstView<int_t, 1>; // ToDo report in ViewTypes.h
175 using CInt_tTabView = ConstView<int_t, 2>; // ToDo report in ViewTypes.h
176 int_t nb_pol_possible;
177 if (motlu=="restriction")
178 {
179 Nom nom_ss_domaine;
180 is >> nom_ss_domaine;
181 const Sous_Domaine_32_64& ssz=ref_cast(Sous_Domaine_32_64,interprete().objet(nom_ss_domaine));
182 nb_pol_possible=ssz.nb_elem_tot();
183 les_polys_possibles_.resize_array(nb_pol_possible);
184 CInt_tArrView les_elems = ssz.les_elems().view_ro();
185 Int_tArrView les_polys_possibles = les_polys_possibles_.view_wo();
186 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pol_possible, KOKKOS_LAMBDA(const int_t i)
187 {
188 les_polys_possibles(i)=les_elems(i);
189 });
190 end_gpu_timer(__KERNEL_NAME__);
191 is>>motlu;
192 }
193 else
194 {
195 // GF de prendre nb_elem_tot au lieu de nb_elem permet de ne plus avoir besoin de decouper les sous domaines..
196 nb_pol_possible=ledomaine.nb_elem_tot();
197 les_polys_possibles_.resize_array(nb_pol_possible);
198 Int_tArrView les_polys_possibles = les_polys_possibles_.view_wo();
199 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pol_possible, KOKKOS_LAMBDA(const int_t i)
200 {
201 les_polys_possibles(i)=i;
202 });
203 end_gpu_timer(__KERNEL_NAME__);
204 }
205 int rang = les_mots.search(motlu);
206 if (rang==-1)
207 {
208 int ok=lire_motcle_non_standard(motlu,is);
209 if (!ok)
210 {
211 Cerr << motlu << " is not understood " << finl;
212 Cerr << "The understood keywords are " << les_mots;
214 }
215 }
216 if ((rang == 0) && (Process::is_parallel()))
217 {
218 Cerr << "When the subareas are defined as lists of elements" << finl;
219 Cerr << "it is necessary to split them for parallel computing." << finl;
221 }
222 switch(rang)
223 {
224 case 0 :
225 is >> les_elems_;
226 break;
227 case 1 :
228 {
229 Cerr<<"Sous_Domaine_32_64<_SIZE_>::readOn : Reading of the polynomials"<<finl;
230 LIST(Polynome) les_polynomes;
231 is >> motlu;
232 if(motlu!=Motcle("{"))
233 {
234 Cerr << "We expected a { " << finl;
236 }
237 while (1)
238 {
239 Polynome un_poly;
240 is >> un_poly;
241 les_polynomes.add(un_poly);
242 is >> motlu;
243 Motcle Et("et");
244 if(motlu==Motcle("}")) break;
245 if(motlu!=Motcle("et"))
246 {
247 Cerr << "We expected " << Et << " or } " << finl;
249 }
250 }
251 {
252 const Domaine_t& le_dom=le_dom_.valeur();
253 int nbsom=le_dom.nb_som_elem();
254 int_t le_poly;
255 DoubleVect x(dimension);
256 int_t compteur=0;
257
258 les_elems_.resize(nb_pol_possible);
259 ToDo_Kokkos("critical");
260 for (int_t n_pol=0; n_pol<nb_pol_possible; n_pol++)
261 {
262 le_poly=les_polys_possibles_[n_pol];
263 x=0;
264 for(int le_som=0; le_som<nbsom; le_som++)
265 {
266 for(int k=0; k<dimension; k++)
267 x(k)+=dom.coord(ledomaine.sommet_elem(le_poly,le_som),k);
268 }
269 x/=((double)(nbsom));
270 int test = 1;
271 for (auto& itr : les_polynomes)
272 {
273 if (dimension==2)
274 {
275 if (itr(x(0), x(1)) <0) test = -1;
276 }
277
278 if (dimension==3)
279 {
280 if (itr(x(0), x(1),x(2)) <0) test = -1;
281 }
282 }
283
284 if(test > 0)
285 {
286 les_elems_(compteur)=le_poly;
287 compteur++;
288 }
289 }
290 les_elems_.resize(compteur);
291 Cerr << "Construction of the subarea OK" << finl;
292 }
293 break;
294 }
295 case 2 :
296 {
297 // Boite
298 if(dimension!=3)
299 {
300 // Une Boite est un volume
301 Cerr << "In 2 dimensions, you must use \"Rectangle\" " << finl;
303 }
304 is >> motlu;
305 if (motlu != Motcle("Origine"))
306 {
307 Cerr << "We expected the keyword \"Origine\"" << finl;
309 }
310 double deux_pi=M_PI*2.0 ;
311 double ox, oy, oz;
312 is >> ox >> oy >> oz ;
313 is >> motlu;
314 if (motlu != Motcle("Cotes"))
315 {
316 Cerr << "We expected the keyword \"Cotes\"" << finl;
318 }
319 double lx, ly, lz;
320 is >> lx >> ly >>lz;
321 lx+= ox;
322 ly+=oy;
323 lz+=oz;
324 if(axi)
325 {
326 oy*=deux_pi;
327 ly*=deux_pi;
328 }
329 {
330 const Domaine_t& le_dom=le_dom_.valeur();
331 int nbsom=le_dom.nb_som_elem();
332 int_t le_poly;
333 double x, y, z;
334 int_t compteur=0;
335 // int nb_poly=le_dom.nb_elem();
336 Cerr << "Construction of the subarea " << le_nom()<< finl;
337 les_elems_.resize(nb_pol_possible);
338 ToDo_Kokkos("critical");
339 for (int_t n_pol=0; n_pol<nb_pol_possible; n_pol++)
340 {
341 le_poly=les_polys_possibles_[n_pol];
342 x=y=z=0;
343 int nb_som_poly = 0;
344 int_t s;
345 for(int le_som = 0; le_som < nbsom && ((s = ledomaine.sommet_elem(le_poly,le_som)) >= 0); le_som++)
346 {
347 x+=dom.coord(s, 0);
348 y+=dom.coord(s, 1);
349 z+=dom.coord(s, 2);
350 nb_som_poly++;
351 }
352 x/=((double)(nb_som_poly));
353 y/=((double)(nb_som_poly));
354 z/=((double)(nb_som_poly));
355 if ( sup_strict(x,ox)
356 && sup_strict(lx,x)
357 && sup_strict(y,oy)
358 && sup_strict(ly,y)
359 && sup_strict(z,oz)
360 && sup_strict(lz,z) )
361 {
362 les_elems_(compteur)=le_poly;
363 compteur++;
364 }
365 }
366 les_elems_.resize(compteur);
367 Cerr << "Construction of the subarea OK" << finl;
368 }
369 break;
370 }
371 case 3 :
372 {
373 // Rectangle
374 if(dimension!=2)
375 {
376 // Un Rectangle est une surface
377 Cerr << "In 3 dimensions, you must use \"Boite\" " << finl;
379 }
380 is >> motlu;
381 if (motlu != Motcle("Origine"))
382 {
383 Cerr << "We expected the keyword \"Origine\"" << finl;
385 }
386 double ox, oy;
387 is >> ox >> oy ;
388 is >> motlu;
389 if (motlu != Motcle("Cotes"))
390 {
391 Cerr << "We expected the keyword \"Cotes\"" << finl;
393 }
394 double lx, ly;
395 is >> lx >> ly ;
396 lx+= ox;
397 ly+=oy;
398 {
399 const Domaine_t& le_dom=le_dom_.valeur();
400 int nbsom=le_dom.nb_som_elem();
401 int_t le_poly;
402 double x, y;
403 int_t compteur=0;
404
405 Cerr << "Construction of the subarea " << le_nom() << finl;
406 les_elems_.resize(nb_pol_possible);
407 ToDo_Kokkos("critical");
408 for (int_t n_pol=0; n_pol<nb_pol_possible; n_pol++)
409 {
410 le_poly=les_polys_possibles_[n_pol];
411 x=y=0;
412 for(int le_som=0; le_som<nbsom; le_som++)
413 {
414 x+=dom.coord(ledomaine.sommet_elem(le_poly,le_som),0);
415 y+=dom.coord(ledomaine.sommet_elem(le_poly,le_som),1);
416 }
417 x/=((double)(nbsom));
418 y/=((double)(nbsom));
419 if ( sup_strict(x,ox)
420 && sup_strict(lx,x)
421 && sup_strict(y,oy)
422 && sup_strict(ly,y) )
423 {
424 les_elems_(compteur)=le_poly;
425 compteur++;
426 }
427 }
428 les_elems_.resize(compteur);
429 Cerr << "Construction of the subarea OK" << finl;
430 }
431 break;
432 }
433 case 4 :
434 {
435 // Intervalle (only be used in sequential calculation)
437 {
438 Cerr << "You can't use Intervalle option for parallel calculation." << finl;
440 }
441 int_t prems, nombre;
442 is >> prems >> nombre;
443 les_elems_.resize(nombre);
444 ToDo_Kokkos("critical");
445 for(int_t i=0; i<nombre; i++)
446 les_elems_[i]=prems+i;
447 break;
448 }
449 case 5 :
450 {
451 // Lecture de la sous-domaine dans un fichier ascii.
452 // Le fichier contient, pour chaque processeur dans l'ordre croissant,
453 // un IntVect contenant les indices dans le domaine(0) des elements reels
454 // qui constituent la sous-domaine.
455 Nom nomfic;
456 is >> nomfic;
457 if(je_suis_maitre())
458 {
459 IntVect_t tab;
460 EFichier fic;
461 Cerr << "Reading of a subarea in the file " << nomfic << finl;
462 if (!fic.ouvrir(nomfic))
463 {
464 Cerr << " Error while opening file." << finl;
466 }
467 fic >> les_elems_;
468 for(int p=1; p<nproc(); p++)
469 {
470 fic >> tab;
471 envoyer(tab,0,p,p);
472 }
473 }
474 else
475 {
476 recevoir(les_elems_,0,me(),me());
477 }
478
479 // Ajout a la liste "les_polys_" des indices des elements virtuels
480 // de la sous-domaine.
481 // On cree un tableau distribue de marqueurs des elements de la sous-domaine
482 const int_t nb_elem = ledomaine.nb_elem();
483 IntVect_t marqueurs;
484 dom.creer_tableau_elements(marqueurs);
485 const int_t nb_polys_reels = les_elems_.size();
486 ToDo_Kokkos("critical");
487 for (int_t i = 0; i < nb_polys_reels; i++)
488 {
489 const int_t elem = les_elems_[i];
490 marqueurs[elem] = 1;
491 }
492 marqueurs.echange_espace_virtuel();
493 // Compter les elements virtuels dans la sous-domaine:
494 const int_t domaine_nb_elem_tot = ledomaine.nb_elem_tot();
495 int_t nb_polys = nb_polys_reels;
496 for (int_t i = nb_elem; i < domaine_nb_elem_tot; i++)
497 nb_polys += marqueurs[i];
498 // Ajouter les indices des elements virtuels a "les_polys_"
499 les_elems_.resize(nb_polys);
500 nb_polys = nb_polys_reels;
501 for (int_t i = nb_elem; i < domaine_nb_elem_tot; i++)
502 if (marqueurs[i])
503 les_elems_[nb_polys++] = i;
504
505 break;
506 }
507 case 6 :
508 {
509 // Plaque
510 if(dimension!=3)
511 {
512 Cerr << "In 2 dimensions, you must use something else like a segment."<< finl;
514 }
515 is >> motlu;
516 if (motlu != Motcle("Origine"))
517 {
518 Cerr << "We expected the keyword \"Origine\"" << finl;
520 }
521 double deux_pi=M_PI*2.0 ;
522 double ox, oy, oz;
523 is >> ox >> oy >> oz ;
524 is >> motlu;
525 if (motlu != Motcle("Cotes"))
526 {
527 Cerr << "We expected the keyword \"Cotes\"" << finl;
529 }
530 double lx, ly, lz;
531 is >> lx >> ly >>lz;
532 if ((lx!=0)&&(ly!=0)&&(lz!=0))
533 {
534 Cerr << "We expected at least one quotation to zero" << finl;
536 }
537 lx+=ox;
538 ly+=oy;
539 lz+=oz;
540 if(axi)
541 {
542 oy*=deux_pi;
543 ly*=deux_pi;
544 }
545 {
546 const Domaine_t& le_dom=le_dom_.valeur();
547 int nbsom=le_dom.nb_som_elem();
548 int_t le_poly;
549 double x, y, z;
550 int_t compteur=0;
551 Cerr << "Construction of the subarea " << le_nom() << finl;
552 les_elems_.resize(nb_pol_possible);
553 ToDo_Kokkos("critical");
554 for (int_t n_pol=0; n_pol<nb_pol_possible; n_pol++)
555 {
556 le_poly=les_polys_possibles_[n_pol];
557 int le_som, nb_som_poly = 0;
558 int_t s;
559 x=y=z=0;
560 for(le_som=0; le_som<nbsom && ((s = ledomaine.sommet_elem(le_poly,le_som)) >= 0); le_som++)
561 {
562 x+=dom.coord(s, 0);
563 y+=dom.coord(s, 1);
564 z+=dom.coord(s, 2);
565 nb_som_poly++;
566 }
567 le_som=0;
568 double xmin,xmax,ymin,ymax,zmin,zmax;
569 xmin=dom.coord(ledomaine.sommet_elem(le_poly,le_som),0);
570 ymin=dom.coord(ledomaine.sommet_elem(le_poly,le_som),1);
571 zmin=dom.coord(ledomaine.sommet_elem(le_poly,le_som),2);
572 xmax=xmin;
573 ymax=ymin;
574 zmax=zmin;
575 for(le_som=1; le_som<nbsom && ((s = ledomaine.sommet_elem(le_poly,le_som)) >= 0); le_som++)
576 {
577 xmin=std::min(xmin,dom.coord(s, 0));
578 ymin=std::min(ymin,dom.coord(s, 1));
579 zmin=std::min(zmin,dom.coord(s, 2));
580 xmax=std::max(xmax,dom.coord(s, 0));
581 ymax=std::max(ymax,dom.coord(s, 1));
582 zmax=std::max(zmax,dom.coord(s, 2));
583 }
584 x/=((double)(nb_som_poly));
585 y/=((double)(nb_som_poly));
586 z/=((double)(nb_som_poly));
587 if (
588 ( sup_strict(x,ox) && sup_strict(lx,x)
589 && sup_strict(y,oy) && sup_strict(ly,y)
590 && sup_strict(oz,zmin) && inf_ou_egal(oz,zmax) )
591 || ( sup_strict(x,ox) && sup_strict(lx,x)
592 && sup_strict(z,oz) && sup_strict(lz,z)
593 && sup_strict(oy,ymin) && inf_ou_egal(oy,ymax) )
594 || ( sup_strict(y,oy) && sup_strict(ly,y)
595 && sup_strict(z,oz) && sup_strict(lz,z)
596 && sup_strict(ox,xmin) && inf_ou_egal(ox,xmax) )
597 )
598 {
599 les_elems_(compteur)=le_poly;
600 compteur++;
601 }
602 }
603 les_elems_.resize(compteur);
604 Cerr << "Construction of the subarea OK" << finl;
605 }
606 break;
607 }
608 case 7:
609 {
610 // Segment
611 if(dimension!=2)
612 {
613 Cerr << "In 3 dimensions, you must use something else like a plaque."<< finl;
615 }
616 is >> motlu;
617 if (motlu != Motcle("Origine"))
618 {
619 Cerr << "We expected the keyword \"Origine\"" << finl;
621 }
622 //double deux_pi=M_PI*2.0 ;
623 double ox, oy;
624 is >> ox >> oy ;
625 is >> motlu;
626 if (motlu != Motcle("Cotes"))
627 {
628 Cerr << "We expected the keyword \"Cotes\"" << finl;
630 }
631 double lx, ly;
632 is >> lx >> ly ;
633 if ((lx!=0)&&(ly!=0))
634 {
635 Cerr << "We expected at least one quotation to zero" << finl;
637 }
638 lx+= ox;
639 ly+=oy;
640
641 {
642 const Domaine_t& le_dom=le_dom_.valeur();
643 int nbsom=le_dom.nb_som_elem();
644 int_t le_poly;
645 double x, y;
646 int_t compteur=0;
647 Cerr << "Construction of the subarea " << le_nom() << finl;
648 les_elems_.resize(nb_pol_possible);
649 ToDo_Kokkos("critical");
650 for (int_t n_pol=0; n_pol<nb_pol_possible; n_pol++)
651 {
652 le_poly=les_polys_possibles_[n_pol];
653 int le_som;
654 x=y=0;
655 for(le_som=0; le_som<nbsom; le_som++)
656 {
657 x+=dom.coord(ledomaine.sommet_elem(le_poly,le_som),0);
658 y+=dom.coord(ledomaine.sommet_elem(le_poly,le_som),1);
659 }
660 le_som=0;
661 double xmin,xmax,ymin,ymax;
662 xmin=dom.coord(ledomaine.sommet_elem(le_poly,le_som),0);
663 ymin=dom.coord(ledomaine.sommet_elem(le_poly,le_som),1);
664 xmax=xmin;
665 ymax=ymin;//zmax=zmin;
666 for(le_som=1; le_som<nbsom; le_som++)
667 {
668 xmin=std::min(xmin,dom.coord(ledomaine.sommet_elem(le_poly,le_som),0));
669 ymin=std::min(ymin,dom.coord(ledomaine.sommet_elem(le_poly,le_som),1));
670 xmax=std::max(xmax,dom.coord(ledomaine.sommet_elem(le_poly,le_som),0));
671 ymax=std::max(ymax,dom.coord(ledomaine.sommet_elem(le_poly,le_som),1));
672 }
673 x/=((double)(nbsom));
674 y/=((double)(nbsom));
675 if (
676 ( sup_strict(x,ox) && sup_strict(lx,x)
677 && sup_strict(oy,ymin) && inf_ou_egal(oy,ymax) )
678 || ( sup_strict(y,oy) && sup_strict(ly,y)
679 && sup_strict(ox,xmin) && inf_ou_egal(ox,xmax) )
680 )
681 {
682 les_elems_(compteur)=le_poly;
683 compteur++;
684 }
685 }
686 les_elems_.resize(compteur);
687 Cerr << "Construction of the subarea OK" << finl;
688 }
689 break;
690 }
691 case 8 :
692 {
693 // Couronne
694 if(dimension!=2)
695 {
696 // Une Couronne en 2D seulement !
697 Cerr << "A crown is only in 2D : in 3 dimensions it is a tube \"Tube\" "<< finl;
699 }
700 is >> motlu;
701 if(motlu!=Motcle("Origine"))
702 {
703 Cerr << "We expected the keyword \"ORIGINE\" " << finl;
705 }
706 double xo,yo;
707 is >> xo >> yo ;
708 is >> motlu;
709 if(motlu!=Motcle("RI"))
710 {
711 Cerr << "We expected the internal radius \"RI\" " << finl;
713 }
714 double ri,re;
715 is >> ri;
716 is >> motlu;
717 if(motlu!=Motcle("RE"))
718 {
719 Cerr << "We expected the external radius \"RE\" " << finl;
721 }
722 is >> re;
723 {
724 double ri2=ri*ri; // Internal radius^2
725 double re2=re*re; // External radius^2
726 const Domaine_t& le_dom=le_dom_.valeur();
727 int nbsom=le_dom.nb_som_elem();
728 DoubleVect x(dimension);
729 int_t compteur=0;
730 Cerr << "Construction of the subarea " << le_nom() << finl;
731 les_elems_.resize(nb_pol_possible);
732 ToDo_Kokkos("critical");
733 for (int_t n_pol=0; n_pol<nb_pol_possible; n_pol++)
734 {
735 int_t le_poly=les_polys_possibles_[n_pol];
736 x=0;
737 for(int som=0; som<nbsom; som++)
738 {
739 for(int k=0; k<dimension; k++)
740 x(k)+=dom.coord(ledomaine.sommet_elem(le_poly,som),k);
741 }
742 x/=((double)(nbsom)); // Center of gravity of the cell
743 if ( sup_strict((x(0)-xo)*(x(0)-xo)+(x(1)-yo)*(x(1)-yo),ri2) && sup_strict(re2,(x(0)-xo)*(x(0)-xo)+ (x(1)-yo)*(x(1)-yo)) )
744 {
745 les_elems_(compteur)=le_poly;
746 compteur++;
747 }
748 }
749 les_elems_.resize(compteur);
750 Cerr << "Construction of the subarea OK" << finl;
751 }
752 break;
753 }
754 case 9 :
755 {
756 // Tube
757 if(dimension!=3)
758 {
759 // Un tube en 3D seulement !
760 Cerr << "A tube is only in 3D : in 2 dimensions it is a crown \"Couronne\" "<< finl;
762 }
763 is >> motlu;
764 if(motlu!=Motcle("Origine"))
765 {
766 Cerr << "We expected the keyword \"ORIGINE\" " << finl;
768 }
769 double xo,yo,zo;
770 is >> xo >> yo >> zo;
771 is >> motlu;
772 if(motlu!=Motcle("DIR"))
773 {
774 Cerr << "We expected the tube direction, keyword \"DIR\" " << finl;
776 }
777 Motcles coords(3);
778 {
779 coords[0] = "X";
780 coords[1] = "Y";
781 coords[2] = "Z";
782 }
783 Nom coord;
784 is >> coord;
785 motlu=coord;
786 int idir = coords.search(motlu);
787 int dir[3];
788 dir[0]=dir[1]=dir[2]=0;
789 double h0=0;
790 switch(idir)
791 {
792 case 0:
793 dir[0]=0;
794 dir[1]=dir[2]=1;
795 h0=xo;
796 break;
797
798 case 1:
799 dir[1]=0;
800 dir[0]=dir[2]=1;
801 h0=yo;
802 break;
803
804 case 2:
805 dir[2]=0;
806 dir[1]=dir[0]=1;
807 h0=zo;
808 break;
809
810 default:
811 h0=-1;
812 Cerr << "DIR is equal to X for a tube parallel to OX ; Y for a tube parallel to OY and Z for a tube parallel to OZ" << finl;
813 Cerr << "Currently, DIR is equal to " << coord << finl;
815 }
816
817 is >> motlu;
818 if(motlu!=Motcle("RI"))
819 {
820 Cerr << "We expected the internal radius, keyword \"RI\" " << finl;
822 }
823 double ri,re,h;
824 is >> ri;
825 is >> motlu;
826 if(motlu!=Motcle("RE"))
827 {
828 Cerr << "We expected the external radius, keyword \"RE\" " << finl;
830 }
831 is >> re;
832 is >> motlu;
833 if(motlu!=Motcle("Hauteur"))
834 {
835 Cerr << "We expected the height of tube, keyword \"Hauteur\" " << finl;
837 }
838 is >> h;
839 h+=h0;
840 {
841 double ri2 = ri*ri, re2=re*re;
842 const Domaine_t& le_dom=le_dom_.valeur();
843 int nbsom=le_dom.nb_som_elem();
844 int_t le_poly;
845 DoubleVect x(dimension);
846 int_t compteur=0;
847 Cerr << "Construction of the subarea " << le_nom() << finl;
848 les_elems_.resize(nb_pol_possible);
849 ToDo_Kokkos("critical");
850 for (int_t n_pol=0; n_pol<nb_pol_possible; n_pol++)
851 {
852 le_poly=les_polys_possibles_[n_pol];
853 x=0;
854 for(int le_som=0; le_som<nbsom; le_som++)
855 {
856 for(int k=0; k<dimension; k++)
857 x(k)+=dom.coord(ledomaine.sommet_elem(le_poly,le_som),k);
858 }
859 x/=((double)(nbsom));
860 double tmp = dir[0]*(x(0)-xo)*(x(0)-xo)+ dir[1]*(x(1)-yo)*(x(1)-yo) + dir[2]*(x(2)-zo)*(x(2)-zo);
861 if ( sup_ou_egal(tmp,ri2) && inf_ou_egal(tmp,re2) && inf_ou_egal(x(idir),h) && sup_ou_egal(x(idir),h0) )
862 {
863 les_elems_(compteur)=le_poly;
864 compteur++;
865 }
866 }
867 les_elems_.resize(compteur);
868 Cerr << "Construction of the subarea OK" << finl;
869 }
870 break;
871 }
872 case 10 :
873 {
874 if(dimension!=3)
875 {
876 // Un tube en 3D seulement !
877 Cerr << "An hexagonal tube \"Tube_hexagonal\" is only in 3D "<< finl;
879 }
880
881 // PQ : 17/09/08 : on suppose le tube hexagonal centre sur l'origine, porte par l'axe z
882 // et pour lequel l'entreplat est entre y=-ep/2 et y=+ep/2
883
884 double ep;
885 bool in=true;
886
887 is >> motlu;
888 if(motlu!=Motcle("ENTREPLAT"))
889 {
890 Cerr << "We expected the entreplat of the tube, keyword \"ENTREPLAT\"" << finl;
892 }
893 is >> ep;
894 is >> motlu;
895 if(motlu==Motcle("IN")) in=1;
896 else if(motlu==Motcle("OUT")) in=0;
897 else
898 {
899 Cerr << "We expected the keyword \"IN\" or \"OUT\" " << finl;
901 }
902
903 {
904 const Domaine_t& le_dom=le_dom_.valeur();
905 int nbsom=le_dom.nb_som_elem();
906 int_t le_poly;
907 DoubleVect x(dimension);
908 int_t compteur=0;
909 Cerr << "Construction of the subarea " << le_nom()<< finl;
910
911 les_elems_.resize(nb_pol_possible);
912 ToDo_Kokkos("critical");
913 for (int_t n_pol=0; n_pol<nb_pol_possible; n_pol++)
914 {
915 le_poly=les_polys_possibles_[n_pol];
916 x=0;
917 for(int le_som=0; le_som<nbsom; le_som++)
918 {
919 for(int k=0; k<dimension; k++)
920 x(k)+=dom.coord(ledomaine.sommet_elem(le_poly,le_som),k);
921 }
922 x/=((double)(nbsom));
923
924 if ( sup_ou_egal(x(1),-ep/2.) && sup_ou_egal(x(1),-ep-x(0)*sqrt(3.)) && sup_ou_egal(x(1),-ep+x(0)*sqrt(3.))
925 && inf_ou_egal(x(1), ep/2.) && inf_ou_egal(x(1), ep-x(0)*sqrt(3.)) && inf_ou_egal(x(1), ep+x(0)*sqrt(3.)) )
926 {
927 if(in==1)
928 {
929 les_elems_(compteur)=le_poly;
930 compteur++;
931 }
932 }
933 else
934 {
935 if(in==0)
936 {
937 les_elems_(compteur)=le_poly;
938 compteur++;
939 }
940 }
941 }
942 les_elems_.resize(compteur);
943 Cerr << "Construction of the subarea OK" << finl;
944 }
945 break;
946 }
947 case 11:
948 case 12:
949 {
950
951 Parser_U F;
953 Nom fct;
954 is>> fct;
955 F.setString(fct);
956 F.addVar("x");
957 F.addVar("y");
958 if (dimension==3)
959 F.addVar("z");
960 F.parseString();
961
962 {
963 ParserView parser(F);
964 parser.parseString();
965 const Domaine_t& le_dom=le_dom_.valeur();
966 int nbsom=le_dom.nb_som_elem();
967 Cerr << "Construction of the subarea " << le_nom()<< finl;
968 int_t compteur=0;
969 int dim = Objet_U::dimension;
970 CDoubleTabView coord = dom.coord_sommets().view_ro();
971 Int_tArrView les_polys_possibles = les_polys_possibles_.view_rw();
972 CInt_tTabView sommet_elem = ledomaine.les_elems().view_ro();
973 Kokkos::parallel_reduce(start_gpu_timer(__KERNEL_NAME__), nb_pol_possible, KOKKOS_LAMBDA(const int_t i, int_t& local_compteur)
974 {
975 int_t le_poly=les_polys_possibles(i);
976 double x[3] = {0.,0.,0.};
977 int nbsom_loc = 0;
978 for(int le_som=0; le_som<nbsom; le_som++)
979 if (sommet_elem(le_poly,le_som) >= 0)
980 {
981 for(int k=0; k<dim; k++)
982 x[k]+=coord(sommet_elem(le_poly,le_som),k);
983 nbsom_loc++;
984 }
985 for(int k=0; k<dim; k++)
986 x[k]/=nbsom_loc;
987 int threadId = parser.acquire();
988 parser.setVar(0,x[0],threadId);
989 parser.setVar(1,x[1],threadId);
990 if (dim==3)
991 parser.setVar(2,x[2],threadId);
992 double test=parser.eval(threadId);
993 parser.release(threadId);
994 // attention le test absolu est voulu
995 // si on fait une fonction qui vaut 0 ou 1 ....
996 if (test>0)
997 local_compteur++;
998 else
999 les_polys_possibles(i) = -1;
1000 }, compteur);
1001 end_gpu_timer(__KERNEL_NAME__);
1002 les_elems_.resize(compteur);
1003 ArrOfInt_t tab_indices(nb_pol_possible);
1004 Int_tArrView indices = tab_indices.view_wo();
1005 Kokkos::parallel_scan(start_gpu_timer(__KERNEL_NAME__), nb_pol_possible, KOKKOS_LAMBDA(const int_t i, int& update, const bool final)
1006 {
1007 if (les_polys_possibles(i) >= 0)
1008 {
1009 if (final) indices(i) = update;
1010 update++;
1011 }
1012 });
1013 end_gpu_timer(__KERNEL_NAME__);
1014 Int_tArrView les_elems = les_elems_.view_wo();
1015 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pol_possible, KOKKOS_LAMBDA(const int_t i)
1016 {
1017 if (les_polys_possibles(i) >= 0)
1018 les_elems(indices(i)) = les_polys_possibles(i);
1019 });
1020 end_gpu_timer(__KERNEL_NAME__);
1021 Cerr << "Construction of the subarea OK" << finl;
1022 }
1023 break;
1024 }
1025 case -1:
1026 // traite avant
1027 break;
1028 default :
1029 {
1030 Cerr << "TRUST error" << finl;
1031 Process::exit();
1032 }
1033 break;
1034 }
1035 is >> motlu;
1036 while (motlu=="union")
1037 {
1038 Nom nom_ss_domaine;
1039 is >> nom_ss_domaine;
1040 const Sous_Domaine_32_64& ssz=ref_cast(Sous_Domaine_32_64, interprete().objet(nom_ss_domaine));
1041 std::set<trustIdType> poly_set(les_elems_.begin(), les_elems_.end()); //to detect already present elements
1042 ToDo_Kokkos("critical");
1043 for (int i = 0; i < ssz.nb_elem_tot(); i++)
1044 if (!poly_set.count(ssz(i))) //only add new elements
1045 {
1046 int_t old_size = les_elems_.size();
1047 les_elems_.resize(old_size + 1);
1048 les_elems_(old_size) = ssz(i);
1049 }
1050
1051 is >>motlu;
1052 }
1053
1054 if(motlu != Motcle("}"))
1055 {
1056 Cerr << "We expected a } to the reading of the subarea" << finl;
1057 Cerr << "instead of " << motlu << finl;
1058 Process::exit();
1059 }
1060}
1061
1062
1063/*! @brief Ajoute un polyedre au sous-domaine.
1064 *
1065 * @return (int)
1066 */
1067template <typename _SIZE_>
1069{
1070 assert(0<=poly);
1071 int_t nb_poly=les_elems_.size();
1072 int OK=1;
1073 for(int_t i=0; i<nb_poly; i++)
1074 if(les_elems_(i)==poly)
1075 OK=0;
1076 if(OK==1)
1077 {
1078 les_elems_.resize(nb_poly+1);
1079 les_elems_(nb_poly)=poly;
1080 }
1081}
1082
1083
1084/*! @brief Associe un Objet_U au sous-domaine.
1085 *
1086 * On controle le type de l'objet a associer
1087 * dynamiquement.
1088 *
1089 * @param (Objet_U& ob) objet a associer au sous-domaine.
1090 * @return (int) renvoie 1 si l'association a reussi 0 sinon.
1091 */
1092template <typename _SIZE_>
1094{
1095 if( sub_type(Domaine_t, ob))
1096 {
1097 if(le_dom_) return 1;
1098 associer_domaine(ref_cast(Domaine_t, ob));
1099 ob.associer_(*this);
1100 return 1;
1101 }
1102 return 0;
1103}
1104
1105template class Sous_Domaine_32_64<int>;
1106#if INT_is_64_ == 2
1107template class Sous_Domaine_32_64<trustIdType>;
1108#endif
int nb_som_elem() const
Renvoie le nombre de sommets des elements geometriques constituants le domaine.
Definition Domaine.h:474
int_t nb_elem_tot() const
Definition Domaine.h:132
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
Definition Domaine.cpp:851
IntTab_t & les_elems()
Definition Domaine.h:129
int_t nb_elem() const
Definition Domaine.h:131
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
double coord(int_t i, int j) const
Definition Domaine.h:110
int_t sommet_elem(int_t i, int j) const
Renvoie le numero (global) du j-ieme sommet du i-ieme element.
Definition Domaine.h:136
Fichier en lecture Cette classe est a la classe C++ ifstream ce que la classe Entree est a la.
Definition EFichier.h:29
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
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
Un tableau d'objets de la classe Motcle.
Definition Motcle.h:63
int search(const Motcle &t) const
Definition Motcle.cpp:321
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
friend class Entree
Definition Objet_U.h:76
virtual int associer_(Objet_U &)
Associe l'Objet_U a un autre Objet_U Methode virtuelle a surcharger.
Definition Objet_U.cpp:201
const Interprete & interprete() const
Definition Objet_U.cpp:212
static int dimension
Definition Objet_U.h:99
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55
static int axi
Definition Objet_U.h:101
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
KOKKOS_INLINE_FUNCTION int acquire() const
Definition ParserView.h:77
KOKKOS_INLINE_FUNCTION void setVar(int i, double val, int threadId) const
Definition ParserView.h:64
void parseString() override
Definition ParserView.h:52
KOKKOS_INLINE_FUNCTION void release(int threadId) const
Definition ParserView.h:79
KOKKOS_INLINE_FUNCTION double eval(int threadId) const
Definition ParserView.h:69
classe Parser_U Version de la classe Parser, derivant de Objet_U.
Definition Parser_U.h:32
void setString(const std::string &s)
Definition Parser_U.h:194
void setNbVar(int nvar)
Definition Parser_U.h:174
void parseString()
Definition Parser_U.h:116
void addVar(const char *v)
Definition Parser_U.h:183
Polynome a n variables, n <= 4 Implementation des coefficients a l'aide d'un DoubleTab.
Definition Polynome.h:26
static bool is_parallel()
Definition Process.cpp:110
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
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
Classe de base des flux de sortie.
Definition Sortie.h:52
Sous_Domaine represents a volumic sub-domain i.e. a sub set of elements of a Domaine.
void add_elem(const int_t poly)
Ajoute un polyedre au sous-domaine.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
void associer_domaine(const Domaine_t &d)
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
ArrOfInt_T< _SIZE_ > ArrOfInt_t
int_t nb_elem_tot() const
Domaine_32_64< _SIZE_ > Domaine_t
int associer_(Objet_U &) override
Associe un Objet_U au sous-domaine.
const IntVect_t & les_elems() const
IntVect_T< _SIZE_ > IntVect_t
void build(Entree &is)
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
Definition TRUSTTab.h:261
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")