TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Prepro_IBM_base.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 <Prepro_IBM_base.h>
17#include <Sous_Domaine.h>
18#include <Domaine_VF.h>
19#include <Ecrire_MED.h>
20#include <LireMED.h>
21#include <Domaine.h>
22#include <stdexcept>
23#include <Faces.h>
24#include <MEDCouplingFieldDouble.hxx>
25
26Implemente_base(Prepro_IBM_base, "Prepro_IBM_base", Objet_U);
27// XD Prepro_IBM_base objet_u Prepro_IBM_base INHERITS_BRACE To perform the intersection of an IB (Lagrange mesh) in a
28// XD_CONT MED-format file .med with the Euler computional mesh.
29
31{
32 Cout << "Prepro_IBM => " << finl;
33 Param param(que_suis_je());
34 set_param(param);
35 Cout<<"constante_prepro_c_IBM = "<<c_prepro_<<finl;
36 return s;
37}
38
40{
41 param.ajouter("epsilon_prepro_IBM",&eps_,Param::OPTIONAL); // XD_ADD_P double
42 // XD_CONT geometric precision (<<1)
43 param.ajouter("constant_c_IBM",&c_prepro_,Param::OPTIONAL); // XD_ADD_P double
44 // XD_CONT additive coefficient to search the purely fluid point (cf. publications G Billo)
45 param.ajouter_non_std("directions_pt_fluid",(this),Param::OPTIONAL); // XD_ADD_P listentier
46 // XD_CONT corresponding to each direction to search the purely fluid point
47 // Exemples :
48 // * [True, True, False] if the case is 2D in plane XY
49 // * [False, True, True] if the case is 2D in plane YZ
50 // * [True, True, True] if the case is 3D
51 param.ajouter_non_std("MESH_Lagrange_file",(this), Param::OPTIONAL); // XD_ADD_P chaine
52 // XD_CONT Name of the .med file including the IB surfacic mesh.
53 param.ajouter("MESH_Lagrange_name",&nom_maillage_IB_, Param::OPTIONAL); // XD_ADD_P chaine
54 // XD_CONT Name of the IB surfacic mesh.
55 param.ajouter_flag("write_results_prepro",&save_prepro_); // XD_ADD_P flag
56 // XD_CONT to save output from prepro IBM
57 param.ajouter("Out_MED_file_name",&nom_fichier_med_Out_, Param::OPTIONAL); // XD_ADD_P chaine
58 // XD_CONT Name of the .med file to save output from prepro IBM
59
60 param.ajouter("prepro_IBM_verbose",&verbose_,Param::OPTIONAL); // XD_ADD_P entier
61 // XD_CONT to get verbose version
62 param.ajouter_flag("verify_results_prepro",&verify_results_prepro_); // XD_ADD_P flag
63 // XD_CONT to save output from prepro IBM
64}
65
67{
68 if (un_mot == "directions_pt_fluid")
69 {
70 Cout << "reading search directions for reference fluid pt ... " << finl;
71 int dim_lu;
72 is >> dim_lu;
73 int dim_geom = Objet_U::dimension;
74 if(dim_lu != dim_geom)
75 {
76 Cerr<<"Prepro_IBM : dim_lu <> dim_geom = "<<dim_geom<<finl;
78 }
79 dimTab_.resize(dim_lu);
80 for (int i = 0; i < dim_lu; i++) is >> dimTab_(i);
81 for (int i = 0; i < dim_lu; i++)
82 {
83 if (i == 0) Cout<<"directions : "<<dimTab_(0);
84 else Cout<<" "<<dimTab_(i);
85 if (i == (dim_lu-1)) Cout<<finl;
86 }
87 }
88
89 if (un_mot == "MESH_Lagrange_file")
90 {
92 Cout << "reading MED IB mesh ... " <<nom_fichier_med_IB_ <<finl;
93 if (nom_maillage_IB_ == "??")
94 {
95 Cerr<<"Name of the IB Lagrange mesh is required. Please, give it using the keyword MESH_Lagrange_name option before MESH_Lagrange_file."<< finl;
97 }
98
99 LireMED liremed(nom_fichier_med_IB_, nom_maillage_IB_);
100 Nom nom_dom_ = "dom_IB";
101 dom_med_IB_.nommer(nom_dom_);
103 liremed.retrieve_MC_objects();
104 aSkinUMesh_ = liremed.get_mc_mesh()->deepCopy();
105
106 int space_dim = aSkinUMesh_->getSpaceDimension();
107 if (space_dim != Objet_U::dimension)
108 {
109 Cerr<<"Prepro_IBM: MC space dimension = " << space_dim << " is different from Trust space dimension = "<< Objet_U::dimension << finl;
111 }
112 int nbElemSur = int(aSkinUMesh_->getNumberOfCells());
113 int nbNodeSur = int(aSkinUMesh_->getNumberOfNodes());
114 Cerr << "Detecting " << nbNodeSur << " nodes and " << nbElemSur << " cells." << finl;
115 const double *coord = aSkinUMesh_->getCoords()->begin();
116 coordsSur3D_.resize(nbNodeSur, space_dim);
117 std::copy(coord, coord+coordsSur3D_.size_array(), coordsSur3D_.addr());
118
119 MCAuto<MEDCoupling::MEDCouplingFieldDouble> normalField(aSkinUMesh_->buildOrthogonalField());
120 const double *normal = normalField->getArray()->begin();
121 normalArr_.resize(nbElemSur, space_dim);
122 std::copy(normal, normal+normalArr_.size_array(), normalArr_.addr());
123
124 MCAuto<MEDCoupling::DataArrayDouble> baryField(aSkinUMesh_->computeIsoBarycenterOfNodesPerCell());
125 const double *bary = baryField->begin();
126 barySurf_.resize(nbElemSur, space_dim);
127 std::copy(bary, bary+barySurf_.size_array(), barySurf_.addr());
128
129 if (verbose_)
130 {
131 Cout << "=== Test: Display of the first 8 vertices ===" << finl;
132 Cout << "--- Coordinates of the vertices (max 8) ---" << finl;
133 for (int i = 0; i < std::min(8, coordsSur3D_.dimension(0)); i++)
134 {
135 Cout << "Vertex " << i << " : ("
136 << coordsSur3D_(i, 0) << ", " << coordsSur3D_(i, 1);
137 if (space_dim == 3) Cout << ", " << coordsSur3D_(i, 2);
138 Cout << ")" << finl;
139 }
140 Cout << "=== Test: Display of the first 2 barycenters/normals ===" << finl;
141 Cout << "Number of surface elements: " << nbElemSur << finl;
142 Cout << "--- Coordinates of barycenters/normals (max 2) ---" << finl;
143 for (int i = 0; i < std::min(2, barySurf_.dimension(0)); i++)
144 {
145 Cout << "Barycenters " << i << " : ("
146 << barySurf_(i, 0) << ", " << barySurf_(i, 1);
147 if (space_dim == 3) Cout << ", " << barySurf_(i, 2);
148 Cout << ")" << finl;
149 }
150 for (int i = 0; i < std::min(2, normalArr_.dimension(0)); i++)
151 {
152 Cout << "Normals " << i << " : ("
153 << normalArr_(i, 0) << ", " << normalArr_(i, 1);
154 if (space_dim == 3) Cout << ", " << normalArr_(i, 2);
155 Cout << ")" << finl;
156 }
157 }
158 }
159
160 return 1;
161}
162
164{
165 return s << que_suis_je() ;
166}
167
169{
170 mon_pb_=pb;
171 discretiser();
172}
173
175{
176 const Probleme_base& pb = mon_pb_.valeur();
177 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
178 int dim_esp = Objet_U::dimension;
179
180 // Rotation
181 assert(dim_esp==3);
182 int nb_comp=dim_esp*dim_esp;
183 Noms nom_c(nb_comp);
184 Noms unites(nb_comp);
185 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nom_c,unites,nb_comp,0.,champ_rotation_);
186 DoubleTab& rotationArray = champ_rotation_->valeurs();
187 rotationArray = 0.;
188
189 // Aire
190 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,"aire","m^2",1,0., champ_aire_);
191 DoubleTab& aireArray = champ_aire_->valeurs();
192 aireArray = 0.;
193
194 // Barycentres
195 nb_comp=dim_esp;
196 Noms nom_bary(nb_comp);
197 Noms unites_bary(nb_comp);
198 nom_bary[0] = "X";
199 nom_bary[1] = "Y";
200 nom_bary[2] = "Z";
201 unites_bary[0] = "m";
202 unites_bary[1] = "m";
203 unites_bary[2] = "m";
204 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nom_bary,unites_bary,nb_comp,0., champ_bary_);
205 DoubleTab& baryArray = champ_bary_->valeurs();
206 baryArray = 0.;
207
208 // Normales
209 nb_comp=dim_esp;
210 Noms nom_c3(nb_comp);
211 Noms unites3(nb_comp);
212 nom_c3[0] = "nx";
213 nom_c3[1] = "ny";
214 nom_c3[2] = "nz";
215 unites3[0] = "m";
216 unites3[1] = "m";
217 unites3[2] = "m";
218 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nom_c3,unites3,nb_comp,0., champ_normal_);
219 DoubleTab& normalArray = champ_normal_->valeurs();
220 normalArray = 0.;
221
222 // IsNodeDirichlet
223 pb.discretisation().discretiser_champ("champ_sommets",le_dom_dis,"is_node_dirichlet"," ",1,0., isNodeDirichlet_);
224 DoubleTab& isNodeDirichletArray = isNodeDirichlet_->valeurs();
225 isNodeDirichletArray = -1.;
226
227 // h_max_elem & h_max_node
228 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,"h_max_elem"," ",1,0., h_max_elem_);
229 DoubleTab& h_max_elem = h_max_elem_->valeurs();
230 h_max_elem = 0.;
231 pb.discretisation().discretiser_champ("champ_sommets",le_dom_dis,"h_max_node"," ",1,0., h_max_node_);
232 DoubleTab& h_max_node = h_max_node_->valeurs();
233 h_max_node = 0.;
234
235 // coord projection solide
236 nb_comp=dim_esp;
237 Noms nom_c4(nb_comp);
238 nom_c4[0] = "X";
239 nom_c4[1] = "Y";
240 nom_c4[2] = "Z";
241 pb.discretisation().discretiser_champ("champ_sommets", le_dom_dis,vectoriel,nom_c4,unites3,nb_comp,0., solid_points_);
242 DoubleTab& solideArray = solid_points_->valeurs();
243 solideArray = 0.;
244
245 // elem number projection solide
246 pb.discretisation().discretiser_champ("champ_sommets",le_dom_dis,"so_elem_number","",1,0., solid_elems_);
247 DoubleTab& solid_elemsArray = solid_elems_->valeurs();
248 solid_elemsArray = -2.0;
249
250 // coord projection fluide
251 nb_comp=dim_esp;
252 Noms nom_c5(nb_comp);
253 nom_c5[0] = "X";
254 nom_c5[1] = "Y";
255 nom_c5[2] = "Z";
256 pb.discretisation().discretiser_champ("champ_sommets", le_dom_dis,vectoriel,nom_c5,unites3,nb_comp,0., fluid_points_);
257 DoubleTab& fluidArray = fluid_points_->valeurs();
258 fluidArray = 0.;
259
260 // elem number projection fluide
261 pb.discretisation().discretiser_champ("champ_sommets",le_dom_dis,"fl_elem_number","",1,0., fluid_elems_);
262 DoubleTab& fluid_elemsArray = fluid_elems_->valeurs();
263 fluid_elemsArray = -2.0;
264
265 // correspondance elems
266 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,"TRUST_SALOME_correspondance","",1,0., corresp_elems_);
267 DoubleTab& corresp_elemsArray = corresp_elems_->valeurs();
268 int nbElemVol = corresp_elemsArray.dimension(0); // Nombre de cellules du maillage volumique
269 for (int elem = 0; elem <nbElemVol; elem++) corresp_elemsArray(elem) = elem;
270
271 // computing effective error :
273
274 // Intersection Euler/Lagrange si lecture du maillage Lagrangien
275 if (barySurf_.dimension(0)) computeAire2();
276}
277
278void Prepro_IBM_base::computeLocalFrame(const DoubleTab& normal, DoubleTab& t1, DoubleTab& t2, int e)
279{
280 int dim_esp = Objet_U::dimension;
281 assert(dim_esp==dimTab_.dimension(0));
282 assert((t1.dimension(1)==dim_esp)&&(t2.dimension(1)==dim_esp));
283 if (dimTab_(0) && dimTab_(1) && dimTab_(2))
284 {
285 t1(e,0) = normal(e,1)+normal(e,2);
286 t1(e,1) = -normal(e,0)+normal(e,2);
287 t1(e,2) = -(normal(e,0)+normal(e,1));
288 }
289 else if (dimTab_(0) && dimTab_(1) && !(dimTab_(2)))
290 {
291 t1(e,0) = normal(e,1);
292 t1(e,1) = -normal(e,0);
293 t1(e,2) = 0.;
294 }
295 else if (dimTab_(0) && !(dimTab_(1)) && dimTab_(2))
296 {
297 t1(e,0) = normal(e,2);
298 t1(e,1) = 0.;
299 t1(e,2) = -normal(e,0);
300 }
301 else if (!(dimTab_(0)) && dimTab_(1) && dimTab_(2))
302 {
303 t1(e,0) = 0.;
304 t1(e,1) = normal(e,2);
305 t1(e,2) = -normal(e,1);
306 }
307 else if (dimTab_(0) && !(dimTab_(1)) && !(dimTab_(2)))
308 {
309 t1(e,0) = 0.;
310 t1(e,1) = 1.;
311 t1(e,2) = 0.;
312 }
313 else if (!(dimTab_(0)) && dimTab_(1) && !(dimTab_(2)))
314 {
315 t1(e,0) = 0.;
316 t1(e,1) = 0.;
317 t1(e,2) = 1.;
318 }
319 else if (!(dimTab_(0)) && !(dimTab_(1)) && dimTab_(2))
320 {
321 t1(e,0) = 1.;
322 t1(e,1) = 0.;
323 t1(e,2) = 0.;
324 }
325 double nt = 0.;
326 for (int c= 0; c < dim_esp; c++) { nt += t1(e,c)*t1(e,c); }
327 if (sqrt(nt) > 1.0e-12) t1 /= sqrt(nt) ;
328 t2(e,0) = t1(e,1)*normal(e,2)-t1(e,2)*normal(e,1);
329 t2(e,1) = t1(e,2)*normal(e,0)-t1(e,0)*normal(e,2);
330 t2(e,2) = t1(e,0)*normal(e,1)-t1(e,1)*normal(e,0);
331 nt = 0.;
332 for (int c= 0; c < dim_esp; c++) { nt += t2(e,c)*t2(e,c); }
333 if (sqrt(nt) > 1.0e-12) t2 /= sqrt(nt) ;
334}
335
336void Prepro_IBM_base::computeMatRot(const DoubleTab& normal, DoubleTab& t1, DoubleTab& t2, int elem) // calcul de la matrice de rotation
337{
338 DoubleTab& rotationArray = champ_rotation_->valeurs();
339 assert(rotationArray.dimension(1) == Objet_U::dimension * Objet_U::dimension);
340
341 rotationArray(elem, 0) = t2(elem,0);
342 rotationArray(elem, 1) = t1(elem,0);
343 rotationArray(elem, 2) = normal(elem,0) ;
344 rotationArray(elem, 3) = t2(elem,1);
345 rotationArray(elem, 4) = t1(elem,1);
346 rotationArray(elem, 5) = normal(elem,1);
347 rotationArray(elem, 6) = t2(elem,2);
348 rotationArray(elem, 7) = t1(elem,2);
349 rotationArray(elem, 8) = normal(elem,2);
350}
351
353{
354 // PARAM
355 int idebug = verbose_;
356
357 const Domaine_dis_base& le_dom_dis = mon_pb_.valeur().domaine_dis();
358 const Domaine& le_dom = mon_pb_.valeur().domaine();
359 const MEDCouplingUMesh* le_mc_mesh = le_dom.get_mc_mesh();
360
361 DoubleTab& normalArray = champ_normal_->valeurs();
362 DoubleTab& aireArray = champ_aire_->valeurs();
363 DoubleTab& isNodeDirichletArray = isNodeDirichlet_->valeurs();
364 DoubleTab& baryArray = champ_bary_->valeurs();
365
366 int nbPtsDom = le_dom_dis.domaine().nb_som();// Nombre de noeuds du maillage volumique
367 int nbElemVol = aireArray.dimension(0); // Nombre de cellules du maillage volumique
368 assert(nbElemVol==le_mc_mesh->getNumberOfCells());
369 int nbElemSur = normalArr_.dimension(0); // Nombre de cellules (faces) du maillage surfacique
370 int dim_esp = Objet_U::dimension; // dimension Euler
371 assert(normalArr_.dimension(1)==dim_esp);
372
373 DoubleTrav t1Arr(nbElemSur, dim_esp), t2Arr(nbElemSur, dim_esp);
374 Sous_Domaine sdom_mesh3D_loc;
375 sdom_mesh3D_loc.associer_domaine(le_dom);
376 std::vector<mcIdType> numNodes, numNodes2D, numNodes3D;
377 ArrOfDouble mesh2DBBox(2*dim_esp);
378 Octree_Double octree_mesh3D;
379 octree_mesh3D.build_nodes(le_dom.les_sommets(), 0, eps_); //ne pas inclure les sommets virtuels
380 MCAuto<MEDCouplingFieldDouble> measure_aSkinUMesh(aSkinUMesh_->getMeasureField(true));
381 assert(measure_aSkinUMesh->getNumberOfComponents()==1);
382 double mesure_tot_aSkinUMesh = measure_aSkinUMesh->accumulate(0);
383
384 Cerr << "<<<<<<<<<<<<<<<< Prepro_IBM: BEGINNING OF AREA COMPUTATION..." << finl;
385 Cerr << "Prepro_IBM: Computing intersection... with " << nbElemSur << " elements (Lagrangien) and " << nbElemVol << " / " << nbPtsDom << " elements/nodes (Eulerian)" << finl;
386 if (idebug) Cerr << "Domaine 3D : "<< le_dom.nb_som() << " nodes and "<< le_dom.nb_som_elem() <<" per element (Eulerian)" << finl;
387
388 Cerr<<"dimTab_ ("<<dimTab_(0)<<" , "<<dimTab_(1)<<" , "<<dimTab_(2)<<")"<<finl;
389
390 aireArray = 0.;
391 normalArray = 0.;
392 baryArray = 0.;
393 isNodeDirichletArray = -1.;
394 double aire_tot_calcul = 0.;
395 double mesure_sig_aSkinUMesh = 0.;
396 /////////////////////////////////////////////////////////////////////
397 // Boucle sur les elements du maillage surfacique dans l'espace 3D
398 /////////////////////////////////////////////////////////////////////
399 for (int e = 0; e < nbElemSur; e++)
400 {
401 Cerr<<" "<<finl;
402 Cerr<<">>>> surface element number: "<< e <<finl;
403 numNodes.clear();
404 aSkinUMesh_->getNodeIdsOfCell(e, numNodes);
405 int nbNodesSur = int(numNodes.size());
406 Cerr<<"nbNodesSur = "<< nbNodesSur <<finl;
407
408 // definition du repere local (normalArr_, t1Arr, t2Arr)
409 Cerr << "normalArr_ (" << normalArr_(e,0) ;
410 for (int cc = 1; cc <dim_esp; cc++) Cerr << " ,"<<normalArr_(e,cc);
411 Cerr << ")" << finl;
412 computeLocalFrame(normalArr_, t1Arr, t2Arr, e);
413 Cerr << "t1Arr[e]_ (" << t1Arr(e,0);
414 for (int cc = 1; cc <dim_esp; cc++) Cerr << " ," << t1Arr(e,cc);
415 Cerr << " )" << finl;
416 Cerr << "t2Arr[e]_ (" << t2Arr(e,0);
417 for (int cc = 1; cc <dim_esp; cc++) Cerr << " ," << t2Arr(e,cc);
418 Cerr << ")" << finl;
419 if (idebug) Cerr<<"barySurf[e]_ ("<<barySurf_(e, 0)<<" , "<<barySurf_(e, 1)<<" , "<<barySurf_(e, 2)<<")"<<finl;
420
421 // Mesh 2D de la facette 3D numero e
422 MCAuto<MEDCouplingUMesh> mesh2DSurf(MEDCouplingUMesh::New("surf_"+std::to_string(e),2));
423 DoubleTrav surfCoords2D(nbNodesSur, 2);
424 for (int node =0; node < nbNodesSur; node++)
425 {
426 int numNode = int(numNodes[node]);
427 surfCoords2D(node,0) = (coordsSur3D_(numNode,0)-barySurf_(e,0))*t1Arr(e,0) + (coordsSur3D_(numNode,1)-barySurf_(e,1))*t1Arr(e,1) + (coordsSur3D_(numNode,2)-barySurf_(e,2))*t1Arr(e,2);
428 surfCoords2D(node,1) = (coordsSur3D_(numNode,0)-barySurf_(e,0))*t2Arr(e,0) + (coordsSur3D_(numNode,1)-barySurf_(e,1))*t2Arr(e,1) + (coordsSur3D_(numNode,2)-barySurf_(e,2))*t2Arr(e,2);
429 }
430 MCAuto<MEDCoupling::DataArrayDouble> array(MEDCoupling::DataArrayDouble::New());
431 array->alloc(nbNodesSur, 2);
432 std::copy(surfCoords2D.addr(), surfCoords2D.addr() + surfCoords2D.size_array(), array->getPointer());
433 array->declareAsNew();
434 mesh2DSurf->setCoords(array);
435 mesh2DSurf->allocateCells(1);
436 IntTrav mesh2DSurf_conect(1, nbNodesSur);
437 for (int node =0; node < nbNodesSur; node++) mesh2DSurf_conect(0,node) = node;
438 auto ptr = mesh2DSurf_conect.addr();
439 std::vector<mcIdType> tmp(ptr, ptr+nbNodesSur);
440 INTERP_KERNEL::NormalizedCellType typ_fac_mc = INTERP_KERNEL::NORM_POLYGON;
441 mesh2DSurf->insertNextCell(typ_fac_mc, nbNodesSur, tmp.data());
442 mesh2DSurf->finishInsertingCells();
443
444 if (idebug)
445 {
446 numNodes2D.clear();
447 mesh2DSurf->getNodeIdsOfCell(0, numNodes2D);
448 const double *mesh2DSurf_coords = mesh2DSurf->getCoords()->begin();
449 DoubleTab Surf2DCoordonnes;
450 Surf2DCoordonnes.resize(int(mesh2DSurf->getNumberOfNodes()), 2);
451 std::copy(mesh2DSurf_coords, mesh2DSurf_coords+Surf2DCoordonnes.size_array(), Surf2DCoordonnes.addr());
452 Cerr << "mesh2DSurf : "<<mesh2DSurf->getNumberOfCells()<<" cells and "<<mesh2DSurf->getNumberOfNodes()<< " nodes in 2D space"<<finl;
453 for (int n = 0; n <mesh2DSurf->getNumberOfNodes(); n++)
454 {
455 for (int cc = 0; cc <2; cc++) Cerr <<Surf2DCoordonnes(n, cc) <<" ";
456 Cerr << finl;
457 }
458 Cerr << "mesh2DSurf : nb nodes cell #1 = "<<int(numNodes2D.size())<<finl;
459 for (int n = 0; n <int(numNodes2D.size()); n++)
460 {
461 Cerr <<int(numNodes2D[n]) <<" ";
462 }
463 Cerr << finl;
464 }
465
466 // Calcul de la Bounding Box 3D du polygone 2D
467 for (int c =0; c < dim_esp; c++)
468 {
469 int index0 = 2*c;
470 int index1 = index0 + 1;
471 mesh2DBBox(index0) = 1.e+30; // min
472 mesh2DBBox(index1) = -1.e+30; // max
473 for (int k =0; k < nbNodesSur; k++)
474 {
475 int numNode = int(numNodes[k]);
476 if (coordsSur3D_(numNode,c) <= mesh2DBBox(index0)) mesh2DBBox(index0) = coordsSur3D_(numNode,c);
477 if (coordsSur3D_(numNode,c) >= mesh2DBBox(index1)) mesh2DBBox(index1) = coordsSur3D_(numNode,c);
478 // Cerr<<"coordsSur3D_("<<numNode<<","<<c<<") = "<<coordsSur3D_(numNode,c)<<finl;
479 }
480 mesh2DBBox(index0) -= eps_effec_;
481 mesh2DBBox(index1) += eps_effec_;
482 }
483 Cerr<<"mesh2DBBox = ";
484 for (int cc = 0; cc <dim_esp; cc++) Cerr<<"["<<mesh2DBBox(2*cc)<<", "<<mesh2DBBox(2*cc+1)<<"] ";
485 Cerr<<finl;
486
487 // Détection des éléments volumiques dans la Bounding Box
488 const double bbox[] = {mesh2DBBox(0), mesh2DBBox(1), mesh2DBBox(2), mesh2DBBox(3), mesh2DBBox(4), mesh2DBBox(5)};
489 MCAuto<MEDCoupling::DataArrayIdType> cellIdsArr(le_mc_mesh->getCellsInBoundingBox(bbox, 0.)); //precision = 0 pour ne pas avoir d'element 3D non coupe par la frontiere
490 const mcIdType *daP = cellIdsArr->begin();
491 int NbCellsInBB = int(cellIdsArr->getNumberOfTuples());
492 int NbCompsInBB = int(cellIdsArr->getNumberOfComponents());
493 Cerr<<"getCellsInBoundingBox cellIdsArr : Nb Cells, Nb comp = "<< NbCellsInBB << " "<< NbCompsInBB<< finl;
494 Cerr<<" " ;
495 for (int k = 0; k <NbCellsInBB ; k++) Cerr<< (int)daP[k] <<" " ;
496 Cerr<< finl;
497
498
499 double aire_elem_calcul = 0.;
500 ////////////////////////////////////////////////////////////////////////////
501 // Calcul de l'intersection volume-surface pour chaque element intercepte
502 ////////////////////////////////////////////////////////////////////////////
503 for (int k = 0; k < NbCellsInBB; k++)
504 {
505 int my_elem = (int)daP[k];
506 if (idebug) Cerr<<"**** num elem = "<<my_elem<<" ****"<<finl ;
507
508 // maillage 3D Euler MC 1 cell
509 const mcIdType cellIds[1]= {my_elem};
510 MCAuto<MEDCouplingUMesh> mesh3D(le_mc_mesh->buildPartOfMySelf(cellIds,cellIds+1,false));
511 assert(mesh3D->getNumberOfCells()==1);
512 int NumberOfNodes3D = int(mesh3D->getNumberOfNodes());
513
514 // verification element mesh3D intercepte par plan infini
515 const double *crd3D = mesh3D->getCoords()->begin();
516 DoubleTab coord3D;
517 coord3D.resize(NumberOfNodes3D, dim_esp);
518 std::copy(crd3D, crd3D+coord3D.size_array(), coord3D.addr());
519 double signmult0;
520 int istop = 1;
521 for (int node3D = 0; node3D <NumberOfNodes3D ; node3D++)
522 {
523 double ps3D = 0.;
524 for (int cc = 0; cc <dim_esp; cc++) ps3D += (coord3D(node3D,cc) - barySurf_(e,cc)) * normalArr_(e,cc);
525 if (node3D == 0) {signmult0 = ps3D;}
526 else if (signmult0 * ps3D < 0.) istop = 0;
527 }
528 if (istop)
529 {
530 if (idebug) Cerr<<"Element not intercepted " <<finl;
531 continue;
532 }
533
534 // on calcule l'intersection entre l'element volumique mesh3D et l'element surfacique "e"
535 const double origin[] = {barySurf_(e,0), barySurf_(e,1), barySurf_(e,2)};
536 const double vec[] = {normalArr_(e,0), normalArr_(e,1), normalArr_(e,2)};
537 if (idebug)
538 {
539 Cerr<<"origin element surfacique "<<e<<" = ";
540 for (int cc = 0; cc <dim_esp; cc++) Cerr<< origin[cc]<<" ";
541 Cerr << finl;
542 Cerr<<"vec normal element surfacique "<<e<<" = ";
543 for (int cc = 0; cc <dim_esp; cc++) Cerr<< vec[cc]<<" ";
544 Cerr << finl;
545 }
546 MEDCoupling::DataArrayIdType * polycellIds = nullptr;
547 try
548 {
549 // Intersection par un plan infini
550 MCAuto<MEDCouplingUMesh> interPoly3D(mesh3D->buildSlice3D(origin, vec, 0., polycellIds));
551 MCAuto<MEDCoupling::DataArrayIdType> polycellIdsAuto(polycellIds);
552 int nbCellsPoly3D = int(interPoly3D->getNumberOfCells());
553 int NumberOfNodes = int(interPoly3D->getNumberOfNodes());
554 const double *interCoords3D = interPoly3D->getCoords()->begin();
555 DoubleTrav interCoordonnes3D;
556 interCoordonnes3D.resize(NumberOfNodes, dim_esp);
557 std::copy(interCoords3D, interCoords3D+interCoordonnes3D.size_array(), interCoordonnes3D.addr());
558
559 // Mesh 2D du polygone d'intersection en 3D interPoly3D
560 numNodes3D.clear();
561 interPoly3D->getNodeIdsOfCell(0, numNodes3D);
562 int nbNodesCell1 = int(numNodes3D.size());
563 if (nbCellsPoly3D != 1)
564 {
565 Cerr<<"<Nb cells> interPoly3D = "<<nbCellsPoly3D<<" <> 1. Exit"<<finl;
567 }
568 // A priori, les noeuds de mesh3D sont repris dans interPoly3D (en debut de la liste de noeuds)
569 if (idebug)
570 {
571 Cerr << "<Nb cells> interPoly3D = "<<nbCellsPoly3D<<finl;
572 Cerr << "<Nb nodes> mesh3D, interPoly3D and Cell#1 = "<<NumberOfNodes3D<<" "<<NumberOfNodes<<" "<<nbNodesCell1<<finl;
573 }
574 assert((NumberOfNodes - NumberOfNodes3D) == nbNodesCell1);
575 MCAuto<MEDCouplingUMesh> interPoly2D(MEDCouplingUMesh::New("interPoly2D_"+std::to_string(my_elem),2));
576 DoubleTrav interPolyCoords2D(nbNodesCell1, (dim_esp - 1));
577 for (int node = 0; node <nbNodesCell1 ; node++)
578 {
579 int numNode = int(numNodes3D[node]);
580 interPolyCoords2D(node,0) = (interCoordonnes3D(numNode,0)-barySurf_(e,0))*t1Arr(e,0) + (interCoordonnes3D(numNode,1)-barySurf_(e,1))*t1Arr(e,1) + (interCoordonnes3D(numNode,2)-barySurf_(e,2))*t1Arr(e,2);
581 interPolyCoords2D(node,1) = (interCoordonnes3D(numNode,0)-barySurf_(e,0))*t2Arr(e,0) + (interCoordonnes3D(numNode,1)-barySurf_(e,1))*t2Arr(e,1) + (interCoordonnes3D(numNode,2)-barySurf_(e,2))*t2Arr(e,2);
582 }
583 MCAuto<MEDCoupling::DataArrayDouble> interPolyarray2D(MEDCoupling::DataArrayDouble::New());
584 interPolyarray2D->alloc(nbNodesCell1, 2);
585 std::copy(interPolyCoords2D.addr(), interPolyCoords2D.addr() + interPolyCoords2D.size_array(), interPolyarray2D->getPointer());
586 interPolyarray2D->declareAsNew();
587 interPoly2D->setCoords(interPolyarray2D);
588 interPoly2D->allocateCells(1);
589 IntTrav Poly2D_conect(1, nbNodesCell1);
590 for (int node =0; node < nbNodesCell1; node++) Poly2D_conect(0,node) = node;
591 auto Poly2D_ptr = Poly2D_conect.addr();
592 std::vector<mcIdType> Poly2D_tmp(Poly2D_ptr, Poly2D_ptr+ nbNodesCell1);
593 typ_fac_mc = INTERP_KERNEL::NORM_POLYGON;
594 interPoly2D->insertNextCell(typ_fac_mc, nbNodesCell1, Poly2D_tmp.data());
595 interPoly2D->finishInsertingCells();
596
597 if (idebug)
598 {
599 numNodes2D.clear();
600 interPoly2D->getNodeIdsOfCell(0, numNodes2D);
601 const double *interPoly2D_coords = interPoly2D->getCoords()->begin();
602 DoubleTab interPoly2DCoordonnes;
603 interPoly2DCoordonnes.resize(int(interPoly2D->getNumberOfNodes()), (dim_esp-1));
604 std::copy(interPoly2D_coords, interPoly2D_coords+interPoly2DCoordonnes.size_array(), interPoly2DCoordonnes.addr());
605 Cerr << "interPoly2D : "<<interPoly2D->getNumberOfCells()<<" cells and "<<interPoly2D->getNumberOfNodes()<< " nodes in 2D space"<<finl;
606 for (int n = 0; n <interPoly2D->getNumberOfNodes(); n++)
607 {
608 for (int cc = 0; cc <(dim_esp-1); cc++) Cerr <<interPoly2DCoordonnes(n, cc) <<" ";
609 Cerr << finl;
610 }
611 Cerr << "interPoly2D : nb nodes cell #1 = "<<int(numNodes2D.size())<<finl;
612 for (int n = 0; n <int(numNodes2D.size()); n++)
613 {
614 Cerr <<int(numNodes2D[n]) <<" ";
615 }
616 Cerr << finl;
617 }
618
619 ////////////////////////////////////////////////////////////////////////////////////
620 // Intersection des polygones 2D de la facette e et de la coupe de l'element my_elem
621 ////////////////////////////////////////////////////////////////////////////////////
622 int status_polypoly = 0;
623 DoubleTab finalcoords;
624 IntTab Tab_conect;
625 intersectPolyPoly2D(interPoly2D, mesh2DSurf, finalcoords, Tab_conect, eps_effec_, status_polypoly);
626 if (idebug && (status_polypoly != 0)) Cerr<<"status intersectPolyPoly2D : "<<status_polypoly<<finl;
627 if (status_polypoly != 0) continue; // next cell
628
629 MCAuto<MEDCouplingUMesh> finalMesh(MEDCouplingUMesh::New("output_mesh",(dim_esp-1)));
630 finalMesh->allocateCells(1);
631
632 MCAuto<MEDCoupling::DataArrayDouble> outputCoords(MEDCoupling::DataArrayDouble::New());
633 outputCoords->alloc(finalcoords.dimension(0), finalcoords.dimension(1));
634 std::copy(finalcoords.addr(), finalcoords.addr() + finalcoords.size_array(), outputCoords->getPointer());
635 outputCoords->declareAsNew();
636 finalMesh->setCoords(outputCoords);
637 auto connect_ptr = Tab_conect.addr();
638 std::vector<mcIdType> finalConnect(connect_ptr, connect_ptr+Tab_conect.dimension(1) );
639 finalMesh->insertNextCell(typ_fac_mc, Tab_conect.dimension(1), finalConnect.data());
640 finalMesh->finishInsertingCells();
641
642
643 // Definition 3D des noeuds de finalmesh 2D
644 DoubleTab interCoordonnes;
645 interCoordonnes.resize(int(finalMesh->getNumberOfNodes()), dim_esp);
646 for (int node =0; node < interCoordonnes.dimension(0); node++)
647 for (int kd=0; kd<dim_esp; kd++)
648 interCoordonnes(node,kd) = barySurf_(e,kd) + finalcoords(node,0)*t1Arr(e,kd) + finalcoords(node,1)*t2Arr(e,kd);
649
650 if (idebug)
651 {
652 Cerr << "finalMesh : "<<int(finalMesh->getNumberOfCells())<<" cells and "<<int(finalMesh->getNumberOfNodes())<< " node in 2D space : "<<" ";
653 for (int cell=0; cell < finalMesh->getNumberOfCells(); cell++)
654 {
655 numNodes2D.clear();
656 finalMesh->getNodeIdsOfCell(cell, numNodes2D);
657 for (int n = 0; n <int(numNodes2D.size()); n++)
658 {
659 Cerr <<int(numNodes2D[n]) <<" ";
660 }
661 Cerr << finl;
662 }
663 for (int n = 0; n <finalMesh->getNumberOfNodes(); n++)
664 {
665 for (int cc = 0; cc <2; cc++) Cerr <<finalcoords(n, cc) <<" ";
666 Cerr<<" ( ";
667 for (int cc = 0; cc <dim_esp; cc++) Cerr <<interCoordonnes(n, cc) <<" ";
668 Cerr <<" ) "<< finl;
669 }
670 }
671
672 /////////////////////////////////////////////////////////////////////////
673 // Exploitation des results d'intersection pour calcul barycentre et aire
674 /////////////////////////////////////////////////////////////////////////
675 int nbpts = interCoordonnes.dimension(0);
676 double inv_nbpts =1.0 /( double(nbpts));
677 DoubleTab baryMean(dim_esp);
678 baryMean= 0.;
679 for (int cc = 0; cc <dim_esp; cc++)
680 for (int n = 0; n <nbpts; n++) baryMean(cc) += interCoordonnes(n, cc);
681 baryMean *= inv_nbpts;
682 if (idebug)
683 {
684 Cerr << "finalMesh : mean barycenter = ";
685 for (int cc = 0; cc <dim_esp; cc++) Cerr << baryMean(cc) <<" ";
686 Cerr << finl;
687 }
688 MCAuto<MEDCouplingFieldDouble> measure(finalMesh->getMeasureField(true));
689 assert(measure->getNumberOfValues()==1);
690 double aire = measure->accumulate(0);
691 if (idebug) Cerr<<"Element measure finalMesh = "<<aire<<finl;
692 aire_elem_calcul += aire;
693
694 aireArray(my_elem) += aire;
695 for (int cc = 0; cc <dim_esp; cc++) baryArray(my_elem, cc) += aire * baryMean(cc);
696 for (int cc = 0; cc <dim_esp; cc++) normalArray(my_elem, cc) += aire*normalArr_(e,cc);
697 numNodes.clear();
698 le_mc_mesh->getNodeIdsOfCell(my_elem, numNodes);
699 int nbNodesElem = int(numNodes.size()), the_node = 0;
700 for (int l = 0; l <nbNodesElem; l++)
701 {
702 the_node = int(numNodes[l]);
703 isNodeDirichletArray(the_node) = 1.0 ;
704 }
705
706 if (idebug)
707 {
708 Cerr<<"TRUST element aireArray measure = "<<aireArray(my_elem)<<finl;
709 Cerr<<"TRUST element aire weighted baryArray = ";
710 for (int cc = 0; cc <dim_esp; cc++) Cerr<<baryArray(my_elem,cc)<<" ";
711 Cerr<<finl;
712 Cerr<<"TRUST element aire weighted normalArray = ";
713 for (int cc = 0; cc <dim_esp; cc++) Cerr<<normalArray(my_elem,cc)<<" ";
714 Cerr<<finl;
715 Cerr<<"TRUST isNodeDirichletArray= 1 for nodes = ";
716 for (int l = 0; l <nbNodesElem; l++) Cerr<< numNodes[l] <<" ";
717 Cerr<<finl;
718 }
719 }
720 catch (const std::runtime_error& err)
721 {
722 std::cerr << "Erreur : " << err.what() << std::endl;
723 }
724 }
725
726 // Bilan AIre element e
727 aire_tot_calcul += aire_elem_calcul ;
728 const auto* arrayskin = measure_aSkinUMesh->getArray();
729 if (arrayskin->getNumberOfComponents() != 1)
730 Process::exit("measure_aSkinUMesh should have one composant \n");
731 const double val1 = arrayskin->getIJ(e, 0);
732
733 Cerr<<"///////////// Measure of surface for element "<<e<<" = "<<val1<<finl;
734 Cerr<<"///////////// Measure of computed surface for element "<<e<<" = "<<aire_elem_calcul <<finl;
735
736 sdom_mesh3D_loc.les_elems().reset();
737 mesure_sig_aSkinUMesh += val1;
738 }
739
740 // Barycentres et Normales moyens ponderes par les aires
741 DoubleTrav t1EulerArr(nbElemVol, dim_esp), t2EulerArr(nbElemVol, dim_esp);
742 for (int elem = 0; elem <nbElemVol; elem++)
743 {
744 if (aireArray(elem) >0.)
745 {
746 double norm = 0.;
747 for (int cc = 0; cc <dim_esp; cc++)
748 {
749 baryArray(elem, cc) /= aireArray(elem) ;
750 normalArray(elem, cc) /= aireArray(elem) ;
751 norm += normalArray(elem, cc)*normalArray(elem, cc);
752 }
753 norm = sqrt(norm);
754 for (int cc = 0; cc <dim_esp; cc++) normalArray(elem, cc) /= norm; // normalisation;
755 // Matrice rotation
756 computeLocalFrame(normalArray, t1EulerArr, t2EulerArr, elem);
757 computeMatRot(normalArray, t1EulerArr, t2EulerArr, elem);
758 }
759 }
760
761 // Bilan AIre totale
762 Cerr<<" "<<finl;
763 Cerr<<"Measure of total surface for Immersed Boundary = "<<mesure_tot_aSkinUMesh<<finl;
764 Cerr<<"Measure of sum of elementary surfaces for Immersed Boundary = "<<mesure_sig_aSkinUMesh<<finl;
765 Cerr<<"Measure of total computed surface = "<<aire_tot_calcul<<" >>>>>>>>>>>>>>>>"<<finl;
766
767 aireArray.echange_espace_virtuel();
768 baryArray.echange_espace_virtuel();
769 normalArray.echange_espace_virtuel();
770 DoubleTab& rotationArray = champ_rotation_->valeurs();
771 rotationArray.echange_espace_virtuel();
772 isNodeDirichletArray.echange_espace_virtuel();
773}
774
775void Prepro_IBM_base::intersectPolyPoly2D(MEDCouplingUMesh * polyMesh1, MEDCouplingUMesh * polyMesh2, DoubleTab& finalcoords, IntTab& Tab_conect, double eps, int& status)
776{
777 int idebug = verbose_;
778 if (status != 0) status = 0;
779 int dim_esp = Objet_U::dimension;
780 MCAuto<MEDCoupling::DataArrayDouble> outputCoords(MEDCoupling::DataArrayDouble::New());
781 MCAuto<MEDCoupling::DataArrayDouble> MC_p_test(MEDCoupling::DataArrayDouble::New());
782 MCAuto<MEDCoupling::DataArrayDouble> dv_outputCoords(MEDCoupling::DataArrayDouble::New());
783
784 // Edges polyMesh1
785 const double *mc_coords1 = polyMesh1->getCoords()->begin();
786 int nbNodes1 = int(polyMesh1->getNumberOfNodes());
787 DoubleTrav coords1;
788 coords1.resize(nbNodes1, (dim_esp-1));
789 std::copy(mc_coords1, mc_coords1+coords1.size_array(), coords1.addr());
790 MCAuto<MEDCouplingUMesh> polyEdgeMesh1(polyMesh1->buildBoundaryMesh(false));
791 int nbEdge1 = int(polyEdgeMesh1->getNumberOfCells());
792 if (idebug)
793 {
794 Cerr<<">>> Prepro_IBM_base::intersectPolyPoly2D: Cell and node nb polyEdgeMesh1 = "<<int(polyEdgeMesh1->getNumberOfCells())<<" "<<int(polyEdgeMesh1->getNumberOfNodes())<<finl;
795 }
796
797 // Edges polyMesh2
798 const double *mc_coords2 = polyMesh2->getCoords()->begin();
799 int nbNodes2 = int(polyMesh2->getNumberOfNodes());
800 DoubleTrav coords2;
801 coords2.resize(nbNodes2, (dim_esp-1));
802 std::copy(mc_coords2, mc_coords2+coords2.size_array(), coords2.addr());
803 MCAuto<MEDCouplingUMesh> polyEdgeMesh2(polyMesh2->buildBoundaryMesh(false));
804 if (idebug)
805 {
806 Cerr<<">>> Prepro_IBM_base::intersectPolyPoly2D: Cell and node nb polyEdgeMesh2 = "<<int(polyEdgeMesh2->getNumberOfCells())<<" "<<int(polyEdgeMesh2->getNumberOfNodes())<<finl;
807 }
808
809 // Prendre tous les noeuds de polyMesh1 inclus dans polyMesh2
810 DoubleTrav p_test(dim_esp-1);
811 for (int i=0; i<nbNodes1; i++)
812 {
813 for (int k=0; k<(dim_esp-1); k++) p_test(k) = coords1(i,k);
814 if (polyMesh2->getCellContainingPoint(p_test.addr(), eps) != -1)
815 {
816 MC_p_test->alloc(1, (dim_esp-1));
817 std::copy(p_test.addr(), p_test.addr() + (dim_esp-1), MC_p_test->getPointer());
818 MC_p_test->declareAsNew();
819 if (outputCoords->isAllocated())
820 {
821 outputCoords->aggregate(MC_p_test);
822 }
823 else
824 {
825 outputCoords->alloc(1,(dim_esp-1));
826 double * tmp = outputCoords->getPointer();
827 std::copy(p_test.addr(), p_test.addr() + (dim_esp-1), tmp);
828 outputCoords->declareAsNew(); // you have modified data pointed by internal pointer notify object
829 }
830 }
831 }
832 // Prendre tous les noeuds de polyMesh2 inclus dans polyMesh1
833 for (int i=0; i<nbNodes2; i++)
834 {
835 for (int k=0; k<(dim_esp-1); k++) p_test(k) = coords2(i,k);
836 if (polyMesh1->getCellContainingPoint(p_test.addr(), eps) != -1)
837 {
838 MC_p_test->alloc(1, (dim_esp-1));
839 std::copy(p_test.addr(), p_test.addr() + (dim_esp-1), MC_p_test->getPointer());
840 MC_p_test->declareAsNew();
841 if (outputCoords->isAllocated())
842 {
843 outputCoords->aggregate(MC_p_test);
844 }
845 else
846 {
847 outputCoords->alloc(1,(dim_esp-1));
848 double * tmp = outputCoords->getPointer();
849 std::copy(p_test.addr(), p_test.addr() + (dim_esp-1), tmp);
850 outputCoords->declareAsNew(); // you have modified data pointed by internal pointer notify object
851 }
852 }
853 }
854 if (!(outputCoords->isAllocated()))
855 {
856 status = -2;
857 return;
858 }
859
860 // Prendre les points d'intersection
861 for (int i=0; i<nbEdge1; i++)
862 {
863 std::vector< mcIdType > numNodes;
864 polyEdgeMesh1->getNodeIdsOfCell(i, numNodes);
865 if (numNodes.size() > 2)
866 {
867 Cerr<<">>>Prepro_IBM_base::intersectPolyPoly2D(): node nb = "<<numNodes.size()<<" for edge "<<i<<" => CHELOU..."<<finl;
868 status = -1;
869 return;
870 }
871 DoubleTrav point0(dim_esp-1), point1(dim_esp-1);
872 for (int k=0; k<(dim_esp-1); k++) point0(k) = coords1(int(numNodes[0]),k);
873 for (int k=0; k<(dim_esp-1); k++) point1(k) = coords1(int(numNodes[1]),k);
874 if (idebug)
875 {
876 Cerr<<">>> Prepro_IBM_base::intersectPolyPoly2D(): polyEdgeMesh1: edge "<<i<<" nodes ";
877 for (int ii=0; ii<int(numNodes.size()); ii++) Cerr<<numNodes[ii]<<" ";
878 Cerr<<finl;
879 Cerr<<" point0: "<<point0(0)<<" "<<point0(1)<<finl;
880 Cerr<<" point1: "<<point1(0)<<" "<<point1(1)<<finl;
881 }
882 int status_segpoly = 0;
883 intersectSegPoly2D(polyEdgeMesh2, point0, point1, eps, outputCoords, status_segpoly);
884 }
885 if (idebug) Cerr<<">>> Prepro_IBM_base::intersectPolyPoly2D(): outputCoords nodes after intersectSegPoly2D = "<<int(outputCoords->getNumberOfTuples())<<finl;
886
887 MCAuto<MEDCouplingUMesh> outputMesh(MEDCouplingUMesh::New("output_mesh",(dim_esp-1)));
888 outputMesh->allocateCells(1);
889
890 MEDCoupling::DataArrayIdType *connect = 0, *connInd = 0;
891 outputCoords->findCommonTuples(eps, -1, connect, connInd);
892 MCAuto<MEDCoupling::DataArrayIdType> connectAuto(connect);
893 MCAuto<MEDCoupling::DataArrayIdType> connIndAuto(connInd);
894 if (idebug) Cerr<<" connect and connInd tuples after findCommonTuples = "<<int(connect->getNumberOfTuples())<<" "<<int(connInd->getNumberOfTuples())<<finl;
895 if(int(connect->getNumberOfTuples()) > 0)
896 {
897 dv_outputCoords = outputCoords->getDifferentValues(eps);
898 if (idebug) Cerr<<" nodes nb after getDifferentValues = "<<int(dv_outputCoords->getNumberOfTuples())<<finl;
899 outputMesh->setCoords(dv_outputCoords);
900 }
901 else outputMesh->setCoords(outputCoords);
902
903 const MEDCoupling::DataArrayDouble *finalCoords = outputMesh->getCoords();
904 int finalCoords_len = int(finalCoords->getNumberOfTuples());
905 if (idebug) Cerr<<" Nb of tuples in finalCoords = "<<finalCoords_len<<finl;
906 if (finalCoords_len < 3)
907 {
908 status = -3; //seulement une droite intersection
909 return;
910 }
911
912 Tab_conect.resize(1, finalCoords_len);
913 for (int node =0; node < finalCoords_len; node++) Tab_conect(0,node) = node;
914 auto connect_ptr = Tab_conect.addr();
915 std::vector<mcIdType> Connect(connect_ptr, connect_ptr+Tab_conect.dimension(1));
916 INTERP_KERNEL::NormalizedCellType typ_fac_mc = INTERP_KERNEL::NORM_POLYGON;
917 outputMesh->insertNextCell(typ_fac_mc, Tab_conect.dimension(1), Connect.data());
918 outputMesh->finishInsertingCells();
919
920 // Butterfly ?
921 // std::vector<mcIdType> cells;
922 // cells.clear();
923 // outputMesh->checkButterflyCells(cells, eps);
924 // if( cells.size() > 0)
925 // {
926 // MEDCoupling::DataArrayIdType * modif_cell = outputMesh->convexEnvelop2D();
927 // if (modif_cell != nullptr)
928 // {
929 // int modNodNb = int(modif_cell->getNumberOfComponents());
930 // Cerr<<" Modified cell connectivity by convexEnvelop2D for "<<modNodNb<<" nodes"<<finl;
931 // }
932 // }
933
934 // Connectivite 2D
935 std::vector<mcIdType> numNodes2D;
936 numNodes2D.clear();
937
938 // Test aire < eps ;
939 MCAuto<MEDCouplingFieldDouble> measure(outputMesh->getMeasureField(true));
940 double aire = measure->accumulate(0);
941 if (aire<eps)
942 {
943 DoubleTab coords;
944 coords.resize(int(outputMesh->getNumberOfNodes()), outputMesh->getMeshDimension());
945 const double *mc_Coords = outputMesh->getCoords()->begin();
946 std::copy(mc_Coords, mc_Coords+coords.size_array(), coords.addr());
947 Cerr << "intersectPolyPoly2D: Element measure outputMesh = "<<aire<<" with tuples : " << finl;
948 for (int n = 0; n <int(outputMesh->getNumberOfNodes()); n++)
949 {
950 for (int cc = 0; cc < outputMesh->getMeshDimension(); cc++) Cerr <<coords(n, cc) <<" ";
951 Cerr << finl;
952 }
953 outputMesh->getNodeIdsOfCell(0, numNodes2D);
954 for (int node =0; node < int(numNodes2D.size()); node++) Cerr <<int(numNodes2D[node]) <<" ";
955 Cerr << finl;
956
957 if (int(outputMesh->getCoords()->getNumberOfTuples()) == 4)
958 {
959 // exchange conectivity 3<->2 of initial mesh
960 const mcIdType old2newIds[] = {0, 1, 3, 2};
961 outputMesh->renumberNodesInConn(old2newIds);
962 numNodes2D.clear();
963 outputMesh->getNodeIdsOfCell(0, numNodes2D);
964 MCAuto<MEDCouplingFieldDouble> measure_modified(outputMesh->getMeasureField(true));
965 aire = measure_modified->accumulate(0);
966 Cerr<<" Element measure outputMesh = "<<aire<<" with modified cell connectivity => ";
967 for (int node =0; node < int(numNodes2D.size()); node++) Cerr <<int(numNodes2D[node]) <<" ";
968 Cerr << finl;
969
970 if (aire<eps)
971 {
972 // exchange conectivity 3<->0 of initial mesh
973 const mcIdType old2newIds_bis[] = {0, 1, 3, 2};
974 outputMesh->renumberNodesInConn(old2newIds_bis);
975 const mcIdType old2newIds_ter[] = {3, 1, 2, 0};
976 outputMesh->renumberNodesInConn(old2newIds_ter);
977 numNodes2D.clear();
978 outputMesh->getNodeIdsOfCell(0, numNodes2D);
979 MCAuto<MEDCouplingFieldDouble> measure_modified_bis(outputMesh->getMeasureField(true));
980 aire = measure_modified_bis->accumulate(0);
981 Cerr<<" Element measure outputMesh = "<<aire<<" with modified cell connectivity => ";
982 for (int node =0; node < int(numNodes2D.size()); node++) Cerr <<int(numNodes2D[node]) <<" ";
983 Cerr << finl;
984
985 if (aire<eps)
986 {
987 Cerr<<"Element measure outputMesh = "<<aire;
988 Cerr<<" nothing to do :-( "<<finl;
989 status = -4;
990 // Process::exit();
991 return;
992 }
993 }
994 }
995 else
996 {
997 Cerr<<" Element measure outputMesh = 0. Wrong number of nodes <> 4 : "<<int(outputMesh->getCoords()->getNumberOfTuples())<<finl;
998 status = -4;
999 // Process::exit();
1000 return;
1001 }
1002 }
1003
1004 // Tables de sortie
1005 const double *mc_finalCoords = outputMesh->getCoords()->begin();
1006 finalcoords.resize(int(outputMesh->getNumberOfNodes()), outputMesh->getMeshDimension());
1007 std::copy(mc_finalCoords, mc_finalCoords+finalcoords.size_array(), finalcoords.addr());
1008
1009 numNodes2D.clear();
1010 outputMesh->getNodeIdsOfCell(0, numNodes2D);
1011 for (int node =0; node < int(numNodes2D.size()); node++) Tab_conect(0,node) = int(numNodes2D[node]);
1012
1013 return;
1014}
1015
1016// intersection d'un segment avec un polygone
1017void Prepro_IBM_base::intersectSegPoly2D(MEDCouplingUMesh * polyEdgeMesh, DoubleTab& p1, DoubleTab& p2, double eps, MCAuto<MEDCoupling::DataArrayDouble> outputCoords, int& status)
1018{
1019 int idebug = verbose_;
1020 int dim_esp = Objet_U::dimension;
1021 if (status != 0) status = 0 ;
1022
1023 int nbEdge = int(polyEdgeMesh->getNumberOfCells());
1024 int nbNodes = int(polyEdgeMesh->getNumberOfNodes());
1025 const double *mc_coords = polyEdgeMesh->getCoords()->begin();
1026 DoubleTrav coords;
1027 coords.resize(nbNodes, (dim_esp-1));
1028 std::copy(mc_coords, mc_coords+coords.size_array(), coords.addr());
1029 std::vector<mcIdType> numNodes;
1030
1031 MCAuto<MEDCoupling::DataArrayDouble> MC_p(MEDCoupling::DataArrayDouble::New());
1032 DoubleTrav pe1(dim_esp-1);
1033 DoubleTrav pe2(dim_esp-1);
1034 if (idebug) Cerr<<">> Prepro_IBM_base::intersectSegPoly2D: Edge nb "<<nbEdge<<finl;
1035 for (int i=0; i<nbEdge; i++)
1036 {
1037 if (int(polyEdgeMesh->getNumberOfNodesInCell(i)) > 2)
1038 {
1039 Cerr<<">> Prepro_IBM_base::intersectSegPoly2D(): >getNumberOfNodesInCell("<<i<<") = "<<int(polyEdgeMesh->getNumberOfNodesInCell(i))<<" CHELOU... Input problem"<<finl;
1040 status = -1;
1041 return;
1042 }
1043 numNodes.clear();
1044 polyEdgeMesh->getNodeIdsOfCell(i, numNodes);
1045
1046 for (int k=0; k<(dim_esp-1); k++) pe1(k) = coords(int(numNodes[0]),k);
1047 for (int k=0; k<(dim_esp-1); k++) pe2(k) = coords(int(numNodes[1]),k);
1048 if (idebug)
1049 {
1050 Cerr<<">> Prepro_IBM_base::intersectSegPoly2D: Edge "<<i<<" index[] = "<<int(numNodes[0])<<" "<<int(numNodes[1])<<finl;
1051 Cerr<<">> Prepro_IBM_base::intersectSegPoly2D: pe1 : "<<pe1(0)<<" "<<pe1(1)<<" pe2 : "<<pe2(0)<<" "<<pe2(1)<<finl;
1052 }
1053 DoubleTab p(dim_esp - 1);
1054 int status_segseg = 0;
1055 intersectSegSeg2D(pe1, pe2, p1, p2, p, eps, status_segseg);
1056 if (status_segseg == 0)
1057 {
1058 MC_p->alloc(1, (dim_esp-1));
1059 std::copy(p.addr(), p.addr() + (dim_esp-1), MC_p->getPointer());
1060 MC_p->declareAsNew();
1061 MC_p->rearrange((dim_esp-1));
1062 outputCoords->aggregate(MC_p);
1063 }
1064 }
1065 if(outputCoords->getNumberOfTuples () <= 0)
1066 {
1067 status = -2;
1068 return;
1069 }
1070}
1071
1072void Prepro_IBM_base::intersectSegSeg2D(DoubleTab& p11, DoubleTab& p12, DoubleTab& p21, DoubleTab& p22, DoubleTab& p, double eps, int& status)
1073{
1074 int idebug = verbose_;
1075 int dim_esp = Objet_U::dimension;
1076 if (status != 0) status = 0 ;
1077 p = 0.;
1078
1079 assert(p11.size() == (dim_esp-1)); // p11 : sommet 1 du segment 1
1080 assert(p11.size() == p12.size());
1081 assert(p12.size() == p21.size()); // p12 : sommet 2 du segment 1
1082 assert(p21.size() == p22.size()); // p21 : sommet 1 du segment 2
1083 assert(p22.size() == p.size()); // p22 : sommet 2 du segment 2
1084
1085 DoubleTrav n1(dim_esp-1); //vecteur directeur du premier segment
1086 n1(0) = p12(0)-p11(0);
1087 n1(1) = p12(1)-p11(1);
1088 DoubleTrav n2(dim_esp-1); //vecteur directeur du second segment
1089 n2(0) = p22(0)-p21(0);
1090 n2(1) = p22(1)-p21(1);
1091 double absprodvect = abs(n1(0)*n2(1) - n2(0)*n1(1)); // n1 ^ n2
1092
1093 if(absprodvect < eps) // n1 et n2 colineaires
1094 {
1095 status = -2;
1096 if (idebug) Cerr<<"> Prepro_IBM_base::intersectSegSeg2D status: "<<status<<" ; p: "<<p(0)<<" "<<p(1)<<" n1 and n2 are colinear"<< finl;
1097 return;
1098 }
1099 else
1100 {
1101 double a = n1(1); // representation en equation de la droite 1
1102 double b = -n1(0);
1103 double c = - a*p11(0) - b*p11(1);
1104 double t1 = - (c + a*p21(0) + b*p21(1)) / (a*n2(0)+b*n2(1)); // representation parametrique de la droite 2
1105 a = n2(1); // representation en equation de la droite 2
1106 b = -n2(0);
1107 c = - a*p21(0) - b*p21(1);
1108 double t2 = - (c + a*p11(0) + b*p11(1)) / (a*n1(0)+b*n1(1)); // representation parametrique de la droite 1
1109 if ((t1 < -eps) || (t1 > 1.0 + eps) || (t2 < -eps) || (t2 > 1.0 + eps)) //si le point est en dehors des deux segments
1110 {
1111 status = -1;
1112 return;
1113 }
1114 else
1115 {
1116 p(0) = p21(0) + n2(0)*t1;
1117 p(1) = p21(1) + n2(1)*t1;
1118 }
1119
1120 if (idebug) Cerr<<"> Prepro_IBM_base::intersectSegSeg2D status: "<<status<<" ; p: "<<p(0)<<" "<<p(1)<<finl;
1121 }
1122}
1123
1125{
1126 const Domaine_dis_base& le_dom_dis = mon_pb_->domaine_dis();
1127 const Domaine& le_dom = mon_pb_.valeur().domaine();
1128 int nb_som = le_dom.nb_som();
1129 const Nom& type_elem = le_dom.type_elem()->que_suis_je();
1130 int dim_esp = Objet_U::dimension;
1131 assert(dim_esp==3);
1132 Noms nom_rot(dim_esp*dim_esp);
1133 Noms unites_rot(dim_esp*dim_esp);
1134 Noms nom_vect(dim_esp );
1135 Noms unites_vect(dim_esp );
1136 unites_vect[0] = "m";
1137 unites_vect[1] = "m";
1138 unites_vect[2] = "m";
1139
1140 Ecrire_MED ecr_med(nom_fichier_med_Out_, le_dom);
1141 ecr_med.ecrire_domaine(false);
1142
1143 ecr_med.ecrire_champ("CHAMPMAILLE", "aire", champ_aire_->valeurs(), champ_aire_->unites(), champ_aire_->noms_compo(), type_elem, 0.);
1144 ecr_med.ecrire_champ("CHAMPMAILLE", "rotation", champ_rotation_->valeurs(), unites_rot, nom_rot, type_elem, 0.);
1145 nom_vect[0] = "X";
1146 nom_vect[1] = "Y";
1147 nom_vect[2] = "Z";
1148 ecr_med.ecrire_champ("CHAMPMAILLE", "barycentre", champ_bary_->valeurs(), unites_vect, nom_vect, type_elem, 0.);
1149 nom_vect[0] = "nx";
1150 nom_vect[1] = "ny";
1151 nom_vect[2] = "nz";
1152 ecr_med.ecrire_champ("CHAMPMAILLE", "normale", champ_normal_->valeurs(), unites_vect, nom_vect, type_elem, 0.);
1153 ecr_med.ecrire_champ("CHAMPMAILLE", "corresp_elems", corresp_elems_->valeurs(), corresp_elems_->unites(), corresp_elems_->noms_compo(), type_elem, 0.);
1154
1155 ecr_med.ecrire_champ("CHAMPPOINT", "is_node_dirichlet", isNodeDirichlet_->valeurs(), isNodeDirichlet_->unites(), isNodeDirichlet_->noms_compo(), type_elem, 0.);
1156
1157 nom_vect[0] = "X";
1158 nom_vect[1] = "Y";
1159 nom_vect[2] = "Z";
1160 ecr_med.ecrire_champ("CHAMPPOINT", "projection_solide", solid_points_->valeurs(), unites_vect, nom_vect, type_elem, 0.);
1161 ecr_med.ecrire_champ("CHAMPPOINT", "element_projection_solide", solid_elems_->valeurs(), unites_vect, nom_vect, type_elem, 0.);
1162
1163 ecr_med.ecrire_champ("CHAMPPOINT", "projection_fluide", fluid_points_->valeurs(), unites_vect, nom_vect, type_elem, 0.);
1164 ecr_med.ecrire_champ("CHAMPPOINT", "element_projection_fluide", fluid_elems_->valeurs(), fluid_elems_->unites(), fluid_elems_->noms_compo(), type_elem, 0.);
1165
1166 ecr_med.ecrire_champ("CHAMPMAILLE", "h_max_elem", h_max_elem_->valeurs(), h_max_elem_->unites(), h_max_elem_->noms_compo(), type_elem, 0.);
1167 ecr_med.ecrire_champ("CHAMPPOINT", "h_max_node", h_max_node_->valeurs(), h_max_node_->unites(), h_max_node_->noms_compo(), type_elem, 0.);
1168
1169 OWN_PTR(Champ_Don_base) sommets_voisins;
1170 mon_pb_.valeur().discretisation().discretiser_champ("champ_sommets",le_dom_dis,"sommets_voisins","",1,0., sommets_voisins);
1171 DoubleTab& sommets_voisinsArray = sommets_voisins->valeurs();
1172 sommets_voisinsArray = 0.0;
1173 for (int node=0; node<nb_som; node++)
1174 {
1175 IntList& the_list = sommets_voisins_[node];
1176 if (!(the_list.est_vide()))
1177 {
1178 for (int index=0; index < the_list.size(); index++) sommets_voisinsArray(the_list[index]) += 1.;
1179 }
1180 }
1181 ecr_med.ecrire_champ("CHAMPPOINT", "sommets_voisins", sommets_voisins->valeurs(), sommets_voisins->unites(), sommets_voisins->noms_compo(), type_elem, 0.);
1182}
1183
1185{
1186 assert(Objet_U::dimension == 3);
1187
1188 const Domaine_dis_base& le_dom_dis = mon_pb_->domaine_dis();
1189 const Domaine& le_dom= le_dom_dis.domaine();
1190 const DoubleTab coordsDom3D=le_dom.les_sommets();
1191 int nb_som_elem =le_dom.nb_som_elem();
1192 const IntTab& elems = le_dom.les_elems() ;
1193 int nbElemVol = le_dom.nb_elem();
1194
1195 // computing effective error (eps_ multiply by min geometric scale)
1196 double hmin= 1.e30;
1197 for (int my_elem = 0; my_elem < nbElemVol; my_elem++)
1198 {
1199 double xmin = 1.e30, ymin = 1.e30, zmin = 1.e30;
1200 double xmax = -1.e30, ymax = -1.e30, zmax = -1.e30;
1201 for (int id_loc=0; id_loc < nb_som_elem; id_loc++)
1202 {
1203 int id = elems(my_elem,id_loc);
1204 xmin = std::min(xmin, coordsDom3D(id , 0));
1205 ymin = std::min(ymin, coordsDom3D(id , 1));
1206 zmin = std::min(zmin, coordsDom3D(id , 2));
1207
1208 xmax = std::max(xmax, coordsDom3D(id , 0));
1209 ymax = std::max(ymax, coordsDom3D(id , 1));
1210 zmax = std::max(zmax, coordsDom3D(id , 2));
1211 }
1212 double hinter = std::min({xmax - xmin, ymax - ymin, zmax - zmin});
1213 // dimension geometrique min local elementaire
1214 hmin = std::min(hmin, hinter);
1215 }
1216 eps_effec_ = std::max(hmin*eps_, 1e-16);
1217 Cerr<<"Prepro_IBM_base:: Eps and effective eps = "<<eps_<<" "<<eps_effec_<<finl;
1218}
1219
1221{
1222 DoubleTab& hmaxArray = h_max_elem_->valeurs();
1223 hmaxArray = 0.;
1224 DoubleTab& hmaxNodeArray = h_max_node_->valeurs();
1225 hmaxNodeArray = 0.;
1226
1227 const Domaine_dis_base& le_dom_dis = mon_pb_->domaine_dis();// contient maillage TRUST
1228 const Domaine& le_dom= le_dom_dis.domaine();
1229 int nb_som_elem =le_dom.nb_som_elem(); // number of nodes per elems ( numerotation local)
1230 const IntTab& elems = le_dom.les_elems() ; // numerotation global des noeuds d'un element ( les_elems.dimension(0)=>nb_elems, les_elems.dimension(1)=> nb_som_elem)
1231 const DoubleTab coordsDom3D=le_dom.les_sommets(); // coordonnées des noeuds TRUST
1232 int nbElemVol = elems.dimension(0);
1233
1234 assert(Objet_U::dimension == 3);
1235 assert(Objet_U::dimension == dimTab_.dimension(0));
1236 double hmax1, hmax2, hmax3;
1237
1238 for (int my_elem = 0; my_elem < nbElemVol; my_elem++)
1239 {
1240 if (dimTab_(0))
1241 {
1242 double xmin = 1.e30;
1243 double xmax = -1.e30;
1244 for (int id_loc=0; id_loc < nb_som_elem; id_loc++)
1245 {
1246 int id = elems(my_elem,id_loc); // global number of node
1247 xmin = std::min(xmin, coordsDom3D(id , 0));
1248 xmax = std::max(xmax, coordsDom3D(id , 0));
1249 }
1250 hmax1 = xmax-xmin;
1251 }
1252 else hmax1 = 0.0;
1253
1254 if (dimTab_(1))
1255 {
1256 double ymin = 1.e30;
1257 double ymax = -1.e30;
1258 for (int id_loc=0; id_loc < nb_som_elem; id_loc++)
1259 {
1260 int id = elems(my_elem,id_loc); // global number of node
1261 ymin = std::min(ymin, coordsDom3D(id , 1));
1262 ymax = std::max(ymax, coordsDom3D(id , 1));
1263 }
1264 hmax2 = ymax-ymin;
1265 }
1266 else hmax2 = 0.0;
1267
1268 if (dimTab_(2))
1269 {
1270 double zmin = 1.e30;
1271 double zmax = -1.e30;
1272 for (int id_loc=0; id_loc < nb_som_elem; id_loc++)
1273 {
1274 int id = elems(my_elem,id_loc); // global number of node
1275 zmin = std::min(zmin, coordsDom3D(id , 2));
1276 zmax = std::max(zmax, coordsDom3D(id , 2));
1277 }
1278 hmax3 = zmax-zmin;
1279 }
1280 else hmax3 = 0.0;
1281
1282 hmaxArray(my_elem) = sqrt(hmax1*hmax1+hmax2*hmax2+hmax3*hmax3) ;
1283
1284 for (int id_loc=0; id_loc < nb_som_elem; id_loc++)
1285 {
1286 int id = elems(my_elem,id_loc);
1287 hmaxNodeArray(id) = max(hmaxNodeArray(id), hmaxArray(my_elem)) ;
1288 }
1289 }
1290 hmaxArray.echange_espace_virtuel();
1291 hmaxNodeArray.echange_espace_virtuel();
1292}
1293
1295{
1296 const Domaine_dis_base& le_dom_dis = mon_pb_->domaine_dis();
1297 const Domaine_VF& the_dom_VF = ref_cast(Domaine_VF,le_dom_dis);
1298 const Domaine& le_dom = le_dom_dis.domaine();
1299 int nb_elem_tot = le_dom.nb_elem_tot();
1300 int nb_som_tot = le_dom.nb_som_tot();
1301 int nb_som_elem = le_dom.nb_som_elem();
1302 int nb_faces_elem = le_dom.nb_faces_elem();
1303 int nb_som_face = the_dom_VF.nb_som_face();
1304 const IntTab& face_voisins = the_dom_VF.face_voisins();
1305 const IntTab& elems = le_dom.les_elems() ;
1306 const IntTab& elem_face = the_dom_VF.elem_faces();
1307 const IntTab& faces_som = the_dom_VF.face_sommets();
1308
1309 DoubleTab& aireArray = champ_aire_->valeurs();
1310
1311 if (nb_niveau != 1)
1312 {
1313 Cerr<<"Prepro_IBM_base::compute_NeighNode : nb_niveau != 1"<<finl;
1314 Process::exit();
1315 }
1316
1317 sommets_voisins_ = IntLists(nb_som_tot);
1318 int nb_nodes_in_list = 0;
1319 for (int num_elem = 0; num_elem < nb_elem_tot; num_elem++) // inclus les elem ghost
1320 {
1321 if (aireArray(num_elem) > eps_effec_)
1322 {
1323 for (int fac=0; fac<nb_faces_elem; fac++)
1324 {
1325 int num_fac = elem_face(num_elem, fac);
1326 for (int voisin=0; voisin<2; voisin++)
1327 {
1328 int num_elem_v = face_voisins(num_fac,voisin);
1329 if ( (num_elem_v!=-1) && (num_elem_v!=num_elem) )
1330 {
1331 // element num_elem_v, voisin de num_elem par une face
1332 for (int nodf=0; nodf<nb_som_face; nodf++)
1333 {
1334 // noeud num_nod, dont on veut trouve les noeuds voisins
1335 int num_nod = faces_som(num_fac, nodf);
1336 // tous les noeuds de num_elem_v sont des neouds voisins de num_nod
1337 for (int nod_v=0; nod_v<nb_som_elem; nod_v++)
1338 {
1339 int num_nod_v = elems(num_elem_v, nod_v);
1340 if (num_nod_v != num_nod)
1341 {
1342 sommets_voisins_[num_nod].add_if_not(num_nod_v);
1343 nb_nodes_in_list += 1;
1344 }
1345 }
1346 // element num_elem_v_v, voisin de num_elem_v par une face
1347 for (int fac_v=0; fac_v<nb_faces_elem; fac_v++)
1348 {
1349 int num_fac_v = elem_face(num_elem_v, fac_v);
1350 for (int voisin_v=0; voisin_v<2; voisin_v++)
1351 {
1352 int num_elem_v_v = face_voisins(num_fac_v,voisin_v);
1353 // boucle sur les noeuds de l'element num_elem_v_v pour savoir
1354 // s'il contient num_nod. si oui, tous ses noeuds sont des
1355 // voisins de num_nod
1356 if ( (num_elem_v_v!=-1) && (num_elem_v_v!=num_elem) )
1357 {
1358 int iok = 0 ;
1359 for (int nod_v_v=0; nod_v_v<nb_som_elem; nod_v_v++)
1360 {
1361 int num_nod_v_v = elems(num_elem_v_v, nod_v_v);
1362 if (num_nod_v_v == num_nod) iok = 1;
1363 }
1364 if (iok == 1)
1365 {
1366 for (int nod_v_v=0; nod_v_v<nb_som_elem; nod_v_v++)
1367 {
1368 int num_nod_v_v = elems(num_elem_v_v, nod_v_v);
1369 if (num_nod_v_v != num_nod)
1370 {
1371 sommets_voisins_[num_nod].add_if_not(num_nod_v_v);
1372 nb_nodes_in_list += 1;
1373 }
1374 }
1375 }
1376 }
1377 }
1378 }
1379 }
1380 }
1381 }
1382 }
1383 }
1384 }
1385 Cerr<<"Prepro_IBM_base::compute_NeighNode : nb nodes for neighborhood = " <<nb_nodes_in_list<<finl;
1386}
1387
1388void Prepro_IBM_base::calculer_normal_proj_solid(DoubleTab& nor, DoubleTab& dist)
1389{
1390 const DoubleTab& solid_points = solid_points_->valeurs();
1391 const DoubleTab& aire = champ_aire_->valeurs();
1392 int nb_elem = aire.dimension(0);
1393 const Domaine_dis_base& le_dom_dis = mon_pb_->domaine_dis();
1394 const IntTab& elems = le_dom_dis.domaine().les_elems();
1395 const Domaine& dom = le_dom_dis.domaine();
1396 int nb_som_elem=dom.nb_som_elem();
1397
1398 assert(nor.dimension(0) == solid_points.dimension(0));
1399 int dim_esp = solid_points.dimension(1);
1400 assert(nor.dimension(1) == dim_esp);
1401 nor = 0.;
1402 double eps = 1.0e-10;
1403 for (int e=0; e<nb_elem; e++)
1404 {
1405 if (aire(e)>0.)
1406 {
1407 for (int il=0; il<nb_som_elem; il++)
1408 {
1409 int i = elems(e,il);
1410 double d1 = 0.0;
1411 for (int k=0; k<dim_esp; k++)
1412 {
1413 double xk = dom.coord(i,k);
1414 double xks = solid_points(i,k);
1415 nor(i, k) = xk - xks;
1416 d1 += (xk-xks)*(xk-xks);
1417 }
1418 d1 = sqrt(d1);
1419 if (d1 > eps )
1420 for (int k=0; k<dim_esp; k++) nor(i, k) /= d1 ;
1421 dist(i) = d1;
1422 }
1423 }
1424 }
1425}
1426
1428{
1429}
classe Champ_Don_base classe de base des Champs donnes (non calcules)
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
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
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
int_t nb_elem() const
Definition Domaine.h:131
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
Definition Domaine.h:484
int_t nb_som_tot() const
Renvoie le nombre total de sommets du domaine i.e. le nombre de sommets reels et virtuels sur le proc...
Definition Domaine.h:123
double coord(int_t i, int j) const
Definition Domaine.h:110
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
Definition Domaine.h:121
class Domaine_VF
Definition Domaine_VF.h:44
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
Definition Domaine_VF.h:583
int nb_som_face() const
renvoie le nombre de sommets par face.
Definition Domaine_VF.h:494
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
const Domaine & domaine() const
void ecrire_champ(const Nom &type, const Nom &nom_cha1, const DoubleTab &val, const Noms &unite, const Noms &noms_compo, const Nom &type_elem, double time)
void ecrire_domaine(bool append=true)
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
void retrieve_MC_objects()
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
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
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
static int dimension
Definition Objet_U.h:99
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
void build_nodes(const DoubleTab_t &coords, const bool include_virtual, const double epsilon=0.)
construit un octree contenant les points de coordonnees coords.
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
@ OPTIONAL
Definition Param.h:115
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
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 computeLocalFrame(const DoubleTab &, DoubleTab &, DoubleTab &, int)
void intersectPolyPoly2D(MEDCouplingUMesh *, MEDCouplingUMesh *, DoubleTab &, IntTab &, double, int &)
void intersectSegPoly2D(MEDCouplingUMesh *, DoubleTab &, DoubleTab &, double, MCAuto< MEDCoupling::DataArrayDouble >, int &)
OWN_PTR(Champ_Don_base) champ_rotation_
void intersectSegSeg2D(DoubleTab &, DoubleTab &, DoubleTab &, DoubleTab &, DoubleTab &, double, int &)
MCAuto< MEDCoupling::MEDCouplingUMesh > aSkinUMesh_
void set_param(Param &) const override
void calculer_normal_proj_solid(DoubleTab &, DoubleTab &)
virtual void compute_solid_fluid(int)
void computeMatRot(const DoubleTab &, DoubleTab &, DoubleTab &, int)
virtual void associer_pb(const Probleme_base &)
DoubleTab coordsSur3D_
IntLists sommets_voisins_
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Discretisation_base & discretisation() const
Renvoie la discretisation associee au probleme.
const Domaine_dis_base & domaine_dis() const
Renvoie le domaine discretise associe au probleme.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
void associer_domaine(const Domaine_t &d)
const IntVect_t & les_elems() const
_SIZE_ size_array() const
_TYPE_ * addr()
int est_vide() const
int size() const
Definition TRUSTList.h:68
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
void reset() override
met l'objet dans l'etat obtenu par le constructeur par defaut.
Definition TRUSTVect.h:189
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")