14#include "arcane/utils/FatalErrorException.h"
16#include "arcane/core/ITimeLoopMng.h"
17#include "arcane/core/ITimeLoopService.h"
18#include "arcane/core/ITimeLoop.h"
19#include "arcane/core/TimeLoopEntryPointInfo.h"
20#include "arcane/core/MeshAreaAccessor.h"
21#include "arcane/core/MeshArea.h"
22#include "arcane/core/ISubDomain.h"
23#include "arcane/core/IMesh.h"
25#include "arcane/cartesianmesh/ICartesianMesh.h"
26#include "arcane/cartesianmesh/CellDirectionMng.h"
27#include "arcane/cartesianmesh/NodeDirectionMng.h"
29#include "arcane/accelerator/core/Runner.h"
30#include "arcane/accelerator/core/IAcceleratorMng.h"
35#include "arcane/tests/AdiProjection_axl.h"
46class AdiProjectionModule
47:
public ArcaneAdiProjectionObject
52 ~AdiProjectionModule();
60 void copyEulerianCoordinates();
61 void cartesianHydroMain();
62 virtual void cartesianHydroStartInit();
74 void evolvePrimalUpwindedVariables(
Integer direction);
75 void evolveDualUpwindedVariables(
Integer direction);
76 void computePressure();
77 void computePressureGradient(
Integer direction);
78 void checkNodalMassConservation();
79 void copyCurrentVariablesToOldVariables();
81 void computePrimalMassFluxInner(
Integer direction);
83 void computeDualMassFluxInner(
Integer direction);
84 void prepareLagrangianVariables();
85 void checkLagrangianVariablesConsistency();
87 void _evolveDualUpwindedVariables1();
88 void _evolvePrimalUpwindedVariablesV2(
Integer direction);
93 void computePrimalMassFluxBoundary(
Integer direction);
94 void computeDualMassFluxBoundary(
Integer direction);
107: ArcaneAdiProjectionObject(mb)
115~AdiProjectionModule()
122void AdiProjectionModule::
123copyCurrentVariablesToOldVariables()
127 m_old_density[current_cell] = m_density[current_cell];
132 m_old_velocity[current_node] = m_velocity[current_node];
139void AdiProjectionModule::
140prepareLagrangianVariables()
145 m_lagrangian_coordinates.copy(nodes_coord);
150 m_lagrangian_velocity[inode] = 0.5 * (m_old_velocity[inode] + m_velocity[inode]);
157void AdiProjectionModule::
158checkLagrangianVariablesConsistency()
167 info() <<
"Test de coherence vitesses lagrangiennes/positions lagrangiennes : residu="
176void AdiProjectionModule::
177computePrimalMassFluxInner(
Integer direction)
179 ARCANE_UNUSED(direction);
185void AdiProjectionModule::
186computePrimalMassFluxBoundary(
Integer direction)
188 info() << A_FUNCINFO;
190 auto queue =
makeQueue(acceleratorMng()->defaultRunner());
193 auto inout_mass_flux_right =
viewInOut(command, m_mass_flux_right);
194 auto inout_mass_flux_left =
viewInOut(command, m_mass_flux_left);
196 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(direction));
202 DirCellLocalId cc(cdm.dirCellId(current_cell));
204 CellLocalId right_cell = cc.next();
205 CellLocalId left_cell = cc.previous();
207 if (left_cell.isNull()) {
210 inout_mass_flux_right[current_cell] = inout_mass_flux_left[right_cell];
211 inout_mass_flux_left[current_cell] = inout_mass_flux_right[current_cell];
213 else if (right_cell.isNull()) {
216 inout_mass_flux_left[current_cell] = inout_mass_flux_right[left_cell];
217 inout_mass_flux_right[current_cell] = inout_mass_flux_left[current_cell];
225void AdiProjectionModule::
226computeDualMassFluxInner(
Integer direction)
228 ARCANE_UNUSED(direction);
234void AdiProjectionModule::
235computeDualMassFluxBoundary(
Integer direction)
237 NodeDirectionMng ndm(m_cartesian_mesh->nodeDirection(direction));
239 auto queue =
makeQueue(acceleratorMng()->defaultRunner());
242 auto inout_nodal_mass_flux_right =
viewInOut(command, m_nodal_mass_flux_right);
243 auto inout_nodal_mass_flux_left =
viewInOut(command, m_nodal_mass_flux_left);
249 DirNodeLocalId cc(ndm.dirNodeId(current_node));
251 NodeLocalId right_node = cc.next();
252 NodeLocalId left_node = cc.previous();
254 if (left_node.isNull()) {
257 inout_nodal_mass_flux_left[current_node] = inout_nodal_mass_flux_left[right_node];
258 inout_nodal_mass_flux_right[current_node] = inout_nodal_mass_flux_right[right_node];
260 else if (right_node.isNull()) {
263 inout_nodal_mass_flux_left[current_node] = inout_nodal_mass_flux_left[left_node];
264 inout_nodal_mass_flux_right[current_node] = inout_nodal_mass_flux_right[left_node];
273void AdiProjectionModule::
274evolvePrimalUpwindedVariables(
Integer direction)
277 _evolvePrimalUpwindedVariablesV2(direction);
281 const Real time_step = m_global_deltat();
282 const Real dx = 0.005;
284 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(direction));
291 DirCell cc(cdm.cell(*current_cell));
293 CellLocalId right_cell = cc.next();
294 CellLocalId left_cell = cc.previous();
299 DirCellNode cn(cdm.cellNode(*current_cell));
303 const Real3 left_face_velocity = m_lagrangian_velocity[cn.previousLeft()];
304 const Real left_face_velocity_dir = left_face_velocity.x;
306 const Real3 right_face_velocity = m_lagrangian_velocity[cn.nextLeft()];
307 const Real right_face_velocity_dir = right_face_velocity.x;
310 const Real sign_left = (left_face_velocity_dir > 0.0 ? 1.0 : -1.0);
311 const Real sign_right = (right_face_velocity_dir > 0.0 ? 1.0 : -1.0);
313 Real m_nrj_left_cell = m_nrj[left_cell];
314 Real m_nrj_right_cell = m_nrj[right_cell];
315 Real m_nrj_current_cell = m_nrj[current_cell];
317 const Real dmass_left = 0.5 * left_face_velocity_dir *
318 ((m_density[current_cell] + m_density[left_cell]) -
319 sign_left * (m_density[current_cell] - m_density[left_cell]));
321 const Real dmass_right = 0.5 * right_face_velocity_dir *
322 ((m_density[right_cell] + m_density[current_cell]) -
323 sign_right * (m_density[right_cell] - m_density[current_cell]));
325 m_mass_flux_left[current_cell] = dmass_left;
326 m_mass_flux_right[current_cell] = dmass_right;
328 m_density[current_cell] =
329 m_density[current_cell] - time_step * (dmass_right - dmass_left) / dx;
332 const Real nrj_left = 0.5 *
333 ((m_nrj_current_cell + m_nrj_left_cell) -
334 sign_left * (m_nrj_current_cell - m_nrj_left_cell));
336 const Real nrj_right = 0.5 *
337 ((m_nrj_right_cell + m_nrj_current_cell) -
338 sign_right * (m_nrj_right_cell - m_nrj_current_cell));
340 Real nrj_current_cell = m_old_density[current_cell] * m_nrj_current_cell -
341 time_step * (nrj_right * dmass_right - nrj_left * dmass_left) / dx;
344 nrj_current_cell = nrj_current_cell -
345 time_step * m_pressure[current_cell] * (right_face_velocity_dir - left_face_velocity_dir) / dx;
347 if (m_density[current_cell] != 0.0) {
349 nrj_current_cell /= m_density[current_cell];
353 info() <<
"Erreur, densite nulle.\n";
356 m_nrj[current_cell] = nrj_current_cell;
359 computePrimalMassFluxBoundary(direction);
366void AdiProjectionModule::
367_evolvePrimalUpwindedVariablesV2(
Integer direction)
370 const Real time_step = m_global_deltat();
371 const Real dx = 0.005;
373 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(direction));
385 DirCell cc(cdm.cell(*i_current_cell));
387 Cell right_cell_c = cc.next();
388 Cell left_cell_c = cc.previous();
390 CellLocalId current_cell = *i_current_cell;
391 Cell right_cell = right_cell_c;
392 Cell left_cell = left_cell_c;
395 DirCellNode cn(cdm.cellNode(*i_current_cell));
397 Real nrj_left_cell = nrj[left_cell];
398 Real nrj_right_cell = nrj[right_cell];
399 Real nrj_current_cell = nrj[current_cell];
403 const Real3 left_face_velocity = m_lagrangian_velocity[cn.previousLeft()];
404 const Real left_face_velocity_dir = left_face_velocity.x;
406 const Real3 right_face_velocity = m_lagrangian_velocity[cn.nextLeft()];
407 const Real right_face_velocity_dir = right_face_velocity.x;
410 const Real sign_left = (left_face_velocity_dir > 0.0 ? 1.0 : -1.0);
411 const Real sign_right = (right_face_velocity_dir > 0.0 ? 1.0 : -1.0);
413 const Real dmass_left = 0.5 * left_face_velocity_dir *
414 ((density[current_cell] + density[left_cell]) -
415 sign_left * (density[current_cell] - density[left_cell]));
417 const Real dmass_right = 0.5 * right_face_velocity_dir *
418 ((density[right_cell] + density[current_cell]) -
419 sign_right * (density[right_cell] - density[current_cell]));
421 m_mass_flux_left[i_current_cell] = dmass_left;
422 m_mass_flux_right[i_current_cell] = dmass_right;
424 density[current_cell] = density[current_cell] - time_step * (dmass_right - dmass_left) / dx;
427 const Real nrj_left = 0.5 * ((nrj_current_cell + nrj_left_cell) - sign_left * (nrj_current_cell - nrj_left_cell));
429 const Real nrj_right = 0.5 * ((nrj_right_cell + nrj_current_cell) - sign_right * (nrj_right_cell - nrj_current_cell));
431 nrj_current_cell = old_density[current_cell] * nrj_current_cell - time_step * (nrj_right * dmass_right - nrj_left * dmass_left) / dx;
434 nrj_current_cell = nrj_current_cell - time_step * pressure[current_cell] * (right_face_velocity_dir - left_face_velocity_dir) / dx;
436 nrj[current_cell] = nrj_current_cell;
438 if (density[current_cell] != 0.0) {
440 nrj[current_cell] /= density[current_cell];
444 info() <<
"Erreur, densite nulle.\n";
449 computePrimalMassFluxBoundary(direction);
455void AdiProjectionModule::
456computePressureGradient(
Integer direction)
462 m_pressure_gradient[current_node] = 0.0;
465 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(direction));
470 DirCell cc(cdm.cell(*current_cell));
473 Cell left_cell = cc.previous();
476 DirCellNode cn(cdm.cellNode(*current_cell));
479 const Real current_pressure_gradient = m_pressure[current_cell] - m_pressure[left_cell];
483 m_pressure_gradient[cn.previousLeft()] = current_pressure_gradient;
484 m_pressure_gradient[cn.previousRight()] = current_pressure_gradient;
491void AdiProjectionModule::
492evolveDualUpwindedVariables(
Integer direction)
494 NodeDirectionMng ndm(m_cartesian_mesh->nodeDirection(direction));
497 const Real time_step = m_global_deltat();
498 const Real dx = 0.005;
500 _evolveDualUpwindedVariables1();
502 computeDualMassFluxBoundary(direction);
504 computePressureGradient(direction);
508 DirNode dir_node(ndm[current_node]);
509 Node left_node = dir_node.previous();
510 Node right_node = dir_node.next();
512 const Real sign_left = (m_nodal_mass_flux_left[current_node] > 0.0 ? 1.0 : -1.0);
513 const Real sign_right = (m_nodal_mass_flux_right[current_node] > 0.0 ? 1.0 : -1.0);
515 const Real3 nodal_velocity_right =
516 0.5 * ((m_old_velocity[right_node] + m_old_velocity[current_node]) - sign_right * (m_old_velocity[right_node] - m_old_velocity[current_node]));
518 const Real3 nodal_velocity_left =
519 0.5 * ((m_old_velocity[current_node] + m_old_velocity[left_node]) - sign_left * (m_old_velocity[current_node] - m_old_velocity[left_node]));
521 m_lagrangian_velocity[current_node] =
522 m_old_nodal_density[current_node] * m_lagrangian_velocity[current_node] -
523 time_step * (m_nodal_mass_flux_right[current_node] * nodal_velocity_right - m_nodal_mass_flux_left[current_node] * nodal_velocity_left) / dx;
525 m_lagrangian_velocity[current_node].x -= time_step * m_pressure_gradient[current_node] / dx;
527 if (m_nodal_density[current_node] != 0.0) {
529 m_lagrangian_velocity[current_node] /= m_nodal_density[current_node];
533 info() <<
"Probleme : densite nodale nulle.\n";
538 m_velocity[current_node] = m_lagrangian_velocity[current_node];
546void AdiProjectionModule::
547_evolveDualUpwindedVariables1()
551 const Node& node = *current_node;
553 const Integer nb_cells = node.nbCell();
559 Real nodal_density_sum = 0.0;
560 Real old_nodal_density_sum = 0.0;
561 Real nodal_mass_flux_right_accumulation = 0.0;
562 Real nodal_mass_flux_left_accumulation = 0.0;
564 for (
Cell node_cell : node.cells() ) {
566 nodal_density_sum += m_density[node_cell];
567 old_nodal_density_sum += m_old_density[node_cell];
568 nodal_mass_flux_right_accumulation += m_mass_flux_right[node_cell];
569 nodal_mass_flux_left_accumulation += m_mass_flux_left[node_cell];
572 m_nodal_density[current_node] = nodal_density_sum / nb_cells;
573 m_old_nodal_density[current_node] = old_nodal_density_sum / nb_cells;
574 m_nodal_mass_flux_right[current_node] = nodal_mass_flux_right_accumulation / nb_cells;
575 m_nodal_mass_flux_left[current_node] = nodal_mass_flux_left_accumulation / nb_cells;
584void AdiProjectionModule::
590 const Real gamma = 1.4;
592 m_pressure[current_cell] =
593 (gamma - 1.0) * m_density[current_cell] * m_nrj[current_cell];
603void AdiProjectionModule::
604checkNodalMassConservation()
608 const Real time_step = m_global_deltat();
609 const Real dx = 0.005;
613 m_delta_mass[current_node] =
614 m_nodal_density[current_node] - m_old_nodal_density[current_node] +
615 time_step * (m_nodal_mass_flux_right[current_node] - m_nodal_mass_flux_left[current_node]) / dx;
623void AdiProjectionModule::
624copyEulerianCoordinates()
627 m_eulerian_coordinates.copy(nodes_coord);
633void AdiProjectionModule::
634cartesianHydroStartInit()
636 m_global_deltat = 1.0;
637 m_lagrangian_velocity.fill(Real3::zero());
638 m_old_velocity.fill(Real3::zero());
639 m_velocity.fill(Real3::zero());
642 IMesh* mesh = defaultMesh();
645 m_cartesian_mesh->computeDirections();
649 Real pressure = m_pressure[icell];
650 Real adiabatic_cst = 1.4;
651 Real density = m_density[icell];
652 m_nrj[icell] = pressure / ((adiabatic_cst - 1.) * density);
659void AdiProjectionModule::
663 copyEulerianCoordinates();
665 copyCurrentVariablesToOldVariables();
673 evolvePrimalUpwindedVariables(direction_x);
675 evolveDualUpwindedVariables(direction_x);
679 checkNodalMassConservation();
685void AdiProjectionModule::
688 String time_loop_name(
"AdiProjectionTestLoop");
690 ITimeLoopMng* tlm = sd->timeLoopMng();
691 ITimeLoop* time_loop = tlm->createTimeLoop(time_loop_name);
694 List<TimeLoopEntryPointInfo> clist;
695 clist.add(TimeLoopEntryPointInfo(
"AdiProjection.CartesianHydroStartInit"));
706 List<TimeLoopEntryPointInfo> clist;
707 clist.add(TimeLoopEntryPointInfo(
"AdiProjection.CartesianHydroMain"));
713 clist.add(
"AdiProjection");
714 time_loop->setRequiredModulesName(clist);
716 clist.add(
"ArcanePostProcessing");
717 clist.add(
"ArcaneCheckpoint");
718 time_loop->setOptionalModulesName(clist);
721 tlm->registerTimeLoop(time_loop);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour gérer les énumérations des entités sur les accélérateurs.
#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group,...)
Macro pour itérer sur accélérateur sur un groupe d'entités.
Interface d'un maillage cartésien.
static ICartesianMesh * getReference(const MeshHandleOrMesh &mesh, bool create=true)
Récupère ou créé la référence associée à mesh.
Interface du gestionnaire d'un sous-domaine.
static const char * WComputeLoop
appelé pendant la boucle de calcul
static const char * WInit
appelé pendant l'initialisation, l'initialisation d'une reprise ou d'un nouveau cas
Informations pour construire un module.
Informations sur une version.
MeshVariableScalarRefT< Cell, Real > VariableCellReal
Grandeur au centre des mailles de type réel.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
auto viewInOut(const ViewBuildInfo &vbi, CellMaterialVariableScalarRef< DataType > &var)
Vue en lecture/écriture pour les variables materiaux scalaire.
RunQueue makeQueue(const Runner &runner)
Créé une file associée à runner.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
List< String > StringList
Tableau de chaînes de caractères unicode.
double Real
Type représentant un réel.
@ Cell
Le maillage est AMR par maille.