14#include "arcane/core/ITimeLoopMng.h"
15#include "arcane/core/ITimeLoopService.h"
16#include "arcane/core/ITimeLoop.h"
17#include "arcane/core/TimeLoopEntryPointInfo.h"
18#include "arcane/core/MeshAreaAccessor.h"
19#include "arcane/core/MeshArea.h"
20#include "arcane/core/ISubDomain.h"
21#include "arcane/core/IMesh.h"
23#include "arcane/cartesianmesh/ICartesianMesh.h"
24#include "arcane/cartesianmesh/CellDirectionMng.h"
25#include "arcane/cartesianmesh/NodeDirectionMng.h"
27#include "arcane/accelerator/core/Runner.h"
28#include "arcane/accelerator/core/IAcceleratorMng.h"
33#include "arcane/tests/AdiProjection_axl.h"
44class AdiProjectionModule
45:
public ArcaneAdiProjectionObject
50 ~AdiProjectionModule();
58 void copyEulerianCoordinates();
59 void cartesianHydroMain();
60 virtual void cartesianHydroStartInit();
72 void evolvePrimalUpwindedVariables(
Integer direction);
73 void evolveDualUpwindedVariables(
Integer direction);
74 void computePressure();
75 void computePressureGradient(
Integer direction);
76 void checkNodalMassConservation();
77 void copyCurrentVariablesToOldVariables();
79 void computePrimalMassFluxInner(
Integer direction);
81 void computeDualMassFluxInner(
Integer direction);
82 void prepareLagrangianVariables();
83 void checkLagrangianVariablesConsistency();
85 void _evolveDualUpwindedVariables1();
86 void _evolvePrimalUpwindedVariablesV2(
Integer direction);
91 void computePrimalMassFluxBoundary(
Integer direction);
92 void computeDualMassFluxBoundary(
Integer direction);
105: ArcaneAdiProjectionObject(mb)
113~AdiProjectionModule()
120void AdiProjectionModule::
121copyCurrentVariablesToOldVariables()
125 m_old_density[current_cell] = m_density[current_cell];
130 m_old_velocity[current_node] = m_velocity[current_node];
137void AdiProjectionModule::
138prepareLagrangianVariables()
143 m_lagrangian_coordinates.copy(nodes_coord);
148 m_lagrangian_velocity[inode] = 0.5 * (m_old_velocity[inode] + m_velocity[inode]);
155void AdiProjectionModule::
156checkLagrangianVariablesConsistency()
165 info() <<
"Test de coherence vitesses lagrangiennes/positions lagrangiennes : residu="
174void AdiProjectionModule::
175computePrimalMassFluxInner(
Integer direction)
177 ARCANE_UNUSED(direction);
183void AdiProjectionModule::
184computePrimalMassFluxBoundary(
Integer direction)
186 info() << A_FUNCINFO;
188 auto queue =
makeQueue(acceleratorMng()->defaultRunner());
191 auto inout_mass_flux_right =
viewInOut(command, m_mass_flux_right);
192 auto inout_mass_flux_left =
viewInOut(command, m_mass_flux_left);
194 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(direction));
200 DirCellLocalId cc(cdm.dirCellId(current_cell));
202 CellLocalId right_cell = cc.next();
203 CellLocalId left_cell = cc.previous();
205 if (left_cell.isNull()) {
208 inout_mass_flux_right[current_cell] = inout_mass_flux_left[right_cell];
209 inout_mass_flux_left[current_cell] = inout_mass_flux_right[current_cell];
211 else if (right_cell.isNull()) {
214 inout_mass_flux_left[current_cell] = inout_mass_flux_right[left_cell];
215 inout_mass_flux_right[current_cell] = inout_mass_flux_left[current_cell];
223void AdiProjectionModule::
224computeDualMassFluxInner(
Integer direction)
226 ARCANE_UNUSED(direction);
232void AdiProjectionModule::
233computeDualMassFluxBoundary(
Integer direction)
235 NodeDirectionMng ndm(m_cartesian_mesh->nodeDirection(direction));
237 auto queue =
makeQueue(acceleratorMng()->defaultRunner());
240 auto inout_nodal_mass_flux_right =
viewInOut(command, m_nodal_mass_flux_right);
241 auto inout_nodal_mass_flux_left =
viewInOut(command, m_nodal_mass_flux_left);
247 DirNodeLocalId cc(ndm.dirNodeId(current_node));
249 NodeLocalId right_node = cc.next();
250 NodeLocalId left_node = cc.previous();
252 if (left_node.isNull()) {
255 inout_nodal_mass_flux_left[current_node] = inout_nodal_mass_flux_left[right_node];
256 inout_nodal_mass_flux_right[current_node] = inout_nodal_mass_flux_right[right_node];
258 else if (right_node.isNull()) {
261 inout_nodal_mass_flux_left[current_node] = inout_nodal_mass_flux_left[left_node];
262 inout_nodal_mass_flux_right[current_node] = inout_nodal_mass_flux_right[left_node];
271void AdiProjectionModule::
272evolvePrimalUpwindedVariables(
Integer direction)
275 _evolvePrimalUpwindedVariablesV2(direction);
279 const Real time_step = m_global_deltat();
280 const Real dx = 0.005;
282 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(direction));
289 DirCell cc(cdm.cell(*current_cell));
291 CellLocalId right_cell = cc.next();
292 CellLocalId left_cell = cc.previous();
297 DirCellNode cn(cdm.cellNode(*current_cell));
301 const Real3 left_face_velocity = m_lagrangian_velocity[cn.previousLeft()];
302 const Real left_face_velocity_dir = left_face_velocity.x;
304 const Real3 right_face_velocity = m_lagrangian_velocity[cn.nextLeft()];
305 const Real right_face_velocity_dir = right_face_velocity.x;
308 const Real sign_left = (left_face_velocity_dir > 0.0 ? 1.0 : -1.0);
309 const Real sign_right = (right_face_velocity_dir > 0.0 ? 1.0 : -1.0);
311 Real m_nrj_left_cell = m_nrj[left_cell];
312 Real m_nrj_right_cell = m_nrj[right_cell];
313 Real m_nrj_current_cell = m_nrj[current_cell];
315 const Real dmass_left = 0.5 * left_face_velocity_dir *
316 ((m_density[current_cell] + m_density[left_cell]) -
317 sign_left * (m_density[current_cell] - m_density[left_cell]));
319 const Real dmass_right = 0.5 * right_face_velocity_dir *
320 ((m_density[right_cell] + m_density[current_cell]) -
321 sign_right * (m_density[right_cell] - m_density[current_cell]));
323 m_mass_flux_left[current_cell] = dmass_left;
324 m_mass_flux_right[current_cell] = dmass_right;
326 m_density[current_cell] =
327 m_density[current_cell] - time_step * (dmass_right - dmass_left) / dx;
330 const Real nrj_left = 0.5 *
331 ((m_nrj_current_cell + m_nrj_left_cell) -
332 sign_left * (m_nrj_current_cell - m_nrj_left_cell));
334 const Real nrj_right = 0.5 *
335 ((m_nrj_right_cell + m_nrj_current_cell) -
336 sign_right * (m_nrj_right_cell - m_nrj_current_cell));
338 Real nrj_current_cell = m_old_density[current_cell] * m_nrj_current_cell -
339 time_step * (nrj_right * dmass_right - nrj_left * dmass_left) / dx;
342 nrj_current_cell = nrj_current_cell -
343 time_step * m_pressure[current_cell] * (right_face_velocity_dir - left_face_velocity_dir) / dx;
345 if (m_density[current_cell] != 0.0) {
347 nrj_current_cell /= m_density[current_cell];
351 info() <<
"Erreur, densite nulle.\n";
354 m_nrj[current_cell] = nrj_current_cell;
357 computePrimalMassFluxBoundary(direction);
364void AdiProjectionModule::
365_evolvePrimalUpwindedVariablesV2(
Integer direction)
368 const Real time_step = m_global_deltat();
369 const Real dx = 0.005;
371 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(direction));
383 DirCell cc(cdm.cell(*i_current_cell));
385 Cell right_cell_c = cc.next();
386 Cell left_cell_c = cc.previous();
388 CellLocalId current_cell = *i_current_cell;
389 Cell right_cell = right_cell_c;
390 Cell left_cell = left_cell_c;
393 DirCellNode cn(cdm.cellNode(*i_current_cell));
395 Real nrj_left_cell = nrj[left_cell];
396 Real nrj_right_cell = nrj[right_cell];
397 Real nrj_current_cell = nrj[current_cell];
401 const Real3 left_face_velocity = m_lagrangian_velocity[cn.previousLeft()];
402 const Real left_face_velocity_dir = left_face_velocity.x;
404 const Real3 right_face_velocity = m_lagrangian_velocity[cn.nextLeft()];
405 const Real right_face_velocity_dir = right_face_velocity.x;
408 const Real sign_left = (left_face_velocity_dir > 0.0 ? 1.0 : -1.0);
409 const Real sign_right = (right_face_velocity_dir > 0.0 ? 1.0 : -1.0);
411 const Real dmass_left = 0.5 * left_face_velocity_dir *
412 ((density[current_cell] + density[left_cell]) -
413 sign_left * (density[current_cell] - density[left_cell]));
415 const Real dmass_right = 0.5 * right_face_velocity_dir *
416 ((density[right_cell] + density[current_cell]) -
417 sign_right * (density[right_cell] - density[current_cell]));
419 m_mass_flux_left[i_current_cell] = dmass_left;
420 m_mass_flux_right[i_current_cell] = dmass_right;
422 density[current_cell] = density[current_cell] - time_step * (dmass_right - dmass_left) / dx;
425 const Real nrj_left = 0.5 * ((nrj_current_cell + nrj_left_cell) - sign_left * (nrj_current_cell - nrj_left_cell));
427 const Real nrj_right = 0.5 * ((nrj_right_cell + nrj_current_cell) - sign_right * (nrj_right_cell - nrj_current_cell));
429 nrj_current_cell = old_density[current_cell] * nrj_current_cell - time_step * (nrj_right * dmass_right - nrj_left * dmass_left) / dx;
432 nrj_current_cell = nrj_current_cell - time_step * pressure[current_cell] * (right_face_velocity_dir - left_face_velocity_dir) / dx;
434 nrj[current_cell] = nrj_current_cell;
436 if (density[current_cell] != 0.0) {
438 nrj[current_cell] /= density[current_cell];
442 info() <<
"Erreur, densite nulle.\n";
447 computePrimalMassFluxBoundary(direction);
453void AdiProjectionModule::
454computePressureGradient(
Integer direction)
460 m_pressure_gradient[current_node] = 0.0;
463 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(direction));
468 DirCell cc(cdm.cell(*current_cell));
471 Cell left_cell = cc.previous();
474 DirCellNode cn(cdm.cellNode(*current_cell));
477 const Real current_pressure_gradient = m_pressure[current_cell] - m_pressure[left_cell];
481 m_pressure_gradient[cn.previousLeft()] = current_pressure_gradient;
482 m_pressure_gradient[cn.previousRight()] = current_pressure_gradient;
489void AdiProjectionModule::
490evolveDualUpwindedVariables(
Integer direction)
492 NodeDirectionMng ndm(m_cartesian_mesh->nodeDirection(direction));
495 const Real time_step = m_global_deltat();
496 const Real dx = 0.005;
498 _evolveDualUpwindedVariables1();
500 computeDualMassFluxBoundary(direction);
502 computePressureGradient(direction);
506 DirNode dir_node(ndm[current_node]);
507 Node left_node = dir_node.previous();
508 Node right_node = dir_node.next();
510 const Real sign_left = (m_nodal_mass_flux_left[current_node] > 0.0 ? 1.0 : -1.0);
511 const Real sign_right = (m_nodal_mass_flux_right[current_node] > 0.0 ? 1.0 : -1.0);
513 const Real3 nodal_velocity_right =
514 0.5 * ((m_old_velocity[right_node] + m_old_velocity[current_node]) - sign_right * (m_old_velocity[right_node] - m_old_velocity[current_node]));
516 const Real3 nodal_velocity_left =
517 0.5 * ((m_old_velocity[current_node] + m_old_velocity[left_node]) - sign_left * (m_old_velocity[current_node] - m_old_velocity[left_node]));
519 m_lagrangian_velocity[current_node] =
520 m_old_nodal_density[current_node] * m_lagrangian_velocity[current_node] -
521 time_step * (m_nodal_mass_flux_right[current_node] * nodal_velocity_right - m_nodal_mass_flux_left[current_node] * nodal_velocity_left) / dx;
523 m_lagrangian_velocity[current_node].x -= time_step * m_pressure_gradient[current_node] / dx;
525 if (m_nodal_density[current_node] != 0.0) {
527 m_lagrangian_velocity[current_node] /= m_nodal_density[current_node];
531 info() <<
"Probleme : densite nodale nulle.\n";
536 m_velocity[current_node] = m_lagrangian_velocity[current_node];
544void AdiProjectionModule::
545_evolveDualUpwindedVariables1()
549 const Node& node = *current_node;
551 const Integer nb_cells = node.nbCell();
557 Real nodal_density_sum = 0.0;
558 Real old_nodal_density_sum = 0.0;
559 Real nodal_mass_flux_right_accumulation = 0.0;
560 Real nodal_mass_flux_left_accumulation = 0.0;
562 for (
Cell node_cell : node.cells() ) {
564 nodal_density_sum += m_density[node_cell];
565 old_nodal_density_sum += m_old_density[node_cell];
566 nodal_mass_flux_right_accumulation += m_mass_flux_right[node_cell];
567 nodal_mass_flux_left_accumulation += m_mass_flux_left[node_cell];
570 m_nodal_density[current_node] = nodal_density_sum / nb_cells;
571 m_old_nodal_density[current_node] = old_nodal_density_sum / nb_cells;
572 m_nodal_mass_flux_right[current_node] = nodal_mass_flux_right_accumulation / nb_cells;
573 m_nodal_mass_flux_left[current_node] = nodal_mass_flux_left_accumulation / nb_cells;
582void AdiProjectionModule::
588 const Real gamma = 1.4;
590 m_pressure[current_cell] =
591 (gamma - 1.0) * m_density[current_cell] * m_nrj[current_cell];
601void AdiProjectionModule::
602checkNodalMassConservation()
606 const Real time_step = m_global_deltat();
607 const Real dx = 0.005;
611 m_delta_mass[current_node] =
612 m_nodal_density[current_node] - m_old_nodal_density[current_node] +
613 time_step * (m_nodal_mass_flux_right[current_node] - m_nodal_mass_flux_left[current_node]) / dx;
621void AdiProjectionModule::
622copyEulerianCoordinates()
625 m_eulerian_coordinates.copy(nodes_coord);
631void AdiProjectionModule::
632cartesianHydroStartInit()
634 m_global_deltat = 1.0;
635 m_lagrangian_velocity.fill(Real3::zero());
636 m_old_velocity.fill(Real3::zero());
637 m_velocity.fill(Real3::zero());
640 IMesh* mesh = defaultMesh();
643 m_cartesian_mesh->computeDirections();
647 Real pressure = m_pressure[icell];
648 Real adiabatic_cst = 1.4;
649 Real density = m_density[icell];
650 m_nrj[icell] = pressure / ((adiabatic_cst - 1.) * density);
657void AdiProjectionModule::
661 copyEulerianCoordinates();
663 copyCurrentVariablesToOldVariables();
671 evolvePrimalUpwindedVariables(direction_x);
673 evolveDualUpwindedVariables(direction_x);
677 checkNodalMassConservation();
683void AdiProjectionModule::
686 String time_loop_name(
"AdiProjectionTestLoop");
688 ITimeLoopMng* tlm = sd->timeLoopMng();
689 ITimeLoop* time_loop = tlm->createTimeLoop(time_loop_name);
692 List<TimeLoopEntryPointInfo> clist;
693 clist.add(TimeLoopEntryPointInfo(
"AdiProjection.CartesianHydroStartInit"));
704 List<TimeLoopEntryPointInfo> clist;
705 clist.add(TimeLoopEntryPointInfo(
"AdiProjection.CartesianHydroMain"));
711 clist.add(
"AdiProjection");
712 time_loop->setRequiredModulesName(clist);
714 clist.add(
"ArcanePostProcessing");
715 clist.add(
"ArcaneCheckpoint");
716 time_loop->setOptionalModulesName(clist);
719 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.