Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
TiedInterface.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* TiedInterface.cc (C) 2000-2023 */
9/* */
10/* Informations sur les semi-conformitées du maillage. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/String.h"
15#include "arcane/utils/HashTableMap.h"
16#include "arcane/utils/Real3.h"
17#include "arcane/utils/OStringStream.h"
18#include "arcane/utils/NotImplementedException.h"
19#include "arcane/utils/PlatformUtils.h"
20#include "arcane/utils/ITraceMng.h"
21#include "arcane/utils/Collection.h"
22#include "arcane/utils/Enumerator.h"
23#include "arcane/utils/CheckedConvert.h"
24
25#include "arcane/mesh/TiedInterface.h"
26
27#include "arcane/IMesh.h"
28#include "arcane/IMeshSubMeshTransition.h"
29#include "arcane/ItemEnumerator.h"
30#include "arcane/ItemGroup.h"
31#include "arcane/Item.h"
32#include "arcane/ISubDomain.h"
33#include "arcane/VariableTypes.h"
34#include "arcane/IItemFamily.h"
35#include "arcane/ItemCompare.h"
36#include "arcane/IParallelMng.h"
37#include "arcane/GeometricUtilities.h"
38#include "arcane/SerializeBuffer.h"
39#include "arcane/ItemPrinter.h"
40#include "arcane/IMeshUtilities.h"
41
42#include <set>
43#include <map>
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
48namespace Arcane::mesh
49{
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
55{
56 public:
57 void printInfos()
58 {
59 std::ostream& o = cout;
60 o << " MasterFacesUid=" << m_master_faces_uid.size()
61 << " SlaveNodesUid=" << m_slave_nodes_uid.size()
62 << " SlaveFacesUid=" << m_slave_faces_uid.size()
63 << " MasterFacesNbSlaveNode=" << m_master_faces_nb_slave_node.size()
64 << " MasterFacesNbSlaveFace=" << m_master_faces_nb_slave_face.size()
65 << " SlaveNodesIso=" << m_slave_nodes_iso.size()
66 << " MasterFacesSlaveFaceIndex=" << m_master_faces_slave_face_index.size()
67 << " MasterFacesSlaveNodeIndex=" << m_master_faces_slave_node_index.size()
68 << "\n";
69 };
70 public:
83
84 IntegerUniqueArray m_master_faces_slave_face_index;
85 IntegerUniqueArray m_master_faces_slave_node_index;
86};
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
92{
93 public:
94 Integer size() const { return m_nodes_unique_id.size(); }
96 {
97 m_nodes_unique_id.add(node_unique_id);
98 }
99public:
100 UniqueArray<ItemUniqueId> m_nodes_unique_id;
101};
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
107{
108 public:
110 : m_unique_id(NULL_ITEM_ID) {}
112 : m_unique_id(node_uid) {}
113 public:
114 ItemUniqueId uniqueId() const
115 {
116 return m_unique_id;
117 }
118 void addConnectedFace(ItemUniqueId uid)
119 {
120 for( Integer i=0,is=m_connected_master_faces.size(); i<is; ++i )
121 if (m_connected_master_faces[i]==uid)
122 return;
124 }
125
126 private:
129 public:
130
131 public:
134
137};
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
148{
149 public:
151 : m_unique_id(NULL_ITEM_ID), m_cell_unique_id(NULL_ITEM_ID), m_owner(-1),
152 m_nb_node(0), m_data_index(-1), m_mng(0) {}
154 Integer data_index,TiedInterfaceFaceInfoMng* mng)
155 : m_unique_id(unique_id), m_cell_unique_id(cell_unique_id), m_owner(owner), m_nb_node(nb_node),
156 m_data_index(data_index), m_mng(mng) {}
157 public:
158 ItemUniqueId uniqueId() const
159 {
160 return m_unique_id;
161 }
162 ItemUniqueId cellUniqueId() const
163 {
164 return m_cell_unique_id;
165 }
166 Integer nbNode() const
167 {
168 return m_nb_node;
169 }
170 ItemUniqueId nodeUniqueId(Integer i) const
171 {
172 return m_mng->m_nodes_unique_id[ m_data_index + i ];
173 }
174 Integer owner() const
175 {
176 return m_owner;
177 }
178 void setCenter(Real3 center)
179 {
180 m_center = center;
181 }
182 Real3 center() const
183 {
184 return m_center;
185 }
186 private:
187 ItemUniqueId m_unique_id;
188 ItemUniqueId m_cell_unique_id;
189 Integer m_owner;
190 Integer m_nb_node;
191 Real3 m_center;
192 public:
193 Integer m_data_index;
195};
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
201{
202 public:
204 {
205 public:
206 NodeInfo() : m_unique_id(NULL_ITEM_ID), m_alpha(-1.0), m_beta(-1.0) {}
208 : m_unique_id(uid), m_alpha(-1.0), m_beta(-1.0) {}
209 public:
210 ItemUniqueId m_unique_id;
211 Real m_alpha;
212 Real m_beta;
213 };
215 public:
217 : m_unique_id(NULL_ITEM_ID) {}
219 : m_unique_id(unique_id) {}
220 public:
221 ItemUniqueId uniqueId() const
222 { return m_unique_id; }
223 public:
224 ItemUniqueId m_unique_id;
225 SharedArray<TiedInterfaceFace*> m_slave_faces;
226};
227
228/*---------------------------------------------------------------------------*/
229/*---------------------------------------------------------------------------*/
230
232{
233 public:
235 : m_uid(uid), m_alpha(alpha), m_beta(beta){ }
236 public:
237 bool operator<(const TiedInterfaceSortedNodeInfo& rhs) const
238 {
239 if (m_alpha!=rhs.m_alpha)
240 return m_alpha<rhs.m_alpha;
241 if (m_beta!=rhs.m_beta)
242 return (m_beta<rhs.m_beta);
243 return (m_uid<rhs.m_uid);
244 }
245 public:
246 ItemUniqueId uniqueId() const { return m_uid; }
247 public:
248 ItemUniqueId m_uid;
249 Real m_alpha;
250 Real m_beta;
251};
252
253/*---------------------------------------------------------------------------*/
254/*---------------------------------------------------------------------------*/
255
257{
258 public:
259 TiedInterfaceStructurationInfo(ItemUniqueId node_uid,Real alpha,Real beta)
260 : m_node_uid(node_uid), m_alpha(alpha), m_beta(beta), m_x(-1), m_y(-1)
261 {
262 }
264 : m_node_uid(NULL_ITEM_UNIQUE_ID), m_alpha(0.0), m_beta(0.0), m_x(-1), m_y(-1)
265 {
266 }
267 public:
269 {
270 if (m_x!=rhs.m_x)
271 return m_x<rhs.m_x;
272 if (m_y!=rhs.m_y)
273 return (m_y<rhs.m_y);
274 return false;
275 }
276 public:
277 void setStructuration(Integer x,Integer y)
278 {
279 if (m_x!=(-1) && x!=m_x)
280 ARCANE_FATAL("already set with a different x value old={0} new={1}",m_x,x);
281 if (m_y!=(-1) && y!=m_y)
282 ARCANE_FATAL("already set with a different y value old={0} new={1}",m_y,y);
283 m_x = x;
284 m_y = y;
285 }
286 bool hasStructuration() const
287 {
288 return (m_x!=(-1) && m_y!=(-1));
289 }
290 public:
291 ItemUniqueId m_node_uid;
292 Real m_alpha;
293 Real m_beta;
294 Integer m_x;
295 Integer m_y;
296};
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
327: public TraceAccessor
328{
329 public:
334 typedef std::set<TiedInterfaceSortedNodeInfo> SortedNodeInfoSet;
337 public:
339 void setPlanarTolerance(Real tolerance);
340 public:
342 void computeInterfaceInfos(TiedInterfaceBuilderInfos& infos,bool is_structured);
344 void changeOwnersOld();
345 const FaceGroup& masterInterface() const { return m_master_interface; }
346 private:
347 bool m_is_debug;
348 IMesh* m_mesh;
349 VariableNodeReal3 m_nodes_coord;
350 TiedInterfaceFaceInfoMng m_face_info_mng;
351 //UniqueArray<TiedInterfaceFace> m_slave_faces;
352 NodeInfoList m_nodes_info;
353 TiedInterfaceFaceMap m_slave_faces;
354 TiedInterfaceFaceMap m_master_faces;
355 String m_slave_interface_name;
356 FaceGroup m_slave_interface;
357 FaceGroup m_master_interface;
360 Real m_planar_tolerance;
361
362 private:
364 void _searchMasterFaces(Array<ItemUniqueId>& slave_faces_to_process,
366 bool _isInsideFace(const TiedInterfaceFace& face,Real3 point);
367 Real3 _computeNormale(const TiedInterfaceFace& face);
371 void _gatherAllNodesInfo();
372 void _printFaces(std::ostream& o,TiedInterfaceFaceMap& face_map);
373 void _computeProjectionInfos(TiedInterfaceBuilderInfos& infos,bool is_structured);
374 void _addFaceToList(const Face& face,TiedInterfaceFaceMap& face_map);
375 void _detectStructuration(const TiedInterfaceMasterFace& master_face,
376 StructurationMap& nodes);
377 void _detectStructurationRecursive(Array<ItemUniqueId>& slave_faces_to_process,
381};
382
383/*---------------------------------------------------------------------------*/
384/*---------------------------------------------------------------------------*/
385
386TiedInterfaceBuilder::
387TiedInterfaceBuilder(IMesh* mesh,const FaceGroup& slave_interface,
388 bool use_own,bool is_debug)
389: TraceAccessor(mesh->traceMng())
390, m_is_debug(is_debug)
391, m_mesh(mesh)
392, m_nodes_coord(m_mesh->toPrimaryMesh()->nodesCoordinates())
393, m_nodes_info(1000,true)
394, m_slave_faces(5000,true)
395, m_master_faces(1000,true)
396, m_slave_interface_name(slave_interface.name())
397, m_slave_interface(slave_interface)
398, m_slave_faces_master_face_uid(1000,true)
399, m_planar_tolerance(0.0)
400{
401 if (use_own)
402 m_slave_interface = slave_interface.own();
403}
404
405/*---------------------------------------------------------------------------*/
406/*---------------------------------------------------------------------------*/
407
408void TiedInterfaceBuilder::
409setPlanarTolerance(Real tolerance)
410{
411 m_planar_tolerance = tolerance;
412}
413
414/*---------------------------------------------------------------------------*/
415/*---------------------------------------------------------------------------*/
416
417void TiedInterfaceBuilder::
418_searchMasterFaces(Array<ItemUniqueId>& slave_faces_to_process,
419 Array<ItemUniqueId>& remaining_slave_faces)
420{
421 String func_name = "TiedInterfaceBuilder::_searchMasterFaces()";
422
423 std::set<ItemUniqueId> master_faces_to_test;
424 UniqueArray<ItemUniqueId> master_faces_found;
425 master_faces_found.reserve(100);
426 Real3UniqueArray slave_face_nodes_coord;
427 slave_face_nodes_coord.reserve(100);
428 Real3UniqueArray triangle_centers;
429 triangle_centers.reserve(100);
430
431 if (m_is_debug){
432 info() << "nb slave faces to process=" << slave_faces_to_process.size();
433 //info() << "nb remaining slave faces=" << remaining_slave_faces.size();
434 }
435 for( Integer islaveface=0, izz=slave_faces_to_process.size(); islaveface<izz; ++islaveface ){
436 master_faces_to_test.clear();
437 master_faces_found.clear();
438
439 TiedInterfaceFace& face = m_slave_faces[ slave_faces_to_process[islaveface] ];
440
441 slave_face_nodes_coord.clear();
442
443 Integer nb_node = face.nbNode();
444 triangle_centers.resize(nb_node);
445
446 for( Integer inode=0; inode<nb_node; ++inode ){
447 TiedInterfaceNodeInfo& node_info = m_nodes_info[face.nodeUniqueId(inode)];
448 slave_face_nodes_coord.add(node_info.m_coord);
449 for( Integer zface=0, zz=node_info.m_connected_master_faces.size(); zface<zz; ++zface ){
450 master_faces_to_test.insert(node_info.m_connected_master_faces[zface]);
451 }
452 }
453
454 for( Integer inode=0; inode<nb_node; ++inode ){
455 triangle_centers[inode] = (slave_face_nodes_coord[inode]
456 + slave_face_nodes_coord[(inode+1)%nb_node]
457 + face.center() ) / 3.;
458 }
459
460 // Parcours la liste des faces maitres possibles, et regarde si l'un des barycentres
461 // de la decomposition en triangle de la face esclave est à l'intérieur d'une de ces faces.
462 for( std::set<ItemUniqueId>::const_iterator i_master_face(master_faces_to_test.begin());
463 i_master_face!=master_faces_to_test.end(); ++i_master_face ){
464 TiedInterfaceFaceMap::Data* data = m_master_faces.lookup(*i_master_face);
465 if (!data)
466 ARCANE_FATAL("INTERNAL: Can not find face uid={0}",*i_master_face);
467 const TiedInterfaceFace& master_face = data->value();
468 bool is_found = false;
469 for( Integer inode=0; inode<nb_node; ++inode ){
470 if (_isInsideFace(master_face,triangle_centers[inode])){
471// info() << "Master found " << master_face.uniqueId() << " vs slave:" << face.uniqueId();
472// info() << "Master coords:" << m_nodes_info[master_face.nodeUniqueId(0)].m_coord
473// << " " << m_nodes_info[master_face.nodeUniqueId(1)].m_coord
474// << " " << m_nodes_info[master_face.nodeUniqueId(2)].m_coord
475// << " " << m_nodes_info[master_face.nodeUniqueId(3)].m_coord;
476// info() << "Slave coords:" << m_nodes_info[face.nodeUniqueId(0)].m_coord
477// << " " << m_nodes_info[face.nodeUniqueId(1)].m_coord
478// << " " << m_nodes_info[face.nodeUniqueId(2)].m_coord
479// << " " << m_nodes_info[face.nodeUniqueId(3)].m_coord;
480// info() << "This point : " << inode << " " << triangle_centers[inode];
481 is_found = true;
482 break;
483 }
484 }
485
486 if (is_found){
487 //info() << "SlaveFace " << face.uniqueId() << " found in face "
488 //<< master_face.uniqueId() << " d=" << best_d.m_distance;
489 master_faces_found.add(master_face.uniqueId());
490 }
491 }
492 switch (master_faces_found.size()){
493 case 1:
494 {
495 ItemUniqueId master_face_uid = master_faces_found[0];
496 //info() << "** GOOD: SlaveFace " << face.uniqueId() << " found in face " << master_face_uid;
497 for( Integer inode=0; inode<nb_node; ++inode ){
498 TiedInterfaceNodeInfo& node_info = m_nodes_info[face.nodeUniqueId(inode)];
499 node_info.m_connected_master_faces.add(master_face_uid);
500 }
501 //face.setMasterFace(master_face_uid);
502 m_slave_faces_master_face_uid.add(face.uniqueId(),master_face_uid);
503 }
504 break;
505 case 0:
506 // Pas trouvé, ajoute dans la liste pour le test suivant.
507 //info() << "** BAD: SlaveFace " << face.uniqueId();
508 remaining_slave_faces.add(face.uniqueId());
509 break;
510 default:
511 {
512 // Ce cas peut se présenter si en 2D ou en 3D une maille possède une soudure sur
513 // deux faces connectées. Dans ce cas, il y a souvent plusieurs
514 // faces maitres possibles. Pour les discréminer, on choisit
515 // la face maitre dont l'orientation (la normale) est la plus colineaire
516 // avec la maille esclave. Pour cela, il suffit de calculer
517 // le produit scalaire entre la face esclave et chaque face maitre
518 // potentielle et de prendre le plus grand en valeur absolue (pour eviter
519 // les problemes d'orientation).
520 Real3 face_normale = _computeNormale(face);
521 OStringStream ostr;
522 ostr() << "Too many master faces for a slave face (max=1) "
523 << " nb_master=" << master_faces_found.size()
524 << " (slave_face=" << face.uniqueId() << ",normal=" << face_normale << ")"
525 << " master_list=";
526 Real max_dot = -1.0;
527 Integer keep_index = -1;
528 for( Integer zz=0; zz< master_faces_found.size(); ++zz ){
529 ItemUniqueId muid = master_faces_found[zz];
530 const TiedInterfaceFace& master_face = m_master_faces.lookupValue(muid);
531 Real3 n = _computeNormale(master_face);
532 Real d = math::scaMul(n,face_normale);
533 if (math::abs(d)>max_dot){
534 max_dot = math::abs(d);
535 keep_index = zz;
536 }
537 ostr() << " (uid=" << muid << ",nb_node=" << master_face.nbNode()
538 << " center=" << master_face.center()
539 << " normale=" << n
540 << " dot=" << d
541 << ")";
542 }
543 if (keep_index>=0){
544 info() << func_name << " " << ostr.str() << ". Keeping index=" << keep_index;
545 {
546 ItemUniqueId master_face_uid = master_faces_found[keep_index];
547 for( Integer inode=0; inode<nb_node; ++inode ){
548 TiedInterfaceNodeInfo& node_info = m_nodes_info[face.nodeUniqueId(inode)];
549 node_info.m_connected_master_faces.add(master_face_uid);
550 }
551 //face.setMasterFace(master_face_uid);
552 m_slave_faces_master_face_uid.add(face.uniqueId(),master_face_uid);
553 }
554 }
555 else
556 ARCANE_FATAL(ostr.str());
557 }
558 }
559 }
560}
561
562/*---------------------------------------------------------------------------*/
563/*---------------------------------------------------------------------------*/
585{
586 Integer nb_node = face.nbNode();
587
589
590 if (nb_node>3){
591 for( Integer inode=0; inode<nb_node; ++inode ){
592 Real3 v1 = m_nodes_info[face.nodeUniqueId(inode)].m_coord;
593 Real3 v2 = m_nodes_info[face.nodeUniqueId((inode+1)%nb_node)].m_coord;
594 GeometricUtilities::ProjectionInfo d = min_distance.projection(face.center(),v1,v2,point);
595 //info() << " DISTANCE: r=" << region << " d=" << d;
596 if (d.m_region==0){
597 if (min_distance.m_region!=0){
598 min_distance = d;
599 }
600 else{
601 if (d.m_distance<min_distance.m_distance){
602 min_distance = d;
603 }
604 }
605 }
606 else{
607 if (min_distance.m_region!=0){
608 if (d.m_distance<min_distance.m_distance){
609 min_distance = d;
610 }
611 }
612 }
613 }
614 }
615 else if (nb_node==3){
616 Real3 v1 = m_nodes_info[face.nodeUniqueId(0)].m_coord;
617 Real3 v2 = m_nodes_info[face.nodeUniqueId(1)].m_coord;
618 Real3 v3 = m_nodes_info[face.nodeUniqueId(2)].m_coord;
619 min_distance = min_distance.projection(v1,v2,v3,point);
620 }
621 else if (nb_node==2){
622 Real3 v1 = m_nodes_info[face.nodeUniqueId(0)].m_coord;
623 Real3 v2 = m_nodes_info[face.nodeUniqueId(1)].m_coord;
624 min_distance = min_distance.projection(v1,v2,point);
625 }
626 return min_distance;
627}
628
629/*---------------------------------------------------------------------------*/
630/*---------------------------------------------------------------------------*/
631
632Real3 TiedInterfaceBuilder::
633_computeNormale(const TiedInterfaceFace& face)
634{
635 Integer nb_node = face.nbNode();
637 if (nb_node>=3){
638 for( Integer inode=0; inode<nb_node; ++inode ){
639 Real3 v1 = m_nodes_info[face.nodeUniqueId(inode)].m_coord;
640 Real3 v2 = m_nodes_info[face.nodeUniqueId((inode+1)%nb_node)].m_coord;
641 Real3 v3 = m_nodes_info[face.nodeUniqueId((inode+2)%nb_node)].m_coord;
642 Real3 vd_a = v1 - v2;
643 Real3 vd_b = v3 - v2;
646 }
647 }
648 else if (nb_node==2){
649 Real3 v1 = m_nodes_info[face.nodeUniqueId(0)].m_coord;
650 Real3 v2 = m_nodes_info[face.nodeUniqueId(1)].m_coord;
651 if (v1.z!=0.0 || v2.z!=0.0)
652 throw NotImplementedException(A_FUNCINFO,"edge in 3D space");
653 Real x = v2.x - v1.x;
654 Real y = v2.y - v1.y;
655 normale = Real3(-y,x,0.0);
656 }
657 else
658 throw NotSupportedException(A_FUNCINFO,"can not compute normal of face with 0 or 1 node");
659 return normale.normalize();
660}
661
662/*---------------------------------------------------------------------------*/
663/*---------------------------------------------------------------------------*/
664
665bool TiedInterfaceBuilder::
666_isInsideFace(const TiedInterfaceFace& face,Real3 point)
667{
668 Integer nb_node = face.nbNode();
669 if (nb_node>2){
670 for( Integer inode=0; inode<nb_node; ++inode ){
671 Real3 v1 = m_nodes_info[face.nodeUniqueId(inode)].m_coord;
672 Real3 v2 = m_nodes_info[face.nodeUniqueId((inode+1)%nb_node)].m_coord;
673 if (m_planar_tolerance!=0.0) { // Ne fait le calcul que si le test est utile
674 Real ecart = math::mixteMul(point-face.center(),math::normalizeReal3(v1-face.center()),math::normalizeReal3(v2-face.center()));
675 if (math::abs(ecart) > m_planar_tolerance * math::normeR3(v1-v2)) {
676 if (m_is_debug)
677 info() << "Reject non planar projection " << point << " from face uid=" << face.uniqueId();
678 return false;
679 }
680 }
681 if (GeometricUtilities::ProjectionInfo::isInside(face.center(),v1,v2,point))
682 return true;
683 }
684 }
685 else if (nb_node==2){
686 Real3 v1 = m_nodes_info[face.nodeUniqueId(0)].m_coord;
687 Real3 v2 = m_nodes_info[face.nodeUniqueId(1)].m_coord;
689 return true;
690 }
691 return false;
692}
693
694/*---------------------------------------------------------------------------*/
695/*---------------------------------------------------------------------------*/
714{
715 // Marqueur faces esclaves
716 std::set<ItemUniqueId> slave_faces_flag;
717
718 Integer nb_slave_face = m_slave_interface.size();
719 m_nodes_info.resize((nb_slave_face*2)+5);
720 m_master_faces.resize(nb_slave_face+5);
721 m_slave_faces.resize((nb_slave_face*2)+5);
722
723 // Construit les informations nécessaires concernant les
724 // faces esclaves et marque l'ensemble des noeuds.
725 ENUMERATE_FACE(iface,m_slave_interface){
726 const Face& face = *iface;
727 slave_faces_flag.insert(face.uniqueId());
728 _addFaceToList(face,m_slave_faces);
729 }
730
731 info() << "SLAVE_INTERFACE: nb_face=" << m_slave_interface.size();
732 // A partir des noeuds marqués, détermine les faces maîtres
734 bool has_not_handled_face = false;
736 const Face& face = *iface;
737 // Vérifie qu'il ne s'agit pas d'une face esclave
738 if (slave_faces_flag.find(face.uniqueId())!=slave_faces_flag.end())
739 continue;
740 Integer nb_node = face.nbNode();
741 bool is_master_face = true;
742 // Une face est maître si chacun de ses noeuds est dans la liste des noeuds esclaves
743 for( Node node : face.nodes() ){
744 ItemUniqueId uid = node.uniqueId();
745 if (!m_nodes_info.lookup(uid)){
746 is_master_face = false;
747 break;
748 }
749 }
750 if (is_master_face){
751 // Pour l'instant, supporte uniquement les faces à 2 et 4 noeuds.
752 if (nb_node!=4 && nb_node!=2)
754 master_faces_lid.add(face.localId());
755 for( Node node : face.nodes() ){
756 TiedInterfaceNodeInfo& znode = m_nodes_info[node.uniqueId()];
757 znode.m_connected_master_faces.add(face.uniqueId());
758 }
759 _addFaceToList(face,m_master_faces);
760 }
761 }
763 ARCANE_FATAL("Some faces of the tied interface '{0}' has incorrect number of nodes (should be 2 or 4)",
764 m_slave_interface.name());
765
766 m_master_interface = m_mesh->faceFamily()->createGroup(m_slave_interface_name+"_MASTER",
767 master_faces_lid,true);
768 info() << "MASTER_INTERFACE: nb_face=" << m_master_interface.size();
769}
770
771/*---------------------------------------------------------------------------*/
772/*---------------------------------------------------------------------------*/
773
774void TiedInterfaceBuilder::
775_addFaceToList(const Face& face,TiedInterfaceFaceMap& face_map)
776{
777 Integer nb_node = face.nbNode();
778 Real3 center(0.,0.,0.);
779 Integer data_index = m_face_info_mng.size();
780 for( Node node : face.nodes() ){
781 Real3 node_coord = m_nodes_coord[node];
782 ItemUniqueId uid = node.uniqueId();
783 NodeInfoList::Data* i = m_nodes_info.lookup(uid);
784 if (!i){
786 node_info.m_coord = node_coord;
787 m_nodes_info.add(uid,node_info);
788 }
789 m_face_info_mng.add(uid);
790 center += node_coord;
791 }
792 center /= nb_node;
793 //info() << "ADD FACE uid=" << face.uniqueId() << " nb_node="
794 //<< nb_node << " center=" << center;
795 TiedInterfaceFace sf(face.uniqueId(),face.cell(0).uniqueId(),nb_node,face.owner(),data_index,&m_face_info_mng);
796 sf.setCenter(center);
797 face_map.add(face.uniqueId(),sf);
798}
799
800/*---------------------------------------------------------------------------*/
801/*---------------------------------------------------------------------------*/
808{
809 std::set<ItemUniqueId> master_face_with_slave;
810
811 for( TiedInterfaceFaceMapEnumerator i(m_slave_faces); ++i; ){
815 }
816
818 ENUMERATE_FACE(iface,m_master_interface.own()){
819 Face face = *iface;
820 ItemUniqueId uid = face.uniqueId();
822 local_ids_to_remove.add(iface.itemLocalId());
823 }
824 }
825
826 if (!local_ids_to_remove.empty()){
827 info() << "Removing faces from master list name=" << m_master_interface.name()
828 << " ids=" << local_ids_to_remove;
829 m_master_interface.removeItems(local_ids_to_remove,false);
830 }
831}
832
833/*---------------------------------------------------------------------------*/
834/*---------------------------------------------------------------------------*/
835
836void TiedInterfaceBuilder::
837_computeProjectionInfos(TiedInterfaceBuilderInfos& infos,bool is_structured)
838{
840 Integer nb_master_face = m_master_interface.size();
842
843 infos.m_master_faces_uid.reserve(nb_master_face);
846
848 ENUMERATE_FACE(iface,m_master_interface.own()){
849 const Face& face = *iface;
852 }
853
854 for( TiedInterfaceFaceMapEnumerator i(m_slave_faces); ++i; ){
855 TiedInterfaceFace& slave_face = *i;
857 TiedInterfaceMasterFace& mf = m_master_faces_full[master_uid];
858 mf.m_slave_faces.add(&slave_face);
859 }
860
861 ENUMERATE_FACE(iface,m_master_interface.own()){
862 Face face = *iface;
863 ItemUniqueId master_uid = face.uniqueId();
864 //TiedInterfaceMasterFace& mf = *enumerator;
865 TiedInterfaceMasterFace& mf = m_master_faces_full[master_uid];
866 Integer master_face_nb_slave_face = mf.m_slave_faces.size();
867 //Int64 master_uid = mf.uniqueId();
868 if (m_is_debug)
869 info() << "MASTER FACE uid=" << master_uid << " NB_SLAVE_FACE=" << master_face_nb_slave_face
870 << " face_owner=" << face.owner();
871 infos.m_master_faces_uid.add(master_uid);
872 infos.m_master_faces_nb_slave_face.add(master_face_nb_slave_face);
873 infos.m_master_faces_slave_face_index.add(infos.m_slave_faces_uid.size());
874 for( Integer zz=0; zz<master_face_nb_slave_face; ++zz ){
875 ItemUniqueId slave_uid = mf.m_slave_faces[zz]->uniqueId();
876 infos.m_slave_faces_uid.add(slave_uid);
877 }
878 }
879
880 std::set<ItemUniqueId> slave_nodes_set;
881 SortedNodeInfoSet slave_nodes_sorted_set;
882
883 bool is_dimension_2d = m_mesh->dimension()==2;
884 ENUMERATE_FACE(imasterface,m_master_interface.own()){
885 Face master_face = *imasterface;
886 ItemUniqueId master_uid = master_face.uniqueId();
887 slave_nodes_set.clear();
888 slave_nodes_sorted_set.clear();
889 TiedInterfaceMasterFace& face2 = m_master_faces_full[master_uid];
890 if (m_is_debug){
891 Integer face2_nb_node = master_face.nbNode();
892 info() << "MASTER FACE: uid=" << face2.uniqueId()
893 << " cell_uid=" << master_face.cell(0).uniqueId()
894 << " cell_owner=" << master_face.cell(0).owner()
895 << " nb_node=" << face2_nb_node;
896 for( Integer in2=0; in2<face2_nb_node; ++in2 )
897 info() << "Node " << in2 << " uid=" << master_face.node(in2).uniqueId();
898 }
899 TiedInterfaceFace& face = m_master_faces[face2.uniqueId()];
900 Integer nb_node = face.nbNode();
901 Integer nb_slave_face = face2.m_slave_faces.size();
902 for( Integer i=0; i<nb_slave_face; ++i ){
903 const TiedInterfaceFace& slave_face = *face2.m_slave_faces[i];
904 Integer slave_nb_node = slave_face.nbNode();
905 for( Integer z=0; z<slave_nb_node; ++z ){
906 ItemUniqueId node_uid = slave_face.nodeUniqueId(z);
907 slave_nodes_set.insert(node_uid);
908 //info() << "ADD NODE uid=" << node_uid;
909 }
910 }
911 if (m_is_debug)
912 info() << "MASTER FACE: NB_SLAVE_FACE=" << nb_slave_face
913 << " NB_SLAVE_NODE=" << slave_nodes_set.size();
914 infos.m_master_faces_slave_node_index.add(infos.m_slave_nodes_uid.size());
915 infos.m_master_faces_nb_slave_node.add(CheckedConvert::toInteger(slave_nodes_set.size()));
916 {
917 std::set<ItemUniqueId>::const_iterator i_node = slave_nodes_set.begin();
918 // Cas 3D, les faces sont des quadrangles
919 if (nb_node==4){
920 GeometricUtilities::QuadMapping face_mapping;
921 for( Integer i=0; i<nb_node; ++i ){
922 ItemUniqueId node_uid = face.nodeUniqueId(i);
923 face_mapping.m_pos[i] = m_nodes_info[node_uid].m_coord;
924 }
925
926 for( ; i_node!=slave_nodes_set.end(); ++i_node ){
927 ItemUniqueId node_uid = *i_node;
928 TiedInterfaceNodeInfo& node_info = m_nodes_info[node_uid];
929 Real3 uvw;
930 Real3 point = node_info.m_coord;
931 GeometricUtilities::ProjectionInfo projection = _findProjection(face,point);
932 if (m_is_debug)
933 info() << "POINT PROJECTION: uid=" << node_uid << ' '
934 << projection.m_projection << " r=" << projection.m_region
935 << " d=" << projection.m_distance
936 << " alpha=" << projection.m_alpha
937 << " beta=" << projection.m_beta;
938 bool is_bad = face_mapping.cartesianToIso(point,uvw,0);
939 if (m_is_debug)
940 info() << "ISO1 =" << uvw;
941 is_bad = face_mapping.cartesianToIso2(point,uvw,0);
942 if (m_is_debug)
943 info() << "ISO2 =" << uvw;
944 if (is_bad){
945 warning() << "Can not compute iso-coordinates for point " << point;
946 face_mapping.cartesianToIso(point,uvw,traceMng());
947 }
948
949 if (math::abs(uvw.x)>1.1 || math::abs(uvw.y)>1.1 || math::abs(uvw.z)>1.1){
950 info() << "BAD PROJECTION INFO";
951 info() << "P0 = " << face_mapping.m_pos[0];
952 info() << "P1 = " << face_mapping.m_pos[1];
953 info() << "P2 = " << face_mapping.m_pos[2];
954 info() << "P3 = " << face_mapping.m_pos[3];
955 warning() << "Internal: bad iso value: " << uvw
956 << " node=" << node_uid << " pos=" << point
957 << " projection=" << projection.m_projection
958 << " face_uid=" << face.uniqueId()
959 << " cell_uid=" << face.cellUniqueId();
960 face_mapping.cartesianToIso(point,uvw,traceMng());
961 face_mapping.cartesianToIso(projection.m_projection,uvw,traceMng());
962 }
963 //else
964 //info() << "POINT ISO1: " << uvw;
965 //Real3 new_point = face_mapping.evaluatePosition(uvw);
966 //info() << "POINT ISO_TO_CART: " << (new_point-point).abs();
967
968 // Cas particulier des noeuds de la face esclave qui sont des noeuds maitres.
969 // Dans ce cas, on fixe en dur leur coordonnées iso pour éviter une
970 // perte de précision.
971 if (node_uid==face.nodeUniqueId(0)){
972 uvw.x = ARCANE_REAL(-1.0);
973 uvw.y = ARCANE_REAL(-1.0);
974 }
975 else if (node_uid==face.nodeUniqueId(1)){
976 uvw.x = ARCANE_REAL( 1.0);
977 uvw.y = ARCANE_REAL(-1.0);
978 }
979 else if (node_uid==face.nodeUniqueId(2)){
980 uvw.x = ARCANE_REAL(1.0);
981 uvw.y = ARCANE_REAL(1.0);
982 }
983 else if (node_uid==face.nodeUniqueId(3)){
984 uvw.x = ARCANE_REAL(-1.0);
985 uvw.y = ARCANE_REAL( 1.0);
986 }
987
988 slave_nodes_sorted_set.insert(TiedInterfaceSortedNodeInfo(node_uid,uvw.x,uvw.y));
989 }
990 }
991 // Case 2D, les faces sont des arêtes
992 else if (nb_node==2){
993 for( ; i_node!=slave_nodes_set.end(); ++i_node ){
994 ItemUniqueId node_uid = *i_node;
995 TiedInterfaceNodeInfo& node_info = m_nodes_info[node_uid];
996 Real3 point = node_info.m_coord;
997 GeometricUtilities::ProjectionInfo projection = _findProjection(face,point);
998 //info() << "POINT PROJECTION: uid=" << node_uid << ' '
999 // << projection.m_projection
1000 //<< " r=" << projection.m_region << " d=" << projection.m_distance;
1001 // Cas particulier des noeuds de la face esclave qui sont des noeuds maitres.
1002 // Dans ce cas, on fixe en dur leur coordonnées iso pour éviter une
1003 // perte de précision.
1004 Real alpha = projection.m_alpha;
1005 if (node_uid==face.nodeUniqueId(0)){
1006 alpha = ARCANE_REAL(0.0);
1007 }
1008 else if (node_uid==face.nodeUniqueId(1)){
1009 alpha = ARCANE_REAL(1.0);
1010 }
1011 slave_nodes_sorted_set.insert(TiedInterfaceSortedNodeInfo(node_uid,alpha,0.0));
1012 }
1013 }
1014 else
1015 ARCANE_FATAL("Can not detect structuration for face with nb_node={0}."
1016 " Valid values are 2 or 4",nb_node);
1017 }
1018 if (slave_nodes_sorted_set.size()!=slave_nodes_set.size()){
1019 ARCANE_FATAL("Internal: error sorting nodes in TiedInterface: bad compare");
1020 }
1021 // En cas de structuration, la détecte et recalcule
1022 // les coordonnées iso avec cette info.
1023 if (is_structured){
1024 StructurationMap struct_map(CheckedConvert::toInteger(slave_nodes_sorted_set.size()*2),true);
1025 SortedNodeInfoSet::const_iterator i_node = slave_nodes_sorted_set.begin();
1026 for( ; i_node!=slave_nodes_sorted_set.end(); ++i_node ){
1027 const TiedInterfaceSortedNodeInfo& node = *i_node;
1028 ItemUniqueId uid = node.uniqueId();
1029 TiedInterfaceStructurationInfo struct_info(uid,node.m_alpha,node.m_beta);
1030 struct_map.add(uid,struct_info);
1031 if (m_is_debug)
1032 info() << "Add to struct map node_uid=" << uid << " alpha=" << node.m_alpha << " beta=" << node.m_beta;
1033 }
1034 _detectStructuration(face2,struct_map);
1035 // Recherche la valeur de la structuration.
1036 // Comme on commence la structuration avec le noeud 0 de la face maitre,
1037 // C'est la valeur (x,y) du noeud 2 la maille maitre pour un quad, et
1038 // le noeud 1 pour une arête
1039 TiedInterfaceStructurationInfo sinfo = struct_map[face.nodeUniqueId(nb_node/2)];
1040 if (m_is_debug)
1041 info() << "********* STRUCTURE X=" << sinfo.m_x << " Y=" << sinfo.m_y;
1042 Integer sx = sinfo.m_x;
1043 Integer sy = sinfo.m_y;
1044 Real rx = (Real)sinfo.m_x;
1045 Real ry = (Real)sinfo.m_y;
1046 slave_nodes_sorted_set.clear();
1047 for( StructurationMapEnumerator imap(struct_map); ++imap; ){
1048 TiedInterfaceStructurationInfo& minfo = *imap;
1049 ItemUniqueId node_uid = minfo.m_node_uid;
1050 Real old_alpha = minfo.m_alpha;
1051 Real old_beta = minfo.m_beta;
1052 Real new_alpha = 0.0;
1053 Real new_beta = 0.0;
1054 if (is_dimension_2d){
1055 // En 2D, les coordonnées iso vont de 0.0 à 1.0
1056 if (sx!=0)
1057 new_alpha = (1.0 * minfo.m_x) / rx;
1058 }
1059 else{
1060 if (sx!=0)
1061 new_alpha = -1.0 + (2.0 * minfo.m_x) / rx;
1062 if (sy!=0)
1063 new_beta = -1.0 + (2.0 * minfo.m_y) / ry;
1064 }
1065 if (m_is_debug)
1066 info() << "NEW NODE oldx=" << old_alpha << " newx=" << new_alpha
1067 << " oldy=" << old_beta << " newy=" << new_beta;
1068 slave_nodes_sorted_set.insert(TiedInterfaceSortedNodeInfo(node_uid,new_alpha,new_beta));
1069 }
1070 }
1071 {
1072 SortedNodeInfoSet::const_iterator i_node = slave_nodes_sorted_set.begin();
1073 for( ; i_node!=slave_nodes_sorted_set.end(); ++i_node ){
1074 const TiedInterfaceSortedNodeInfo& node = *i_node;
1075 if (m_is_debug)
1076 info() << "ADD TO SLAVE NODE: node_uid=" << node.m_uid
1077 << " alpha=" << node.m_alpha
1078 << " beta=" << node.m_beta;
1079 infos.m_slave_nodes_uid.add(node.m_uid);
1080 infos.m_slave_nodes_iso.add(Real2(node.m_alpha,node.m_beta));
1081 }
1082 }
1083 }
1084}
1085
1086/*---------------------------------------------------------------------------*/
1087/*---------------------------------------------------------------------------*/
1088
1089void TiedInterfaceBuilder::
1090_detectStructuration(const TiedInterfaceMasterFace& master_face,
1091 StructurationMap& slave_nodes)
1092{
1093 Integer nb_slave_face = master_face.m_slave_faces.size();
1094 // Positionne le premier noeud de la face comme étant le noeud (0,0)
1095 // de la structuration.
1096 TiedInterfaceFace& mface = m_master_faces[master_face.uniqueId()];
1097 TiedInterfaceStructurationInfo& sinfo = slave_nodes[mface.nodeUniqueId(0)];
1098 sinfo.setStructuration(0,0);
1099 //info() << "** SET STRUCTURATION node=" << mface.nodeUniqueId(0);
1100 UniqueArray<ItemUniqueId> slave_faces;
1101 UniqueArray<ItemUniqueId> remaining_slave_faces;
1102 for( Integer i=0; i<nb_slave_face; ++i ){
1103 const TiedInterfaceFace& slave_face = *master_face.m_slave_faces[i];
1104 slave_faces.add(slave_face.uniqueId());
1105 }
1106
1107 for( Integer zz=0; zz<(nb_slave_face+1); ++zz ){
1108 remaining_slave_faces.clear();
1109 Integer nb_to_process = slave_faces.size();
1110 _detectStructurationRecursive(slave_faces,remaining_slave_faces,slave_nodes);
1111 Integer nb_remaining = remaining_slave_faces.size();
1112 if (nb_remaining==0)
1113 break;
1114 if (nb_to_process==nb_remaining){
1115 ARCANE_FATAL("Can not compute structuration for a tied interface"
1116 " remaining_slaves={0}",nb_remaining);
1117 }
1118 slave_faces.copy(remaining_slave_faces);
1119 }
1120}
1121
1122/*---------------------------------------------------------------------------*/
1123/*---------------------------------------------------------------------------*/
1124
1125void TiedInterfaceBuilder::
1126_detectStructurationRecursive(Array<ItemUniqueId>& slave_faces,
1127 Array<ItemUniqueId>& remaining_slave_faces,
1128 StructurationMap& slave_nodes)
1129{
1130 // Parcours chaque face.
1131 // Une face peut être traitée si un de ses noeuds a déjà une structuration.
1132 // Si ce n'est pas le cas, la face est ajoutée à remaining_slave_faces
1133 // pour être traitée ultérieurement.
1134 // En cas de structuration, on prend le premier trouvé. A partir de ce noeud A,
1135 // on regarde le noeud suivant B dans la face. On regarde si ce
1136 // noeud B différe de notre noeud de référence suivant alpha ou beta.
1137 // S'il s'agit de alpha, il aura le même y et il sera en (x+1) si alpha
1138 // de B est supérieur à celui de A.
1139 // La même chose pour y si la différence est en beta.
1140 // NOTE. Comme la projection n'est pas forcément très bonne, deux
1141 // noeuds de même x par exemple peuvent avoir un alpha légèrement différent.
1142 // Pour déterminer si c'est alpha ou beta qui varie le plus, on
1143 // prend le plus grand de abs(A.alpha-B.alpha) et abs(A.beta-B.beta)
1144 for( Integer i=0, is=slave_faces.size(); i<is; ++i ){
1145 Integer node_index = (-1);
1146 TiedInterfaceStructurationInfo old_sinfo;
1147 const TiedInterfaceFace& face = m_slave_faces[ slave_faces[i] ];
1148 Integer nb_node = face.nbNode();
1149 for( Integer z=0; z<nb_node; ++z ){
1150 ItemUniqueId node_uid = face.nodeUniqueId(z);
1151 const TiedInterfaceStructurationInfo& sinfo = slave_nodes[node_uid];
1152 if (m_is_debug)
1153 info() << "CHECK NODE face_uid=" << face.uniqueId()
1154 << " node_uid=" << node_uid
1155 << " x=" << sinfo.m_x
1156 << " y=" << sinfo.m_y
1157 << " alpha=" << sinfo.m_alpha
1158 << " beta=" << sinfo.m_beta;
1159 if (sinfo.hasStructuration()){
1160 node_index = z;
1161 old_sinfo = sinfo;
1162 break;
1163 }
1164 }
1165 if (node_index==(-1)){
1166 remaining_slave_faces.add(slave_faces[i]);
1167 continue;
1168 }
1169
1170 for( Integer z=1; z<nb_node; ++z ){
1171 ItemUniqueId next_uid = face.nodeUniqueId((node_index+z)%nb_node);
1172 TiedInterfaceStructurationInfo& next_info = slave_nodes[next_uid];
1173 Real diff_alpha = next_info.m_alpha - old_sinfo.m_alpha;
1174 Real diff_beta = next_info.m_beta - old_sinfo.m_beta;
1175 Integer x = old_sinfo.m_x;
1176 Integer y = old_sinfo.m_y;
1177 if (math::abs(diff_alpha)>math::abs(diff_beta)){
1178 // La variation est en x.
1179 if (next_info.m_alpha > old_sinfo.m_alpha){
1180 if (m_is_debug)
1181 info() << "SUP_ALPHA SET NEXT uid=" << next_uid << " x=" << (x+1) << " y=" << (y);
1182 next_info.setStructuration(x+1,y);
1183 }
1184 else{
1185 if (m_is_debug)
1186 info() << "INF_ALPHA SET NEXT uid=" << next_uid << " x=" << (x-1) << " y=" << (y);
1187 next_info.setStructuration(x-1,y);
1188 }
1189 }
1190 else{
1191 // La variation est en y.
1192 if (next_info.m_beta > old_sinfo.m_beta){
1193 if (m_is_debug)
1194 info() << "SUP_BETA SET NEXT uid=" << next_uid << " x=" << (x) << " y=" << (y+1);
1195 next_info.setStructuration(x,y+1);
1196 }
1197 else{
1198 if (m_is_debug)
1199 info() << "INF_BETA SET NEXT uid=" << next_uid << " x=" << (x) << " y=" << (y-1);
1200 next_info.setStructuration(x,y-1);
1201 }
1202 }
1203 old_sinfo = next_info;
1204 }
1205 }
1206}
1207
1208/*---------------------------------------------------------------------------*/
1209/*---------------------------------------------------------------------------*/
1210
1211void TiedInterfaceBuilder::
1212_printFaces(std::ostream& o,TiedInterfaceFaceMap& face_map)
1213{
1214 // Utilise une map pour trier les faces suivant leur uniqueId() afin
1215 // que l'affichage soit toujours le meme.
1216 typedef std::map<ItemUniqueId,TiedInterfaceFace*> FacesMap;
1217
1218 FacesMap faces;
1219 for( TiedInterfaceFaceMapEnumerator i(face_map); ++i; ){
1220 TiedInterfaceFace* mf = &i.m_current_data->value();
1221 faces.insert(std::make_pair(mf->uniqueId(),mf));
1222 }
1223
1224 for( FacesMap::const_iterator i(faces.begin()); i!=faces.end(); ++i ){
1225 TiedInterfaceFace& mf = *(i->second);
1226 Integer nb_node = mf.nbNode();
1227 o << " face=" << mf.uniqueId() << " nb_node=" << nb_node
1228 << " center=" << mf.center() << '\n';
1229 for( Integer z=0; z<nb_node; ++z ){
1230 ItemUniqueId nuid(mf.nodeUniqueId(z));
1231 o << " node uid=" << nuid << " coord=" << m_nodes_info[nuid].m_coord << '\n';
1232 }
1233 }
1234}
1235
1236/*---------------------------------------------------------------------------*/
1237/*---------------------------------------------------------------------------*/
1249{
1251 Integer nb_to_send = 0;
1252 RealUniqueArray coords;
1256 for( NodeInfoListEnumerator i(m_nodes_info); ++i; ){
1257 const TiedInterfaceNodeInfo& ni = *i;
1258 ++nb_to_send;
1259 unique_ids.add(ni.uniqueId());
1260 coords.add(ni.m_coord.x);
1261 coords.add(ni.m_coord.y);
1262 coords.add(ni.m_coord.z);
1263 Integer nb_connected = ni.m_connected_master_faces.size();
1265 for( Integer z=0; z<nb_connected; ++z )
1266 connected_master_faces.add(ni.m_connected_master_faces[z]);
1267 }
1268
1269 IParallelMng* pm = m_mesh->parallelMng();
1270 Integer nb_rank = pm->commSize();
1271
1273 sbuf.setMode(ISerializer::ModeReserve);
1274 sbuf.reserveInteger(1); // pour le nombre de noeuds
1275 sbuf.reserveInteger(1); // pour le nombre de faces connectées
1276 sbuf.reserve(DT_Int64,unique_ids.size()); // pour les uniqueId() des noeuds
1277 sbuf.reserveInteger(nb_connected_master_faces.size()); // pour le nombre de faces connectées
1278 sbuf.reserve(DT_Int64,connected_master_faces.size()); // pour les uniqueId() des faces
1279 sbuf.reserve(DT_Real,coords.size());
1280
1281 sbuf.allocateBuffer();
1282 sbuf.setMode(ISerializer::ModePut);
1283 sbuf.putInteger(nb_to_send);
1284 sbuf.putInteger(connected_master_faces.size());
1285 sbuf.put(unique_ids);
1288 sbuf.put(coords);
1289
1290 SerializeBuffer recv_buf;
1291 pm->allGather(&sbuf,&recv_buf);
1292 recv_buf.setMode(ISerializer::ModeGet);
1293
1294 for( Integer i=0; i<nb_rank; ++i ){
1295 Integer nb_node = recv_buf.getInteger();
1296 Integer nb_connected_face = recv_buf.getInteger();
1297 unique_ids.resize(nb_node);
1300 coords.resize(nb_node*3);
1301
1302 recv_buf.get(unique_ids);
1304 recv_buf.get(connected_master_faces);
1305 recv_buf.get(coords);
1306
1307 // Parcours toutes les faces reçues si certaines sont absentes,
1308 // les ajoute.
1309 Integer face_index = 0;
1310 for( Integer z=0; z<nb_node; ++z ){
1312 if (nb_face!=0){
1313 ItemUniqueId uid(unique_ids[z]);
1314 NodeInfoList::Data* data = m_nodes_info.lookup(uid);
1315 if (data){
1316 TiedInterfaceNodeInfo& ni = data->value();
1317 //info() << "RECEIVE NODE uid=" << uid << " nb_face=" << nb_face;
1318 for( Integer zz=0; zz<nb_face; ++zz ){
1320 //info() << " FACE=" << fuid;
1321 ni.addConnectedFace(fuid);
1322 }
1323 }
1324 }
1325 face_index += nb_face;
1326 }
1327 }
1328 pm->barrier();
1329}
1330
1331/*---------------------------------------------------------------------------*/
1332/*---------------------------------------------------------------------------*/
1343{
1344 IParallelMng* pm = m_mesh->parallelMng();
1345 Int32 my_rank = pm->commRank();
1346 Int32 nb_rank = pm->commSize();
1347
1349 sbuf.setMode(ISerializer::ModeReserve);
1350 Integer nb_to_send = faces_to_send.size();
1351
1354 Int64UniqueArray nodes_unique_id;
1355 nodes_unique_id.reserve(nb_to_send*4);
1357 RealUniqueArray coords;
1358 coords.reserve(3*nb_to_send);
1360 nodes_coords.reserve(3*nb_to_send);
1361 for( Integer i=0; i<nb_to_send; ++i ){
1363 for( Integer z=0, zs=mf.nbNode(); z<zs; ++z ){
1364 ItemUniqueId nuid(mf.nodeUniqueId(z));
1365 nodes_unique_id.add(nuid.asInt64());
1366 TiedInterfaceNodeInfo ni = m_nodes_info[nuid];
1367 nodes_coords.add(ni.m_coord.x);
1368 nodes_coords.add(ni.m_coord.y);
1369 nodes_coords.add(ni.m_coord.z);
1370 }
1371 unique_ids[i] = mf.uniqueId().asInt64();
1372 cells_unique_ids[i] = mf.cellUniqueId().asInt64();
1373 nb_nodes[i] = mf.nbNode();
1374
1375 coords.add(mf.center().x);
1376 coords.add(mf.center().y);
1377 coords.add(mf.center().z);
1378 }
1379 sbuf.reserveInteger(1); // pour le nombre de faces
1380 sbuf.reserveInteger(1); // pour le numéro du sous-domaine
1381 sbuf.reserveInteger(1); // pour le nombre de noeuds dans la liste
1382 sbuf.reserve(DT_Int64,unique_ids.size()); // pour le unique id des faces
1383 sbuf.reserve(DT_Int64,cells_unique_ids.size()); // pour le unique id des mailles des faces
1384 sbuf.reserveInteger(nb_nodes.size()); // pour le nombre de noeuds
1385 sbuf.reserve(DT_Int64,nodes_unique_id.size()); // pour la liste des noeuds
1386 sbuf.reserve(DT_Real,coords.size()); // pour les coordonnées du centre
1387 sbuf.reserve(DT_Real,nodes_coords.size()); // pour les coordonnées des noeuds
1388 sbuf.allocateBuffer();
1389 sbuf.setMode(ISerializer::ModePut);
1390 sbuf.putInteger(nb_to_send);
1391 sbuf.putInteger(my_rank);
1392 sbuf.putInteger(nodes_unique_id.size());
1393 sbuf.put(unique_ids);
1394 sbuf.put(cells_unique_ids);
1395 sbuf.put(nb_nodes);
1396 sbuf.put(nodes_unique_id);
1397 sbuf.put(coords);
1398 sbuf.put(nodes_coords);
1399
1400 SerializeBuffer recv_buf;
1401 pm->allGather(&sbuf,&recv_buf);
1402 recv_buf.setMode(ISerializer::ModeGet);
1403
1404 for( Integer i=0; i<nb_rank; ++i ){
1405 Integer nb_face = recv_buf.getInteger();
1406 Integer sid = recv_buf.getInteger();
1407 Integer nb_node_unique_id = recv_buf.getInteger();
1408 //info() << " READ n=" << nb_face << " sid=" << sid;
1409 unique_ids.resize(nb_face);
1410 cells_unique_ids.resize(nb_face);
1411 nb_nodes.resize(nb_face);
1412 nodes_unique_id.resize(nb_node_unique_id);
1413 coords.resize(nb_face*3);
1415
1416 recv_buf.get(unique_ids);
1417 recv_buf.get(cells_unique_ids);
1418 recv_buf.get(nb_nodes);
1419 recv_buf.get(nodes_unique_id);
1420 recv_buf.get(coords);
1421 recv_buf.get(nodes_coords);
1422
1423 // Parcours toutes les faces reçues si certaines sont absentes,
1424 // les ajoute.
1425 Integer node_index = 0;
1426 for( Integer z=0; z<nb_face; ++z ){
1427 Integer nb_node = nb_nodes[z];
1428 ItemUniqueId uid(unique_ids[z]);
1429 ItemUniqueId cell_uid(cells_unique_ids[z]);
1430 if (!face_map.hasKey(uid)){
1431 Real3 center;
1432 center.x = coords[z*3];
1433 center.y = coords[z*3 + 1];
1434 center.z = coords[z*3 + 2];
1435 //info() << " RECV FACE: " << uid << " owner=" << sid << " center=" << center;
1436
1437 Integer data_index = m_face_info_mng.size();
1438 for( Integer zz=0; zz<nb_node; ++zz ){
1439 ItemUniqueId nuid(nodes_unique_id[node_index+zz]);
1440 m_face_info_mng.add(nuid);
1441 // Ajoute le noeud à la liste.
1443 ni.m_coord.x = nodes_coords[(node_index+zz)*3];
1444 ni.m_coord.y = nodes_coords[(node_index+zz)*3 + 1];
1445 ni.m_coord.z = nodes_coords[(node_index+zz)*3 + 2];
1446 //info() << "ADD NODE uid=" << nuid << " coord=" << ni.m_coord;
1447 m_nodes_info.add(nuid,ni);
1448 }
1449 TiedInterfaceFace sf(uid,cell_uid,nb_node,sid,data_index,&m_face_info_mng);
1450 sf.setCenter(center);
1451 face_map.add(uid,sf);
1452 }
1454 }
1455 }
1456 pm->barrier();
1457}
1458
1459/*---------------------------------------------------------------------------*/
1460/*---------------------------------------------------------------------------*/
1475{
1476 IItemFamily* cell_family = m_mesh->cellFamily();
1478 cells_nb_connected.fill(0);
1479 VariableItemInt32 cells_owner = cell_family->itemsNewOwner();
1480 {
1481 ENUMERATE_FACE(iface,m_slave_interface.own()){
1482 Face face = *iface;
1483 const TiedInterfaceFace& slave_face = m_slave_faces[face.uniqueId()];
1485 Integer master_owner = m_master_faces[master_face].owner();
1486 Cell slave_cell = face.cell(0);
1487 Int32 cell_lid = slave_cell.localId();
1490 ARCANE_FATAL("Cell {0} is connected to more than one master face",
1492 }
1494 }
1495 }
1496}
1497
1498/*---------------------------------------------------------------------------*/
1499/*---------------------------------------------------------------------------*/
1513{
1514 IItemFamily* cell_family = m_mesh->cellFamily();
1517 //VariableItemInt32 cells_owner = cell_family->itemsNewOwner();
1518 {
1519 ENUMERATE_FACE(iface,m_slave_interface.own()){
1520 Face face = *iface;
1521 const TiedInterfaceFace& slave_face = m_slave_faces[face.uniqueId()];
1523 Int32 master_owner = m_master_faces[master_face].owner();
1524 Cell slave_cell = face.cell(0);
1525 Int32 cell_lid = slave_cell.localId();
1528 ItemUniqueId master_face_cell_uid = m_master_faces[master_face].cellUniqueId();
1529 // Le premier élément doit être le uid le plus petit
1533 linked_owners.add(face.owner());
1534 }
1535 else{
1539 }
1540 if (last_master_uid!=NULL_ITEM_UNIQUE_ID){
1541 // Maille connectée à plusieurs faces maîtres.
1542 // Vérifie qu'elles sont toutes dans le même sous-domaine.
1543 Int32 last_master_owner = m_master_faces[last_master_uid].owner();
1545 ARCANE_FATAL("Cell {0} is connected to more than one master face:"
1546 " face1={1} owner1={2} face2={3} owner2={4}", ItemPrinter(slave_cell),
1548 }
1550 }
1551 }
1552}
1553
1554/*---------------------------------------------------------------------------*/
1555/*---------------------------------------------------------------------------*/
1565{
1566 IParallelMng* pm = m_mesh->parallelMng();
1567 Int32 my_rank = pm->commRank();
1568
1570
1571 // En parallèle, il faut envoyer à tous le monde les infos sur la surface maître.
1574 for( TiedInterfaceFaceMapEnumerator i(m_master_faces); ++i; ){
1575 TiedInterfaceFace& sf = *i;
1576 if (sf.owner()==my_rank)
1577 master_faces_to_send.add(sf.uniqueId());
1578 }
1579 _gatherFaces(master_faces_to_send,m_master_faces);
1580 }
1581
1582#if 0
1584 String fname = "master_face_";
1585 fname += m_slave_interface.name();
1586 if (is_parallel){
1587 fname += ".";
1588 fname += pm->commRank();
1589 }
1590 ofstream ofile(fname.localstr());
1591 _printFaces(ofile,m_master_faces);
1592 }
1593#endif
1594
1595 {
1597 for( TiedInterfaceFaceMapEnumerator i(m_slave_faces); ++i; ){
1598 slave_faces_to_process.add((*i).uniqueId());
1599 }
1600
1602 //TODO supprimer le 10000
1603 for( Integer zz=0; zz<10000; ++zz ){
1605 info() << " SEND RECV NODES INFO n=" << zz;
1607 }
1608 //slave_faces_to_process.resize(remaining_slave_faces_index.size());
1609 //slave_faces_to_process.copy(remaining_slave_faces_index);
1610 //warning() << " SEARCH: NB=" << slave_faces_to_proceed.size();
1611 remaining_slave_faces.clear();
1613 Integer nb_remaining = remaining_slave_faces.size();
1614 Integer nb_to_process = slave_faces_to_process.size();
1616 info() << "NB REMAINING n=" << nb_remaining;
1617 nb_remaining = pm->reduce(Parallel::ReduceSum,nb_remaining);
1618 info() << "CUMULATIVE NB REMAINING n=" << nb_remaining;
1619 nb_to_process = pm->reduce(Parallel::ReduceSum,nb_to_process);
1620 }
1621 if (nb_remaining==0)
1622 break;
1624 ARCANE_FATAL("Can not compute master/slave infos for a tied interface. Remaining_slaves={0}",
1625 nb_remaining);
1626 }
1628 }
1629 }
1630}
1631
1632/*---------------------------------------------------------------------------*/
1633/*---------------------------------------------------------------------------*/
1634
1635void TiedInterfaceBuilder::
1636computeInterfaceInfos(TiedInterfaceBuilderInfos& infos,bool is_structured)
1637{
1639 _computeProjectionInfos(infos,is_structured);
1640}
1641
1642/*---------------------------------------------------------------------------*/
1643/*---------------------------------------------------------------------------*/
1644
1645/*---------------------------------------------------------------------------*/
1646/*---------------------------------------------------------------------------*/
1647
1648bool TiedInterface::m_is_debug = false;
1649
1650/*---------------------------------------------------------------------------*/
1651/*---------------------------------------------------------------------------*/
1652
1653TiedInterface::
1654TiedInterface(IMesh* mesh)
1655: TraceAccessor(mesh->traceMng())
1656, m_mesh(mesh)
1657, m_planar_tolerance(0.)
1658{
1659 if (!platform::getEnvironmentVariable("ARCANE_DEBUG_TIED_INTERFACE").null())
1660 m_is_debug = true;
1661}
1662
1663/*---------------------------------------------------------------------------*/
1664/*---------------------------------------------------------------------------*/
1665
1666TiedInterface::
1667~TiedInterface()
1668{
1669}
1670
1671/*---------------------------------------------------------------------------*/
1672/*---------------------------------------------------------------------------*/
1673
1674/*---------------------------------------------------------------------------*/
1675/*---------------------------------------------------------------------------*/
1676
1679masterInterface() const
1680{
1681 return m_master_interface;
1682}
1683
1686slaveInterface() const
1687{
1688 return m_slave_interface;
1689}
1690
1692masterInterfaceName() const
1693{
1694 return m_master_interface_name;
1695}
1696
1698slaveInterfaceName() const
1699{
1700 return m_slave_interface_name;
1701}
1702
1704tiedNodes() const
1705{
1706 return m_tied_nodes;
1707}
1708
1710tiedFaces() const
1711{
1712 return m_tied_faces;
1713}
1714
1715void TiedInterface::
1717{
1718 m_tied_nodes.resize(new_sizes);
1719}
1720
1721void TiedInterface::
1722resizeFaces(IntegerConstArrayView new_sizes)
1723{
1724 m_tied_faces.resize(new_sizes);
1725}
1726
1727void TiedInterface::
1728setNodes(Integer index,ConstArrayView<TiedNode> nodes)
1729{
1730 for( Integer i=0, is=nodes.size(); i<is; ++i )
1731 m_tied_nodes[index][i] = nodes[i];
1732}
1733
1734void TiedInterface::
1735setFaces(Integer index,ConstArrayView<TiedFace> faces)
1736{
1737 for( Integer i=0, is=faces.size(); i<is; ++i )
1738 m_tied_faces[index][i] = faces[i];
1739}
1740
1741/*---------------------------------------------------------------------------*/
1742/*---------------------------------------------------------------------------*/
1743
1746{
1747 public:
1748
1750 : m_mesh(mesh), m_slave_interfaces(slave_interfaces), m_is_debug(is_debug), m_is_initial(true)
1751 {
1752 }
1753
1754 public:
1755
1757 {
1758 IParallelMng* pm = m_mesh->parallelMng();
1759 ITraceMng* tm = pm->traceMng();
1760 // Il faut faire les comms que pour le partitionnement initial car par la suite
1761 // les faces de part et d'autre d'une liaison sont dans le même sous-domaine.
1762 if (m_is_initial){
1763 Integer nb_interface = m_slave_interfaces.size();
1764 for( Integer i=0; i<nb_interface; ++i ){
1765 TiedInterfaceBuilder builder(m_mesh,m_slave_interfaces[i],false,m_is_debug);
1766 builder.computeInterfaceConnections(true);
1768 }
1769 }
1770 else{
1771 TiedInterfaceCollection tied_interfaces = m_mesh->tiedInterfaces();
1772 for( TiedInterfaceCollection::Enumerator itied(tied_interfaces); ++itied; ){
1773 _addLinkedCells(*itied,linked_cells,linked_owners);
1774 }
1775 }
1776 tm->info() << "NB_LINKED_CELL=" << linked_cells.size();
1777 }
1778
1779 virtual void setInitialRepartition(bool is_initial)
1780 {
1781 m_is_initial = is_initial;
1782 }
1783
1784 void _addLinkedCells(ITiedInterface* interface,Int64Array& linked_cells,Int32Array& linked_owners)
1785 {
1787 //TiedInterfaceFaceList tied_faces = interface->tiedFaces();
1789 Face face = *iface;
1790 Cell cell = face.cell(0);
1791 Int64 cell_uid = cell.uniqueId();
1792 Int32 owner = cell.owner();
1793 for( Face isubface : face.slaveFaces() ){
1794 Cell sub_cell = isubface.cell(0);
1795 Int64 sub_cell_uid = sub_cell.uniqueId();
1796 if (sub_cell_uid<cell_uid){
1798 linked_cells.add(cell_uid);
1799 linked_owners.add(owner);
1800 }
1801 else{
1802 linked_cells.add(cell_uid);
1803 linked_cells.add(sub_cell_uid);
1804 linked_owners.add(owner);
1805 }
1806 }
1807 }
1808 }
1809
1810 private:
1811
1812 IMesh* m_mesh;
1813 UniqueArray<FaceGroup> m_slave_interfaces;
1814 bool m_is_debug;
1815 bool m_is_initial;
1816};
1817
1818/*---------------------------------------------------------------------------*/
1819/*---------------------------------------------------------------------------*/
1825{
1826 return new TiedInterfacePartitionConstraint(mesh,slave_interfaces,m_is_debug);
1827}
1828
1829/*---------------------------------------------------------------------------*/
1830/*---------------------------------------------------------------------------*/
1836{
1837 info() << "Compute information for the tied interface " << slave_interface.name();
1838
1839 TiedInterfaceBuilder builder(m_mesh,slave_interface,true,m_is_debug);
1840 TiedInterfaceBuilderInfos infos;
1841
1842 builder.setPlanarTolerance(m_planar_tolerance);
1843 builder.computeInterfaceConnections(false);
1844 builder.computeInterfaceInfos(infos,is_structured);
1845
1846 //infos.printInfos();
1847
1848 m_slave_interface = slave_interface.own();
1849 m_slave_interface_name = slave_interface.name();
1850 m_master_interface = builder.masterInterface().own();
1851 m_master_interface_name = builder.masterInterface().name();
1852
1853 {
1854 Integer nb_master_face = infos.m_master_faces_uid.size();
1855 m_tied_nodes.resize(infos.m_master_faces_nb_slave_node);
1856 m_tied_faces.resize(infos.m_master_faces_nb_slave_face);
1857
1860
1861 Int32UniqueArray slave_nodes_lid(infos.m_slave_nodes_uid.size());
1862 node_family->itemsUniqueIdToLocalId(slave_nodes_lid,infos.m_slave_nodes_uid);
1864
1865 Int32UniqueArray slave_faces_lid(infos.m_slave_faces_uid.size());
1866 face_family->itemsUniqueIdToLocalId(slave_faces_lid,infos.m_slave_faces_uid);
1868
1869 for( Integer i_master=0; i_master<nb_master_face; ++i_master ){
1870 Integer nb_slave_node = infos.m_master_faces_nb_slave_node[i_master];
1871 Integer nb_slave_face = infos.m_master_faces_nb_slave_face[i_master];
1872 if (m_is_debug)
1873 info() << "Master Face: " << infos.m_master_faces_uid[i_master]
1874 << " nb_slave_face=" << nb_slave_face
1875 << " nb_slave_node=" << nb_slave_node
1876 << " node_index=" << infos.m_master_faces_slave_node_index[i_master];
1877 for( Integer zz=0; zz<nb_slave_node; ++zz ){
1878 Integer first_index = infos.m_master_faces_slave_node_index[i_master];
1879
1880 if (m_is_debug)
1881 info() << "Node: uid=" << infos.m_slave_nodes_uid[first_index+zz]
1882 << " uv=" << infos.m_slave_nodes_iso[first_index+zz];
1883 Integer local_id = slave_nodes_lid[first_index+zz];
1884 TiedNode tn(zz,nodes[local_id],infos.m_slave_nodes_iso[first_index+zz]);
1885 m_tied_nodes[i_master][zz] = tn;
1886 }
1887
1888 for( Integer zz=0; zz<nb_slave_face; ++zz ){
1889 Integer first_index = infos.m_master_faces_slave_face_index[i_master];
1890
1891 if (m_is_debug)
1892 info() << "Face: uid=" << infos.m_slave_faces_uid[first_index+zz];
1893 Integer local_id = slave_faces_lid[first_index+zz];
1894 m_tied_faces[i_master][zz] = TiedFace(zz,faces[local_id]);
1895 }
1896 }
1897 }
1898}
1899
1900/*---------------------------------------------------------------------------*/
1901/*---------------------------------------------------------------------------*/
1902
1905{
1906 m_planar_tolerance = tol;
1907}
1908
1909/*---------------------------------------------------------------------------*/
1910/*---------------------------------------------------------------------------*/
1911
1912void TiedInterface::
1913reload(IItemFamily* face_family,
1916{
1917 m_master_interface_name = master_interface_name;
1918 m_slave_interface_name = slave_interface_name;
1919 ItemGroup group = face_family->findGroup(master_interface_name);
1920 if (group.null())
1921 ARCANE_FATAL("Can not find master group named '{0}'",master_interface_name);
1922 m_master_interface = group.own();
1923 group = face_family->findGroup(slave_interface_name);
1924 if (group.null())
1925 ARCANE_FATAL("Can not find slave group named '{0}'",slave_interface_name);
1926 m_slave_interface = group.own();
1927}
1928
1929/*---------------------------------------------------------------------------*/
1930/*---------------------------------------------------------------------------*/
1931
1932void TiedInterface::
1933rebuild(ITiedInterfaceRebuilder* rebuilder,
1934 IntegerConstArrayView nb_slave_node,
1935 IntegerConstArrayView nb_slave_face)
1936{
1937 info() << "REBUILD_TIED_INTERFACE name=" << m_master_interface.name();
1938 m_tied_nodes.resize(nb_slave_node);
1939 m_tied_faces.resize(nb_slave_face);
1940
1941 IItemFamily* node_family = m_mesh->itemFamily(IK_Node);
1942 IItemFamily* face_family = m_mesh->itemFamily(IK_Face);
1943
1944 NodeInfoListView nodes(node_family);
1945 FaceInfoListView faces(face_family);
1946
1947 Integer master_index = 0;
1948 Int32UniqueArray work_nodes_local_id;
1949 Real2UniqueArray work_nodes_iso;
1950 Int32UniqueArray work_faces_local_id;
1951
1952 ENUMERATE_FACE(iface,m_master_interface){
1953 Face face = *iface;
1954 ArrayView<TiedNode> face_tied_nodes = m_tied_nodes[master_index];
1955 ArrayView<TiedFace> face_tied_faces = m_tied_faces[master_index];
1956 ++master_index;
1957
1958 info(4) << "NEW VALUES face=" << ItemPrinter(face) << " n=" << face_tied_nodes.size() << " m=" << face_tied_faces.size();
1959 for( Node inode : face.nodes() )
1960 info(4) << "MasterFace node=" << ItemPrinter(inode);
1961 Integer nb_node = face_tied_nodes.size();
1962 Integer nb_face = face_tied_faces.size();
1963 work_nodes_local_id.resize(nb_node);
1964 work_nodes_iso.resize(nb_node);
1965 work_faces_local_id.resize(nb_face);
1966
1967 rebuilder->fillTiedInfos(face,work_nodes_local_id,work_nodes_iso,work_faces_local_id);
1968
1969 for( Integer zz=0; zz<nb_node; ++zz ){
1970 Integer local_id = work_nodes_local_id[zz];
1971 Real2 iso = work_nodes_iso[zz];
1972 info(4) << "NEW NODE slave_node=" << ItemPrinter(nodes[local_id]) << " iso=" << iso;
1973 face_tied_nodes[zz] = TiedNode(zz,nodes[local_id],iso);
1974 }
1975
1976 for( Integer zz=0; zz<nb_face; ++zz ){
1977 Int32 local_id = work_faces_local_id[zz];
1978 info(4) << "NEW FACE slave_face=" << ItemPrinter(faces[local_id]);
1979 face_tied_faces[zz] = TiedFace(zz,faces[local_id]);
1980 }
1981 }
1982}
1983
1984/*---------------------------------------------------------------------------*/
1985/*---------------------------------------------------------------------------*/
1986
1987void TiedInterface::
1988checkValid()
1989{
1990 _checkValid(false);
1991}
1992
1993/*---------------------------------------------------------------------------*/
1994/*---------------------------------------------------------------------------*/
1995
1996void TiedInterface::
1997_checkValid(bool is_print)
1998{
1999 Integer nb_error = 0;
2000 Integer max_print_error = 50;
2001 std::set<Int64> nodes_in_master_face;
2002 ITiedInterface* interface = this;
2003 FaceGroup slave_group = interface->slaveInterface();
2004 FaceGroup master_group = interface->masterInterface();
2005 info() << "Interface: Slave=" << slave_group.name()
2006 << " nb_face=" << slave_group.size();
2007 info() << "Interface: Master=" << master_group.name()
2008 << " nb_face=" << master_group.size();
2009 TiedInterfaceNodeList tied_nodes(interface->tiedNodes());
2010 TiedInterfaceFaceList tied_faces(interface->tiedFaces());
2011 ENUMERATE_FACE(iface,master_group){
2012 Face face = *iface;
2013 Int32 master_face_owner = face.owner();
2014 FaceVectorView slave_faces = face.slaveFaces();
2015 if (!face.isMasterFace()){
2016 ++nb_error;
2017 if (nb_error<max_print_error)
2018 error() << " Face uid=" << ItemPrinter(face) << " should have isMaster() true";
2019 }
2020 if (iface.index()>100000)
2021 break;
2022 nodes_in_master_face.clear();
2023 if (is_print)
2024 info() << "Master face uid=" << ItemPrinter(face)
2025 << " kind=" << face.kind()
2026 << " cell=" << ItemPrinter(face.cell(0))
2027 << " iface.index()=" << iface.index();
2028
2029 Int32 cell_face_owner = face.cell(0).owner();
2030 if (cell_face_owner!=master_face_owner){
2031 ++nb_error;
2032 if (nb_error<max_print_error)
2033 error() << "master_face and its cell do not have the same owner: face_owner=" << master_face_owner
2034 << " cell_owner=" << cell_face_owner;
2035 }
2036 if (is_print)
2037 for( Node inode : face.nodes() )
2038 info() << "Master face node uid=" << inode.uniqueId();
2039 for( Integer zz=0, zs=tied_nodes[iface.index()].size(); zz<zs; ++zz ){
2040 const TiedNode& tn = tied_nodes[iface.index()][zz];
2041 nodes_in_master_face.insert(tn.node().uniqueId());
2042 if (is_print){
2043 info() << " node_uid=" << tn.node().uniqueId()
2044 << " iso=" << tn.isoCoordinates()
2045 << " kind=" << tn.node().kind();
2046 }
2047 }
2048 for( Node inode : face.nodes() )
2049 if (nodes_in_master_face.find(inode.uniqueId())==nodes_in_master_face.end()){
2050 ++nb_error;
2051 if (nb_error<max_print_error)
2052 error() << "node in master face not in slave node list node=" << ItemPrinter(inode);
2053 }
2054 Integer nb_tied = tied_faces[iface.index()].size();
2055 if (nb_tied!=slave_faces.size()){
2056 ++nb_error;
2057 if (nb_error<max_print_error){
2058 error() << "face=" << ItemPrinter(face) << " bad number of slave faces interne="
2059 << slave_faces.size() << " struct=" << nb_tied;
2060 ENUMERATE_FACE(islaveface,slave_faces){
2061 info() << "SLAVE " << ItemPrinter(*islaveface);
2062 }
2063 }
2064 }
2065 for( Integer zz=0, zs=tied_faces[iface.index()].size(); zz<zs; ++zz ){
2066 const TiedFace& tf = tied_faces[iface.index()][zz];
2067 Face tied_slave_face = tf.face();
2068 if (!tied_slave_face.isSlaveFace()){
2069 ++nb_error;
2070 if (nb_error<max_print_error)
2071 error() << "slave face uid=" << ItemPrinter(tf.face()) << " should have isSlave() true";
2072 }
2073 if (tied_slave_face.masterFace()!=face){
2074 ++nb_error;
2075 if (nb_error<max_print_error)
2076 error() << "slave face uid=" << ItemPrinter(tf.face()) << " should have masterSlave() valid";
2077 }
2078 if (tied_slave_face!=slave_faces[zz]){
2079 ++nb_error;
2080 if (nb_error<max_print_error)
2081 error() << "bad slave face internal=" << ItemPrinter(slave_faces[zz])
2082 << " struct=" << ItemPrinter(tied_slave_face);
2083 }
2084 Int32 slave_face_owner = tf.face().owner();
2085 if (slave_face_owner!=master_face_owner){
2086 ++nb_error;
2087 if (nb_error<max_print_error)
2088 error() << "master_face and its slave_face do not have the same owner:"
2089 << " master_face=" << ItemPrinter(face)
2090 << " master_cell=" << ItemPrinter(face.cell(0))
2091 << " slave_face=" << ItemPrinter(tf.face())
2092 << " slave_cell=" << ItemPrinter(tf.face().cell(0));
2093 }
2094 if (is_print){
2095 info() << " face_uid=" << tf.face().uniqueId() << " cell=" << ItemPrinter(tf.face().cell(0));
2096 }
2097 }
2098 }
2099
2100 if (nb_error!=0){
2101 ARCANE_FATAL("Errors in tied interface nb_error={0}",nb_error);
2102 }
2103}
2104
2105/*---------------------------------------------------------------------------*/
2106/*---------------------------------------------------------------------------*/
2107
2108} // End namespace Arcane::mesh
2109
2110/*---------------------------------------------------------------------------*/
2111/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
Tableau d'items de types quelconques.
Maille d'un maillage.
Definition Item.h:1178
Vue sur les informations des faces.
Face d'une maille.
Definition Item.h:932
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1617
Informations sur la projection d'un point sur un segment ou un triangle.
int m_region
Région dans laquelle se situe la projection (0 si intérieur au segment ou au triangle)
static bool isInside(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Indique si un la projection du point point est à l'intérieur du triangle défini par v1,...
Real m_distance
Distance du point à sa projection.
Data * lookup(KeyTypeConstRef id)
Recherche la valeur correspondant à la clé id.
void resize(Integer new_size, bool use_prime=false)
Redimensionne la table de hachage.
ValueType & lookupValue(KeyTypeConstRef id)
Recherche la valeur correspondant à la clé id.
bool add(KeyTypeConstRef id, const ValueType &value)
Ajoute la valeur value correspondant à la clé id.
void clear()
Supprime tous les éléments de la table.
Interface d'une famille d'entités.
virtual FaceGroup outerFaces()=0
Groupe de toutes les faces sur la frontière.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual TiedInterfaceCollection tiedInterfaces()=0
Liste des interfaces semi-conformes.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Effectue un regroupement sur tous les processeurs. Il s'agit d'une opération collective....
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
virtual void barrier()=0
Effectue une barière.
Interface d'un classe gérant une semi-conformité du maillage.
virtual TiedInterfaceFaceList tiedFaces() const =0
Liste des informations sur les faces esclaves d'une face maître.
virtual FaceGroup masterInterface() const =0
Groupe contenant les faces maîtres.
virtual FaceGroup slaveInterface() const =0
Groupe contenant les faces esclaves.
virtual TiedInterfaceNodeList tiedNodes() const =0
Liste des informations sur les noeuds esclaves d'une face maître.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
const String & name() const
Nom du groupe.
Definition ItemGroup.h:76
void removeItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Supprime des entités.
Definition ItemGroup.cc:467
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
ItemGroup own() const
Groupe équivalent à celui-ci mais contenant uniquement les éléments propres au sous-domaine.
Definition ItemGroup.cc:189
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
Identifiant unique d'une entité.
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:771
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:765
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:210
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:229
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Vue sur les informations des noeuds.
Noeud d'un maillage.
Definition Dom.h:204
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Real3 & normalize()
Normalise le triplet.
Definition Real3.h:362
Implémentation d'un tampon pour la sérialisation.
Face semi-conforme du maillage.
Definition TiedFace.h:35
virtual FaceGroup slaveInterface() const
Groupe contenant les faces esclaves.
virtual String slaveInterfaceName() const
Nom du groupe contenant les mailles esclaves.
static PartitionConstraintBase * createConstraint(IMesh *mesh, ConstArrayView< FaceGroup > slave_interfaces)
Créé les informations pour l'interface soudée slave_interface/.
virtual void setPlanarTolerance(Real tol)
Definit le seuil relative d'acceptation d'un point projete a une face candidate.
virtual String masterInterfaceName() const
Nom du groupe contenant les mailles maîtres.
virtual void build(const FaceGroup &interface, bool is_structured)
Construit l'interface liée sur le group interface.
virtual TiedInterfaceFaceList tiedFaces() const
Liste des informations sur les faces esclaves d'une face maître.
virtual FaceGroup masterInterface() const
Groupe contenant les faces maîtres.
virtual TiedInterfaceNodeList tiedNodes() const
Liste des informations sur les noeuds esclaves d'une face maître.
Noeud semi-conforme du maillage.
Definition TiedNode.h:41
IItemFamily * itemFamily(eItemKind ik) override
Retourne la famille d'entité de type ik.
IntegerUniqueArray m_master_faces_nb_slave_node
Nombre de noeuds esclaves pour chaque face maitre.
Real2UniqueArray m_slave_nodes_iso
Liste des coordonnées iso-barycentriques des noeuds esclaves.
UniqueArray< ItemUniqueId > m_slave_nodes_uid
Liste des uniqueId() des noeuds esclaves.
IntegerUniqueArray m_master_faces_nb_slave_face
Nombre de faces esclaves pour chaque face maitre.
UniqueArray< ItemUniqueId > m_slave_faces_uid
Liste des uniqueId() des faces esclaves.
UniqueArray< ItemUniqueId > m_master_faces_uid
Liste des uniqueId() des faces maitres.
Construction des informations d'une interface semi-conforme.
HashTableMapT< ItemUniqueId, ItemUniqueId > m_slave_faces_master_face_uid
Table indiquant pour chaque face esclave, le uid de la face maitre correspondante.
void computeInterfaceConnections(bool allow_communication)
Construit les infos sur une interface liée.
void _computeMasterInterface()
Détermine la surface maitre de l'interface.
void changeOwners(Int64Array &linked_cells, Int32Array &linked_owers)
Positionne les liaisons entre mailles.
void _gatherFaces(ConstArrayView< ItemUniqueId > faces_to_send, TiedInterfaceFaceMap &face_map)
void _gatherAllNodesInfo()
envoie et récupère les informations sur les noeuds de l'interface.
GeometricUtilities::ProjectionInfo _findProjection(const TiedInterfaceFace &face, Real3 point)
Calcule la projection d'un point sur une face.
void _removeMasterFacesWithNoSlave()
Supprime du groupe des faces maîtres les faces qui ne sont connectées à aucune face esclave.
void changeOwnersOld()
Migre les mailles sur les liaisons.
Face maitre ou esclave d'une interface.
ItemUniqueId m_unique_id
Numéro de ce noeud.
Real3 m_coord
Coordonnées de ce noeud.
SharedArray< ItemUniqueId > m_connected_master_faces
Liste des uniqueId() des faces maîtres auquel ce noeud peut être connecté
virtual void addLinkedCells(Int64Array &linked_cells, Int32Array &linked_owners)
Ajoute un ensemble de contraintes sur les mailles.
Integer size() const
Nombre d'éléments du vecteur.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Integer getInteger() override
Récupère une taille.
void setMode(eMode new_mode) override
Positionne le fonctionnement actuel.
void get(RealArrayView values) override
Récupère le tableau values.
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
Chaîne de caractères unicode.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage warning() const
Flot pour un message d'avertissement.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
ARCCORE_HOST_DEVICE Real3 normalizeReal3(Real3 v)
Normalisation d'un Real3.
Definition MathUtils.h:741
ARCCORE_HOST_DEVICE Real scaMul(Real2 u, Real2 v)
Produit scalaire de u par v dans .
Definition MathUtils.h:113
ARCCORE_HOST_DEVICE Real3 vecMul(Real3 u, Real3 v)
Produit vectoriel de u par v. dans .
Definition MathUtils.h:52
ARCCORE_HOST_DEVICE Real mixteMul(Real3 u, Real3 v, Real3 w)
Produit mixte de u, v et w.
Definition MathUtils.h:159
ItemGroupT< Face > FaceGroup
Groupe de faces.
Definition ItemTypes.h:178
ItemVectorViewT< Face > FaceVectorView
Vue sur un vecteur de faces.
Definition ItemTypes.h:299
Integer toInteger(Real r)
Converti un Int64 en un Integer.
Real normeR3(Real3 v1)
Norme d'un vecteur.
Definition MathUtils.h:653
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:151
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
Definition UtilsTypes.h:529
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Face
Entité de maillage de genre face.
@ DT_Int64
Donnée de type entier 64 bits.
Definition DataTypes.h:44
@ DT_Real
Donnée de type réel.
Definition DataTypes.h:41
UniqueArray< Real2 > Real2UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 2.
Definition UtilsTypes.h:527
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:644
Int32 Integer
Type représentant un entier.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35