Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
SodStandardGroupsBuilder.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/* SodStandardGroupsBuilder.cc (C) 2000-2025 */
9/* */
10/* Creation of groups for Sod shock tube test cases. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/internal/SodStandardGroupsBuilder.h"
15
16#include "arcane/utils/ArrayView.h"
17#include "arcane/utils/Real3.h"
18
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IItemFamily.h"
21#include "arcane/core/Item.h"
22#include "arcane/core/ItemPrinter.h"
24#include "arcane/core/MeshVariable.h"
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35void SodStandardGroupsBuilder::
36_createFaceGroup(IMesh* mesh, const String& name, Int32ConstArrayView faces_lid)
37{
38 info() << "Creation group de face '" << name << "'"
39 << " size=" << faces_lid.size();
40
41 IItemFamily* face_family = mesh->faceFamily();
42 if (arcaneIsDebug()) {
43 FaceInfoListView mesh_faces(face_family);
44 VariableNodeReal3& var_nodes(mesh->nodesCoordinates());
45 for (Integer z = 0, zs = faces_lid.size(); z < zs; ++z) {
46 Face face(mesh_faces[faces_lid[z]]);
47 debug(Trace::High) << "Face " << ItemPrinter(face);
48 for (NodeLocalId inode : face.nodes())
49 debug(Trace::Highest) << "XYZ= " << var_nodes[inode];
50 }
51 }
52
53 face_family->createGroup(name, faces_lid);
54}
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
60generateGroups(IMesh* mesh, Real3 min_pos, Real3 max_pos, Real middle_x, Real middle_height, bool do_zg_and_zd)
61{
62 VariableNodeReal3& nodes_coord_var(mesh->nodesCoordinates());
63 Int32 mesh_dimension = mesh->dimension();
64
65 const Real min_x = min_pos.x;
66 const Real min_y = min_pos.y;
67 const Real min_z = min_pos.z;
68 const Real max_x = max_pos.x;
69 const Real max_y = max_pos.y;
70 const Real max_z = max_pos.z;
71 IItemFamily* cell_family = mesh->cellFamily();
72 info() << "Generate standard groups for SOD: "
73 << " min=" << min_pos << " max=" << max_pos
74 << " middle_x=" << middle_x << " middle_height=" << middle_height;
75
76 {
77 UniqueArray<Int32> xmin_surface_lid;
78 UniqueArray<Int32> xmax_surface_lid;
79 UniqueArray<Int32> ymin_surface_lid;
80 UniqueArray<Int32> ymax_surface_lid;
81 UniqueArray<Int32> zmin_surface_lid;
82 UniqueArray<Int32> zmax_surface_lid;
83
84 ENUMERATE_ (Face, iface, mesh->allFaces()) {
85 Face face = *iface;
86 Int32 face_local_id = face.localId();
87 bool is_xmin = true;
88 bool is_xmax = true;
89 bool is_ymin = true;
90 bool is_ymax = true;
91 bool is_zmin = true;
92 bool is_zmax = true;
93 //info() << "Face local id = " << face_local_id;
94 for (Node inode : face.nodes()) {
95 Real3 coord = nodes_coord_var[inode];
96 if (!math::isNearlyEqual(coord.x, min_x))
97 is_xmin = false;
98 if (!math::isNearlyEqual(coord.x, max_x))
99 is_xmax = false;
100
101 if (!math::isNearlyEqual(coord.y, min_y))
102 is_ymin = false;
103 if (!math::isNearlyEqual(coord.y, max_y))
104 is_ymax = false;
105
106 if (!math::isNearlyEqual(coord.z, min_z))
107 is_zmin = false;
108 if (!math::isNearlyEqual(coord.z, max_z))
109 is_zmax = false;
110 }
111 if (is_xmin)
112 xmin_surface_lid.add(face_local_id);
113 if (is_xmax)
114 xmax_surface_lid.add(face_local_id);
115 if (is_ymin)
116 ymin_surface_lid.add(face_local_id);
117 if (is_ymax)
118 ymax_surface_lid.add(face_local_id);
119 if (is_zmin)
120 zmin_surface_lid.add(face_local_id);
121 if (is_zmax)
122 zmax_surface_lid.add(face_local_id);
123 }
124 _createFaceGroup(mesh, "XMIN", xmin_surface_lid);
125 _createFaceGroup(mesh, "XMAX", xmax_surface_lid);
126 if (mesh_dimension >= 2) {
127 _createFaceGroup(mesh, "YMIN", ymin_surface_lid);
128 _createFaceGroup(mesh, "YMAX", ymax_surface_lid);
129 }
130 if (mesh_dimension == 3) {
131 _createFaceGroup(mesh, "ZMIN", zmin_surface_lid);
132 _createFaceGroup(mesh, "ZMAX", zmax_surface_lid);
133 }
134 }
135
136 // Determines the ZG and ZD layers
137 if (do_zg_and_zd) {
138 UniqueArray<Int32> zg_lid;
139 UniqueArray<Int32> zd_lid;
140 const Real xlimit = middle_x; // Position separating the two ZG and ZD zones
141 ENUMERATE_ (Cell, icell, mesh->allCells()) {
142 bool is_in_zd = false;
143 bool is_in_zg = false;
144 const Cell& cell = *icell;
145 Integer local_id = cell.localId();
146 for (Node inode : cell.nodes()) {
147 Real x = nodes_coord_var[inode].x;
148 if (math::isNearlyEqual(x, xlimit))
149 continue;
150 if (x > xlimit)
151 is_in_zd = true;
152 else
153 is_in_zg = true;
154 }
155 if (is_in_zg) {
156 if (is_in_zd) {
157 for (Node inode : cell.nodes()) {
158 Real x = nodes_coord_var[inode].x;
159 info() << " X=" << x;
160 if (math::isNearlyEqual(x, xlimit))
161 info() << " is equal to " << xlimit;
162 {
163 Real s = math::abs(x) + math::abs(xlimit);
164 Real d = x - xlimit;
165 Real r = d / s;
166 info() << " nearly s=" << s << " d=" << d << " r=" << r;
167 info() << " r<0.0=" << (r < 0.0) << " r>-e=" << (r > -FloatInfo<Real>::nearlyEpsilon())
168 << " r<e=" << (r < FloatInfo<Real>::nearlyEpsilon());
169 }
170 if (x > xlimit)
171 info() << " is in zd";
172 else
173 info() << " is in zg";
174 }
175 ARCANE_FATAL("SodGenerator: cell '{0}' is in both ZG and ZD", ItemPrinter(cell));
176 }
177 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZG";
178 zg_lid.add(local_id);
179 }
180 else {
181 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD";
182 zd_lid.add(local_id);
183 }
184 }
185 info() << "Create ZG with " << zg_lid.size() << " cells";
186 cell_family->createGroup("ZG", zg_lid);
187 info() << "Create ZD with " << zd_lid.size() << " cells";
188 cell_family->createGroup("ZD", zd_lid);
189 }
190
191 // Determines the ZD_HAUT and ZD_BAS groups
192 if (do_zg_and_zd) {
193 ItemGroup zdGroup = cell_family->findGroup("ZD");
194 if (zdGroup.null())
195 ARCANE_FATAL("Group 'ZD' has not been found!");
196 UniqueArray<Int32> zd_bas_lid;
197 UniqueArray<Int32> zd_haut_lid;
198 const Real height_limit = middle_height; // Position separating the two HAUT and BAS zones
199 ENUMERATE_CELL (icell, zdGroup) {
200 bool is_in_zd_bas = false;
201 bool is_in_zd_haut = false;
202 Cell cell = *icell;
203 Integer local_id = cell.localId();
204 for (Node inode : cell.nodes()) {
205 Real height = (mesh_dimension == 2) ? nodes_coord_var[inode].y : nodes_coord_var[inode].z;
206 //info()<< "\tcoords="<<nodes_coord_var[inode]<<", height="<<height<<" vs "<<height_limit;
207 if (math::isNearlyEqual(height, height_limit))
208 continue;
209 if (height > height_limit)
210 is_in_zd_haut = true;
211 else
212 is_in_zd_bas = true;
213 }
214 if (is_in_zd_bas) {
215 if (is_in_zd_haut)
216 fatal() << "SodGenerator: cell " << ItemPrinter(cell) << " in ZD_BAS and ZD_HAUT";
217 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD_BAS";
218 zd_bas_lid.add(local_id);
219 }
220 else {
221 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD_HAUT";
222 zd_haut_lid.add(local_id);
223 }
224 }
225 info() << "Create ZD_BAS with " << zd_bas_lid.size() << " cells";
226 cell_family->createGroup("ZD_BAS", zd_bas_lid);
227 info() << "Create ZD_HAUT with " << zd_haut_lid.size() << " cells";
228 cell_family->createGroup("ZD_HAUT", zd_haut_lid);
229 }
230}
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
235} // End namespace Arcane
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Types and macros for iterating over mesh entities.
#define ENUMERATE_(type, name, group)
Generic enumerator for an entity group.
#define ENUMERATE_CELL(name, group)
Generic enumerator for a cell group.
Integer size() const
Number of elements in the vector.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Cell of a mesh.
Definition Item.h:1300
Face of a cell.
Definition Item.h:1032
Information about the floating-point type.
Definition Limits.h:49
Interface of an entity family.
Definition IItemFamily.h:83
virtual ItemGroup findGroup(const String &name) const =0
Searches for a group.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Creates an entity group named name containing the entities local_ids.
Mesh entity group.
Definition ItemGroup.h:51
bool null() const
true means the group is the null group
Definition ItemGroup.h:75
Utility class for printing information about an entity.
Definition ItemPrinter.h:35
NodeConnectedListViewType nodes() const
List of nodes of the entity.
Definition Item.h:843
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
Node of a mesh.
Definition Item.h:598
Class managing a 3-dimensional real vector.
Definition Real3.h:132
void generateGroups(IMesh *mesh, Real3 min_pos, Real3 max_pos, Real middle_x, Real middle_height, bool do_zg_and_zd)
Creates the groups for initializing a Sod shock tube.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage fatal() const
Flow for a fatal error message.
TraceMessage info() const
Flow for an information message.
1D data vector with value semantics (STL style).
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
constexpr __host__ __device__ bool isNearlyEqual(const _Type &a, const _Type &b)
Tests if two values are approximately equal. For integer types, this function is equivalent to IsEqua...
Definition Numeric.h:219
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
bool arcaneIsDebug()
True if the ARCANE_DEBUG macro is defined.
Definition Misc.cc:76
double Real
Type representing a real number.
std::int32_t Int32
Signed integer type of 32 bits.
Real y
second component of the triplet
Definition Real3.h:36
Real z
third component of the triplet
Definition Real3.h:37
Real x
first component of the triplet
Definition Real3.h:35