Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MicroHydroModule.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2#include "MicroHydroModule.h"
3
4#include <arcane/MathUtils.h>
5#include <arcane/IParallelMng.h>
6#include <arcane/ITimeLoopMng.h>
7
8using namespace Arcane;
9
10/*---------------------------------------------------------------------------*/
11/*---------------------------------------------------------------------------*/
12
14{
15 // Dimensionne les variables tableaux
16 m_cell_cqs.resize(8);
17
18 // Initialise le delta-t
19 Real deltat_init = options()->deltatInit();
20 m_global_deltat = deltat_init;
21
22 // Initialise les données géométriques: volume, cqs, longueurs caractéristiques
24
25 // Initialisation de la masses des mailles et des masses nodale
26 ENUMERATE_CELL(icell, allCells())
27 {
28 const Cell & cell = * icell;
29 m_cell_mass[icell] = m_density[icell] * m_cell_volume[icell];
30
31 Real contrib_node_mass = 0.125 * m_cell_mass[cell];
32 for (NodeEnumerator inode(cell.nodes()); inode.isEnd(); ++inode)
33 {
34 m_node_mass[inode] += contrib_node_mass;
35 }
36 }
37
38 m_node_mass.synchronize();
39
40 // Initialise l'énergie et la vitesse du son
41 // Compléter ici l'appel au service d'équation d'état
42}
43
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
49{
50 // Remise à zéro du vecteur des forces.
51 m_force.fill(Real3::null());
52
53 // Calcul pour chaque noeud de chaque maille la contribution
54 // des forces de pression
55 ENUMERATE_CELL(icell, allCells())
56 {
57 const Cell & cell = * icell;
58 Real pressure = m_pressure[icell];
59 for (NodeEnumerator inode(cell.nodes()); inode.isEnd(); ++inode)
60 m_force[inode] += pressure * m_cell_cqs[icell] [inode.index()];
61 }
62}
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
66
68{
69 // Calcule l'impulsion aux noeuds
70 ENUMERATE_NODE(inode, ownNodes())
71 {
72 Real node_mass = m_node_mass[inode];
73
74 Real3 old_velocity = m_velocity[inode];
75 Real3 new_velocity = old_velocity + (m_global_deltat() / node_mass) * m_force[inode];
76
77 m_velocity[inode] = new_velocity;
78 }
79
80 m_velocity.synchronize();
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
87{
88 for (Integer i = 0, nb = options()->boundaryCondition.size(); i < nb; ++i)
89 {
90 FaceGroup face_group = options()->boundaryCondition[i]->surface();
91 Real value = options()->boundaryCondition[i]->value();
92 TypesMicroHydro::eBoundaryCondition type = options()->boundaryCondition[i]->type();
93
94 // boucle sur les faces de la surface
95 ENUMERATE_FACE(j, face_group)
96 {
97 const Face & face = * j;
98 Integer nb_node = face.nbNode();
99
100 // boucle sur les noeuds de la face
101 for (Integer k = 0; k < nb_node; ++k)
102 {
103 const Node & node = face.node(k);
104 Real3 & velocity = m_velocity[node];
105
106 switch (type)
107 {
109 velocity.x = value;
110 break;
112 velocity.y = value;
113 break;
115 velocity.z = value;
116 break;
118 break;
119 }
120 }
121 }
122 }
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
129{
130 Real deltat = m_global_deltat();
131
132 ENUMERATE_NODE(inode, allNodes())
133 {
134 m_node_coord[inode] += deltat * m_velocity[inode];
135 }
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
142{
143 m_old_cell_volume.copy(m_cell_volume);
144
145 // Copie locale des coordonnées des sommets d'une maille
146 Real3 coord[8];
147 // Coordonnées des centres des faces
148 Real3 face_coord[6];
149
150 ENUMERATE_CELL(icell, allCells())
151 {
152 const Cell & cell = * icell;
153
154 // Recopie les coordonnées locales (pour le cache)
155 for (NodeEnumerator inode(cell.nodes()); inode.index() < 8; ++inode)
156 coord[inode.index()] = m_node_coord[inode];
157
158 // Calcul les coordonnées des centres des faces
159 face_coord[0] = 0.25 * (coord[0] + coord[3] + coord[2] + coord[1]);
160 face_coord[1] = 0.25 * (coord[0] + coord[4] + coord[7] + coord[3]);
161 face_coord[2] = 0.25 * (coord[0] + coord[1] + coord[5] + coord[4]);
162 face_coord[3] = 0.25 * (coord[4] + coord[5] + coord[6] + coord[7]);
163 face_coord[4] = 0.25 * (coord[1] + coord[2] + coord[6] + coord[5]);
164 face_coord[5] = 0.25 * (coord[2] + coord[3] + coord[7] + coord[6]);
165
166 // Calcule la longueur caractéristique de la maille.
167 {
168 Real3 median1 = face_coord[0] - face_coord[3];
169 Real3 median2 = face_coord[2] - face_coord[5];
170 Real3 median3 = face_coord[1] - face_coord[4];
171 Real d1 = median1.abs();
172 Real d2 = median2.abs();
173 Real d3 = median3.abs();
174
175 Real dx_numerator = d1 * d2 * d3;
176 Real dx_denominator = d1 * d2 + d1 * d3 + d2 * d3;
177 m_caracteristic_length[icell] = dx_numerator / dx_denominator;
178 }
179
180 // Calcule les résultantes aux sommets
181 computeCQs(coord, face_coord, cell);
182
183 // Calcule le volume de la maille
184 {
185 Real volume = 0.;
186 for (Integer inode = 0; inode < 8; ++inode)
187 volume += math::scaMul(coord[inode], m_cell_cqs[icell] [inode]);
188 volume /= 3.;
189
190 m_cell_volume[icell] = volume;
191 }
192
193 }
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198
200{
201 ENUMERATE_CELL(icell, ownCells())
202 {
203 Real old_density = m_density[icell];
204 Real new_density = m_cell_mass[icell] / m_cell_volume[icell];
205
206 m_density[icell] = new_density;
207 }
208
209 m_density.synchronize();
210}
211
212/*---------------------------------------------------------------------------*/
213/*---------------------------------------------------------------------------*/
214
216{
217 // Calcul de l'énergie interne
218 ENUMERATE_CELL(icell, allCells())
219 {
220 Real adiabatic_cst = m_adiabatic_cst[icell];
221 Real volume_ratio = m_cell_volume[icell] / m_old_cell_volume[icell];
222 Real x = 0.5 * (adiabatic_cst - 1.);
223 Real numer_accrois_nrj = 1. + x * (1. - volume_ratio);
224 Real denom_accrois_nrj = 1. + x * (1. - 1. / volume_ratio);
225
226 m_internal_energy[icell] *= numer_accrois_nrj / denom_accrois_nrj;
227 }
228
229 // Calcul de la pression et de la vitesse du son
230 // Compléter ici l'appel au service d'équation d'état
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
237{
238 const Real old_dt = m_global_deltat();
239
240 // Calcul du pas de temps pour le respect du critère de CFL
241
242 Real minimum_aux = float_info < Real >::maxValue();
243 Real new_dt = float_info < Real >::maxValue();
244
245 ENUMERATE_CELL(icell, ownCells())
246 {
247 Real cell_dx = m_caracteristic_length[icell];
248 Real density = m_density[icell];
249 Real pressure = m_pressure[icell];
250 Real sound_speed = m_sound_speed[icell];
251 Real dx_sound = cell_dx / sound_speed;
252 minimum_aux = math::min(minimum_aux, dx_sound);
253 }
254
255 new_dt = options()->cfl() * minimum_aux;
256
257 new_dt = parallelMng()->reduce(Parallel::ReduceMin, new_dt);
258
259 Real density_ratio_dt = new_dt;
260
261 // respect des valeurs min et max imposées par le fichier de données .plt
262 new_dt = math::min(new_dt, options()->deltatMax());
263 new_dt = math::max(new_dt, options()->deltatMin());
264
265 Real data_min_max_dt = new_dt;
266
267 // Le dernier calcul se fait exactement au temps stopTime()
268 Real stop_time = options()->finalTime();
269 bool not_yet_finish = (m_global_time() < stop_time);
270 bool too_much = ((m_global_time()+new_dt) > stop_time);
271
272 if ( not_yet_finish && too_much )
273 {
274 new_dt = stop_time - m_global_time();
275 subDomain()->timeLoopMng()->stopComputeLoop(true);
276 }
277
278 // Mise à jour du pas de temps
279 m_global_deltat = new_dt;
280}
281
282/*---------------------------------------------------------------------------*/
283/*---------------------------------------------------------------------------*/
284
285inline void MicroHydroModule::computeCQs(Real3 node_coord[8], Real3 face_coord[6], const Cell & cell)
286{
287 const Real3 c0 = face_coord[0];
288 const Real3 c1 = face_coord[1];
289 const Real3 c2 = face_coord[2];
290 const Real3 c3 = face_coord[3];
291 const Real3 c4 = face_coord[4];
292 const Real3 c5 = face_coord[5];
293
294 // Calcul des normales face 1 :
295 const Real3 n1a04 = 0.5 * math::vecMul(node_coord[0] - c0, node_coord[3] - c0);
296 const Real3 n1a03 = 0.5 * math::vecMul(node_coord[3] - c0, node_coord[2] - c0);
297 const Real3 n1a02 = 0.5 * math::vecMul(node_coord[2] - c0, node_coord[1] - c0);
298 const Real3 n1a01 = 0.5 * math::vecMul(node_coord[1] - c0, node_coord[0] - c0);
299
300 // Calcul des normales face 2 :
301 const Real3 n2a05 = 0.5 * math::vecMul(node_coord[0] - c1, node_coord[4] - c1);
302 const Real3 n2a12 = 0.5 * math::vecMul(node_coord[4] - c1, node_coord[7] - c1);
303 const Real3 n2a08 = 0.5 * math::vecMul(node_coord[7] - c1, node_coord[3] - c1);
304 const Real3 n2a04 = 0.5 * math::vecMul(node_coord[3] - c1, node_coord[0] - c1);
305
306 // Calcul des normales face 3 :
307 const Real3 n3a01 = 0.5 * math::vecMul(node_coord[0] - c2, node_coord[1] - c2);
308 const Real3 n3a06 = 0.5 * math::vecMul(node_coord[1] - c2, node_coord[5] - c2);
309 const Real3 n3a09 = 0.5 * math::vecMul(node_coord[5] - c2, node_coord[4] - c2);
310 const Real3 n3a05 = 0.5 * math::vecMul(node_coord[4] - c2, node_coord[0] - c2);
311
312 // Calcul des normales face 4 :
313 const Real3 n4a09 = 0.5 * math::vecMul(node_coord[4] - c3, node_coord[5] - c3);
314 const Real3 n4a10 = 0.5 * math::vecMul(node_coord[5] - c3, node_coord[6] - c3);
315 const Real3 n4a11 = 0.5 * math::vecMul(node_coord[6] - c3, node_coord[7] - c3);
316 const Real3 n4a12 = 0.5 * math::vecMul(node_coord[7] - c3, node_coord[4] - c3);
317
318 // Calcul des normales face 5 :
319 const Real3 n5a02 = 0.5 * math::vecMul(node_coord[1] - c4, node_coord[2] - c4);
320 const Real3 n5a07 = 0.5 * math::vecMul(node_coord[2] - c4, node_coord[6] - c4);
321 const Real3 n5a10 = 0.5 * math::vecMul(node_coord[6] - c4, node_coord[5] - c4);
322 const Real3 n5a06 = 0.5 * math::vecMul(node_coord[5] - c4, node_coord[1] - c4);
323
324 // Calcul des normales face 6 :
325 const Real3 n6a03 = 0.5 * math::vecMul(node_coord[2] - c5, node_coord[3] - c5);
326 const Real3 n6a08 = 0.5 * math::vecMul(node_coord[3] - c5, node_coord[7] - c5);
327 const Real3 n6a11 = 0.5 * math::vecMul(node_coord[7] - c5, node_coord[6] - c5);
328 const Real3 n6a07 = 0.5 * math::vecMul(node_coord[6] - c5, node_coord[2] - c5);
329
330 // Calcul des résultantes aux sommets :
331 m_cell_cqs[cell] [0] = (5. * (n1a01 + n1a04 + n2a04 + n2a05 + n3a05 + n3a01) +
332 (n1a02 + n1a03 + n2a08 + n2a12 + n3a06 + n3a09)) * (1. / 12.);
333 m_cell_cqs[cell] [1] = (5. * (n1a01 + n1a02 + n3a01 + n3a06 + n5a06 + n5a02) +
334 (n1a04 + n1a03 + n3a09 + n3a05 + n5a10 + n5a07)) * (1. / 12.);
335 m_cell_cqs[cell] [2] = (5. * (n1a02 + n1a03 + n5a07 + n5a02 + n6a07 + n6a03) +
336 (n1a01 + n1a04 + n5a06 + n5a10 + n6a11 + n6a08)) * (1. / 12.);
337 m_cell_cqs[cell] [3] = (5. * (n1a03 + n1a04 + n2a08 + n2a04 + n6a08 + n6a03) +
338 (n1a01 + n1a02 + n2a05 + n2a12 + n6a07 + n6a11)) * (1. / 12.);
339 m_cell_cqs[cell] [4] = (5. * (n2a05 + n2a12 + n3a05 + n3a09 + n4a09 + n4a12) +
340 (n2a08 + n2a04 + n3a01 + n3a06 + n4a10 + n4a11)) * (1. / 12.);
341 m_cell_cqs[cell] [5] = (5. * (n3a06 + n3a09 + n4a09 + n4a10 + n5a10 + n5a06) +
342 (n3a01 + n3a05 + n4a12 + n4a11 + n5a07 + n5a02)) * (1. / 12.);
343 m_cell_cqs[cell] [6] = (5. * (n4a11 + n4a10 + n5a10 + n5a07 + n6a07 + n6a11) +
344 (n4a12 + n4a09 + n5a06 + n5a02 + n6a03 + n6a08)) * (1. / 12.);
345 m_cell_cqs[cell] [7] = (5. * (n2a08 + n2a12 + n4a12 + n4a11 + n6a11 + n6a08) +
346 (n2a04 + n2a05 + n4a09 + n4a10 + n6a07 + n6a03)) * (1. / 12.);
347}
348
349/*---------------------------------------------------------------------------*/
350/*---------------------------------------------------------------------------*/
351
352ARCANE_REGISTER_MODULE_MICROHYDRO(MicroHydroModule);
#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.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
Maille d'un maillage.
Definition Item.h:1178
Face d'une maille.
Definition Item.h:932
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
Noeud d'un maillage.
Definition Dom.h:204
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
__host__ __device__ Real abs() const
Retourne la norme du triplet .
Definition Real3.h:238
virtual void updateDensity()
virtual void computeVelocity()
virtual void computeGeometricValues()
virtual void computeDeltaT()
virtual void applyBoundaryCondition()
virtual void hydroStartInit()
virtual void moveNodes()
virtual void applyEquationOfState()
virtual void computePressureForce()
ItemEnumeratorT< Node > NodeEnumerator
Enumérateurs sur des noeuds.
Definition ItemTypes.h:254
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
double Real
Type représentant un réel.
Int32 Integer
Type représentant un entier.
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
@ VelocityY
Vitesse Y fixée.
@ VelocityX
Vitesse X fixée.
@ VelocityZ
Vitesse Z fixée.
@ Unknown
Type inconnu.