Arcane  v4.1.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
SodStandardGroupsBuilder.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/* SodStandardGroupsBuilder.cc (C) 2000-2025 */
9/* */
10/* Création des groupes pour les cas test de tube à choc de Sod. */
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/IMesh.h"
20#include "arcane/IItemFamily.h"
21#include "arcane/Item.h"
22#include "arcane/ItemPrinter.h"
23#include "arcane/ItemEnumerator.h"
24#include "arcane/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 }
125 _createFaceGroup(mesh,"XMIN",xmin_surface_lid);
126 _createFaceGroup(mesh,"XMAX",xmax_surface_lid);
127 if (mesh_dimension>=2){
128 _createFaceGroup(mesh,"YMIN",ymin_surface_lid);
129 _createFaceGroup(mesh,"YMAX",ymax_surface_lid);
130 }
131 if (mesh_dimension==3){
132 _createFaceGroup(mesh,"ZMIN",zmin_surface_lid);
133 _createFaceGroup(mesh,"ZMAX",zmax_surface_lid);
134 }
135 }
136
137 // Détermine les couches ZG et ZD
138 if (do_zg_and_zd) {
139 UniqueArray<Int32> zg_lid;
140 UniqueArray<Int32> zd_lid;
141 const Real xlimit = middle_x; // Position séparant les deux zones ZG et ZD
142 ENUMERATE_ (Cell, icell, mesh->allCells()) {
143 bool is_in_zd = false;
144 bool is_in_zg = false;
145 const Cell& cell = *icell;
146 Integer local_id = cell.localId();
147 for( Node inode : cell.nodes() ){
148 Real x = nodes_coord_var[inode].x;
149 if (math::isNearlyEqual(x,xlimit))
150 continue;
151 if (x > xlimit)
152 is_in_zd = true;
153 else
154 is_in_zg = true;
155 }
156 if (is_in_zg){
157 if (is_in_zd){
158 for( Node inode : cell.nodes() ){
159 Real x = nodes_coord_var[inode].x;
160 info() << " X=" << x;
161 if (math::isNearlyEqual(x,xlimit))
162 info() << " is equal to " << xlimit;
163 {
164 Real s = math::abs(x) + math::abs(xlimit);
165 Real d = x - xlimit;
166 Real r = d/s;
167 info() << " nearly s=" << s << " d=" << d << " r=" << r;
168 info() << " r<0.0=" << (r<0.0) << " r>-e=" << (r>-FloatInfo<Real>::nearlyEpsilon())
169 << " r<e=" << (r<FloatInfo<Real>::nearlyEpsilon());
170 }
171 if (x > xlimit)
172 info() << " is in zd";
173 else
174 info() << " is in zg";
175 }
176 ARCANE_FATAL("SodGenerator: cell '{0}' is in both ZG and ZD",ItemPrinter(cell));
177 }
178 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZG";
179 zg_lid.add(local_id);
180 }
181 else{
182 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD";
183 zd_lid.add(local_id);
184 }
185 }
186 info() << "Create ZG with " << zg_lid.size() << " cells";
187 cell_family->createGroup("ZG",zg_lid);
188 info() << "Create ZD with " << zd_lid.size() << " cells";
189 cell_family->createGroup("ZD",zd_lid);
190 }
191
192 // Détermine les groupes ZD_HAUT et ZD_BAS
193 if (do_zg_and_zd) {
194 ItemGroup zdGroup = cell_family->findGroup("ZD");
195 if (zdGroup.null())
196 ARCANE_FATAL("Group 'ZD' has not been found!");
197 UniqueArray<Int32> zd_bas_lid;
198 UniqueArray<Int32> zd_haut_lid;
199 const Real height_limit = middle_height; // Position séparant les deux zones HAUT et BAS
200 ENUMERATE_CELL(icell, zdGroup){
201 bool is_in_zd_bas = false;
202 bool is_in_zd_haut = false;
203 Cell cell = *icell;
204 Integer local_id = cell.localId();
205 for( Node inode : cell.nodes() ){
206 Real height = (mesh_dimension==2)?nodes_coord_var[inode].y:nodes_coord_var[inode].z;
207 //info()<< "\tcoords="<<nodes_coord_var[inode]<<", height="<<height<<" vs "<<height_limit;
208 if (math::isNearlyEqual(height, height_limit))
209 continue;
210 if (height > height_limit)
211 is_in_zd_haut = true;
212 else
213 is_in_zd_bas = true;
214 }
215 if (is_in_zd_bas){
216 if (is_in_zd_haut)
217 fatal() << "SodGenerator: cell " << ItemPrinter(cell) << " in ZD_BAS and ZD_HAUT";
218 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD_BAS";
219 zd_bas_lid.add(local_id);
220 }
221 else{
222 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD_HAUT";
223 zd_haut_lid.add(local_id);
224 }
225 }
226 info() << "Create ZD_BAS with " << zd_bas_lid.size() << " cells";
227 cell_family->createGroup("ZD_BAS",zd_bas_lid);
228 info() << "Create ZD_HAUT with " << zd_haut_lid.size() << " cells";
229 cell_family->createGroup("ZD_HAUT",zd_haut_lid);
230 }
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
236} // End namespace Arcane
237
238/*---------------------------------------------------------------------------*/
239/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
Integer size() const
Nombre d'éléments du vecteur.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Maille d'un maillage.
Definition Item.h:1214
Face d'une maille.
Definition Item.h:964
Informations sur le type flottant.
Definition Limits.h:48
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual ItemGroup findGroup(const String &name) const =0
Recherche un groupe.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:34
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:794
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
Noeud d'un maillage.
Definition Item.h:582
Classe gérant un vecteur de réel de dimension 3.
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)
Créé les groupes pour un initialiser un tube à choc de sod.
Chaîne de caractères unicode.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
constexpr __host__ __device__ bool isNearlyEqual(const _Type &a, const _Type &b)
Teste si deux valeurs sont à un peu près égales. Pour les types entiers, cette fonction est équivalen...
Definition Numeric.h:212
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:498
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
Definition Misc.cc:80
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35