Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
HyodaEnvs.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* HyodaEnvs.cc (C) 2000-2013 */
9/*---------------------------------------------------------------------------*/
10/*---------------------------------------------------------------------------*/
11#ifndef _HYODA_PLUGIN_ENVIRONMENTS_H_
12#define _HYODA_PLUGIN_ENVIRONMENTS_H_
13
14#include "arcane/IApplication.h"
15#include "arcane/IParallelMng.h"
16
17#include "arcane/AbstractService.h"
18#include "arcane/FactoryService.h"
19
20#include "arcane/IVariableMng.h"
21#include "arcane/SharedVariable.h"
22#include "arcane/CommonVariables.h"
23
24#include "arcane/IMesh.h"
25#include "arcane/IItemFamily.h"
26
27#include "arcane/materials/IMeshMaterialMng.h"
28#include "arcane/materials/IMeshMaterial.h"
29#include "arcane/materials/IMeshEnvironment.h"
30#include "arcane/materials/MeshMaterialModifier.h"
31#include "arcane/materials/MeshMaterialVariableRef.h"
32#include "arcane/materials/MaterialVariableBuildInfo.h"
33#include "arcane/materials/MeshEnvironmentBuildInfo.h"
34#include "arcane/materials/CellToAllEnvCellConverter.h"
35#include "arcane/materials/MatItemVector.h"
36
37#include "arcane/hyoda/Hyoda.h"
38#include "arcane/hyoda/HyodaArc.h"
39#include "arcane/hyoda/HyodaMix.h"
40#include "arcane/hyoda/HyodaIceT.h"
41#include "arcane/hyoda/IHyodaPlugin.h"
42
43//#include <GL/osmesa.h>
44#include "GL/glu.h"
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
49ARCANE_BEGIN_NAMESPACE
50class HyodaMix;
51using namespace Arcane;
52using namespace Arcane::Materials;
53
54// *****************************************************************************
55// * DEFINES
56// *****************************************************************************
57#define HYODA_MAX_ENV 2
58
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
63public:
64 // **************************************************************************
65 // * Arcane Service HyodaEnvs
66 // **************************************************************************
69 m_sub_domain(sbi.subDomain()),
70 m_default_mesh(m_sub_domain->defaultMesh()),
71 m_material_mng(IMeshMaterialMng::getReference(m_default_mesh)),
72 m_interface_normal(VariableBuildInfo(m_default_mesh,
73 "InterfaceNormal")),
74 m_interface_distance_env(VariableBuildInfo(m_default_mesh,
75 "InterfaceDistance2ForEnv",
76 IVariable::PNoDump|IVariable::PNoRestore))
77 {
78 info() << "Loading Hyoda's environments plugin";
79 info() << "Setting a maximum of " << HYODA_MAX_ENV << " environments";
80 }
81
82
83 // **************************************************************************
84 // * drawGlobalCell
85 // **************************************************************************
86 int drawGlobalCell(Cell cell, Real min, Real max, Real val){
87 Real3 rgb;
89 hyoda()->meshIceT()->setColor(min,max,val,rgb);
90 glColor3d(rgb[0], rgb[1], rgb[2]);
91 ENUMERATE_NODE(node, cell->nodes()){
92 glColor3d(rgb[0], rgb[1], rgb[2]);
93 glVertex2d(m_default_mesh->nodesCoordinates()[node].x,
94 m_default_mesh->nodesCoordinates()[node].y);
95 }
96 glEnd();
97 // On repasse pour dessiner les contours de la maille
99 glColor3d(0.0, 0.0, 0.0);
100 ENUMERATE_NODE(node, cell->nodes()){
101 glVertex2d(m_default_mesh->nodesCoordinates()[node].x,
102 m_default_mesh->nodesCoordinates()[node].y);
103 }
104 glEnd();
105 return 0;
106 }
107
108
109 // **************************************************************************
110 // * computeDistMinMax
111 // **************************************************************************
112 void computeDistMinMax(Cell cell, Real3 normal, Real &dist_min, Real &dist_max){
113 // Détermination de l'intervalle de recherche pour le Newton
114 dist_min = math::scaMul(m_default_mesh->nodesCoordinates()[cell.node(0)],normal);
115 dist_max =math::scaMul(m_default_mesh->nodesCoordinates()[cell.node(0)],normal);
116 const Integer& cell_nb_node=cell.nbNode();
117 for (Integer node_id = 0; node_id < cell_nb_node; ++node_id) {
118 const Node& node=cell.node(node_id);
119 Real dist = math::scaMul(m_default_mesh->nodesCoordinates()[node],normal);
120 if (dist < dist_min) dist_min = dist; // premier sommet d'une maille quelconque
121 if (dist > dist_max) dist_max = dist; // dernier sommet d'une maille quelconque
122 }
123 }
124
125
126 // **************************************************************************
127 // * draw
128 // **************************************************************************
129 int draw(IVariable *variable, Real global_min, Real global_max)
130 {
131 ARCANE_UNUSED(global_min);
132 ARCANE_UNUSED(global_max);
133 // On ne supporte pour l'instant que l'affichage pour des variables aux mailles
134 // Le test se fait au sein de HyodaMix::xLine2Cell
135 info()<<"\n\r\33[7m[HyodaEnvs::draw] Focusing on variable "<<variable->name()<< "\33[m";
138 VariableCellArrayInteger number_env(VariableBuildInfo(m_default_mesh,"NumberEnv"));
139 VariableCellInteger m_x_codes(VariableBuildInfo(m_default_mesh,"IntersectionCodes"));
140
141 // Calcul des min et max locaux aux envCells
142 debug()<<"\33[7m[HyodaEnvs::draw] Calcul des min et max locaux aux envCells\33[m";
143 Real local_min, local_max;
145 ENUMERATE_ALLENVCELL(iAllEnvCell, m_material_mng, m_default_mesh->allCells()){
146 AllEnvCell allEnvCell = *iAllEnvCell;
147 Cell cell=allEnvCell.globalCell();
148 for(int iEnvOrder=0, mx=allEnvCell.nbEnvironment(); iEnvOrder<mx; ++iEnvOrder){
149 Integer num_env = number_env[cell][iEnvOrder];
150 if (num_env==-1) continue;
152 EnvCell envCell = *iEnvCell;
153 if (num_env!=envCell.environmentId()) continue;
154 Real val=cell_variable[envCell];
155 local_min = math::min(local_min,val);
156 local_max = math::max(local_max,val);
157 break;
158 } // ENUMERATE_CELL_ENVCELL
159 } // for
160 } // ENUMERATE_ALLENVCELL
161 local_min=m_sub_domain->parallelMng()->reduce(Parallel::ReduceMin, local_min);
162 local_max=m_sub_domain->parallelMng()->reduce(Parallel::ReduceMax, local_max);
163
164
165 debug()<<"\33[7m[HyodaEnvs::draw] ENUMERATE_ALLENVCELL\33[m";
166 ENUMERATE_ALLENVCELL(iAllEnvCell, m_material_mng, m_default_mesh->allCells()){
167 AllEnvCell allEnvCell = *iAllEnvCell;
168 Cell cell=allEnvCell.globalCell();
169 Real3 normal = m_interface_normal[cell];
171
172 // Si c'est pas initialisé, on se retrouve avec normal=(0,0,0)
173 if (normal.abs()==0.) continue;
174 info()<<"\n\r\33[7m[HyodaEnvs::draw] #"<<cell.uniqueId()<<", normal="<<normal << "\33[m";
175
176 // On a qu'une seule origine par maille, on la calcule
177 hyodaMix()->setCellOrigin(cell);
178 m_x_codes[cell]=0;
179 Real dist_min, dist_max;
180
181 // On calcule les distance min et max pour être dans la maille
182 computeDistMinMax(cell,normal,dist_min,dist_max);
183
184 // On compte le nombre de milieux
185 Int32 nbMilieux=0;
187
188 // On compte le nombre de milieux trouvés à partir des number_env
189 Int32 nbNumberedMilieux=0;
190 for(int iEnvOrder=0, mx=allEnvCell.nbEnvironment(); iEnvOrder<mx; ++iEnvOrder){
191 Integer num_env = number_env[cell][iEnvOrder];
192 if (num_env==-1) continue;
194 }
195
196 // On compte le nombre de milieux trouvés à partir des order_env
197 Int32 nbOrderedMilieux=0;
199 Integer ord_env = order_env[iEnvCell];
200 if (ord_env==-1) continue;
201 if (ord_env > HYODA_MAX_ENV)
202 warning() << "\33[7m[HyodaEnvs::draw] #"<<cell.uniqueId()
203 << ": while counting nbOrderedMilieux, ord_env="
204 << ord_env << " > " << HYODA_MAX_ENV << "\33[m";
205 if (ord_env > HYODA_MAX_ENV) continue;
207 }
208
209
210 // Focus sur une maille
211 //if (cell.uniqueId()==49){
212 {
213 //info()<< "\n\33[7m[HyodaEnvs::draw] Cell "<<cell.uniqueId()<<"\33[m";
214 //info()<< "[HyodaEnvs::draw] nbMilieux " << nbMilieux;
215 //info()<< "[HyodaEnvs::draw] nbNumberedMilieux "<< nbNumberedMilieux;
216 //info()<< "[HyodaEnvs::draw] nbOrderedMilieux " << nbOrderedMilieux;
217 /*ENUMERATE_CELL_ENVCELL(iEnvCell,allEnvCell){
218 Integer ord_env = order_env[iEnvCell];
219 if (ord_env>nbMilieux){
220 warning()<<"ord_env="<<ord_env<<" > nbMilieux="<<nbMilieux;
221 ord_env=nbMilieux-1;
222 //if (nbMilieux==1) ord_env=0; else fatal()<<"Cannot fix ord_env>nbMilieux";
223 }
224 info()<<"\t[HyodaEnvs::draw] ord_env="<<ord_env;
225 info()<<"\t[HyodaEnvs::draw] number_env[cell][ord_env]="<<number_env[cell][ord_env];
226 }*/
227 }
228
229 Int32 iMilieux=0;
230 for(int iEnvOrder=0, mx=allEnvCell.nbEnvironment(); iEnvOrder<mx; ++iEnvOrder){
231 Integer num_env = number_env[cell][iEnvOrder];
232 if (num_env==-1) continue;
233 Real its_distance=m_interface_distance_env[cell][num_env];
234 info() << "[HyodaEnvs::draw] num_env=" << num_env << ", its distance=" << its_distance;
235 if (its_distance < dist_min) warning()<<"its_distance < dist_min";
236 if (its_distance > dist_max) warning()<<"its_distance > dist_max";
237 // Il faut faire le xCellPoints pour setter les x[i]
238 Int32 xPts=hyodaMix()->xCellPoints(cell, normal, its_distance, /*order=*/iMilieux);
239 // Il faut traiter le cas < dist_min: on set le code à 0x0
240 if (its_distance < dist_min) xPts=0x0;
241 // Il faut traiter le cas > dist_max: on set le code à 0xF
242 if (its_distance > dist_max) xPts=0xF;
243 // Cas où on a qu'un seul milieu
244 if (nbNumberedMilieux==1) xPts=0xF;
245 info() << "\t\33[7m[HyodaEnvs::draw] xPts["<<iEnvOrder<<"]="<<xPts<< "\33[m";
246 // Dans tous les cas, on l'ajoute pour pouvoir faire la distinction apres entre les x[i[0~11]]
247 // On sauve les codes
248 m_x_codes[cell]|=xPts<<(iMilieux<<2);
249 xCodes.add(xPts);
250 //if ((xPts!=0) && (xPts!=0xF)) hyodaMix()->xCellDrawNormal(cell, iOrg, its_distance);
251 // On doit incrémenter iMilieux, c'est lui qui nous permet de trouver les bons x[i]
252 iMilieux+=1;
253 }
254
255 //if (cell.uniqueId()==49)
256 //info() << "[HyodaEnvs::draw] \33[7m#" << cell.uniqueId() << "\t" << xCodes<< "\33[m";
257 //<< ", m_x_codes[this]=" << m_x_codes[cell] << "\33[m";
258
259 // Pour chaque milieu, on revient pour remplir dans l'ordre
260 // On fait dans ce sens (for, ENUMERATE_CELL_ENVCELL & break) pour éviter de jouer
261 // avec order_env qui a tendance à être > nbMilieux
262 // Mais dans ce sens, il y a des cas où l'on obtient pas (iMilieux==nbMilieux)
263 // du fait de la non correspondance des number_env et environmentId()
264 iMilieux=0;
265 for(int iEnvOrder=0, mx=allEnvCell.nbEnvironment(); iEnvOrder<mx; ++iEnvOrder){
266 Integer hit_env=-1;
267 Integer num_env = number_env[cell][iEnvOrder];
268 if (num_env==-1) continue;
269 debug()<<"\t[HyodaEnvs::draw] Looking for num_env="<<num_env;
270 // On déclenche les remplissage
272 EnvCell envCell = *iEnvCell;
273 //if (cell.uniqueId()==49)
274 debug()<<"\t\t[HyodaEnvs::draw] envCell.environmentId()="<<envCell.environmentId();
275 if (num_env!=envCell.environmentId()) continue;
276 //if (cell.uniqueId()==49){
277 {
278 debug() << "\t\t[HyodaEnvs::draw] \33[7m"
279 << iMilieux << "/" << (nbNumberedMilieux-1)
280 << " val=" << cell_variable[envCell] << "\33[m";
281 debug()<<"\t\t[HyodaEnvs::draw] iMilieux="<<iMilieux;
282 }
283 hyodaMix()->xCellFill(cell, xCodes,
285 cell_variable[envCell],
286 /*order=*/iMilieux,
288 // On dit que l'on a hité le bon environment
290 iMilieux+=1;
291 // On break car on a trouvé notre bonne envCell
292 break;
293 } // ENUMERATE_CELL_ENVCELL
294 // Si on a pas trouvé le bon environment, on break pour essayer l'autre methode
295 if (hit_env!=num_env){
296 warning()<< "\33[7m[HyodaEnvs::draw] #"<<cell.uniqueId()
297 <<": Environement "<<num_env<<" non trouvé dans les milieux!\33[m";
298 break;
299 }
300 } // for
301
302 // Si on a pas réussi à tout dessiner, on revient en passant par les order_env
303 // en esperant ne pas tomber sur les cas où les orders sont > HYODA_MAX_ENV
304 // Cas i23.plt à l'iteration 186
306 warning()<< "\33[7m[HyodaEnvs::draw] #"<<cell.uniqueId()
307 <<": tous les milieux n'ont pas été dessinés!\33[m";
308 Integer iOrderedMilieux=0;
309 Integer iPatchOffset=0;
311 EnvCell envCell = *ienvcell;
312 Integer order = order_env[ienvcell];
313 if (order == -1 ) continue;
314 if (order > HYODA_MAX_ENV){
315 warning() << "\33[7m[HyodaEnvs::draw] #"<<cell.uniqueId()
316 <<": order_env > "<<HYODA_MAX_ENV<<"\33[m";
317 continue;
318 }
319 if (order>=nbOrderedMilieux){
320 warning() << "\33[7m[HyodaEnvs::draw] #"<<cell.uniqueId()
321 << ": En redessinant via order_env, le milieu "<<order
322 << " est réclamé, alors qu'on en a "<<nbOrderedMilieux<<"\33[m";
323 warning() << "\33[7m[HyodaEnvs::draw] #"<<cell.uniqueId()
324 << ": On tente de patcher l'offset\33[m";
325 iPatchOffset=1;
326 }
327 // On vérifie qu'on ne tombe pas négatif
328 if (order<iPatchOffset) continue;
329 hyodaMix()->xCellFill(cell, xCodes,
331 cell_variable[envCell],
332 order-iPatchOffset,
335 }
336 // Cette fois ci, on ne peut plus rien faire
338 warning() << "\33[7m[HyodaEnvs::draw] #"<<cell.uniqueId()
339 << ": Même via les order_env, les milieux n'ont pas tous été dessinés\33[m";
340 }
341
342 } // ENUMERATE_ALLENVCELL
343 return 0;
344 }
345
346
347 private:
348 ISubDomain *m_sub_domain;
349 IMesh* m_default_mesh;
350 IMeshMaterialMng *m_material_mng ;
351 VariableCellReal3 m_interface_normal;
352 VariableCellArrayReal m_interface_distance_env;
353 };
354
355
357
358/*---------------------------------------------------------------------------*/
359/*---------------------------------------------------------------------------*/
360
361ARCANE_END_NAMESPACE
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
366#endif // _HYODA_PLUGIN_ENVIRONMENTS_H_
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Classe de base d'un service.
Maille d'un maillage.
Definition Item.h:1178
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Interface d'une variable.
Definition IVariable.h:54
virtual String name() const =0
Nom de la variable.
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:768
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:771
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:765
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Maille arcane avec info matériaux et milieux.
ARCCORE_HOST_DEVICE Int32 nbEnvironment() const
Nombre de milieux présents dans la maille.
Maille arcane d'un milieu.
ARCCORE_HOST_DEVICE Int32 environmentId() const
Identifiant du milieu.
Interface du gestionnaire des matériaux et des milieux d'un maillage.
Noeud d'un maillage.
Definition Dom.h:204
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
ARCCORE_HOST_DEVICE Real abs() const
Retourne la norme du triplet .
Definition Real3.h:238
Structure contenant les informations pour créer un service.
Paramètres nécessaires à la construction d'une variable.
Vecteur 1D de données avec sémantique par valeur (style STL).
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro pour itérer sur tous les milieux d'une maille.
#define ENUMERATE_ALLENVCELL(iname,...)
Macro pour itérer sur toutes les mailles AllEnvCell d'un groupe.
Active toujours les traces dans les parties Arcane concernant les matériaux.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-