Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
TiedInterfaceMng.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/* TiedInterfaceMng.cc (C) 2000-2023 */
9/* */
10/* Gestionnaire des interfaces liées. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/TiedInterfaceMng.h"
15#include "arcane/mesh/DynamicMesh.h"
16#include "arcane/mesh/FaceFamily.h"
17
18#include "arcane/mesh/TiedInterface.h"
19
20#include "arcane/XmlNode.h"
21#include "arcane/IMesh.h"
22#include "arcane/ISubDomain.h"
23#include "arcane/ICaseDocument.h"
24#include "arcane/CaseNodeNames.h"
25#include "arcane/IParallelMng.h"
26#include "arcane/IMeshPartitionConstraintMng.h"
27#include "arcane/IMeshUtilities.h"
28#include "arcane/ArcaneException.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane::mesh
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39TiedInterfaceMng::
40TiedInterfaceMng(DynamicMesh* mesh)
41: TraceAccessor(mesh->traceMng())
42, m_mesh(mesh)
43, m_sub_domain(mesh->subDomain())
44, m_name(mesh->name())
45, m_tied_interface_items_info(VariableBuildInfo(m_sub_domain,m_name+"TiedInterfaceItemsInfo"))
46, m_tied_interface_nodes_iso(VariableBuildInfo(m_sub_domain,m_name+"TiedInterfaceNodesIso"))
47, m_tied_interface_face_groups(VariableBuildInfo(m_sub_domain,m_name+"TiedInterfaceFaceGroups"))
48, m_tied_constraint(0)
49{
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55TiedInterfaceMng::
56~TiedInterfaceMng()
57{
58 // Le m_tied_constraint est détruit par le gestionnaire de contraintes du maillage
59 m_tied_constraint = 0;
60
61 _deleteTiedInterfaces();
62}
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
66
67void TiedInterfaceMng::
68computeTiedInterfaces(const XmlNode& mesh_node)
69{
70 ICaseDocument* doc = subDomain()->caseDocument();
71 CaseNodeNames* cnn = doc->caseNodeNames();
72 String tied_interfaces_name = cnn->tied_interfaces;
73 String tied_interface_not_structured_name = cnn->tied_interfaces_not_structured;
74 String tied_interfaces_planar_tolerance = cnn->tied_interfaces_planar_tolerance;
75 String semi_conform_name = cnn->tied_interfaces_semi_conform;
76 String name_attribute = cnn->tied_interfaces_slave;
77 XmlNode tied_interface_elem = mesh_node.child(tied_interfaces_name);
78 XmlNodeList child_list = tied_interface_elem.children(semi_conform_name);
79 bool has_error = false;
80
81 IParallelMng* pm = m_mesh->parallelMng();
82 bool is_parallel = pm->isParallel();
83 UniqueArray<FaceGroup> interfaces_group;
84 UniqueArray<bool> is_structured_list;
85 UniqueArray<Real> planar_tolerance_list;
86 FaceFamily& face_family = m_mesh->trueFaceFamily();
87 for( auto& i : child_list ){
88 XmlNode group_attr = i.attr(name_attribute);
89 if (group_attr.null()){
90 error() << "Attribute '" << name_attribute << "' missing";
91 has_error = true;
92 continue;
93 }
94 String group_name = i.attrValue(name_attribute);
95 FaceGroup face_group = face_family.findGroup(group_name);
96 if (face_group.null()){
97 error() << "Can't find the interface '" << group_name << "'";
98 has_error = true;
99 continue;
100 }
101 if (interfaces_group.contains(face_group)){
102 error() << "The group '" << group_name << "' is already present in list of tied interfaces.";
103 has_error = true;
104 continue;
105 }
106 interfaces_group.add(face_group);
107
108 bool is_not_structured = i.attr(tied_interface_not_structured_name).valueAsBoolean();
109 info() << "** NOT STRUCTURED? = " << is_not_structured;
110 is_structured_list.add(!is_not_structured);
111 XmlNode tolerance_node = i.attr(tied_interfaces_planar_tolerance);
112 if (tolerance_node.null()) {
113 planar_tolerance_list.add(0.);
114 } else {
115 planar_tolerance_list.add(tolerance_node.valueAsReal());
116 }
117 }
118 if (has_error)
119 fatal() << "Can't determine the tied interfaces";
120
121 // S'il n'y a pas d'interface liée spécifié dans le jeu de données,
122 // recherche si un groupe de face de nom SOUDURE ou SOUDURES
123 // existe et dans ce cas le considère comme une interface de soudure
124 {
125 FaceGroup g1 = face_family.findGroup("SOUDURE");
126 if (g1.null())
127 g1 = face_family.findGroup("SOUDURES");
128 if (!g1.null()){
129 // N'ajoute le groupe que s'il n'est pas déjà dans la liste
130 if (!interfaces_group.contains(g1)){
131 info() << "Add automatically the group '" << g1.name() << "' to the list of tied interfaces";
132 interfaces_group.add(g1);
133 is_structured_list.add(true);
134 planar_tolerance_list.add(0.0);
135 }
136 else{
137 info() << "built-in group " << g1.name() << " already in list of tied interfaces";
138 }
139 }
140 }
141 Integer nb_interface = interfaces_group.size();
142 IItemFamily* cell_family = m_mesh->cellFamily();
143 if (nb_interface!=0){
144 // En parallèle, il faudra migrer des mailles pour que les mailles
145 // de part et d'autre d'une face de l'interface soient dans le même sous-domaine.
146 // En parallèle, il faut d'abord recalculer les propriétaire, faire
147 // l'échange puis enfin calculer les projections
148 if (is_parallel){
149 VariableItemInt32& cells_owner = cell_family->itemsNewOwner();
150 ENUMERATE_ITEM(iitem,cell_family->allItems()){
151 cells_owner[iitem] = (*iitem).owner();
152 }
153 //for( Integer i=0, is=interfaces_group.size(); i<is; ++i ){
154 //FaceGroup face_group = interfaces_group[i];
155 TiedInterface::PartitionConstraintBase* c = TiedInterface::createConstraint(m_mesh,interfaces_group);
156 m_tied_constraint = c;
157 IMeshPartitionConstraintMng* pcmng = m_mesh->partitionConstraintMng();
158 pcmng->addConstraint(c);
159 pcmng->computeAndApplyConstraints();
160 //}
161 cells_owner.synchronize();
162 m_mesh->utilities()->changeOwnersFromCells();
163 m_mesh->setDynamic(true);
164 m_mesh->exchangeItems();
165 // Indique que le partitionnement initial a été effectué
166 c->setInitialRepartition(false);
167 }
168 for( Integer i=0, is=interfaces_group.size(); i<is; ++i ){
169 FaceGroup face_group = interfaces_group[i];
170 info() << " Semi-conform interface name=" << face_group.name();
171 TiedInterface* tied_interface = new TiedInterface(m_mesh);
172 if (planar_tolerance_list[i] > 0)
173 tied_interface->setPlanarTolerance(planar_tolerance_list[i]);
174 tied_interface->build(face_group,is_structured_list[i]);
175 //if (is_structured_list[i]){
176 //_applyTiedInterfaceStructuration(tied_interface);
177 //}
178 m_true_tied_interfaces.add(tied_interface);
179 m_tied_interfaces.add(tied_interface);
180 face_family.applyTiedInterface(tied_interface);
181 }
182
183 face_family.endUpdate();
184 face_family.prepareForDump();
185 }
186 prepareTiedInterfacesForDump();
187}
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
192void TiedInterfaceMng::
193prepareTiedInterfacesForDump()
194{
195 Integer nb_tied_interface = m_tied_interfaces.count();
196 m_tied_interface_face_groups.resize(nb_tied_interface*2);
197
198 Integer total_nb_node = 0;
199 Integer total_nb_face = 0;
200 Integer nb_tied_node_per_interface = 0;
201 Integer nb_tied_face_per_interface = 0;
202 for( Integer i=0; i<nb_tied_interface; ++i ){
203 ITiedInterface* ti = m_tied_interfaces[i];
204
205 TiedInterfaceNodeList nodes = ti->tiedNodes();
206 nb_tied_node_per_interface += nodes.dim1Size();
207 for( Integer zz=0, zs=nodes.dim1Size(); zz<zs; ++zz )
208 total_nb_node += nodes[zz].size();
209
210 TiedInterfaceFaceList faces = ti->tiedFaces();
211 nb_tied_face_per_interface += faces.dim1Size();
212 for( Integer zz=0, zs=faces.dim1Size(); zz<zs; ++zz )
213 total_nb_face += faces[zz].size();
214 }
215
216 Integer items_info_size = total_nb_node + total_nb_face +
217 nb_tied_node_per_interface + nb_tied_face_per_interface + nb_tied_interface*2;
218
219 Integer nodes_iso_size = total_nb_node;
220
221 m_tied_interface_items_info.resize(items_info_size);
222 m_tied_interface_nodes_iso.resize(nodes_iso_size);
223
224 Integer items_info_index = 0;
225 Integer nodes_iso_index = 0;
226 for( Integer i=0; i<nb_tied_interface; ++i ){
227 ITiedInterface* ti = m_tied_interfaces[i];
228
229 TiedInterfaceNodeList nodes = ti->tiedNodes();
230 Integer nb_node = nodes.dim1Size();
231 m_tied_interface_items_info[items_info_index] = nb_node;
232 ++items_info_index;
233 for( Integer zz=0; zz<nb_node; ++zz ){
234 Integer nb_node2 = nodes[zz].size();
235 m_tied_interface_items_info[items_info_index] = nb_node2;
236 ++items_info_index;
237 }
238
239 for( Integer zz=0; zz<nb_node; ++zz ){
240 Integer nb_node2 = nodes[zz].size();
241 for( Integer zz2=0; zz2<nb_node2; ++zz2 ){
242 m_tied_interface_items_info[items_info_index] = nodes[zz][zz2].node().uniqueId().asInt64();
243 ++items_info_index;
244 m_tied_interface_nodes_iso[nodes_iso_index] = nodes[zz][zz2].isoCoordinates();
245 ++nodes_iso_index;
246 }
247 }
248
249 TiedInterfaceFaceList faces = ti->tiedFaces();
250 Integer nb_face = faces.dim1Size();
251 m_tied_interface_items_info[items_info_index] = nb_face;
252 ++items_info_index;
253 for( Integer zz=0; zz<nb_face; ++zz ){
254 Integer nb_face2 = faces[zz].size();
255 m_tied_interface_items_info[items_info_index] = nb_face2;
256 ++items_info_index;
257 }
258
259 for( Integer zz=0; zz<nb_face; ++zz ){
260 Integer nb_face2 = faces[zz].size();
261 for( Integer zz2=0; zz2<nb_face2; ++zz2 ){
262 m_tied_interface_items_info[items_info_index] = faces[zz][zz2].face().uniqueId().asInt64();
263 ++items_info_index;
264 }
265 }
266 }
267 debug() << "ITEMS_INFO_INDEX=" << items_info_index << " N=" << items_info_size;
268 debug() << "NODES_ISO_INDEX=" << nodes_iso_index << " N=" << nodes_iso_size;
269 if (nodes_iso_index!=nodes_iso_size)
270 throw InternalErrorException(A_FUNCINFO,"Bad size for 'nodes_iso_index'");
271 if (items_info_index!=items_info_size)
272 throw InternalErrorException(A_FUNCINFO,"Bad size for 'items_info_index'");
273 for( Integer i=0; i<nb_tied_interface; ++i ){
274 ITiedInterface* ti = m_tied_interfaces[i];
275 m_tied_interface_face_groups[(i*2)] = ti->masterInterfaceName();
276 m_tied_interface_face_groups[(i*2)+1] = ti->slaveInterfaceName();
277 }
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
283void TiedInterfaceMng::
284readTiedInterfacesFromDump()
285{
286 _deleteTiedInterfaces();
287 Integer nb_tied_interface = m_tied_interface_face_groups.size() / 2;
288
289 Integer items_info_index = 0;
290 Integer nodes_iso_index = 0;
291
292 IItemFamily* node_family = m_mesh->nodeFamily();
293 FaceFamily& face_family = m_mesh->trueFaceFamily();
294 NodeInfoListView nodes_internal(node_family);
295 FaceInfoListView faces_internal(&face_family);
296 UniqueArray<TiedNode> nodes;
297 UniqueArray<TiedFace> faces;
298
299 for( Integer i=0; i<nb_tied_interface; ++i ){
300 TiedInterface* tied_interface = new TiedInterface(m_mesh);
301 String master_group_name = m_tied_interface_face_groups[(i*2)];
302 String slave_group_name = m_tied_interface_face_groups[(i*2)+1];
303 tied_interface->reload(&face_family,master_group_name,slave_group_name);
304 FaceGroup master_group = tied_interface->masterInterface();
305 FaceGroup slave_group = tied_interface->slaveInterface();
306 m_tied_interfaces.add(tied_interface);
307 m_true_tied_interfaces.add(tied_interface);
308
309 Integer nb_node = arcaneCheckArraySize(m_tied_interface_items_info[items_info_index]);
310 ++items_info_index;
311 IntegerUniqueArray items_size(nb_node);
312 for( Integer zz=0; zz<nb_node; ++zz ){
313 Integer nb_node2 = arcaneCheckArraySize(m_tied_interface_items_info[items_info_index]);
314 ++items_info_index;
315 items_size[zz] = nb_node2;
316 }
317 tied_interface->resizeNodes(items_size);
318 Int32UniqueArray local_ids;
319 for( Integer zz=0; zz<nb_node; ++zz ){
320 Integer nb_node2 = items_size[zz];
321 nodes.clear();
322 local_ids.resize(nb_node2);
323 Int64ConstArrayView unique_ids(nb_node2,&m_tied_interface_items_info[items_info_index]);
324 node_family->itemsUniqueIdToLocalId(local_ids,unique_ids,true);
325 items_info_index += nb_node2;
326
327 for( Integer zz2=0; zz2<nb_node2; ++zz2 ){
328 Node node(nodes_internal[local_ids[zz2]]);
329 nodes.add(TiedNode(zz2,node,m_tied_interface_nodes_iso[nodes_iso_index]));
330 ++nodes_iso_index;
331 }
332 tied_interface->setNodes(zz,nodes);
333 }
334
335 Integer nb_face = arcaneCheckArraySize(m_tied_interface_items_info[items_info_index]);
336 ++items_info_index;
337 items_size.resize(nb_face);
338 for( Integer zz=0; zz<nb_face; ++zz ){
339 Integer nb_face2 = arcaneCheckArraySize(m_tied_interface_items_info[items_info_index]);
340 ++items_info_index;
341 items_size[zz] = nb_face2;
342 }
343 tied_interface->resizeFaces(items_size);
344 UniqueArray<TiedFace> faces2;
345 for( Integer zz=0; zz<nb_face; ++zz ){
346 Integer nb_face2 = items_size[zz];
347 faces2.clear();
348 local_ids.resize(nb_face2);
349 Int64ConstArrayView unique_ids(nb_face2,&m_tied_interface_items_info[items_info_index]);
350 face_family.itemsUniqueIdToLocalId(local_ids,unique_ids,true);
351 items_info_index += nb_face2;
352 for( Integer zz2=0; zz2<nb_face2; ++zz2 ){
353 Face face(faces_internal[local_ids[zz2]]);
354 faces2.add(TiedFace(zz2,face));
355 }
356 tied_interface->setFaces(zz,faces2);
357 }
358 info() << "Read interface nb_face=" << nb_face << " nb_node=" << nb_node;
359 }
360
361 // Reconstruit les contraintes si necessaire
362 if (!m_tied_constraint){
363 info() << "Rebuilding tied interface constraints";
364 UniqueArray<FaceGroup> interface_groups;
365 for( Integer i=0, n=m_true_tied_interfaces.size(); i<n; ++i )
366 interface_groups.add(m_true_tied_interfaces[i]->slaveInterface());
367
368 Integer nb_interface = interface_groups.size();
369 if (nb_interface!=0){
370 TiedInterface::PartitionConstraintBase* c = TiedInterface::createConstraint(m_mesh,interface_groups);
371 m_tied_constraint = c;
372 IMeshPartitionConstraintMng* pcmng = m_mesh->partitionConstraintMng();
373 pcmng->addConstraint(c);
374 // Indique que le partitionnement initial a été effectué
375 c->setInitialRepartition(false);
376 }
377 }
378}
379
380/*---------------------------------------------------------------------------*/
381/*---------------------------------------------------------------------------*/
382
383void TiedInterfaceMng::
384_applyTiedInterfaceStructuration(TiedInterface* tied_interface)
385{
386 // Suppose que l'interface est structurée MxN.
387 // Pour chercher M, parcours la liste des noeuds liées et détecte
388 // quand un noeud à une coordonnées iso.y inférieure à celle du
389 // noeud précédent. Cela signifie qu'on change de ligne dans
390 // la structuration.
391 // Une fois MxN connu, normalise les coordonnées iso pour
392 // qu'elles correspondent à cette structuration
393
394 TiedInterfaceNodeList nodes = tied_interface->tiedNodes();
395 for( Integer zz=0, zs=nodes.dim1Size(); zz<zs; ++zz ){
396 Integer current_nb_node = nodes[zz].size();
397 Real old_y = -10.0;
398 Integer computed_m = 0;
399 for( Integer i=0; i<current_nb_node; ++i ){
400 Real2 iso_val = nodes[zz][i].isoCoordinates();
401 info() << "ISO zz=" << zz << " i=" << i << " v=" << iso_val << " old=" << old_y;
402 if (iso_val.y>old_y){
403 ++computed_m;
404 }
405 else{
406 info() << "COMPUTED M = "<< computed_m;
407 computed_m = 0;
408 }
409 old_y = iso_val.y;
410 }
411 }
412}
413
414/*---------------------------------------------------------------------------*/
415/*---------------------------------------------------------------------------*/
416
417void TiedInterfaceMng::
418_deleteTiedInterfaces()
419{
420 for( Integer i=0, is=m_tied_interfaces.count(); i<is; ++i )
421 delete m_tied_interfaces[i];
422 m_tied_interfaces.clear();
423 m_true_tied_interfaces.clear();
424}
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
429}
430
431/*---------------------------------------------------------------------------*/
432/*---------------------------------------------------------------------------*/
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
const String & name() const
Nom du groupe.
Definition ItemGroup.h:76
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
ItemGroupT< Face > FaceGroup
Groupe de faces.
Definition ItemTypes.h:178
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:638
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
Definition UtilsTypes.h:519
Int32 Integer
Type représentant un entier.