TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Extraire_plan.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 <Extraire_surface.h>
17#include <Probleme_base.h>
18#include <Extraire_plan.h>
19#include <Equation_base.h>
20#include <NettoieNoeuds.h>
21#include <Domaine_VF.h>
22#include <EChaine.h>
23#include <SChaine.h>
24#include <Domaine.h>
25#include <Param.h>
26
27Implemente_instanciable(Extraire_plan,"Extraire_plan",Interprete_geometrique_base);
28// XD extraire_plan interprete extraire_plan BRACE This keyword extracts a plane mesh named domain_name (this domain
29// XD_CONT should have been declared before) from the mesh of the pb_name problem. The plane can be either a triangle
30// XD_CONT (defined by the keywords Origine, Point1, Point2 and Triangle), either a regular quadrangle (with keywords
31// XD_CONT Origine, Point1 and Point2), or either a generalized quadrangle (with keywords Origine, Point1, Point2,
32// XD_CONT Point3). The keyword Epaisseur specifies the thickness of volume around the plane which contains the faces of
33// XD_CONT the extracted mesh. The keyword via_extraire_surface will create a plan and use Extraire_surface algorithm.
34// XD_CONT Inverse_condition_element keyword then will be used in the case where the plane is a boundary not well
35// XD_CONT oriented, and avec_certains_bords_pour_extraire_surface is the option related to the Extraire_surface option
36// XD_CONT named avec_certains_bords. Point1, Point2 and Triangle), either a regular quadrangle (with keywords Origine,
37// XD_CONT Point1 and Point2), or either a generalized quadrangle (with keywords Origine, Point1, Point2, Point3). The
38// XD_CONT keyword Epaisseur specifies the thickness of volume around the plane which contains the faces of the
39// XD_CONT extracted mesh. The keyword via_extraire_surface will create a plan and use Extraire_surface algorithm.
40// XD_CONT Inverse_condition_element keyword then will be used in the case where the plane is a boundary not well
41// XD_CONT oriented, and avec_certains_bords_pour_extraire_surface is the option related to the Extraire_surface option
42// XD_CONT named avec_certains_bords.
43
45
47
48void calcul_normal_norme(const ArrOfDouble& org, const ArrOfDouble& point1, const ArrOfDouble& point2, ArrOfDouble& normal)
49{
50 calcul_normal(org.addr(), point1.addr(), point2.addr(), normal.addr());
51 normal/=norme_array(normal);
52}
53
55{
56 Nom nom_pb;
57 Nom nom_dom;
58 ArrOfDouble origine,point1,point2,point3;
59 bool triangle = false;
60 double epaisseur = -123.;
61 Param param(que_suis_je());
62 param.ajouter("domaine",&nom_dom,Param::REQUIRED); // XD_ADD_P ref_domaine
63 // XD_CONT domain name
64 param.ajouter("probleme",&nom_pb,Param::REQUIRED); // XD_ADD_P ref_Pb_base
65 // XD_CONT pb_name
66 param.ajouter("origine",&origine,Param::REQUIRED); // XD_ADD_P list
67 // XD_CONT not_set
68 param.ajouter("point1",&point1,Param::REQUIRED); // XD_ADD_P list
69 // XD_CONT not_set
70 param.ajouter("point2",&point2,Param::REQUIRED); // XD_ADD_P list
71 // XD_CONT not_set
72 param.ajouter("point3",&point3); // XD_ADD_P list
73 // XD_CONT not_set
74 param.ajouter_flag("triangle",&triangle); // XD_ADD_P rien
75 // XD_CONT not_set
76 param.ajouter("epaisseur",&epaisseur,Param::REQUIRED); // XD_ADD_P floattant
77 // XD_CONT thickness
78
79 bool via_extraire_surface = false;
80 bool inverse_condition_element = false;
81 param.ajouter_flag("via_extraire_surface",&via_extraire_surface); // XD_ADD_P rien
82 // XD_CONT not_set
83 param.ajouter_flag("inverse_condition_element",&inverse_condition_element); // XD_ADD_P rien
84 // XD_CONT not_set
85
86 Noms bords;
87
88 param.ajouter("avec_certains_bords_pour_extraire_surface",&bords); // XD_ADD_P listchaine
89 // XD_CONT name of boundaries to include when extracting plan
90
92
93 associer_domaine(nom_dom);
94
95 if (point3.size_array()==0)
96 {
97 point3.resize_array(3);
98 for (int dir=0; dir<3; dir++)
99 if (triangle)
100 point3[dir]=(point1[dir]+point2[dir])/2.;
101 else
102 point3[dir]=point1[dir]+point2[dir]-origine[dir];
103 }
104
105
106 if (via_extraire_surface)
107 {
108 // determination de la normale
109 ArrOfDouble normal(3);
110 calcul_normal_norme(origine,point1,point2,normal);
111
112 double dx=0;
113 for (int dir=0; dir<3; dir++)
114 dx+=normal[dir]*origine[dir];
115 Noms axes(3);
116 axes[0]="x";
117 axes[1]="y";
118 axes[2]="z";
119
120 SChaine out;
121 out << " { domaine "<<nom_dom <<" probleme "<<nom_pb <<finl;
122 out<<" condition_elements (" <<-dx ;
123 for (int dir=0; dir<3; dir++)
124 if (normal[dir])
125 out<<"+"<<axes[dir]<<"*("<<normal[dir]<<")";
126 if (inverse_condition_element)
127 out<<")_ge_0"<<finl;
128 else
129 out<<")_le_0"<<finl;
130 out<<" condition_faces (";
131 for (int ori=0; ori<2; ori++)
132
133 {
134 ArrOfDouble& A=(ori==0?origine:point3);
135 ArrOfDouble& D=(ori!=0?origine:point3);
136 ArrOfDouble normal2(3),prov(3);
137 for (int te=0; te<2; te++)
138 {
139 ArrOfDouble& B=(te==0?point1:point2);
140 //ArrOfDouble& C=(ori!=0?point1:point2);
141 prov=normal;
142 prov+=A;
143 calcul_normal_norme(A,B,prov,normal2);
144 //prov=REF;
145 //prov-=A;
146 double dxbis=0;
147 double ref=0;
148 out<<"((";
149 for (int dir=0; dir<3; dir++)
150 {
151 dxbis+=normal2[dir]*D[dir];
152 ref+=normal2[dir]*A[dir];
153 if (normal2[dir])
154 out << axes[dir]<<"*("<< normal2[dir]<<")+";
155 }
156 out<<"("<<-ref<<"))";
157 //Cout<<"INFO " << dx-ref<<finl;
158 if ((dxbis-ref)>0)
159 out <<"_ge_0)*";
160 else
161 out <<"_le_0)*";
162 }
163 }
164 out<<"1)"<<finl;
165 //out<<" avec_les_bords "<<finl;
166 if (bords.size())
167 out<<"avec_certains_bords " <<bords<<finl;
168 out<<"}" << finl;
169 Cout<<" Creation of the plan through Extraire_surface "<< out.get_str()<<finl;;
170 EChaine in(out.get_str());
171 Extraire_surface extraction;
172 extraction.interpreter(in);
173 // abort();
174 return is;
175 }
176
177 Domaine& dom=domaine();
178 // on recupere le pb
179 if(! sub_type(Probleme_base, objet(nom_pb)))
180 {
181 Cerr << nom_pb << " is of type " << objet(nom_pb).que_suis_je() << finl;
182 Cerr << "and not of type Probleme_base" << finl;
183 exit();
184 }
185 Probleme_base& pb=ref_cast(Probleme_base, objet(nom_pb));
186 const Domaine_VF& domaine_vf=ref_cast(Domaine_VF,pb.domaine_dis());
187 dom.les_sommets()=domaine_vf.domaine().les_sommets();
188 const DoubleTab& coord=dom.les_sommets();
189 const Nom& type_elem=domaine_vf.domaine().type_elem()->que_suis_je();
190 if (type_elem==Motcle("Tetraedre"))
191 dom.typer("Triangle");
192 else
193 {
194 Cerr<<que_suis_je()<<" not coded for this type of elements "<<finl;
195 exit();
196 }
197
198 // creation d'un domaine pipo pour pouvoir chercher les faces
199 Domaine domaine_test;
200 ArrOfDouble normal(3);
201 {
202 if (triangle)
203 domaine_test.typer("Prisme");
204 else
205 domaine_test.typer("Hexaedre_vef");
206
207 DoubleTab& somm_hexa=domaine_test.les_sommets();
208 int nb_som=4;
209 if (triangle) nb_som=3;
210 somm_hexa.resize(nb_som*2,3);
211
212 for (int dir=0; dir<3; dir++)
213 {
214 somm_hexa(0,dir)=origine[dir];
215 somm_hexa(1,dir)=point1[dir];
216 somm_hexa(2,dir)=point2[dir];
217 somm_hexa(3,dir)=point3[dir];
218 for (int t=0; t<nb_som; t++)
219 somm_hexa(t+nb_som,dir)=somm_hexa(t,dir);
220 }
221 // il faut maintenant epaissir l'hexa dans la direction normale
222
223 calcul_normal_norme(origine,point1,point2,normal);
224 double d_epaisseur=epaisseur/2.;
225 for (int t=0; t<nb_som; t++)
226 for (int dir=0; dir<3; dir++)
227 {
228 somm_hexa(t,dir)=somm_hexa(t,dir)-d_epaisseur*normal[dir];
229 somm_hexa(nb_som+t,dir)=somm_hexa(nb_som+t,dir)+d_epaisseur*normal[dir];
230 }
231 IntTab& elem_test=domaine_test.les_elems();
232 elem_test.resize(1,nb_som*2);
233 for (int s=0; s<nb_som*2; s++) elem_test(0,s)=s;
234 /*
235 SFichier es("hex.geom");
236 es<<test;
237 */
238 }
239 const DoubleTab& xv =domaine_vf.xv();
240
241 int nbfaces=domaine_vf.nb_faces();
242
243 ArrOfInt marq(nbfaces);
244 // on marque les joints
245 //const Joints& joints=domaine_vf.face_joints();
246 int nbjoints=domaine_vf.nb_joints();
247
248 for(int njoint=0; njoint<nbjoints; njoint++)
249 {
250 const Joint& joint_temp = domaine_vf.joint(njoint);
251 int pe_voisin=joint_temp.PEvoisin();
252 if (pe_voisin<me())
253 {
254 const IntTab& indices_faces_joint = joint_temp.joint_item(JOINT_ITEM::FACE).renum_items_communs();
255 const int nb_faces_j = indices_faces_joint.dimension(0);
256 for (int j = 0; j < nb_faces_j; j++)
257 {
258 int face_de_joint = indices_faces_joint(j, 1);
259 marq[face_de_joint] = -1;
260 }
261 }
262 }
263 int nb_t=0;
264
265 for (int fac=0; fac<nbfaces; fac++)
266 {
267 if (domaine_test.chercher_elements(xv(fac,0),xv(fac,1),xv(fac,2))==0)
268 if (marq[fac]!=-1)
269 {
270 // tester si item_commun....
271 marq[fac]=1;
272 nb_t++;
273 }
274 }
275 ArrOfDouble point0b(3),point1b(3),point2b(3);
276 Cerr<<"Number of elements of the new domain "<<nb_t<<finl;
277 IntTab& les_elems=dom.les_elems();
278 les_elems.resize(nb_t,3);
279 const IntTab& face_sommets=domaine_vf.face_sommets();
280 int nb=0;
281 for (int fac=0; fac<nbfaces; fac++)
282 if (marq[fac]==1)
283 {
284 //Cerr<<fac <<" ";
285 for (int s=0; s<3; s++)
286 les_elems(nb,s)=face_sommets(fac,s);
287 // on calcule la normale
288 ArrOfDouble normal_b(3);
289 for (int i=0; i<3; i++)
290 {
291 point0b[i]=coord(les_elems(nb,0),i);
292 point1b[i]=coord(les_elems(nb,1),i);
293 point2b[i]=coord(les_elems(nb,2),i);
294 }
295 calcul_normal(point0b.addr(),point1b.addr(),point2b.addr(),normal_b.addr());
296 if (dotproduct_array(normal,normal_b)<0)
297 {
298 // si normal a l'envers on inverse les deux sommets
299 les_elems(nb,1)=face_sommets(fac,2);
300 les_elems(nb,2)=face_sommets(fac,1);
301 }
302 nb++;
303 }
304 Cerr<<finl;;
305 assert(nb==nb_t);
307
308 return is;
309}
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Recherche des elements contenant les points dont les coordonnees sont specifiees.
Definition Domaine.cpp:405
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
void typer(const Nom &)
Type les elements du domaine avec le nom passe en parametre.
Definition Domaine.h:457
class Domaine_VF
Definition Domaine_VF.h:44
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
int nb_joints() const
Definition Domaine_VF.h:65
const Joint & joint(int i) const
Definition Domaine_VF.h:105
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
Definition Domaine_VF.h:583
const Domaine & domaine() const
Une entree dont la source est une chaine de caracteres.
Definition EChaine.h:31
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe Extraire_plan Lecture d'un fichier.
Entree & interpreter_(Entree &) override
Classe Extraire_surface Lecture d'un fichier.
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
const Joint_Items_t & joint_item(JOINT_ITEM type) const
Renvoie les informations de joint pour le type demande.
Definition Joint.cpp:128
int PEvoisin() const
Definition Joint.h:49
const IntTab_t & renum_items_communs() const
Voir renum_items_communs_.
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
static void nettoie(Domaine_t &)
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
friend class Entree
Definition Objet_U.h:76
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
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
Definition Param.cpp:474
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
@ REQUIRED
Definition Param.h:115
int lire_avec_accolades_depuis(Entree &is)
Parse the parameter block { ... } from is.
Definition Param.cpp:32
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Domaine_dis_base & domaine_dis() const
Renvoie le domaine discretise associe au probleme.
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
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
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const
_TYPE_ * addr()
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133