TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
ALE_CheckpointManager.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15#include <ALE_CheckpointManager.h>
16#include <Domaine_ALE.h>
17#include <EcritureLectureSpecial.h>
18#include <Probleme_base.h>
19#include <Process.h>
20#include <TRUST_2_PDI.h>
21#include <Schema_Temps_base.h>
22#include <Avanc.h>
23#include <Objet_U.h>
24#include <algorithm>
25
27 const Domaine_ALE& dom) const
28{
29 int bytes = 0, a_faire, special;
31
32 // Helper lambda: allocate a temporary discretized field.
33 auto make_champ = [&](const std::string& name, int nbComp, const std::string& directive)
34 {
35 OWN_PTR(Champ_Inc_base) champ;
36 Noms noms(1), unit(1);
37 noms[0] = name;
38 unit[0] = "none";
39 pb.discretisation().discretiser_champ(directive.c_str(), pb.domaine_dis(),
40 vectoriel, noms, unit, nbComp, 1,
41 pb.schema_temps().temps_courant(), champ);
42 champ->associer_eqn(dom.getEquation());
43 return champ;
44 };
45
46 int dimension=Objet_U::dimension;
47
48 if (a_faire)
49 {
50 // Standard binary / xyz save path
51 OWN_PTR(Champ_Inc_base) meshCoords = make_champ("meshCoords", dimension, "champ_sommets");
52 meshCoords->valeurs() = pb.domaine_dis().domaine().les_sommets();
53
54 if (special && Process::nproc() > 1)
55 Cerr << "ATTENTION : parallel calculation, meshCoords not saved in xyz format" << finl;
56 else
57 bytes += meshCoords->sauvegarder(os);
58
59 if (dom.getMeshMotionModel() == 1)
60 {
61 // Node-wise kinematic fields
62 OWN_PTR(Champ_Inc_base) meshDisplacement = make_champ("meshDisplacement", dimension, "champ_sommets");
63 meshDisplacement->valeurs() = dom.getMeshDisplacement();
64
65 OWN_PTR(Champ_Inc_base) meshVelocity = make_champ("meshVelocity", dimension, "champ_sommets");
66 meshVelocity->valeurs() = dom.getMeshVelocity();
67
68 OWN_PTR(Champ_Inc_base) meshAcceleration = make_champ("meshAcceleration", dimension, "champ_sommets");
69 meshAcceleration->valeurs() = dom.getMeshAcceleration();
70
71 OWN_PTR(Champ_Inc_base) meshPosition = make_champ("meshPosition", dimension, "champ_sommets");
72 meshPosition->valeurs() = dom.getMeshPosition();
73
74 // Element-wise mechanical state fields
75 OWN_PTR(Champ_Inc_base) meshRefConfig = make_champ("meshReferenceConfiguration",
76 dom.getMeshReferenceConfigurationNbComp(), "champ_elem");
77 meshRefConfig->valeurs() = dom.getMeshReferenceConfiguration();
78
79 OWN_PTR(Champ_Inc_base) meshTransGrad = make_champ("meshTransformationGradient",
80 dom.getMeshTransformationGradientNbComp(), "champ_elem");
81 meshTransGrad->valeurs() = dom.getMeshTransformationGradient();
82
83 OWN_PTR(Champ_Inc_base) meshStress = make_champ("meshStress", dom.getMeshStressNbComp(), "champ_elem");
84 meshStress->valeurs() = dom.getMeshStress();
85
86 if (special && Process::nproc() > 1)
87 Cerr << "ATTENTION : parallel calculation, mesh fields not saved in xyz format" << finl;
88 else
89 {
90 bytes += meshDisplacement->sauvegarder(os);
91 bytes += meshVelocity->sauvegarder(os);
92 bytes += meshAcceleration->sauvegarder(os);
93 bytes += meshPosition->sauvegarder(os);
94 bytes += meshRefConfig->sauvegarder(os);
95 bytes += meshTransGrad->sauvegarder(os);
96 bytes += meshStress->sauvegarder(os);
97 }
98 }
99 }
101 {
102 //PDI / HDF5 parallel save path
103 bytes += write_pdi(pb.domaine_dis().domaine().les_sommets(),
104 (pb.le_nom() + "_MeshCoords").majuscule());
105
106 if (dom.getMeshMotionModel() == 1)
107 {
108 bytes += write_pdi(dom.getMeshDisplacement(), (pb.le_nom() + "_MeshDisplacement").majuscule());
109 bytes += write_pdi(dom.getMeshVelocity(), (pb.le_nom() + "_MeshVelocity").majuscule());
110 bytes += write_pdi(dom.getMeshAcceleration(), (pb.le_nom() + "_MeshAcceleration").majuscule());
111 bytes += write_pdi(dom.getMeshPosition(), (pb.le_nom() + "_MeshPosition").majuscule());
112 bytes += write_pdi(dom.getMeshReferenceConfiguration(),(pb.le_nom() + "_MeshReferenceConfiguration").majuscule());
113 bytes += write_pdi(dom.getMeshTransformationGradient(),(pb.le_nom() + "_MeshTransformationGradient").majuscule());
114 bytes += write_pdi(dom.getMeshStress(), (pb.le_nom() + "_MeshStress").majuscule());
115 }
116 }
117
118 return bytes;
119}
120
122{
123 const bool pdi_restart = static_cast<bool>(TRUST_2_PDI::is_PDI_restart());
124 int dimension=Objet_U::dimension;
125
127 {
128 Cerr << "Error in ALE_CheckpointManager::restore !" << finl;
129 Cerr << "Use serial checkpoint for parallel calculation." << finl;
131 }
132
133 // Helper lambda: allocate a temporary discretized field
134 auto make_champ = [&](const std::string& name, int nbComp, const std::string& directive)
135 {
136 OWN_PTR(Champ_Inc_base) champ;
137 Noms noms(1), unit(1);
138 noms[0] = name;
139 unit[0] = "none";
140 pb.discretisation().discretiser_champ(directive.c_str(), pb.domaine_dis(),
141 vectoriel, noms, unit, nbComp, 1,
142 pb.schema_temps().temps_courant(), champ);
143 champ->associer_eqn(dom.getEquation()); // non-const overload, dom is non-const here
144 return champ;
145 };
146
147 // Step 1: mesh coordinates
148 OWN_PTR(Champ_Inc_base) meshCoords = make_champ("meshCoords", dimension, "champ_sommets");
149
150 if (!pdi_restart)
151 {
152 avancer_fichier(is, generate_field_tag(meshCoords.valeur(), pb));
153 meshCoords->reprendre(is);
154 }
155 else
156 read_pdi(meshCoords, "_MeshCoords", pb);
157
158 dom.resumptionCoords(meshCoords->valeurs());
159 dom.updateMetrics(pb.domaine_dis(), pb);
160
161 // Step 2: structural dynamics fields (model == 1 only)
162 if (dom.getMeshMotionModel() == 1)
163 {
164 OWN_PTR(Champ_Inc_base) meshDisplacement = make_champ("meshDisplacement", dimension, "champ_sommets");
165 OWN_PTR(Champ_Inc_base) meshVelocity = make_champ("meshVelocity", dimension, "champ_sommets");
166 OWN_PTR(Champ_Inc_base) meshAcceleration = make_champ("meshAcceleration", dimension, "champ_sommets");
167 OWN_PTR(Champ_Inc_base) meshPosition = make_champ("meshPosition", dimension, "champ_sommets");
168 OWN_PTR(Champ_Inc_base) meshRefConfig = make_champ("meshReferenceConfiguration",
169 dom.getMeshReferenceConfigurationNbComp(), "champ_elem");
170 OWN_PTR(Champ_Inc_base) meshTransGrad = make_champ("meshTransformationGradient",
171 dom.getMeshTransformationGradientNbComp(), "champ_elem");
172 OWN_PTR(Champ_Inc_base) meshStress = make_champ("meshStress", dom.getMeshStressNbComp(), "champ_elem");
173
174 if (!pdi_restart)
175 {
176 // Standard binary: fields must be read in the exact order they were written
177 avancer_fichier(is, generate_field_tag(meshDisplacement.valeur(), pb));
178 meshDisplacement->reprendre(is);
179 avancer_fichier(is, generate_field_tag(meshVelocity.valeur(), pb));
180 meshVelocity->reprendre(is);
181 avancer_fichier(is, generate_field_tag(meshAcceleration.valeur(), pb));
182 meshAcceleration->reprendre(is);
183 avancer_fichier(is, generate_field_tag(meshPosition.valeur(), pb));
184 meshPosition->reprendre(is);
185 avancer_fichier(is, generate_field_tag(meshRefConfig.valeur(), pb));
186 meshRefConfig->reprendre(is);
187 avancer_fichier(is, generate_field_tag(meshTransGrad.valeur(), pb));
188 meshTransGrad->reprendre(is);
189 avancer_fichier(is, generate_field_tag(meshStress.valeur(), pb));
190 meshStress->reprendre(is);
191 }
192 else
193 {
194 // PDI: fields accessed by name, order is irrelevant
195 read_pdi(meshDisplacement, "_MeshDisplacement", pb);
196 read_pdi(meshVelocity, "_MeshVelocity", pb);
197 read_pdi(meshAcceleration, "_MeshAcceleration", pb);
198 read_pdi(meshPosition, "_MeshPosition", pb);
199 read_pdi(meshRefConfig, "_MeshReferenceConfiguration",pb);
200 read_pdi(meshTransGrad, "_MeshTransformationGradient",pb);
201 read_pdi(meshStress, "_MeshStress", pb);
202 }
203
206 meshDisplacement->valeurs(), meshVelocity->valeurs(),
207 meshAcceleration->valeurs(), meshPosition->valeurs(),
208 meshRefConfig->valeurs(), meshTransGrad->valeurs(),
209 meshStress->valeurs());
210 }
211
212 return 1;
213}
214
215int ALE_CheckpointManager::write_pdi(const DoubleTab& d, const Nom& pdi_name) const
216{
217 TRUST_2_PDI pdi_interface;
218 pdi_interface.share_TRUSTTab_dimensions(d, pdi_name, 1);
219 if (d.dimension_tot(0))
220 pdi_interface.TRUST_start_sharing(pdi_name.getString(), d.addr());
221 else
222 {
223 ArrOfDouble garbage(d.nb_dim()); // PDI requires non-null pointer on empty MPI ranks
224 pdi_interface.TRUST_start_sharing(pdi_name.getString(), garbage.addr());
225 }
226 return 8 * d.size_array();
227}
228
229void ALE_CheckpointManager::read_pdi(OWN_PTR(Champ_Inc_base)& champ,
230 const std::string& suffix,
231 const Probleme_base& pb) const
232{
233 TRUST_2_PDI pdi_interface;
234 Nom pdi_name = (pb.le_nom() + Nom(suffix.c_str())).majuscule();
235 pdi_interface.share_TRUSTTab_dimensions(champ->valeurs(), pdi_name, 0);
236 if (champ->valeurs().dimension_tot(0))
237 pdi_interface.read(pdi_name.getChar(), champ->valeurs().addr());
238 else
239 {
240 ArrOfDouble garbage(champ->valeurs().nb_dim());
241 pdi_interface.read(pdi_name.getChar(), garbage.addr());
242 }
243}
244
246 const Probleme_base& pb) const
247{
248 Nom tag = champ.le_nom();
249 tag += champ.que_suis_je();
250 tag += pb.domaine().le_nom();
252 return tag;
253}
254
255YAML_data ALE_CheckpointManager::make_yaml(const std::string& suffix, int nb_dim,
256 const Probleme_base& pb) const
257{
258 std::string name = pb.le_nom().getString() + suffix;
259 std::transform(name.begin(), name.end(), name.begin(), ::toupper);
260 return YAML_data(name, "double", nb_dim);
261}
262
264 const Domaine_ALE& dom) const
265{
266 constexpr int nb_dim = 2;
267 std::vector<YAML_data> data;
268 data.push_back(make_yaml("_MeshCoords", nb_dim, pb));
269 if (dom.getMeshMotionModel() == 1)
270 {
271 data.push_back(make_yaml("_MeshDisplacement", nb_dim, pb));
272 data.push_back(make_yaml("_MeshVelocity", nb_dim, pb));
273 data.push_back(make_yaml("_MeshAcceleration", nb_dim, pb));
274 data.push_back(make_yaml("_MeshPosition", nb_dim, pb));
275 data.push_back(make_yaml("_MeshReferenceConfiguration",nb_dim, pb));
276 data.push_back(make_yaml("_MeshTransformationGradient",nb_dim, pb));
277 data.push_back(make_yaml("_MeshStress", nb_dim, pb));
278 }
279 return data;
280}
281
283 const std::string& name, int nbComp,
284 const Motcle& directive,
285 const Probleme_base& pb,
286 Domaine_ALE& dom) const
287{
288 double temps = pb.schema_temps().temps_courant();
289 Noms noms(1), unit(1);
290 unit[0] = "none";
291 noms[0] = name;
292 pb.discretisation().discretiser_champ(directive, pb.domaine_dis(),
293 vectoriel, noms, unit, nbComp, 1, temps, champ);
294 dom.get_champs_compris().ajoute_champ(champ); // via public accessor, no friend needed
295 champ->add_synonymous(name);
296}
Nom generate_field_tag(const Champ_Inc_base &champ, const Probleme_base &pb) const
int restore(Entree &is, Probleme_base &pb, Domaine_ALE &dom)
YAML_data make_yaml(const std::string &suffix, int nb_dim, const Probleme_base &pb) const
void create_field(OWN_PTR(Champ_Inc_base)&champ, const std::string &name, int nbComp, const Motcle &directive, const Probleme_base &pb, Domaine_ALE &dom) const
std::vector< YAML_data > data_a_sauvegarder(const Probleme_base &pb, const Domaine_ALE &dom) const
int save(Sortie &os, const Probleme_base &pb, const Domaine_ALE &dom) const
Classe Champ_Inc_base.
void ajoute_champ(const FIELD_TYPE &champ)
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
DoubleTab_t & les_sommets()
Definition Domaine.h:113
const DoubleTab & getMeshTransformationGradient() const
const DoubleTab & getMeshPosition() const
int getMeshMotionModel() const
Definition Domaine_ALE.h:84
Champs_compris & get_champs_compris()
void updateMetrics(Domaine_dis_base &, Probleme_base &)
const DoubleTab & getMeshStress() const
void resumptionCoords(DoubleTab &)
const DoubleTab & getMeshDisplacement() const
const int & getMeshStressNbComp() const
const int & getMeshTransformationGradientNbComp() const
Equation_base & getEquation()
const DoubleTab & getMeshVelocity() const
const int & getMeshReferenceConfigurationNbComp() const
void resumptionStructuralDynamicsMesh(double, DoubleTab &, DoubleTab &, DoubleTab &, DoubleTab &, DoubleTab &, DoubleTab &, DoubleTab &)
const DoubleTab & getMeshReferenceConfiguration() const
const DoubleTab & getMeshAcceleration() const
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
const Domaine & domaine() const
static int is_ecriture_special(int &special, int &a_faire)
indique si le format special a ete demande en lecture active par sauvegarde xyz .
static int is_lecture_special()
indique si le format special a ete demande en lecture active par reprise xyz .
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const char * getChar() const
Definition Nom.h:91
Nom & majuscule()
Transforme le nom en majuscules Seules les lettres 'a'-'z' sont modifiees.
Definition Nom.cpp:180
const std::string & getString() const
Definition Nom.h:92
const Nom & le_nom() const override
Renvoie *this;.
Definition Nom.cpp:563
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual int sauvegarder(Sortie &) const
Sauvegarde d'un Objet_U sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:352
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Domaine & domaine() const
Renvoie le domaine associe au probleme.
const Discretisation_base & discretisation() const
Renvoie la discretisation associee au probleme.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
const Domaine_dis_base & domaine_dis() const
Renvoie le domaine discretise associe au probleme.
const char * reprise_format_temps() const
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
double temps_courant() const
Renvoie le temps courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const
_TYPE_ * addr()
int nb_dim() const
Definition TRUSTTab.h:199
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
classe TRUST_2_PDI Encapsulation of PDI methods (library used for IO operations). See the website pdi...
Definition TRUST_2_PDI.h:59
void read(const std::string &name, void *data)
static int is_PDI_checkpoint()
static int is_PDI_restart()
void share_TRUSTTab_dimensions(const DoubleTab &tab, const Nom &name, int write)
Generic method to share the dimensions of a TRUST DoubleTab with PDI.
void TRUST_start_sharing(const std::string &name, const void *data)
classe YAML_data : collection of all needed information for data to save/restore in order to write th...
Definition YAML_data.h:26