Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
GeometryKernelSurfaceToolsService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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 "arcane/corefinement/surfaceutils/geometrykernelsurfacetools/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/core/IParallelMng.h"
21#include "arcane/core/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
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30using namespace Arcane;
31
32#include "arcane/corefinement/surfaceutils/geometrykernelsurfacetools/GeometryKernelSurfaceInternalUtils.h"
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
42
43/*---------------------------------------------------------------------------*/
44
51
52/*---------------------------------------------------------------------------*/
53
56 FaceGroup face_group)
57{
58 buildFaceGroupSurface(face_group, castSurface(surface));
59}
60
61/*---------------------------------------------------------------------------*/
62
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 // hack to skip unwanted boost pointer issues
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 on indexA is handled separately
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 of current positions of sub-faces B associated with this 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 // Calculate the minimal indexB: selection of a candidate faceB
168 Integer minIndexB = voidIndex;
169 for (Integer iA = 0; iA < split_sizeA; ++iA) {
170 Integer indexB = voidIndex;
171 if (jB[iA] != endB[iA])
172 indexB = jB[iA]->indexB();
173 if (indexB != voidIndex) {
174 if (minIndexB == voidIndex)
175 minIndexB = indexB;
176 else
177 minIndexB = math::min(minIndexB, indexB);
178 }
179 }
180
181 // Operator which convert Iter to Face (according to indexVoid special case)
182 struct ConvertFace
183 {
184 ConvertFace(const Array<Face>& face_array, const Integer voidIndex)
185 : m_face_array(face_array)
186 , m_void_index(voidIndex)
187 {}
188 Face operator()(Integer index) const
189 {
190 if (index == m_void_index)
191 return Face();
192 else
193 return m_face_array[index];
194 }
195
196 private:
197
198 const Array<Face>& m_face_array;
199 const Integer m_void_index;
200 } convertFace(face_arrayB, voidIndex);
201
202 // Use this minIndexB to get faceB
203 Face faceB = convertFace(minIndexB);
204
205 // Current accumulator for co-refinement values for faceA/faceB
206 FaceFaceContact c(faceA, faceB);
207
208 // Collection of information associated with the current faceB
209 canContinue = false; // recalculate possible end
210 for (Integer iA = 0; iA < split_sizeA; ++iA) {
211 while (jB[iA] != endB[iA] and convertFace(jB[iA]->indexB()) == faceB) {
212 const Handle& handle = *jB[iA];
213 Real3 normal = convertGKVector(handle.normalA());
214 Real3 center = convertGKVector(handle.centreA());
215 c.centerA += center * math::normeR3(normal);
216 if (face_reorientA[indexA + iA])
217 c.normalA -= normal;
218 else
219 c.normalA += normal;
220
221 if (not faceB.null()) {
222 Real3 normal = convertGKVector(handle.normalB());
223 Real3 center = convertGKVector(handle.centreB());
224 c.centerB += center * math::normeR3(normal);
225 if (face_reorientB[jB[iA]->indexB()])
226 c.normalB -= normal;
227 else
228 c.normalB += normal;
229 }
230 ++jB[iA];
231 }
232 canContinue |= (jB[iA] != endB[iA]);
233 }
234 c.centerA /= math::normeR3(c.normalA);
235 if (not faceB.null())
236 c.centerB /= math::normeR3(c.normalB);
237 contact.add(c);
238 ++count;
239 }
240 indexA += split_sizeA;
241 }
242
243 { // case for indexA == voidIndex
244 Iter jB = s.beginB(voidIndex);
245 Iter endB = s.endB(voidIndex);
246 while (jB != endB) {
247 ARCANE_ASSERT((jB->indexB() != voidIndex), ("By construction indexB cannot be voidIndex when indexA is voidIndex"));
248 Face faceB = face_arrayB[jB->indexB()];
249
250 // Current accumulator for co-refinement values for faceA/faceB
251 FaceFaceContact c(Face(), faceB);
252
253 // Collection of information associated with the current faceB
254 while (jB != endB and face_arrayB[jB->indexB()] == faceB) {
255 const Handle& handle = *jB;
256 Real3 normal = convertGKVector(handle.normalB());
257 Real3 center = convertGKVector(handle.centreB());
258 c.centerB += center * math::normeR3(normal);
259 if (face_reorientB[jB->indexB()])
260 c.normalB -= normal;
261 else
262 c.normalB += normal;
263 ++jB;
264 }
265 c.centerB /= math::normeR3(c.normalB);
266 contact.add(c);
267 ++count;
268 }
269 }
270
271 info() << "Co-refinement"
272 << " : maxDeviation = " << s.maxDeviation()
273 << " ; meanDeviation = " << s.meanDeviation()
274 << " ; connections = " << count;
275}
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279
281GeometryKernelSurfaceToolsService::
282castSurface(ISurface* s) const
283{
285 if (gks == NULL)
286 fatal() << "Cannot use non own ISurface implementation";
287 return gks;
288}
289
290/*---------------------------------------------------------------------------*/
291
292void GeometryKernelSurfaceToolsService::
293buildFaceGroupSurface(FaceGroup group, GeometryKernelSurfaceImpl* surface_impl) const
294{
295 ::buildFaceGroupSurface(group,
296 surface_impl->m_triangulation,
297 surface_impl->m_node_array,
298 surface_impl->m_face_array,
299 surface_impl->m_face_reorient,
300 surface_impl->m_mean_normal);
301}
302
303/*---------------------------------------------------------------------------*/
304/*---------------------------------------------------------------------------*/
305
306ARCANE_REGISTER_SERVICE_GEOMETRYKERNELSURFACETOOLS(GeometryKernelSurfaceTools, GeometryKernelSurfaceToolsService);
Base class for 1D data vectors.
void clear()
Removes the elements from the array.
Face of a cell.
Definition Item.h:1032
Int32 nbNode() const
Number of nodes of the entity.
Definition Item.h:837
constexpr bool null() const
true if the entity is null (i.e. not connected to the mesh)
Definition Item.h:230
UniqueArray< bool > m_face_reorient
Original faces of the triangulation.
Real3 m_mean_normal
Flag for face orientation of the triangulation (true => orientation != original).
UniqueArray< Face > m_face_array
Original nodes of the triangulation.
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)
Defines the faces of a surface.
Purely virtual interface for surface representation.
Definition ISurface.h:32
Class managing a 3-dimensional real vector.
Definition Real3.h:132
1D data vector with value semantics (STL style).
__host__ __device__ Real2 min(Real2 a, Real2 b)
Returns the minimum of two Real2.
Definition MathUtils.h:346
ItemGroupT< Face > FaceGroup
Group of faces.
Definition ItemTypes.h:179
@ ReduceSum
Sum of values.
Real normeR3(Real3 v1)
Norm of a vector.
Definition MathUtils.h:684
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.