Arcane  v3.16.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
GeometryKernelSurfaceToolsService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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#ifdef WIN32
9#include <iso646.h>
10#endif
11
12#include "GeometryKernelSurfaceToolsService.h"
13/* Author : havep at Wed Aug 27 14:57:32 2008
14 * Generated by createNew
15 */
16
17#include <arcane/corefinement/surfaceutils/geometrykernelsurfacetools/GeometryKernelSurfaceImpl.h>
18
19#include <arcane/utils/NotImplementedException.h>
20#include <arcane/IParallelMng.h>
21#include <arcane/IMesh.h>
22
23#include <GeometryKernel/algorithms/surface/surface-corefinement.h>
24#include <GeometryKernel/tools/surface/triangulation-topo-tools.h>
25#include <GeometryKernel/datamodel/geometry/vector.h>
26
27using namespace Arcane;
28
29#include "GeometryKernelSurfaceInternalUtils.h"
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34void
40
41/*---------------------------------------------------------------------------*/
42
49
50/*---------------------------------------------------------------------------*/
51
52void
55 FaceGroup face_group)
56{
57 buildFaceGroupSurface(face_group,castSurface(surface));
58}
59
60/*---------------------------------------------------------------------------*/
61
62void
65 ISurface* s2,
66 FaceFaceContactList & contact)
67{
68 GeometryKernelSurfaceImpl * surface1 = castSurface(s1);
69 GeometryKernelSurfaceImpl * surface2 = castSurface(s2);
70
71 GK::TriangulationDataStructurePtr gkSurface1 = surface1->m_triangulation;
72 GK::TriangulationDataStructurePtr gkSurface2 = surface2->m_triangulation;
73
74 // bidouille pour sauter les pb de pointeurs boost non voulus
75 GK::TriangulationDataStructurePtr surfaceA = gkSurface1;
76 GK::TriangulationDataStructurePtr surfaceB = gkSurface2;
77
78// { // GK debug purpose
79// const bool use_surface_count = false;
80// const bool force_cpu_id = true;
81
82// char cpu_suffix[16] = "";
83// if (force_cpu_id or subDomain()->nbSubDomain() > 1)
84// sprintf(cpu_suffix,"_cpu=%d",subDomain()->subDomainId());
85
86// char count_suffix[32] = "";
87// if (use_surface_count)
88// {
89// static Integer surface_count = 0;
90// sprintf(count_suffix,"_%d",surface_count);
91// ++surface_count;
92// }
93
94// char filename[256];
95// sprintf(filename,"surfaceA%s%s",cpu_suffix,count_suffix);
96// ::saveSurface(filename,*surfaceA);
97// sprintf(filename,"surfaceB%s%s",cpu_suffix,count_suffix);
98// ::saveSurface(filename,*surfaceB);
99// }
100
101 UniqueArray<Real3> normals(2);
102 normals[0] = surface1->m_mean_normal;
103 normals[1] = surface2->m_mean_normal;
104 //subDomain()->parallelMng()->reduce(Parallel::ReduceSum,normals);
105
106#ifndef NO_USER_WARNING
107#warning "Work around strange UniqueArray<Real3> reduction"
108#endif /* NO_USER_WARNING */
109 UniqueArray<Real> __normals(6);
110 __normals[0] = normals[0].x;
111 __normals[1] = normals[0].y;
112 __normals[2] = normals[0].z;
113 __normals[3] = normals[1].x;
114 __normals[4] = normals[1].y;
115 __normals[5] = normals[1].z;
116 subDomain()->parallelMng()->reduce(Parallel::ReduceSum,__normals);
117 normals[0].x = __normals[0];
118 normals[0].y = __normals[1];
119 normals[0].z = __normals[2];
120 normals[1].x = __normals[3];
121 normals[1].y = __normals[4];
122 normals[1].z = __normals[5];
123
124 // Clear container
125 contact.clear();
126
127 // No premature return before this point since reduction needs all processors
128 if (surfaceA->numberOfFaces() == 0) // non empty master surface
129 return;
130
131 typedef GK::SurfaceCorefinement::IntersectionIterator Iter;
132 typedef GK::SurfaceCorefinement::IntersectionHandle Handle;
133 long requested_info = GK::SurfaceCorefinement::NORMAL | GK::SurfaceCorefinement::CENTRE;
134#ifndef NO_USER_WARNING
135#warning "global plane computation disabled"
136#endif /* NO_USER_WARNING */
137 GK::SurfaceCorefinement s(surfaceA, surfaceB,
138 convertGKVector(normals[0]), convertGKVector(normals[1]),
139 requested_info, options()->areaEpsilon());
140
141 const Integer voidIndex = s.indexVoid();
142
143 const Array<Face> & face_arrayA = surface1->m_face_array;
144 const Array<Face> & face_arrayB = surface2->m_face_array;
145 const Array<bool> & face_reorientA = surface1->m_face_reorient;
146 const Array<bool> & face_reorientB = surface2->m_face_reorient;
147
148 Integer count = 0;
149
150 // voidIndex sur indexA est traité à part
151 for (Integer indexA = s.beginA(); indexA < s.endA(); /*incr inside*/) {
152 ARCANE_ASSERT((indexA != voidIndex),("indexA cannot be voidIndex by documentation"));
153 Face faceA = face_arrayA[indexA];
154 Integer split_sizeA = faceA.nbNode()-2; // assume what split method has been used
155
156 // Table des positions courantes des sous-faces B associées à cette face A
157 UniqueArray<Iter> jB(split_sizeA);
158 UniqueArray<Iter> endB(split_sizeA);
159 bool canContinue = false;
160 for(Integer iA=0;iA<split_sizeA;++iA) {
161 jB[iA] = s.beginB(indexA+iA);
162 endB[iA] = s.endB(indexA+iA);
163 canContinue |= (jB[iA] != endB[iA]);
164 }
165
166 while (canContinue) {
167 // Calcul de l'indexB minimal : selection d'une faceB candidate
168 Integer minIndexB = voidIndex;
169 for(Integer iA=0;iA<split_sizeA;++iA) {
170 Integer indexB = voidIndex;
171 if (jB[iA] != endB[iA]) indexB = jB[iA]->indexB();
172 if (indexB != voidIndex) {
173 if (minIndexB == voidIndex) minIndexB = indexB;
174 else minIndexB = math::min(minIndexB,indexB);
175 }
176 }
177
178 // Operator which convert Iter to Face (according to indexVoid special case)
179 struct ConvertFace {
180 ConvertFace(const Array<Face> & face_array, const Integer voidIndex) : m_face_array(face_array), m_void_index(voidIndex) { }
181 Face operator()(Integer index) const {
182 if (index == m_void_index) return Face();
183 else return m_face_array[index];
184 }
185 private:
186 const Array<Face> & m_face_array;
187 const Integer m_void_index;
188 } convertFace(face_arrayB,voidIndex);
189
190 // Utilise de cet minIndexB donne le faceB
191 Face faceB = convertFace(minIndexB);
192
193 // Current accumulator for co-refinement values for faceA/faceB
194 FaceFaceContact c(faceA,faceB);
195
196 // Collecte des informations associées à la faceB courante
197 canContinue = false; // recalcul de la fin possible
198 for(Integer iA=0;iA<split_sizeA;++iA) {
199 while (jB[iA] != endB[iA] and convertFace(jB[iA]->indexB()) == faceB) {
200 const Handle & handle = *jB[iA];
201 Real3 normal = convertGKVector(handle.normalA());
202 Real3 center = convertGKVector(handle.centreA());
203 c.centerA += center * math::normeR3(normal);
204 if (face_reorientA[indexA+iA])
205 c.normalA -= normal;
206 else
207 c.normalA += normal;
208
209 if (not faceB.null()) {
210 Real3 normal = convertGKVector(handle.normalB());
211 Real3 center = convertGKVector(handle.centreB());
212 c.centerB += center * math::normeR3(normal);
213 if (face_reorientB[jB[iA]->indexB()])
214 c.normalB -= normal;
215 else
216 c.normalB += normal;
217 }
218 ++jB[iA];
219 }
220 canContinue |= (jB[iA] != endB[iA]);
221 }
222 c.centerA /= math::normeR3(c.normalA);
223 if (not faceB.null())
224 c.centerB /= math::normeR3(c.normalB);
225 contact.add(c);
226 ++count;
227 }
228 indexA += split_sizeA;
229 }
230
231 { // case for indexA == voidIndex
232 Iter jB = s.beginB(voidIndex);
233 Iter endB = s.endB(voidIndex);
234 while(jB != endB) {
235 ARCANE_ASSERT((jB->indexB() != voidIndex),("By construction indexB cannot be voidIndex when indexA is voidIndex"));
236 Face faceB = face_arrayB[jB->indexB()];
237
238 // Current accumulator for co-refinement values for faceA/faceB
239 FaceFaceContact c(Face(),faceB);
240
241 // Collecte des informations associées à la faceB courante
242 while (jB != endB and face_arrayB[jB->indexB()] == faceB) {
243 const Handle & handle = *jB;
244 Real3 normal = convertGKVector(handle.normalB());
245 Real3 center = convertGKVector(handle.centreB());
246 c.centerB += center * math::normeR3(normal);
247 if (face_reorientB[jB->indexB()])
248 c.normalB -= normal;
249 else
250 c.normalB += normal;
251 ++jB;
252 }
253 c.centerB /= math::normeR3(c.normalB);
254 contact.add(c);
255 ++count;
256 }
257 }
258
259 info() << "Co-refinement"
260 << " : maxDeviation = " << s.maxDeviation()
261 << " ; meanDeviation = " << s.meanDeviation()
262 << " ; connections = " << count;
263}
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
269GeometryKernelSurfaceToolsService::
270castSurface(ISurface * s) const
271{
273 if (gks == NULL)
274 fatal() << "Cannot use non own ISurface implementation";
275 return gks;
276}
277
278/*---------------------------------------------------------------------------*/
279
280void
281GeometryKernelSurfaceToolsService::
282buildFaceGroupSurface(FaceGroup group, GeometryKernelSurfaceImpl * surface_impl) const
283{
285 surface_impl->m_triangulation,
286 surface_impl->m_node_array,
287 surface_impl->m_face_array,
288 surface_impl->m_face_reorient,
289 surface_impl->m_mean_normal);
290}
291
292/*---------------------------------------------------------------------------*/
293/*---------------------------------------------------------------------------*/
294
295ARCANE_REGISTER_SERVICE_GEOMETRYKERNELSURFACETOOLS(GeometryKernelSurfaceTools,GeometryKernelSurfaceToolsService);
Tableau d'items de types quelconques.
void clear()
Supprime les éléments du tableau.
Face d'une maille.
Definition Item.h:958
Real3 m_mean_normal
Flag d'orientation des faces de la triangulation (true => orientation != originale)
UniqueArray< Face > m_face_array
Noeuds originaux de la triangulation.
UniqueArray< bool > m_face_reorient
Faces originales de la triangulation.
ISurface * createSurface()
Création d'une nouvelle surface.
void computeSurfaceContact(ISurface *surface1, ISurface *surface2, FaceFaceContactList &contact)
compute for each face of surface1 the nearest face of surface2
void setFaceToSurface(ISurface *surface, FaceGroup face_group)
Définit les faces d'une surface.
Purely virtual interface for surface representation.
Definition ISurface.h:25
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:785
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:216
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Vecteur 1D de données avec sémantique par valeur (style STL).
__host__ __device__ Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
Definition MathUtils.h:336
ItemGroupT< Face > FaceGroup
Groupe de faces.
Definition ItemTypes.h:178
@ ReduceSum
Somme des valeurs.
Real normeR3(Real3 v1)
Norme d'un vecteur.
Definition MathUtils.h:653
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
Real3 convertGKVector(const GeometryKernel::Vector &v)
convert GeometryKernel vector to Real3
void buildFaceGroupSurface(FaceGroup group, GeometryKernel::TriangulationDataStructurePtr surface, Array< Node > &node_array, Array< Face > &face_array, Array< bool > &face_reorient, Real3 &normal)
Build GK triangulation and additional data from a face group.