Skip to content

Commit e4c38c4

Browse files
committed
allow usage of immutable externally allocated memory: API break in the definition of the FieldHolder data structure
1 parent 4348716 commit e4c38c4

5 files changed

Lines changed: 667 additions & 312 deletions

File tree

include/MGIS/Behaviour/MaterialStateManager.hxx

Lines changed: 138 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,15 @@ namespace mgis::behaviour {
100100
* - The internal state variables are treated as a block.
101101
*/
102102
struct MGIS_EXPORT MaterialStateManager {
103-
//! \brief a simple alias
104-
struct FieldHolder {
105-
FieldHolder& operator=(const mgis::real) noexcept;
103+
/*!
104+
* \brief a structure defining a mutable field holder
105+
*
106+
* A mutable field holder may be a scalar value, a reference to externally
107+
* allocated date (`std:span` case), or values handled internally
108+
* (`std::vector` case).
109+
*/
110+
struct MGIS_EXPORT MutableFieldHolder {
111+
MutableFieldHolder& operator=(const mgis::real) noexcept;
106112
//! \brief pointer to the values of the field
107113
std::variant<real, std::span<mgis::real>, std::vector<mgis::real>> value;
108114
/*!
@@ -111,8 +117,27 @@ namespace mgis::behaviour {
111117
*
112118
* Setting this flag is usefull when the update of the field is already
113119
* handled.
120+
*
121+
* \warning `shall_be_updated` must not be equal to `true` if the value of
122+
* the constant (i.e. is of type `std::span<const real>`)
114123
*/
115124
bool shall_be_updated = true;
125+
}; // end of struct MutableFieldHolder
126+
/*!
127+
*
128+
*/
129+
struct MGIS_EXPORT FieldHolder : std::variant<std::monostate,
130+
std::span<const mgis::real>,
131+
MutableFieldHolder> {
132+
// exposing constructors
133+
using std::variant<std::monostate,
134+
std::span<const mgis::real>,
135+
MutableFieldHolder>::variant;
136+
//
137+
using std::variant<std::monostate,
138+
std::span<const mgis::real>,
139+
MutableFieldHolder>::operator=;
140+
FieldHolder& operator=(const mgis::real) noexcept;
116141
};
117142
/*!
118143
* \brief enum used to express if a variable (material property, external
@@ -159,21 +184,22 @@ namespace mgis::behaviour {
159184
std::span<mgis::real> dissipated_energies;
160185
/*!
161186
* \brief material properties
187+
*
162188
* The material properties can be uniform or not.
163189
* In the non uniform case, the data can be hold by the structure
164190
* (std::vector<real>) or simply borrow a reference
165-
* (std::span<mgis::real>
166-
* case).
191+
* (std::span<mgis::real> case).
167192
*/
168193
std::map<std::string, FieldHolder, std::less<>> material_properties;
169-
/*! \brief mass density
194+
/*!
195+
* \brief mass density
196+
*
170197
* The mass density can be uniform or not.
171198
* In the non uniform case, the data can be hold by the structure
172199
* (std::vector<real>) or simply borrow a reference
173-
* (std::span<mgis::real>
174-
* case).
200+
* (std::span<mgis::real> case).
175201
*/
176-
std::optional<FieldHolder> mass_density;
202+
std::optional<MutableFieldHolder> mass_density;
177203
//! \brief view to the values of the internal state variables
178204
std::span<mgis::real> internal_state_variables;
179205
/*!
@@ -184,6 +210,7 @@ namespace mgis::behaviour {
184210
const size_type internal_state_variables_stride;
185211
/*!
186212
* \brief values of the external state variables
213+
*
187214
* The external state variables can be uniform or not.
188215
* In the non uniform case, the data can be hold by the structure
189216
* (std::vector<real>) or simply borrow a reference
@@ -240,7 +267,7 @@ namespace mgis::behaviour {
240267
MGIS_EXPORT void setMaterialProperty(
241268
MaterialStateManager&,
242269
std::string_view,
243-
const std::span<mgis::real>&,
270+
std::span<mgis::real>,
244271
const MaterialStateManager::StorageMode =
245272
MaterialStateManager::LOCAL_STORAGE,
246273
const MaterialStateManager::UpdatePolicy = MaterialStateManager::UPDATE);
@@ -261,20 +288,43 @@ namespace mgis::behaviour {
261288
const MaterialStateManager::UpdatePolicy =
262289
MaterialStateManager::UPDATE) noexcept;
263290
/*!
264-
* \brief set the given material property
291+
* \brief set the given material property from a modifiable memory region
292+
*
293+
* \param[in, out] ctx: execution context
294+
* \param[out] m: material state manager
295+
* \param[in] n: name
296+
* \param[in] v: values
297+
* \param[in] s: storage mode
298+
* \param[in] p: update policy
299+
*/
300+
MGIS_EXPORT [[nodiscard]] bool setMaterialProperty(
301+
Context&,
302+
MaterialStateManager&,
303+
std::string_view,
304+
std::span<mgis::real>,
305+
const MaterialStateManager::StorageMode =
306+
MaterialStateManager::LOCAL_STORAGE,
307+
const MaterialStateManager::UpdatePolicy =
308+
MaterialStateManager::UPDATE) noexcept;
309+
/*!
310+
* \brief set the given material property from an immutable memory region
265311
*
266312
* \param[in, out] ctx: execution context
267313
* \param[out] m: material state manager
268314
* \param[in] n: name
269315
* \param[in] v: values
270316
* \param[in] s: storage mode
271317
* \param[in] p: update policy
318+
*
319+
* \note the `UpdatePolicy` can be set to `UPDATE` in case of local storage,
320+
* i.e. the `UpdatePolicy` must be set to `NOUPDATE` in case of external
321+
* storage
272322
*/
273323
MGIS_EXPORT [[nodiscard]] bool setMaterialProperty(
274324
Context&,
275325
MaterialStateManager&,
276326
std::string_view,
277-
const std::span<mgis::real>&,
327+
std::span<const mgis::real>,
278328
const MaterialStateManager::StorageMode =
279329
MaterialStateManager::LOCAL_STORAGE,
280330
const MaterialStateManager::UpdatePolicy =
@@ -291,51 +341,68 @@ namespace mgis::behaviour {
291341
Context&, MaterialStateManager&, std::string_view) noexcept;
292342
/*!
293343
* \return true if the given external state variable is defined.
294-
* \param[out] m: material state manager
344+
* \param[in] m: material state manager
295345
* \param[in] n: name
296346
*/
297347
MGIS_EXPORT bool isMaterialPropertyDefined(const MaterialStateManager&,
298348
std::string_view);
299349
/*!
300350
* \brief chek if the given material property is uniform
301-
* \param[out] m: material state manager
351+
* \param[in] m: material state manager
302352
* \param[in] n: name
303353
*/
304354
MGIS_EXPORT bool isMaterialPropertyUniform(const MaterialStateManager&,
305355
std::string_view);
356+
/*!
357+
* \brief chek if the given material property is uniform
358+
*
359+
* \param[in, out] ctx: execution context
360+
* \param[in] m: material state manager
361+
* \param[in] n: name
362+
*/
363+
MGIS_EXPORT [[nodiscard]] std::optional<bool> isMaterialPropertyUniform(
364+
Context&, const MaterialStateManager&, std::string_view) noexcept;
306365
/*!
307366
* \brief set the mass density
308367
* \param[out] m: material state manager
309368
* \param[in] v: value
310369
* \param[in] p: update policy
311370
*/
312-
MGIS_EXPORT void setMassDensity(
313-
MaterialStateManager&,
314-
const real,
315-
const MaterialStateManager::UpdatePolicy = MaterialStateManager::UPDATE);
371+
MGIS_EXPORT void setMassDensity(MaterialStateManager&,
372+
const real,
373+
const MaterialStateManager::UpdatePolicy =
374+
MaterialStateManager::UPDATE) noexcept;
316375
/*!
317376
* \brief set the mass density
318-
* \param[out] m: material state manager
377+
* \param[in] m: material state manager
319378
* \param[in] v: values
320379
* \param[in] s: storage mode
321380
* \param[in] p: update policy
322381
*/
323382
MGIS_EXPORT void setMassDensity(
324383
MaterialStateManager&,
325-
const std::span<mgis::real>&,
384+
std::span<mgis::real>,
326385
const MaterialStateManager::StorageMode =
327386
MaterialStateManager::LOCAL_STORAGE,
328387
const MaterialStateManager::UpdatePolicy = MaterialStateManager::UPDATE);
329388
/*!
330389
* \return true if the given external state variable is defined.
331390
* \param[out] m: material state manager
332391
*/
333-
MGIS_EXPORT bool isMassDensityDefined(const MaterialStateManager&);
392+
MGIS_EXPORT bool isMassDensityDefined(const MaterialStateManager&) noexcept;
334393
/*!
335394
* \return true if the mass density is uniform
336-
* \param[out] m: material state manager
395+
* \param[in] m: material state manager
337396
*/
338397
MGIS_EXPORT bool isMassDensityUniform(const MaterialStateManager&);
398+
/*!
399+
* \return true if the mass density is uniform
400+
*
401+
* \param[in, out] ctx: execution context
402+
* \param[in] m: material state manager
403+
*/
404+
MGIS_EXPORT [[nodiscard]] std::optional<bool> isMassDensityUniform(
405+
Context&, const MaterialStateManager&) noexcept;
339406
/*!
340407
* \brief set the given external state variable
341408
* \param[out] m: material state manager
@@ -359,7 +426,7 @@ namespace mgis::behaviour {
359426
MGIS_EXPORT void setExternalStateVariable(
360427
MaterialStateManager&,
361428
std::string_view,
362-
const std::span<mgis::real>&,
429+
std::span<mgis::real>,
363430
const MaterialStateManager::StorageMode =
364431
MaterialStateManager::LOCAL_STORAGE,
365432
const MaterialStateManager::UpdatePolicy = MaterialStateManager::UPDATE);
@@ -393,7 +460,31 @@ namespace mgis::behaviour {
393460
Context&,
394461
MaterialStateManager&,
395462
std::string_view,
396-
const std::span<mgis::real>&,
463+
std::span<mgis::real>,
464+
const MaterialStateManager::StorageMode =
465+
MaterialStateManager::LOCAL_STORAGE,
466+
const MaterialStateManager::UpdatePolicy =
467+
MaterialStateManager::UPDATE) noexcept;
468+
/*!
469+
* \brief set the given external state variable from a non-modifiable memory
470+
* region
471+
*
472+
* \param[in, out] ctx: execution context
473+
* \param[out] m: material state manager
474+
* \param[in] n: name
475+
* \param[in] v: values
476+
* \param[in] s: storage mode
477+
* \param[in] p: update policy
478+
*
479+
* \note the `UpdatePolicy` can be set to `UPDATE` in case of local storage,
480+
* i.e. the `UpdatePolicy` must be set to `NOUPDATE` in case of external
481+
* storage
482+
*/
483+
MGIS_EXPORT [[nodiscard]] bool setExternalStateVariable(
484+
Context&,
485+
MaterialStateManager&,
486+
std::string_view,
487+
std::span<const mgis::real>,
397488
const MaterialStateManager::StorageMode =
398489
MaterialStateManager::LOCAL_STORAGE,
399490
const MaterialStateManager::UpdatePolicy =
@@ -410,25 +501,41 @@ namespace mgis::behaviour {
410501
Context&, MaterialStateManager&, std::string_view) noexcept;
411502
/*!
412503
* \return true if the given external state variable is defined.
413-
* \param[out] m: material state manager
504+
* \param[int] m: material state manager
414505
* \param[in] n: name
415506
*/
416507
MGIS_EXPORT bool isExternalStateVariableDefined(const MaterialStateManager&,
417508
std::string_view);
418509
/*!
419510
* \return true if the given external state variable is uniform.
420-
* \param[out] m: material state manager
511+
* \param[int] m: material state manager
421512
* \param[in] n: name
422513
*/
423514
MGIS_EXPORT bool isExternalStateVariableUniform(const MaterialStateManager&,
424515
std::string_view);
516+
/*!
517+
* \return true if the given external state variable is uniform.
518+
*
519+
* \param[in, out] ctx: execution context
520+
* \param[int] m: material state manager
521+
* \param[in] n: name
522+
*/
523+
MGIS_EXPORT [[nodiscard]] std::optional<bool> isExternalStateVariableUniform(
524+
Context&, const MaterialStateManager&, std::string_view) noexcept;
425525
/*!
426526
* \brief update the values of a state from another state
427527
* \param[out] o: output state
428528
* \param[out] i: input state
429529
*/
430530
MGIS_EXPORT void updateValues(MaterialStateManager&,
431531
const MaterialStateManager&);
532+
/*!
533+
* \brief update the values of a state from another state
534+
* \param[out] o: output state
535+
* \param[out] i: input state
536+
*/
537+
MGIS_EXPORT [[nodiscard]] bool updateValues(
538+
Context&, MaterialStateManager&, const MaterialStateManager&) noexcept;
432539
/*!
433540
* \brief extract an internal state variable
434541
*
@@ -496,6 +603,11 @@ namespace mgis::behaviour {
496603
const bool restore_internal_state_variables = true;
497604
const bool restore_mass_densities = true;
498605
const bool restore_material_properties = true;
606+
/*!
607+
* \brief flag stating if constant variables is ignored. If not, an error is
608+
* reported stating that constant variables can't be restored
609+
*/
610+
const bool ignore_constant_variables = true;
499611
//! \brief list of material properties that shall not be restored
500612
const std::vector<std::string> ignored_material_properties = {};
501613
const bool restore_external_state_variables = true;

src/Integrate.cxx

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,27 @@ namespace mgis::behaviour::internals {
9393
std::make_tuple(offset, s, variable_values.data()));
9494
}
9595
};
96-
if (std::holds_alternative<real>(p->second.value)) {
97-
if (d.type != Variable::SCALAR) {
98-
mgis::raise(
99-
"buildEvaluators: invalid type for "
100-
"variable '" +
101-
d.name + "'");
102-
}
103-
v[offset] = std::get<real>(p->second.value);
104-
} else if (std::holds_alternative<std::span<real>>(p->second.value)) {
105-
set_values(std::get<std::span<real>>(p->second.value));
96+
if (std::holds_alternative<std::monostate>(p->second)) {
97+
raise("uninitialized field holder '" + p->first + "'");
98+
}
99+
if (std::holds_alternative<std::span<const real>>(p->second)) {
100+
set_values(std::get<std::span<const real>>(p->second));
106101
} else {
107-
set_values(std::get<std::vector<real>>(p->second.value));
102+
const auto& fh =
103+
std::get<MaterialStateManager::MutableFieldHolder>(p->second);
104+
if (std::holds_alternative<real>(fh.value)) {
105+
if (d.type != Variable::SCALAR) {
106+
mgis::raise(
107+
"buildEvaluators: invalid type for "
108+
"variable '" +
109+
d.name + "'");
110+
}
111+
v[offset] = std::get<real>(fh.value);
112+
} else if (std::holds_alternative<std::span<real>>(fh.value)) {
113+
set_values(std::get<std::span<real>>(fh.value));
114+
} else {
115+
set_values(std::get<std::vector<real>>(fh.value));
116+
}
108117
}
109118
offset += s;
110119
}

0 commit comments

Comments
 (0)