24#ifdef ESPRESSO_WALBERLA
32#include <boost/algorithm/string/join.hpp>
40#include <unordered_map>
51 bool m_include_boundaries;
52 std::string m_identifier;
53 std::filesystem::path m_base_folder;
55 std::shared_ptr<::VTKHandle> m_vtk_handle;
56 std::weak_ptr<Field> m_field;
58 std::vector<Variant> m_pending_arguments;
61 return m_base_folder.generic_string() +
"/" + m_identifier;
64 [[
nodiscard]] std::shared_ptr<Field> get_field_instance()
const {
65 if (
auto const field = m_field.lock()) {
69 auto const err_expired =
"Attempted access to an expired lattice object";
70 auto const err_detached =
"This VTK object isn't attached to a lattice";
74 virtual std::unordered_map<std::string, int>
const &
get_obs_map()
const = 0;
76 [[
nodiscard]]
auto get_valid_observable_names()
const {
79 std::ranges::sort(
names);
84 deserialize_obs_flag(std::vector<std::string>
const &
names)
const {
88 if (
not obs_map.contains(
name)) {
89 auto const valid_names = get_valid_observable_names();
90 std::stringstream message;
91 message <<
"Only the following VTK observables are supported: ['"
92 << boost::algorithm::join(
valid_names,
"', '") <<
"'], got '"
94 throw std::invalid_argument(message.str());
115 {
"enabled", read_only, [
this]() {
return m_vtk_handle->enabled; }},
116 {
"delta_N", read_only, [
this]() {
return m_delta_N; }},
117 {
"vtk_uid", read_only, [
this]() {
return get_vtk_uid(); }},
118 {
"identifier", read_only, [
this]() {
return m_identifier; }},
119 {
"base_folder", read_only, [
this]() {
return m_base_folder; }},
120 {
"prefix", read_only, [
this]() {
return m_prefix; }},
121 {
"force_pvtu", read_only, [
this]() {
return m_force_pvtu; }},
122 {
"include_boundaries", read_only,
123 [
this]() {
return m_include_boundaries; }},
124 {
"observables", read_only,
125 [
this]() {
return serialize_obs_flag(m_obs_flag); }},
126 {
"execution_count", read_only,
127 [
this]() {
return m_vtk_handle->execution_count; }},
140 m_include_boundaries =
143 auto const execution_count =
get_value<int>(params,
"execution_count");
145 m_obs_flag = deserialize_obs_flag(
146 get_value<std::vector<std::string>>(params,
"observables"));
148 throw std::domain_error(
"Parameter 'delta_N' must be >= 0");
150 if (m_identifier.empty()) {
151 throw std::domain_error(
"Parameter 'identifier' cannot be empty");
153 if (m_identifier.find(std::filesystem::path::preferred_separator) !=
155 throw std::invalid_argument(
156 "Parameter 'identifier' cannot be a filepath");
159 m_pending_arguments.emplace_back(is_enabled);
160 m_pending_arguments.emplace_back(execution_count);
165 if (
name ==
"enable") {
167 if (m_delta_N == 0) {
168 throw std::runtime_error(
"Manual VTK callbacks cannot be enabled");
170 get_field_instance()->switch_vtk(get_vtk_uid(),
true);
174 if (
name ==
"disable") {
176 if (m_delta_N == 0) {
177 throw std::runtime_error(
"Manual VTK callbacks cannot be disabled");
179 get_field_instance()->switch_vtk(get_vtk_uid(),
false);
183 if (
name ==
"write") {
186 throw std::runtime_error(
"Automatic VTK callbacks cannot be "
187 "triggered manually");
189 get_field_instance()->write_vtk(get_vtk_uid());
193 if (
name ==
"get_valid_observable_names") {
206 if (
not m_field.expired()) {
207 throw std::runtime_error(
"Cannot attach VTK object to multiple lattices");
210 throw std::runtime_error(
"Detached VTK objects cannot be attached again");
212 assert(m_pending_arguments.size() == 2u);
214 auto const execution_count =
get_value<int>(m_pending_arguments[1]);
215 auto const base_folder = m_base_folder.generic_string();
218 auto instance = get_field_instance();
219 m_vtk_handle = instance->create_vtk(
220 m_delta_N, execution_count, m_obs_flag, m_units, m_identifier,
221 base_folder, m_prefix, m_force_pvtu, m_include_boundaries);
222 if (m_delta_N
and not is_enabled) {
223 instance->switch_vtk(get_vtk_uid(),
false);
225 m_pending_arguments.clear();
std::unordered_map< std::string, double > units_map
Bind parameters in the script interface.
void add_parameters(std::vector< AutoParameter > &¶ms)
virtual void parallel_try_catch(std::function< void()> const &cb) const =0
Context * context() const
Responsible context.
std::string_view name() const
void detach_from_lattice()
void do_construct(VariantMap const ¶ms) override
Variant do_call_method(std::string const &name, VariantMap const &) override
void attach_to_lattice(std::weak_ptr< Field > field, ::LatticeModel::units_map const &units)
virtual std::unordered_map< std::string, int > const & get_obs_map() const =0
T get_value(Variant const &v)
Extract value of specific type T from a Variant.
std::unordered_map< std::string, Variant > VariantMap
auto make_unordered_map_of_variants(std::unordered_map< K, V > const &v)
auto make_vector_of_variants(std::vector< T > const &v)
make_recursive_variant< ObjectRef > Variant
Possible types for parameters.
static constexpr const ReadOnly read_only
Recursive variant implementation.