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