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"
25#include "arcane/mesh/TiedInterface.h"
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"
59 std::ostream& o = cout;
66 <<
" MasterFacesSlaveFaceIndex=" << m_master_faces_slave_face_index.
size()
67 <<
" MasterFacesSlaveNodeIndex=" << m_master_faces_slave_node_index.
size()
94 Integer size()
const {
return m_nodes_unique_id.size(); }
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) {}
156 m_data_index(data_index), m_mng(
mng) {}
164 return m_cell_unique_id;
166 Integer nbNode()
const
172 return m_mng->m_nodes_unique_id[ m_data_index + i ];
174 Integer owner()
const
178 void setCenter(
Real3 center)
193 Integer m_data_index;
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) {}
217 : m_unique_id(NULL_ITEM_ID) {}
222 {
return m_unique_id; }
224 ItemUniqueId m_unique_id;
225 SharedArray<TiedInterfaceFace*> m_slave_faces;
235 : m_uid(uid), m_alpha(alpha), m_beta(
beta){ }
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);
260 : m_node_uid(node_uid), m_alpha(alpha), m_beta(
beta),
m_x(-1),
m_y(-1)
264 : m_node_uid(NULL_ITEM_UNIQUE_ID), m_alpha(0.0), m_beta(0.0),
m_x(-1),
m_y(-1)
277 void setStructuration(Integer x,Integer y)
280 ARCANE_FATAL(
"already set with a different x value old={0} new={1}",
m_x,x);
282 ARCANE_FATAL(
"already set with a different y value old={0} new={1}",
m_y,y);
286 bool hasStructuration()
const
288 return (
m_x!=(-1) &&
m_y!=(-1));
334 typedef std::set<TiedInterfaceSortedNodeInfo> SortedNodeInfoSet;
345 const FaceGroup& masterInterface()
const {
return m_master_interface; }
355 String m_slave_interface_name;
360 Real m_planar_tolerance;
386TiedInterfaceBuilder::
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)
398, m_slave_faces_master_face_uid(1000,
true)
399, m_planar_tolerance(0.0)
408void TiedInterfaceBuilder::
417void TiedInterfaceBuilder::
418_searchMasterFaces(Array<ItemUniqueId>& slave_faces_to_process,
419 Array<ItemUniqueId>& remaining_slave_faces)
421 String func_name =
"TiedInterfaceBuilder::_searchMasterFaces()";
423 std::set<ItemUniqueId> master_faces_to_test;
424 UniqueArray<ItemUniqueId> master_faces_found;
425 master_faces_found.reserve(100);
427 slave_face_nodes_coord.
reserve(100);
432 info() <<
"nb slave faces to process=" << slave_faces_to_process.size();
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();
439 TiedInterfaceFace& face = m_slave_faces[ slave_faces_to_process[islaveface] ];
441 slave_face_nodes_coord.
clear();
443 Integer nb_node = face.nbNode();
444 triangle_centers.resize(nb_node);
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]);
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.;
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);
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])){
489 master_faces_found.add(master_face.uniqueId());
492 switch (master_faces_found.size()){
495 ItemUniqueId master_face_uid = master_faces_found[0];
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);
508 remaining_slave_faces.add(face.uniqueId());
520 Real3 face_normale = _computeNormale(face);
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 <<
")"
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);
533 if (math::abs(d)>max_dot){
534 max_dot = math::abs(d);
537 ostr() <<
" (uid=" << muid <<
",nb_node=" << master_face.nbNode()
538 <<
" center=" << master_face.center()
544 info() << func_name <<
" " << ostr.str() <<
". Keeping index=" << keep_index;
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);
586 Integer
nb_node = face.nbNode();
592 Real3 v1 = m_nodes_info[face.nodeUniqueId(
inode)].m_coord;
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;
622 Real3 v1 = m_nodes_info[face.nodeUniqueId(0)].m_coord;
623 Real3 v2 = m_nodes_info[face.nodeUniqueId(1)].m_coord;
632Real3 TiedInterfaceBuilder::
635 Integer
nb_node = face.nbNode();
639 Real3 v1 = m_nodes_info[face.nodeUniqueId(
inode)].m_coord;
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);
658 throw NotSupportedException(A_FUNCINFO,
"can not compute normal of face with 0 or 1 node");
665bool TiedInterfaceBuilder::
666_isInsideFace(
const TiedInterfaceFace& face,Real3 point)
668 Integer nb_node = face.nbNode();
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) {
675 if (math::abs(ecart) > m_planar_tolerance *
math::normeR3(v1-v2)) {
677 info() <<
"Reject non planar projection " << point <<
" from face uid=" << face.uniqueId();
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;
728 _addFaceToList(face,m_slave_faces);
731 info() <<
"SLAVE_INTERFACE: nb_face=" << m_slave_interface.
size();
745 if (!m_nodes_info.
lookup(uid)){
759 _addFaceToList(face,m_master_faces);
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());
766 m_master_interface = m_mesh->
faceFamily()->createGroup(m_slave_interface_name+
"_MASTER",
768 info() <<
"MASTER_INTERFACE: nb_face=" << m_master_interface.
size();
774void TiedInterfaceBuilder::
775_addFaceToList(
const Face& face,TiedInterfaceFaceMap&
face_map)
778 Real3 center(0.,0.,0.);
779 Integer data_index = m_face_info_mng.size();
780 for(
Node node : face.nodes() ){
783 NodeInfoList::Data* i = m_nodes_info.
lookup(uid);
789 m_face_info_mng.add(uid);
796 sf.setCenter(center);
827 info() <<
"Removing faces from master list name=" << m_master_interface.
name()
836void TiedInterfaceBuilder::
854 for( TiedInterfaceFaceMapEnumerator i(m_slave_faces); ++i; ){
863 ItemUniqueId master_uid = face.uniqueId();
865 TiedInterfaceMasterFace& mf = m_master_faces_full[master_uid];
866 Integer master_face_nb_slave_face = mf.m_slave_faces.size();
869 info() <<
"MASTER FACE uid=" << master_uid <<
" NB_SLAVE_FACE=" << master_face_nb_slave_face
870 <<
" face_owner=" << face.owner();
874 for( Integer zz=0; zz<master_face_nb_slave_face; ++zz ){
875 ItemUniqueId slave_uid = mf.m_slave_faces[zz]->uniqueId();
880 std::set<ItemUniqueId> slave_nodes_set;
881 SortedNodeInfoSet slave_nodes_sorted_set;
883 bool is_dimension_2d = m_mesh->
dimension()==2;
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];
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();
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);
912 info() <<
"MASTER FACE: NB_SLAVE_FACE=" << nb_slave_face
913 <<
" NB_SLAVE_NODE=" << slave_nodes_set.size();
917 std::set<ItemUniqueId>::const_iterator i_node = slave_nodes_set.begin();
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;
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];
930 Real3 point = node_info.m_coord;
931 GeometricUtilities::ProjectionInfo projection =
_findProjection(face,point);
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);
940 info() <<
"ISO1 =" << uvw;
941 is_bad = face_mapping.cartesianToIso2(point,uvw,0);
943 info() <<
"ISO2 =" << uvw;
945 warning() <<
"Can not compute iso-coordinates for point " << point;
946 face_mapping.cartesianToIso(point,uvw,
traceMng());
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());
971 if (node_uid==face.nodeUniqueId(0)){
972 uvw.x = ARCANE_REAL(-1.0);
973 uvw.y = ARCANE_REAL(-1.0);
975 else if (node_uid==face.nodeUniqueId(1)){
976 uvw.x = ARCANE_REAL( 1.0);
977 uvw.y = ARCANE_REAL(-1.0);
979 else if (node_uid==face.nodeUniqueId(2)){
980 uvw.x = ARCANE_REAL(1.0);
981 uvw.y = ARCANE_REAL(1.0);
983 else if (node_uid==face.nodeUniqueId(3)){
984 uvw.x = ARCANE_REAL(-1.0);
985 uvw.y = ARCANE_REAL( 1.0);
988 slave_nodes_sorted_set.insert(TiedInterfaceSortedNodeInfo(node_uid,uvw.x,uvw.y));
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);
1004 Real alpha = projection.m_alpha;
1005 if (node_uid==face.nodeUniqueId(0)){
1006 alpha = ARCANE_REAL(0.0);
1008 else if (node_uid==face.nodeUniqueId(1)){
1009 alpha = ARCANE_REAL(1.0);
1011 slave_nodes_sorted_set.insert(TiedInterfaceSortedNodeInfo(node_uid,alpha,0.0));
1015 ARCANE_FATAL(
"Can not detect structuration for face with nb_node={0}."
1016 " Valid values are 2 or 4",nb_node);
1018 if (slave_nodes_sorted_set.size()!=slave_nodes_set.size()){
1019 ARCANE_FATAL(
"Internal: error sorting nodes in TiedInterface: bad compare");
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);
1032 info() <<
"Add to struct map node_uid=" << uid <<
" alpha=" << node.m_alpha <<
" beta=" << node.m_beta;
1034 _detectStructuration(face2,struct_map);
1039 TiedInterfaceStructurationInfo sinfo = struct_map[face.nodeUniqueId(nb_node/2)];
1041 info() <<
"********* STRUCTURE X=" << sinfo.m_x <<
" Y=" << 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){
1057 new_alpha = (1.0 * minfo.m_x) / rx;
1061 new_alpha = -1.0 + (2.0 * minfo.m_x) / rx;
1063 new_beta = -1.0 + (2.0 * minfo.m_y) / ry;
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));
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;
1076 info() <<
"ADD TO SLAVE NODE: node_uid=" << node.m_uid
1077 <<
" alpha=" << node.m_alpha
1078 <<
" beta=" << node.m_beta;
1089void TiedInterfaceBuilder::
1090_detectStructuration(
const TiedInterfaceMasterFace& master_face,
1091 StructurationMap& slave_nodes)
1093 Integer nb_slave_face = master_face.m_slave_faces.size();
1096 TiedInterfaceFace& mface = m_master_faces[master_face.uniqueId()];
1097 TiedInterfaceStructurationInfo& sinfo = slave_nodes[mface.nodeUniqueId(0)];
1098 sinfo.setStructuration(0,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());
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)
1114 if (nb_to_process==nb_remaining){
1115 ARCANE_FATAL(
"Can not compute structuration for a tied interface"
1116 " remaining_slaves={0}",nb_remaining);
1118 slave_faces.copy(remaining_slave_faces);
1125void TiedInterfaceBuilder::
1126_detectStructurationRecursive(Array<ItemUniqueId>& slave_faces,
1127 Array<ItemUniqueId>& remaining_slave_faces,
1128 StructurationMap& slave_nodes)
1144 for( Integer i=0, is=slave_faces.size(); i<is; ++i ){
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];
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()){
1165 if (node_index==(-1)){
1166 remaining_slave_faces.add(slave_faces[i]);
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;
1177 if (math::abs(diff_alpha)>math::abs(diff_beta)){
1179 if (next_info.m_alpha > old_sinfo.m_alpha){
1181 info() <<
"SUP_ALPHA SET NEXT uid=" << next_uid <<
" x=" << (x+1) <<
" y=" << (y);
1182 next_info.setStructuration(x+1,y);
1186 info() <<
"INF_ALPHA SET NEXT uid=" << next_uid <<
" x=" << (x-1) <<
" y=" << (y);
1187 next_info.setStructuration(x-1,y);
1192 if (next_info.m_beta > old_sinfo.m_beta){
1194 info() <<
"SUP_BETA SET NEXT uid=" << next_uid <<
" x=" << (x) <<
" y=" << (y+1);
1195 next_info.setStructuration(x,y+1);
1199 info() <<
"INF_BETA SET NEXT uid=" << next_uid <<
" x=" << (x) <<
" y=" << (y-1);
1200 next_info.setStructuration(x,y-1);
1203 old_sinfo = next_info;
1211void TiedInterfaceBuilder::
1212_printFaces(std::ostream& o,TiedInterfaceFaceMap& face_map)
1216 typedef std::map<ItemUniqueId,TiedInterfaceFace*> FacesMap;
1219 for( TiedInterfaceFaceMapEnumerator i(face_map); ++i; ){
1220 TiedInterfaceFace* mf = &i.m_current_data->value();
1221 faces.insert(std::make_pair(mf->uniqueId(),mf));
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';
1260 coords.
add(
ni.m_coord.x);
1261 coords.
add(
ni.m_coord.y);
1262 coords.
add(
ni.m_coord.z);
1273 sbuf.setMode(ISerializer::ModeReserve);
1274 sbuf.reserveInteger(1);
1275 sbuf.reserveInteger(1);
1281 sbuf.allocateBuffer();
1294 for( Integer i=0; i<nb_rank; ++i ){
1305 recv_buf.
get(coords);
1309 Integer face_index = 0;
1310 for( Integer z=0; z<
nb_node; ++z ){
1314 NodeInfoList::Data* data = m_nodes_info.
lookup(uid);
1321 ni.addConnectedFace(
fuid);
1349 sbuf.setMode(ISerializer::ModeReserve);
1363 for( Integer z=0,
zs=
mf.nbNode(); z<
zs; ++z ){
1365 nodes_unique_id.
add(
nuid.asInt64());
1375 coords.
add(
mf.center().x);
1376 coords.
add(
mf.center().y);
1377 coords.
add(
mf.center().z);
1379 sbuf.reserveInteger(1);
1380 sbuf.reserveInteger(1);
1381 sbuf.reserveInteger(1);
1388 sbuf.allocateBuffer();
1392 sbuf.putInteger(nodes_unique_id.
size());
1396 sbuf.put(nodes_unique_id);
1404 for( Integer i=0; i<nb_rank; ++i ){
1419 recv_buf.
get(nodes_unique_id);
1420 recv_buf.
get(coords);
1426 for( Integer z=0; z<
nb_face; ++z ){
1432 center.
x = coords[z*3];
1433 center.
y = coords[z*3 + 1];
1434 center.
z = coords[z*3 + 2];
1437 Integer data_index = m_face_info_mng.size();
1440 m_face_info_mng.add(
nuid);
1450 sf.setCenter(center);
1490 ARCANE_FATAL(
"Cell {0} is connected to more than one master face",
1545 ARCANE_FATAL(
"Cell {0} is connected to more than one master face:"
1591 _printFaces(
ofile,m_master_faces);
1603 for( Integer
zz=0;
zz<10000; ++
zz ){
1605 info() <<
" SEND RECV NODES INFO n=" <<
zz;
1624 ARCANE_FATAL(
"Can not compute master/slave infos for a tied interface. Remaining_slaves={0}",
1635void TiedInterfaceBuilder::
1648bool TiedInterface::m_is_debug =
false;
1654TiedInterface(
IMesh* mesh)
1657, m_planar_tolerance(0.)
1659 if (!platform::getEnvironmentVariable(
"ARCANE_DEBUG_TIED_INTERFACE").null())
1681 return m_master_interface;
1688 return m_slave_interface;
1694 return m_master_interface_name;
1700 return m_slave_interface_name;
1706 return m_tied_nodes;
1712 return m_tied_faces;
1724 m_tied_faces.resize(new_sizes);
1728setNodes(Integer index,ConstArrayView<TiedNode> nodes)
1730 for( Integer i=0, is=nodes.size(); i<is; ++i )
1731 m_tied_nodes[index][i] = nodes[i];
1735setFaces(Integer index,ConstArrayView<TiedFace> faces)
1737 for( Integer i=0, is=faces.size(); i<is; ++i )
1738 m_tied_faces[index][i] = faces[i];
1779 virtual void setInitialRepartition(
bool is_initial)
1792 Int32 owner = cell.
owner();
1802 linked_cells.add(cell_uid);
1803 linked_cells.add(sub_cell_uid);
1804 linked_owners.add(owner);
1813 UniqueArray<FaceGroup> m_slave_interfaces;
1826 return new TiedInterfacePartitionConstraint(mesh,
slave_interfaces,m_is_debug);
1837 info() <<
"Compute information for the tied interface " <<
slave_interface.name();
1840 TiedInterfaceBuilderInfos infos;
1842 builder.setPlanarTolerance(m_planar_tolerance);
1843 builder.computeInterfaceConnections(
false);
1850 m_master_interface = builder.masterInterface().own();
1851 m_master_interface_name = builder.masterInterface().name();
1855 m_tied_nodes.resize(infos.m_master_faces_nb_slave_node);
1856 m_tied_faces.resize(infos.m_master_faces_nb_slave_face);
1873 info() <<
"Master Face: " << infos.m_master_faces_uid[
i_master]
1876 <<
" node_index=" << infos.m_master_faces_slave_node_index[
i_master];
1881 info() <<
"Node: uid=" << infos.m_slave_nodes_uid[
first_index+
zz]
1892 info() <<
"Face: uid=" << infos.m_slave_faces_uid[
first_index+
zz];
1906 m_planar_tolerance =
tol;
1922 m_master_interface = group.
own();
1926 m_slave_interface = group.
own();
1933rebuild(ITiedInterfaceRebuilder* rebuilder,
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);
1944 NodeInfoListView nodes(node_family);
1945 FaceInfoListView faces(face_family);
1947 Integer master_index = 0;
1954 ArrayView<TiedNode> face_tied_nodes = m_tied_nodes[master_index];
1955 ArrayView<TiedFace> face_tied_faces = m_tied_faces[master_index];
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);
1967 rebuilder->fillTiedInfos(face,work_nodes_local_id,work_nodes_iso,work_faces_local_id);
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);
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]);
1997_checkValid(
bool is_print)
2001 std::set<Int64> nodes_in_master_face;
2002 ITiedInterface*
interface = this;
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());
2013 Int32 master_face_owner = face.owner();
2015 if (!face.isMasterFace()){
2017 if (nb_error<max_print_error)
2018 error() <<
" Face uid=" << ItemPrinter(face) <<
" should have isMaster() true";
2020 if (iface.index()>100000)
2022 nodes_in_master_face.clear();
2024 info() <<
"Master face uid=" << ItemPrinter(face)
2025 <<
" kind=" << face.kind()
2026 <<
" cell=" << ItemPrinter(face.cell(0))
2027 <<
" iface.index()=" << iface.index();
2029 Int32 cell_face_owner = face.cell(0).owner();
2030 if (cell_face_owner!=master_face_owner){
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;
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());
2043 info() <<
" node_uid=" << tn.node().uniqueId()
2044 <<
" iso=" << tn.isoCoordinates()
2045 <<
" kind=" << tn.node().kind();
2048 for( Node inode : face.nodes() )
2049 if (nodes_in_master_face.find(inode.uniqueId())==nodes_in_master_face.end()){
2051 if (nb_error<max_print_error)
2052 error() <<
"node in master face not in slave node list node=" << ItemPrinter(inode);
2054 Integer nb_tied = tied_faces[iface.index()].size();
2055 if (nb_tied!=slave_faces.size()){
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;
2061 info() <<
"SLAVE " << ItemPrinter(*islaveface);
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()){
2070 if (nb_error<max_print_error)
2071 error() <<
"slave face uid=" << ItemPrinter(tf.face()) <<
" should have isSlave() true";
2073 if (tied_slave_face.masterFace()!=face){
2075 if (nb_error<max_print_error)
2076 error() <<
"slave face uid=" << ItemPrinter(tf.face()) <<
" should have masterSlave() valid";
2078 if (tied_slave_face!=slave_faces[zz]){
2080 if (nb_error<max_print_error)
2081 error() <<
"bad slave face internal=" << ItemPrinter(slave_faces[zz])
2082 <<
" struct=" << ItemPrinter(tied_slave_face);
2084 Int32 slave_face_owner = tf.face().owner();
2085 if (slave_face_owner!=master_face_owner){
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));
2095 info() <<
" face_uid=" << tf.face().uniqueId() <<
" cell=" << ItemPrinter(tf.face().cell(0));
2101 ARCANE_FATAL(
"Errors in tied interface nb_error={0}",nb_error);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Tableau d'items de types quelconques.
Vue sur les informations des faces.
Cell cell(Int32 i) const
i-ème maille de la face
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.
const String & name() const
Nom du groupe.
void removeItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Supprime des entités.
Integer size() const
Nombre d'éléments du groupe.
bool null() const
true is le groupe est le groupe nul
ItemGroup own() const
Groupe équivalent à celui-ci mais contenant uniquement les éléments propres au sous-domaine.
Classe utilitaire pour imprimer les infos sur une entité.
Identifiant unique d'une entité.
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Vue sur les informations des noeuds.
Classe gérant un vecteur de réel de dimension 3.
Real3 & normalize()
Normalise le triplet.
Implémentation d'un tampon pour la sérialisation.
Face semi-conforme du maillage.
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.
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 m_x
Structuration X.
Integer m_y
Structuration Y.
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.
@ ModePut
Le sérialiseur attend des reserve()
@ ModeGet
Le sérialiseur attend des get()
Interface du gestionnaire de traces.
Chaîne de caractères unicode.
Classe d'accès aux traces.
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.
ARCCORE_HOST_DEVICE Real scaMul(Real2 u, Real2 v)
Produit scalaire de u par v dans .
ARCCORE_HOST_DEVICE Real3 vecMul(Real3 u, Real3 v)
Produit vectoriel de u par v. dans .
ARCCORE_HOST_DEVICE Real mixteMul(Real3 u, Real3 v, Real3 w)
Produit mixte de u, v et w.
ItemGroupT< Face > FaceGroup
Groupe de faces.
ItemVectorViewT< Face > FaceVectorView
Vue sur un vecteur de faces.
Integer toInteger(Real r)
Converti un Int64 en un Integer.
Real normeR3(Real3 v1)
Norme d'un vecteur.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
@ 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.
@ DT_Real
Donnée de type réel.
UniqueArray< Real2 > Real2UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 2.
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Int32 Integer
Type représentant un entier.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet