Arcane  v3.14.10.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-2023 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-2023 */
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
59void SodStandardGroupsBuilder::
60generateGroups(IMesh* mesh,Real3 min_pos,Real3 max_pos,Real middle_x,Real middle_height)
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 Int32UniqueArray xmin_surface_lid;
78 Int32UniqueArray xmax_surface_lid;
79 Int32UniqueArray ymin_surface_lid;
80 Int32UniqueArray ymax_surface_lid;
81 Int32UniqueArray zmin_surface_lid;
82 Int32UniqueArray zmax_surface_lid;
83
84 ENUMERATE_FACE(iface,mesh->allFaces()){
85 Face face = *iface;
86 Integer 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 {
139 Int32UniqueArray zg_lid;
140 Int32UniqueArray zd_lid;
141 const Real xlimit = middle_x; // Position séparant les deux zones ZG et ZD
142 ENUMERATE_CELL(icell,mesh->allCells()){
143 //Real xpos = 0.;
144 bool is_in_zd = false;
145 bool is_in_zg = false;
146 const Cell& cell = *icell;
147 Integer local_id = cell.localId();
148 for( Node inode : cell.nodes() ){
149 Real x = nodes_coord_var[inode].x;
150 if (math::isNearlyEqual(x,xlimit))
151 continue;
152 if (x > xlimit)
153 is_in_zd = true;
154 else
155 is_in_zg = true;
156 }
157 if (is_in_zg){
158 if (is_in_zd){
159 for( Node inode : cell.nodes() ){
160 Real x = nodes_coord_var[inode].x;
161 info() << " X=" << x;
162 if (math::isNearlyEqual(x,xlimit))
163 info() << " is equal to " << xlimit;
164 {
165 Real s = math::abs(x) + math::abs(xlimit);
166 Real d = x - xlimit;
167 Real r = d/s;
168 info() << " nearly s=" << s << " d=" << d << " r=" << r;
169 info() << " r<0.0=" << (r<0.0) << " r>-e=" << (r>-FloatInfo<Real>::nearlyEpsilon())
170 << " r<e=" << (r<FloatInfo<Real>::nearlyEpsilon());
171 }
172 if (x > xlimit)
173 info() << " is in zd";
174 else
175 info() << " is in zg";
176 }
177 ARCANE_FATAL("SodGenerator: cell '{0}' is in both ZG and ZD",ItemPrinter(cell));
178 }
179 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZG";
180 zg_lid.add(local_id);
181 }
182 else{
183 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD";
184 zd_lid.add(local_id);
185 }
186 }
187 info() << "Create ZG with " << zg_lid.size() << " cells";
188 cell_family->createGroup("ZG",zg_lid);
189 info() << "Create ZD with " << zd_lid.size() << " cells";
190 cell_family->createGroup("ZD",zd_lid);
191 }
192
193 // Détermine les groupes ZD_HAUT et ZD_BAS
194 {
195 ItemGroup zdGroup = cell_family->findGroup("ZD");
196 if (zdGroup.null())
197 fatal()<<"zdGroup has not been found!";
198 Int32UniqueArray zd_bas_lid;
199 Int32UniqueArray zd_haut_lid;
200 const Real height_limit = middle_height; // Position séparant les deux zones HAUT et BAS
201 ENUMERATE_CELL(icell, zdGroup){
202 bool is_in_zd_bas = false;
203 bool is_in_zd_haut = false;
204 Cell cell = *icell;
205 Integer local_id = cell.localId();
206 for( Node inode : cell.nodes() ){
207 Real height = (mesh_dimension==2)?nodes_coord_var[inode].y:nodes_coord_var[inode].z;
208 //info()<< "\tcoords="<<nodes_coord_var[inode]<<", height="<<height<<" vs "<<height_limit;
209 if (math::isNearlyEqual(height, height_limit))
210 continue;
211 if (height > height_limit)
212 is_in_zd_haut = true;
213 else
214 is_in_zd_bas = true;
215 }
216 if (is_in_zd_bas){
217 if (is_in_zd_haut)
218 fatal() << "SodGenerator: cell " << ItemPrinter(cell) << " in ZD_BAS and ZD_HAUT";
219 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD_BAS";
220 zd_bas_lid.add(local_id);
221 }
222 else{
223 debug(Trace::High) << "Add Cell " << ItemPrinter(cell) << " to ZD_HAUT";
224 zd_haut_lid.add(local_id);
225 }
226 }
227 info() << "Create ZD_BAS with " << zd_bas_lid.size() << " cells";
228 cell_family->createGroup("ZD_BAS",zd_bas_lid);
229 info() << "Create ZD_HAUT with " << zd_haut_lid.size() << " cells";
230 cell_family->createGroup("ZD_HAUT",zd_haut_lid);
231 }
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
237} // End namespace Arcane
238
239/*---------------------------------------------------------------------------*/
240/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
constexpr ARCCORE_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 -*-
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
Definition Misc.cc:163
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
Namespace contenant les types liés aux traces.
Int32 Integer
Type représentant un entier.