TrioCFD 1.9.9_beta
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
Class 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
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
const Domaine & domaine() const
static int is_ecriture_special(int &special, int &a_faire)
Indicates whether the special format was requested in active writing by xyz save.
static int is_lecture_special()
Indicates whether the special format was requested in active reading by xyz restart.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
const char * getChar() const
Definition Nom.h:91
Nom & majuscule()
Converts the name to uppercase. Only letters 'a'-'z' are modified.
Definition Nom.cpp:176
const std::string & getString() const
Definition Nom.h:92
const Nom & le_nom() const override
Returns *this.
Definition Nom.cpp:555
An array of character strings (VECT(Nom)).
Definition Noms.h:26
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual int sauvegarder(Sortie &) const
Saves an Objet_U to an output stream. Virtual method to override.
Definition Objet_U.cpp:350
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Probleme_U.h:109
class Probleme_base It is a Probleme_U that is not a coupling.
const Domaine & domaine() const
Returns the domain associated with the problem.
const Discretisation_base & discretisation() const
Returns the discretization associated with the problem.
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
const Domaine_dis_base & domaine_dis() const
Returns the discretized domain associated with the problem (const version).
const char * reprise_format_temps() const
static int nproc()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
Definition Process.cpp:102
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
double temps_courant() const
Returns the current time.
Base class for output streams.
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
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)
YAML_data class: collection of all needed information for data to save/restore in order to write the ...
Definition YAML_data.h:26