14#include "arcane/ITimeLoopMng.h"
15#include "arcane/ITimeLoopService.h"
16#include "arcane/ITimeLoop.h"
17#include "arcane/TimeLoopEntryPointInfo.h"
19#include "arcane/cea/ICartesianMesh.h"
20#include "arcane/cea/CellDirectionMng.h"
21#include "arcane/cea/NodeDirectionMng.h"
23#include "arcane/MeshAreaAccessor.h"
24#include "arcane/MeshArea.h"
25#include "arcane/ISubDomain.h"
27#include "arcane/IMesh.h"
29#include "arcane/accelerator/core/Runner.h"
30#include "arcane/accelerator/core/IAcceleratorMng.h"
35#include "arcane/tests/AdiProjection_axl.h"
48:
public ArcaneAdiProjectionObject
61 void copyEulerianCoordinates();
62 void cartesianHydroMain();
63 virtual void cartesianHydroStartInit();
75 void evolvePrimalUpwindedVariables(Integer direction);
76 void evolveDualUpwindedVariables(Integer direction);
77 void computePressure();
78 void computePressureGradient(Integer direction);
79 void checkNodalMassConservation();
80 void copyCurrentVariablesToOldVariables();
82 void computePrimalMassFluxInner(Integer direction);
84 void computeDualMassFluxInner(Integer direction);
85 void prepareLagrangianVariables();
86 void checkLagrangianVariablesConsistency();
88 void _evolveDualUpwindedVariables1();
89 void _evolvePrimalUpwindedVariablesV2(Integer direction);
94 void computePrimalMassFluxBoundary(Integer direction);
95 void computeDualMassFluxBoundary(Integer direction);
108: ArcaneAdiProjectionObject(
mb)
116~AdiProjectionModule()
123void AdiProjectionModule::
124copyCurrentVariablesToOldVariables()
128 m_old_density[current_cell] = m_density[current_cell];
133 m_old_velocity[current_node] = m_velocity[current_node];
140void AdiProjectionModule::
141prepareLagrangianVariables()
146 m_lagrangian_coordinates.copy(nodes_coord);
151 m_lagrangian_velocity[inode] = 0.5 * (m_old_velocity[inode] + m_velocity[inode]);
158void AdiProjectionModule::
159checkLagrangianVariablesConsistency()
168 info() <<
"Test de coherence vitesses lagrangiennes/positions lagrangiennes : residu="
177void AdiProjectionModule::
178computePrimalMassFluxInner(Integer direction)
180 ARCANE_UNUSED(direction);
186void AdiProjectionModule::
187computePrimalMassFluxBoundary(Integer direction)
189 info() << A_FUNCINFO;
191 auto queue =
makeQueue(acceleratorMng()->defaultRunner());
194 auto inout_mass_flux_right =
viewInOut(command, m_mass_flux_right);
195 auto inout_mass_flux_left =
viewInOut(command, m_mass_flux_left);
197 CellDirectionMng cdm(m_cartesian_mesh->
cellDirection(direction));
203 DirCellLocalId cc(cdm.dirCellId(current_cell));
205 CellLocalId right_cell = cc.next();
206 CellLocalId left_cell = cc.previous();
208 if (left_cell.isNull()) {
211 inout_mass_flux_right[current_cell] = inout_mass_flux_left[right_cell];
212 inout_mass_flux_left[current_cell] = inout_mass_flux_right[current_cell];
214 else if (right_cell.isNull()) {
217 inout_mass_flux_left[current_cell] = inout_mass_flux_right[left_cell];
218 inout_mass_flux_right[current_cell] = inout_mass_flux_left[current_cell];
226void AdiProjectionModule::
227computeDualMassFluxInner(Integer direction)
229 ARCANE_UNUSED(direction);
235void AdiProjectionModule::
236computeDualMassFluxBoundary(Integer direction)
238 NodeDirectionMng ndm(m_cartesian_mesh->
nodeDirection(direction));
240 auto queue =
makeQueue(acceleratorMng()->defaultRunner());
243 auto inout_nodal_mass_flux_right =
viewInOut(command, m_nodal_mass_flux_right);
244 auto inout_nodal_mass_flux_left =
viewInOut(command, m_nodal_mass_flux_left);
250 DirNodeLocalId cc(ndm.dirNodeId(current_node));
252 NodeLocalId right_node = cc.next();
253 NodeLocalId left_node = cc.previous();
255 if (left_node.isNull()) {
258 inout_nodal_mass_flux_left[current_node] = inout_nodal_mass_flux_left[right_node];
259 inout_nodal_mass_flux_right[current_node] = inout_nodal_mass_flux_right[right_node];
261 else if (right_node.isNull()) {
264 inout_nodal_mass_flux_left[current_node] = inout_nodal_mass_flux_left[left_node];
265 inout_nodal_mass_flux_right[current_node] = inout_nodal_mass_flux_right[left_node];
274void AdiProjectionModule::
275evolvePrimalUpwindedVariables(Integer direction)
278 _evolvePrimalUpwindedVariablesV2(direction);
282 const Real time_step = m_global_deltat();
283 const Real dx = 0.005;
285 CellDirectionMng cdm(m_cartesian_mesh->
cellDirection(direction));
292 DirCell cc(cdm.cell(*current_cell));
294 Cell::Index right_cell = cc.next();
295 Cell::Index left_cell = cc.previous();
300 DirCellNode cn(cdm.cellNode(*current_cell));
304 const Real3 left_face_velocity = m_lagrangian_velocity[cn.previousLeft()];
305 const Real left_face_velocity_dir = left_face_velocity.x;
307 const Real3 right_face_velocity = m_lagrangian_velocity[cn.nextLeft()];
308 const Real right_face_velocity_dir = right_face_velocity.x;
311 const Real sign_left = (left_face_velocity_dir > 0.0 ? 1.0 : -1.0);
312 const Real sign_right = (right_face_velocity_dir > 0.0 ? 1.0 : -1.0);
314 Real m_nrj_left_cell = m_nrj[left_cell];
315 Real m_nrj_right_cell = m_nrj[right_cell];
316 Real m_nrj_current_cell = m_nrj[current_cell];
318 const Real dmass_left = 0.5 * left_face_velocity_dir *
319 ((m_density[current_cell] + m_density[left_cell]) -
320 sign_left * (m_density[current_cell] - m_density[left_cell]));
322 const Real dmass_right = 0.5 * right_face_velocity_dir *
323 ((m_density[right_cell] + m_density[current_cell]) -
324 sign_right * (m_density[right_cell] - m_density[current_cell]));
326 m_mass_flux_left[current_cell] = dmass_left;
327 m_mass_flux_right[current_cell] = dmass_right;
329 m_density[current_cell] =
330 m_density[current_cell] - time_step * (dmass_right - dmass_left) / dx;
333 const Real nrj_left = 0.5 *
334 ((m_nrj_current_cell + m_nrj_left_cell) -
335 sign_left * (m_nrj_current_cell - m_nrj_left_cell));
337 const Real nrj_right = 0.5 *
338 ((m_nrj_right_cell + m_nrj_current_cell) -
339 sign_right * (m_nrj_right_cell - m_nrj_current_cell));
341 Real nrj_current_cell = m_old_density[current_cell] * m_nrj_current_cell -
342 time_step * (nrj_right * dmass_right - nrj_left * dmass_left) / dx;
345 nrj_current_cell = nrj_current_cell -
346 time_step * m_pressure[current_cell] * (right_face_velocity_dir - left_face_velocity_dir) / dx;
348 if (m_density[current_cell] != 0.0) {
350 nrj_current_cell /= m_density[current_cell];
354 info() <<
"Erreur, densite nulle.\n";
357 m_nrj[current_cell] = nrj_current_cell;
360 computePrimalMassFluxBoundary(direction);
367void AdiProjectionModule::
368_evolvePrimalUpwindedVariablesV2(Integer direction)
371 const Real time_step = m_global_deltat();
372 const Real dx = 0.005;
374 CellDirectionMng cdm(m_cartesian_mesh->
cellDirection(direction));
386 DirCell cc(cdm.cell(*i_current_cell));
388 Cell right_cell_c = cc.next();
389 Cell left_cell_c = cc.previous();
391 Cell::Index current_cell = *i_current_cell;
392 Cell right_cell = right_cell_c;
393 Cell left_cell = left_cell_c;
396 DirCellNode cn(cdm.cellNode(*i_current_cell));
398 Real nrj_left_cell = nrj[left_cell];
399 Real nrj_right_cell = nrj[right_cell];
400 Real nrj_current_cell = nrj[current_cell];
404 const Real3 left_face_velocity = m_lagrangian_velocity[cn.previousLeft()];
405 const Real left_face_velocity_dir = left_face_velocity.x;
407 const Real3 right_face_velocity = m_lagrangian_velocity[cn.nextLeft()];
408 const Real right_face_velocity_dir = right_face_velocity.x;
411 const Real sign_left = (left_face_velocity_dir > 0.0 ? 1.0 : -1.0);
412 const Real sign_right = (right_face_velocity_dir > 0.0 ? 1.0 : -1.0);
414 const Real dmass_left = 0.5 * left_face_velocity_dir *
415 ((density[current_cell] + density[left_cell]) -
416 sign_left * (density[current_cell] - density[left_cell]));
418 const Real dmass_right = 0.5 * right_face_velocity_dir *
419 ((density[right_cell] + density[current_cell]) -
420 sign_right * (density[right_cell] - density[current_cell]));
422 m_mass_flux_left[i_current_cell] = dmass_left;
423 m_mass_flux_right[i_current_cell] = dmass_right;
425 density[current_cell] = density[current_cell] - time_step * (dmass_right - dmass_left) / dx;
428 const Real nrj_left = 0.5 * ((nrj_current_cell + nrj_left_cell) - sign_left * (nrj_current_cell - nrj_left_cell));
430 const Real nrj_right = 0.5 * ((nrj_right_cell + nrj_current_cell) - sign_right * (nrj_right_cell - nrj_current_cell));
432 nrj_current_cell = old_density[current_cell] * nrj_current_cell - time_step * (nrj_right * dmass_right - nrj_left * dmass_left) / dx;
435 nrj_current_cell = nrj_current_cell - time_step * pressure[current_cell] * (right_face_velocity_dir - left_face_velocity_dir) / dx;
437 nrj[current_cell] = nrj_current_cell;
439 if (density[current_cell] != 0.0) {
441 nrj[current_cell] /= density[current_cell];
445 info() <<
"Erreur, densite nulle.\n";
450 computePrimalMassFluxBoundary(direction);
456void AdiProjectionModule::
457computePressureGradient(Integer direction)
463 m_pressure_gradient[current_node] = 0.0;
466 CellDirectionMng cdm(m_cartesian_mesh->
cellDirection(direction));
471 DirCell cc(cdm.cell(*current_cell));
474 Cell left_cell = cc.previous();
477 DirCellNode cn(cdm.cellNode(*current_cell));
480 const Real current_pressure_gradient = m_pressure[current_cell] - m_pressure[left_cell];
484 m_pressure_gradient[cn.previousLeft()] = current_pressure_gradient;
485 m_pressure_gradient[cn.previousRight()] = current_pressure_gradient;
492void AdiProjectionModule::
493evolveDualUpwindedVariables(Integer direction)
495 NodeDirectionMng ndm(m_cartesian_mesh->
nodeDirection(direction));
498 const Real time_step = m_global_deltat();
499 const Real dx = 0.005;
501 _evolveDualUpwindedVariables1();
503 computeDualMassFluxBoundary(direction);
505 computePressureGradient(direction);
509 DirNode dir_node(ndm[current_node]);
510 Node left_node = dir_node.previous();
511 Node right_node = dir_node.next();
513 const Real sign_left = (m_nodal_mass_flux_left[current_node] > 0.0 ? 1.0 : -1.0);
514 const Real sign_right = (m_nodal_mass_flux_right[current_node] > 0.0 ? 1.0 : -1.0);
516 const Real3 nodal_velocity_right =
517 0.5 * ((m_old_velocity[right_node] + m_old_velocity[current_node]) - sign_right * (m_old_velocity[right_node] - m_old_velocity[current_node]));
519 const Real3 nodal_velocity_left =
520 0.5 * ((m_old_velocity[current_node] + m_old_velocity[left_node]) - sign_left * (m_old_velocity[current_node] - m_old_velocity[left_node]));
522 m_lagrangian_velocity[current_node] =
523 m_old_nodal_density[current_node] * m_lagrangian_velocity[current_node] -
524 time_step * (m_nodal_mass_flux_right[current_node] * nodal_velocity_right - m_nodal_mass_flux_left[current_node] * nodal_velocity_left) / dx;
526 m_lagrangian_velocity[current_node].x -= time_step * m_pressure_gradient[current_node] / dx;
528 if (m_nodal_density[current_node] != 0.0) {
530 m_lagrangian_velocity[current_node] /= m_nodal_density[current_node];
534 info() <<
"Probleme : densite nodale nulle.\n";
539 m_velocity[current_node] = m_lagrangian_velocity[current_node];
547void AdiProjectionModule::
548_evolveDualUpwindedVariables1()
552 const Node& node = *current_node;
554 const Integer nb_cells = node.nbCell();
560 Real nodal_density_sum = 0.0;
561 Real old_nodal_density_sum = 0.0;
562 Real nodal_mass_flux_right_accumulation = 0.0;
563 Real nodal_mass_flux_left_accumulation = 0.0;
565 for (Cell node_cell : node.cells() ) {
567 nodal_density_sum += m_density[node_cell];
568 old_nodal_density_sum += m_old_density[node_cell];
569 nodal_mass_flux_right_accumulation += m_mass_flux_right[node_cell];
570 nodal_mass_flux_left_accumulation += m_mass_flux_left[node_cell];
573 m_nodal_density[current_node] = nodal_density_sum / nb_cells;
574 m_old_nodal_density[current_node] = old_nodal_density_sum / nb_cells;
575 m_nodal_mass_flux_right[current_node] = nodal_mass_flux_right_accumulation / nb_cells;
576 m_nodal_mass_flux_left[current_node] = nodal_mass_flux_left_accumulation / nb_cells;
585void AdiProjectionModule::
591 const Real gamma = 1.4;
593 m_pressure[current_cell] =
594 (gamma - 1.0) * m_density[current_cell] * m_nrj[current_cell];
604void AdiProjectionModule::
605checkNodalMassConservation()
609 const Real time_step = m_global_deltat();
610 const Real dx = 0.005;
614 m_delta_mass[current_node] =
615 m_nodal_density[current_node] - m_old_nodal_density[current_node] +
616 time_step * (m_nodal_mass_flux_right[current_node] - m_nodal_mass_flux_left[current_node]) / dx;
624void AdiProjectionModule::
625copyEulerianCoordinates()
628 m_eulerian_coordinates.copy(nodes_coord);
634void AdiProjectionModule::
635cartesianHydroStartInit()
637 m_global_deltat = 1.0;
638 m_lagrangian_velocity.fill(Real3::zero());
639 m_old_velocity.fill(Real3::zero());
640 m_velocity.fill(Real3::zero());
643 IMesh* mesh = defaultMesh();
645 m_cartesian_mesh = arcaneCreateCartesianMesh(mesh);
650 Real pressure = m_pressure[icell];
651 Real adiabatic_cst = 1.4;
652 Real density = m_density[icell];
653 m_nrj[icell] = pressure / ((adiabatic_cst - 1.) * density);
660void AdiProjectionModule::
664 copyEulerianCoordinates();
666 copyCurrentVariablesToOldVariables();
674 evolvePrimalUpwindedVariables(direction_x);
676 evolveDualUpwindedVariables(direction_x);
680 checkNodalMassConservation();
686void AdiProjectionModule::
687staticInitialize(ISubDomain* sd)
689 String time_loop_name(
"AdiProjectionTestLoop");
691 ITimeLoopMng* tlm = sd->timeLoopMng();
692 ITimeLoop* time_loop = tlm->createTimeLoop(time_loop_name);
695 List<TimeLoopEntryPointInfo> clist;
696 clist.add(TimeLoopEntryPointInfo(
"AdiProjection.CartesianHydroStartInit"));
707 List<TimeLoopEntryPointInfo> clist;
708 clist.add(TimeLoopEntryPointInfo(
"AdiProjection.CartesianHydroMain"));
714 clist.add(
"AdiProjection");
715 time_loop->setRequiredModulesName(clist);
717 clist.add(
"ArcanePostProcessing");
718 clist.add(
"ArcaneCheckpoint");
719 time_loop->setOptionalModulesName(clist);
722 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.
virtual CellDirectionMng cellDirection(eMeshDirection dir)=0
Liste des mailles dans la direction dir.
virtual NodeDirectionMng nodeDirection(eMeshDirection dir)=0
Liste des noeuds dans la direction dir.
virtual void computeDirections()=0
Calcule les infos pour les accès par direction.
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
Lecteur des fichiers de maillage via la bibliothèque LIMA.
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.
Espace de nom pour l'utilisation des accélérateurs.
auto viewInOut(RunCommand &cmd, CellMaterialVariableScalarRef< DataType > &var)
Vue en lecture/écriture pour les variables materiaux scalaire.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
RunQueue makeQueue(const Runner &runner)
Créé une file associée à runner.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
List< String > StringList
Tableau de chaînes de caractères unicode.
Int32 Integer
Type représentant un entier.