Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
Euclidian3Geometry.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#include <arcane/geometry/euclidian/Euclidian3Geometry.h>
8/* Author : havep at Wed Nov 14 14:23:21 2007
9 * Generated by createNew
10 */
11using namespace Arcane;
12#include <arcane/utils/FatalErrorException.h>
13#include <arcane/utils/NotImplementedException.h>
14
15/*---------------------------------------------------------------------------*/
16/*---------------------------------------------------------------------------*/
17
18namespace Arcane::Numerics
19{
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
26{
27 Real3 orientation, center;
28 Real measure;
29
30 switch (item.type()) {
31 case IT_Line2:
32 ComputeLine2(this).computeOrientedMeasureAndCenter(item, orientation, center);
33 return center;
34 case IT_Triangle3:
35 ComputeTriangle3(this).computeOrientedMeasureAndCenter(item, orientation, center);
36 return center;
37 case IT_Quad4:
38 ComputeQuad4(this).computeOrientedMeasureAndCenter(item, orientation, center);
39 return center;
40 case IT_Pentagon5:
41 ComputePentagon5(this).computeOrientedMeasureAndCenter(item, orientation, center);
42 return center;
43 case IT_Hexagon6:
44 ComputeHexagon6(this).computeOrientedMeasureAndCenter(item, orientation, center);
45 return center;
46 case IT_Tetraedron4:
47 ComputeTetraedron4(this).computeOrientedMeasureAndCenter(item, measure, center);
48 return center;
49 case IT_Pyramid5:
50 ComputePyramid5(this).computeOrientedMeasureAndCenter(item, measure, center);
51 return center;
52 case IT_Pentaedron6:
53 ComputePentaedron6(this).computeOrientedMeasureAndCenter(item, measure, center);
54 return center;
55 case IT_Hexaedron8:
56 ComputeHexaedron8(this).computeOrientedMeasureAndCenter(item, measure, center);
57 return center;
58 case IT_Heptaedron10:
59 ComputeHeptaedron10(this).computeOrientedMeasureAndCenter(item, measure, center);
60 return center;
61 case IT_Octaedron12:
62 ComputeOctaedron12(this).computeOrientedMeasureAndCenter(item, measure, center);
63 return center;
64 default:
65 throw FatalErrorException(A_FUNCINFO, "Not supported Item Type");
66 }
67}
68
71{
72 Real3 orientation, center;
73 Real measure;
74 switch (item.type()) {
75 case IT_Line2:
76 ComputeLine2(this).computeOrientedMeasureAndCenter(item, orientation, center);
77 return orientation;
78 case IT_Triangle3:
79 ComputeTriangle3(this).computeOrientedMeasureAndCenter(item, orientation, center);
80 return orientation;
81 case IT_Quad4:
82 ComputeQuad4(this).computeOrientedMeasureAndCenter(item, orientation, center);
83 return orientation;
84 case IT_Pentagon5:
85 ComputePentagon5(this).computeOrientedMeasureAndCenter(item, orientation, center);
86 return orientation;
87 case IT_Hexagon6:
88 ComputeHexagon6(this).computeOrientedMeasureAndCenter(item, orientation, center);
89 return orientation;
90 case IT_Tetraedron4:
91 ComputeTetraedron4(this).computeOrientedMeasureAndCenter(item, measure, center);
92 return Real3(0, 0, measure);
93 case IT_Pyramid5:
94 ComputePyramid5(this).computeOrientedMeasureAndCenter(item, measure, center);
95 return Real3(0, 0, measure);
96 case IT_Pentaedron6:
97 ComputePentaedron6(this).computeOrientedMeasureAndCenter(item, measure, center);
98 return Real3(0, 0, measure);
99 case IT_Hexaedron8:
100 ComputeHexaedron8(this).computeOrientedMeasureAndCenter(item, measure, center);
101 return Real3(0, 0, measure);
102 case IT_Heptaedron10:
103 ComputeHeptaedron10(this).computeOrientedMeasureAndCenter(item, measure, center);
104 return Real3(0, 0, measure);
105 case IT_Octaedron12:
106 ComputeOctaedron12(this).computeOrientedMeasureAndCenter(item, measure, center);
107 return Real3(0, 0, measure);
108 default:
109 throw FatalErrorException(A_FUNCINFO, "Not supported Item Type");
110 }
111}
112
114computeMeasure(const ItemWithNodes& item)
115{
116 Real3 orientation, center;
117 Real measure;
118
119 switch (item.type()) {
120 case IT_Line2:
121 ComputeLine2(this).computeOrientedMeasureAndCenter(item, orientation, center);
122 return math::normeR3(orientation);
123 case IT_Triangle3:
124 ComputeTriangle3(this).computeOrientedMeasureAndCenter(item, orientation, center);
125 return math::normeR3(orientation);
126 case IT_Quad4:
127 ComputeQuad4(this).computeOrientedMeasureAndCenter(item, orientation, center);
128 return math::normeR3(orientation);
129 case IT_Pentagon5:
130 ComputePentagon5(this).computeOrientedMeasureAndCenter(item, orientation, center);
131 return math::normeR3(orientation);
132 case IT_Hexagon6:
133 ComputeHexagon6(this).computeOrientedMeasureAndCenter(item, orientation, center);
134 return math::normeR3(orientation);
135 case IT_Tetraedron4:
136 ComputeTetraedron4(this).computeOrientedMeasureAndCenter(item, measure, center);
137 return measure;
138 case IT_Pyramid5:
139 ComputePyramid5(this).computeOrientedMeasureAndCenter(item, measure, center);
140 return measure;
141 case IT_Pentaedron6:
142 ComputePentaedron6(this).computeOrientedMeasureAndCenter(item, measure, center);
143 return measure;
144 case IT_Hexaedron8:
145 ComputeHexaedron8(this).computeOrientedMeasureAndCenter(item, measure, center);
146 return measure;
147 case IT_Heptaedron10:
148 ComputeHeptaedron10(this).computeOrientedMeasureAndCenter(item, measure, center);
149 return measure;
150 case IT_Octaedron12:
151 ComputeOctaedron12(this).computeOrientedMeasureAndCenter(item, measure, center);
152 return measure;
153 default:
154 ARCANE_THROW(NotSupportedException, "Not supported Item Type {0}", item.type());
155 }
156}
157
159computeLength(const ItemWithNodes& item)
160{
161 ARCANE_UNUSED(item);
163}
164
166computeArea(const ItemWithNodes& item)
167{
168 Real3 orientation, center;
169
170 switch (item.type()) {
171 case IT_Line2:
172 return 0.;
173 case IT_Triangle3:
174 ComputeTriangle3(this).computeOrientedMeasureAndCenter(item, orientation, center);
175 return math::normeR3(orientation);
176 case IT_Quad4:
177 ComputeQuad4(this).computeOrientedMeasureAndCenter(item, orientation, center);
178 return math::normeR3(orientation);
179 case IT_Pentagon5:
180 ComputePentagon5(this).computeOrientedMeasureAndCenter(item, orientation, center);
181 return math::normeR3(orientation);
182 case IT_Hexagon6:
183 ComputeHexagon6(this).computeOrientedMeasureAndCenter(item, orientation, center);
184 return math::normeR3(orientation);
185 case IT_Tetraedron4:
186 case IT_Pyramid5:
187 case IT_Pentaedron6:
188 case IT_Hexaedron8:
189 case IT_Heptaedron10:
190 case IT_Octaedron12:
191 case IT_HemiHexa7:
192 case IT_HemiHexa6:
193 case IT_HemiHexa5:
194 case IT_AntiWedgeLeft6:
195 case IT_AntiWedgeRight6:
196 case IT_DiTetra5:
197 return 0.;
198 default:
199 throw FatalErrorException(A_FUNCINFO, "Not supported Item Type");
200 }
201}
202
204computeVolume(const ItemWithNodes& item)
205{
206 Real3 center;
207 Real measure;
208
209 switch (item.type()) {
210 case IT_Line2:
211 return 0.;
212 break;
213 case IT_Triangle3:
214 case IT_Quad4:
215 case IT_Pentagon5:
216 case IT_Hexagon6:
217 return 0.;
218 case IT_Tetraedron4:
219 ComputeTetraedron4(this).computeOrientedMeasureAndCenter(item, measure, center);
220 return measure;
221 case IT_Pyramid5:
222 ComputePyramid5(this).computeOrientedMeasureAndCenter(item, measure, center);
223 return measure;
224 case IT_Pentaedron6:
225 ComputePentaedron6(this).computeOrientedMeasureAndCenter(item, measure, center);
226 return measure;
227 case IT_Hexaedron8:
228 ComputeHexaedron8(this).computeOrientedMeasureAndCenter(item, measure, center);
229 return measure;
230 case IT_Heptaedron10:
231 ComputeHeptaedron10(this).computeOrientedMeasureAndCenter(item, measure, center);
232 return measure;
233 case IT_Octaedron12:
234 ComputeOctaedron12(this).computeOrientedMeasureAndCenter(item, measure, center);
235 return measure;
236 case IT_HemiHexa7:
237 ComputeHemiHexa7(this).computeOrientedMeasureAndCenter(item, measure, center);
238 return measure;
239 case IT_HemiHexa6:
240 ComputeHemiHexa6(this).computeOrientedMeasureAndCenter(item, measure, center);
241 return measure;
242 case IT_HemiHexa5:
243 ComputeHemiHexa5(this).computeOrientedMeasureAndCenter(item, measure, center);
244 return measure;
245 case IT_AntiWedgeLeft6:
246 ComputeAntiWedgeLeft6(this).computeOrientedMeasureAndCenter(item, measure, center);
247 return measure;
248 case IT_AntiWedgeRight6:
249 ComputeAntiWedgeRight6(this).computeOrientedMeasureAndCenter(item, measure, center);
250 return measure;
251 case IT_DiTetra5:
252 ComputeDiTetra5(this).computeOrientedMeasureAndCenter(item, measure, center);
253 return measure;
254 default:
255 throw FatalErrorException(A_FUNCINFO, "Not supported Item Type");
256 }
257}
258
260computeSurfaceCenter(Integer n, const Real3* coords)
261{
262 if (n == 3)
263 return computeTriangleCenter(coords[0], coords[1], coords[2]);
264
265 Real3 center(0, 0, 0);
266 Real area = 0;
267 for (Integer i = 1; i < n - 1; ++i) {
268 Real local_area = math::normeR3(computeTriangleNormal(coords[0], coords[i], coords[i + 1]));
269 center += local_area * computeTriangleCenter(coords[0], coords[i], coords[i + 1]);
270 area += local_area;
271 }
272 return center / area;
273}
274
276computeOrientedArea(Integer n, const Real3* coords)
277{
278 Real3 normal(0., 0., 0.);
279 for (Integer i = 1; i < n - 1; ++i)
280 normal += computeTriangleNormal(coords[0], coords[i], coords[i + 1]);
281 return normal;
282}
283
285computeLength(const Real3& m, const Real3& n)
286{
287 const Real3 d = m - n;
288 return math::sqrt(math::scaMul(d, d));
289}
290
291/*---------------------------------------------------------------------------*/
292
293void Euclidian3Geometry::ComputeLine2::
294computeOrientedMeasureAndCenter(const ItemWithNodes& item, Real3& orientation, Real3& center)
295{
296 orientation = m_coords[item.node(1)] - m_coords[item.node(0)];
297 center = 0.5 * (m_coords[item.node(1)] + m_coords[item.node(0)]);
298}
299
300void Euclidian3Geometry::ComputeTriangle3::
301computeOrientedMeasureAndCenter(const ItemWithNodes& item, Real3& orientation, Real3& center)
302{
303 orientation =
304 computeTriangleNormal(m_coords[item.node(0)],
305 m_coords[item.node(1)],
306 m_coords[item.node(2)]);
307
308 center =
309 computeTriangleCenter(m_coords[item.node(0)],
310 m_coords[item.node(1)],
311 m_coords[item.node(2)]);
312}
313
314void Euclidian3Geometry::ComputeQuad4::
315computeOrientedMeasureAndCenter(const ItemWithNodes& item, Real3& orientation, Real3& center)
316{
317 orientation =
318 computeTriangleNormal(m_coords[item.node(0)],
319 m_coords[item.node(1)],
320 m_coords[item.node(2)]) +
321 computeTriangleNormal(m_coords[item.node(0)],
322 m_coords[item.node(2)],
323 m_coords[item.node(3)]);
324
325 center =
326 computeQuadrilateralCenter(m_coords[item.node(0)],
327 m_coords[item.node(1)],
328 m_coords[item.node(2)],
329 m_coords[item.node(3)]);
330}
331
332void Euclidian3Geometry::ComputePentagon5::
333computeOrientedMeasureAndCenter(const ItemWithNodes& item, Real3& orientation, Real3& center)
334{
335 orientation =
336 computeTriangleNormal(m_coords[item.node(0)],
337 m_coords[item.node(1)],
338 m_coords[item.node(2)]) +
339 computeTriangleNormal(m_coords[item.node(0)],
340 m_coords[item.node(2)],
341 m_coords[item.node(3)]) +
342 computeTriangleNormal(m_coords[item.node(0)],
343 m_coords[item.node(3)],
344 m_coords[item.node(4)]);
345
346 center =
347 computePentagonalCenter(m_coords[item.node(0)],
348 m_coords[item.node(1)],
349 m_coords[item.node(2)],
350 m_coords[item.node(3)],
351 m_coords[item.node(4)]);
352}
353
354void Euclidian3Geometry::ComputeHexagon6::
355computeOrientedMeasureAndCenter(const ItemWithNodes& item, Real3& orientation, Real3& center)
356{
357 orientation =
358 computeTriangleNormal(m_coords[item.node(0)],
359 m_coords[item.node(1)],
360 m_coords[item.node(2)]) +
361 computeTriangleNormal(m_coords[item.node(0)],
362 m_coords[item.node(2)],
363 m_coords[item.node(3)]) +
364 computeTriangleNormal(m_coords[item.node(0)],
365 m_coords[item.node(3)],
366 m_coords[item.node(4)]) +
367 computeTriangleNormal(m_coords[item.node(0)],
368 m_coords[item.node(4)],
369 m_coords[item.node(5)]);
370
371 center =
372 computeHexagonalCenter(m_coords[item.node(0)],
373 m_coords[item.node(1)],
374 m_coords[item.node(2)],
375 m_coords[item.node(3)],
376 m_coords[item.node(4)],
377 m_coords[item.node(5)]);
378}
379
380void Euclidian3Geometry::ComputeTetraedron4::
381computeOrientedMeasureAndCenter(const ItemWithNodes& item, Real& measure, Real3& center)
382{
383 ARCANE_ASSERT((item.type() == IT_Tetraedron4), ("Bad item type: %d vs %d (Tetra4)", item.type(), IT_Tetraedron4));
384 measure = computeTetraedronVolume(m_coords[item.node(0)],
385 m_coords[item.node(1)],
386 m_coords[item.node(2)],
387 m_coords[item.node(3)]);
388 center = computeTetraedronCenter(m_coords[item.node(0)],
389 m_coords[item.node(1)],
390 m_coords[item.node(2)],
391 m_coords[item.node(3)]);
392}
393
394void Euclidian3Geometry::ComputeTetraedron4::
395computeVolumeArea(const ItemWithNodes& item, Real& area)
396{
397 ARCANE_ASSERT((item.type() == IT_Tetraedron4), ("Bad item type: %d vs %d (Tetra4)", item.type(), IT_Tetraedron4));
398 const Cell cell = item.toCell();
399 for (Integer i = 0; i < 4; ++i) {
400 const Face face = cell.face(i);
401 area += math::abs(computeTriangleSurface(m_coords[face.node(0)],
402 m_coords[face.node(1)],
403 m_coords[face.node(2)]));
404 }
405}
406
407/*---------------------------------------------------------------------------*/
408
409void Euclidian3Geometry::ComputeGenericVolume::
410computeOrientedMeasureAndCenter(const ItemWithNodes& item, Real& measure, Real3& center)
411{
412 // Choice of an arbitrary star point, but "close" to the center
413 Real3 vcenter(0, 0, 0);
414 for (Integer i = 0; i < item.nbNode(); ++i) {
415 vcenter += m_coords[item.node(i)];
416 }
417 vcenter /= item.nbNode();
418
419 Real volume = 0;
420 center = Real3(0, 0, 0);
421
422 // Starring the faces and then the volume into tetrahedrons
423 const Cell cell = item.toCell();
424 for (Integer i = 0; i < cell.nbFace(); ++i) {
425 const Face face = cell.face(i);
426 const Real orientation = (face.frontCell() == cell) ? 1 : -1;
427
428 if (face.nbNode() == 3) {
429 Real v = orientation * computeTetraedronVolume(m_coords[face.node(0)], m_coords[face.node(1)], m_coords[face.node(2)], vcenter);
430 center += v * computeTetraedronCenter(m_coords[face.node(0)], m_coords[face.node(1)], m_coords[face.node(2)], vcenter);
431 volume += v;
432 }
433 else if (face.nbNode() == 4) {
434 // The array contains the modulo ...
435 const Real3 coords[5] = { m_coords[face.node(0)],
436 m_coords[face.node(1)],
437 m_coords[face.node(2)],
438 m_coords[face.node(3)],
439 m_coords[face.node(0)] };
440 const Real3 fcenter = computeQuadrilateralCenter(coords[0], coords[1], coords[2], coords[3]);
441 for (Integer j = 0; j < 4; ++j) {
442 const Real v = orientation * computeTetraedronVolume(coords[j], coords[j + 1], fcenter, vcenter);
443 center += v * computeTetraedronCenter(coords[j], coords[j + 1], fcenter, vcenter);
444 volume += v;
445 }
446 }
447 else {
448 throw NotImplementedException(A_FUNCINFO, "Not implemented for face with more than 4 nodes");
449 }
450 }
451
452 center /= volume;
453 measure = volume;
454}
455
456/*---------------------------------------------------------------------------*/
457
458void Euclidian3Geometry::ComputeGenericVolume::
459computeVolumeArea(const ItemWithNodes& item, Real& area)
460{
461 const Cell cell = item.toCell();
462 for (Integer i = 0; i < cell.nbFace(); ++i) {
463 const Face face = cell.face(i);
464 if (face.nbNode() == 3) {
465 area += math::abs(computeTriangleSurface(m_coords[face.node(0)],
466 m_coords[face.node(1)],
467 m_coords[face.node(2)]));
468 }
469 else if (face.nbNode() == 4) {
470 area += math::abs(computeTriangleSurface(m_coords[item.node(0)],
471 m_coords[item.node(1)],
472 m_coords[item.node(2)])) +
473 math::abs(computeTriangleSurface(m_coords[item.node(0)],
474 m_coords[item.node(3)],
475 m_coords[item.node(3)]));
476 }
477 else {
478 throw NotImplementedException(A_FUNCINFO, "Not implemented for face with more than 4 nodes");
479 }
480 }
481}
482
483/*---------------------------------------------------------------------------*/
484/*---------------------------------------------------------------------------*/
485
486} // namespace Arcane::Numerics
487
488/*---------------------------------------------------------------------------*/
489/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
Face face(Int32 i) const
i-th face of the cell
Definition Item.h:1400
Int32 nbFace() const
Number of faces of the cell.
Definition Item.h:1397
Cell frontCell() const
Cell in front of the face (null cell if none).
Definition Item.h:1780
Mesh element based on nodes (Edge,Face,Cell).
Definition Item.h:773
Node node(Int32 i) const
i-th node of the entity
Definition Item.h:840
Int32 nbNode() const
Number of nodes of the entity.
Definition Item.h:837
Cell toCell() const
Converts the entity to the Cell kind.
Definition Item.h:1830
Int16 type() const
Entity type.
Definition Item.h:255
Real3 computeCenter(const ItemWithNodes &item)
Calculation of the center of mass.
Real computeVolume(const ItemWithNodes &item)
Calculation of the volume.
Real3 computeSurfaceCenter(Integer n, const Real3 *coords)
Calculation of the center.
Real3 computeOrientedArea(Integer n, const Real3 *coords)
Calculation of the oriented area (i.e., normal).
Real3 computeOrientedMeasure(const ItemWithNodes &item)
Calculation of the oriented measure.
Real computeArea(const ItemWithNodes &item)
Calculation of the area.
Real computeLength(const ItemWithNodes &item)
Calculation of the length.
Real computeMeasure(const ItemWithNodes &item)
Calculation of the measure (without orientation).
Class managing a 3-dimensional real vector.
Definition Real3.h:132
__host__ __device__ Real scaMul(Real2 u, Real2 v)
Dot product of u by v in .
Definition MathUtils.h:112
__host__ __device__ double sqrt(double v)
Square root of v.
Definition Math.h:142
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.
double Real
Type representing a real number.
@ Cell
The mesh is AMR by cell.
Definition MeshKind.h:53