21#ifdef ESPRESSO_WALBERLA
46#include <boost/mpi.hpp>
47#include <boost/mpi/collectives/all_reduce.hpp>
48#include <boost/mpi/collectives/broadcast.hpp>
60#include <unordered_map>
65std::unordered_map<std::string, int>
const LBVTKHandle::obs_map = {
74 if (
name ==
"activate") {
75 auto &
system = get_system();
83 if (
name ==
"deactivate") {
88 if (
not name.starts_with(
"get_")) {
92 if (
name ==
"add_force_at_pos") {
93 auto const &box_geo = *get_system().
box_geo;
96 auto const folded_pos = box_geo.folded_position(pos);
100 if (
name ==
"get_interpolated_velocity") {
102 return get_interpolated_velocity(pos);
104 if (
name ==
"get_boundary_force_from_shape") {
105 return get_boundary_force_from_shape(
106 get_value<std::vector<int>>(params,
"raster"));
108 if (
name ==
"get_boundary_force") {
109 return get_boundary_force();
111 if (
name ==
"get_pressure_tensor") {
112 return get_average_pressure_tensor();
114 if (
name ==
"load_checkpoint") {
117 load_checkpoint(path,
mode);
120 if (
name ==
"save_checkpoint") {
123 save_checkpoint(path,
mode);
126 if (
name ==
"clear_boundaries") {
131 if (
name ==
"add_boundary_from_shape") {
133 get_value<std::vector<int>>(params,
"raster"),
134 get_value<std::vector<double>>(params,
"values"));
137 if (
name ==
"get_lattice_speed") {
159 m_lattice->get_parameter(
"blocks_per_mpi_rank"));
161 throw std::runtime_error(
162 "Using more than one block per MPI rank is not supported for GPU LB");
185 throw std::domain_error(
"Parameter 'tau' must be > 0");
200 throw std::domain_error(
"Parameter 'seed' must be >= 0");
203 throw std::domain_error(
"Parameter 'kT' must be >= 0");
206 throw std::domain_error(
"Parameter 'density' must be > 0");
209 throw std::domain_error(
"Parameter 'kinematic_viscosity' must be >= 0");
223LBFluid::get_boundary_force_from_shape(std::vector<int>
const &raster)
const {
229Variant LBFluid::get_boundary_force()
const {
234std::vector<Variant> LBFluid::get_average_pressure_tensor()
const {
239 return std::vector<Variant>{
tensor.row<0>().as_vector(),
240 tensor.row<1>().as_vector(),
241 tensor.row<2>().as_vector()};
252void LBFluid::load_checkpoint(std::filesystem::path
const &path,
int mode) {
263 std::stringstream message;
264 message <<
"grid dimensions mismatch, read [" <<
read_grid_size <<
"], "
266 throw std::runtime_error(message.str());
269 throw std::runtime_error(
"population size mismatch, read " +
282 for (
int i = 0; i <
i_max; i++) {
284 for (
int k = 0; k <
k_max; k++) {
293 lb_obj.set_node_last_applied_force(ind,
cpnode.last_applied_force);
295 lb_obj.set_node_velocity_at_boundary(ind,
cpnode.slip_velocity);
303 lb_obj.ghost_communication();
304 lb_obj.reallocate_ubb_field();
311void LBFluid::save_checkpoint(std::filesystem::path
const &path,
int mode) {
326 auto const on_failure = [](std::shared_ptr<CheckpointFile>
const &,
338 [&](
Utils::Vector3i const &ind) -> std::optional<LBWalberlaNodeState> {
339 auto const pop =
lb_obj.get_node_population(ind);
340 auto const laf =
lb_obj.get_node_last_applied_force(ind);
341 auto const lbb =
lb_obj.get_node_is_boundary(ind);
342 auto const vbb =
lb_obj.get_node_velocity_at_boundary(ind);
356 auto failure =
false;
366 for (
int i = 0; i <
i_max; i++) {
368 for (
int k = 0; k <
k_max; k++) {
372 assert(1 == boost::mpi::all_reduce(comm,
static_cast<int>(!!result),
374 "Incorrect number of return values");
380 comm.recv(boost::mpi::any_source, 42,
cpnode);
389 boost::mpi::broadcast(comm, failure, 0);
392 comm.send(0, 42, *result);
394 boost::mpi::broadcast(comm, failure, 0);
Vector implementation and trait types for boost qvm interoperability.
virtual void parallel_try_catch(std::function< void()> const &cb) const =0
virtual bool is_head_node() const =0
virtual boost::mpi::communicator const & get_comm() const =0
Context * context() const
Responsible context.
std::string_view name() const
std::optional< ResourceObserver > m_mpi_cart_comm_observer
void do_construct(VariantMap const ¶ms) override
void make_instance(VariantMap const ¶ms) override
::LatticeModel::units_map get_lattice_to_md_units_conversion() const override
Variant do_call_method(std::string const &name, VariantMap const ¶ms) override
std::shared_ptr<::LB::LBWalberlaParams > m_lb_params
std::shared_ptr< ::LBWalberlaBase > m_instance
Variant do_call_method(std::string const &method_name, VariantMap const ¶ms) override
std::vector< std::shared_ptr< LBVTKHandle > > m_vtk_writers
std::shared_ptr< LatticeWalberla > m_lattice
void on_lb_boundary_conditions_change()
Called when the LB boundary conditions change (geometry, slip velocity, or both).
std::shared_ptr< BoxGeometry > box_geo
std::shared_ptr< LBWalberlaBase > new_lb_walberla_cpu(std::shared_ptr< LatticeWalberla > const &lattice, double viscosity, double density, bool single_precision)
std::shared_ptr< LBWalberlaBase > new_lb_walberla_gpu(std::shared_ptr< LatticeWalberla > const &lattice, double viscosity, double density, bool single_precision)
Matrix implementation and trait types for boost qvm interoperability.
void check_features(std::vector< std::string > const &features)
void save_checkpoint_common(Context const &context, std::string const classname, std::filesystem::path const &path, int mode, F1 const write_metadata, F2 const write_data, F3 const on_failure)
void lb_throw_if_expired(std::optional< ResourceObserver > const &mpi_obs)
void unit_test_handle(int mode)
Inject code for unit tests.
void load_checkpoint_common(Context const &context, std::string const classname, std::filesystem::path const &path, int mode, F1 const read_metadata, F2 const read_data, F3 const on_success)
T get_value(Variant const &v)
Extract value of specific type T from a Variant.
std::unordered_map< std::string, Variant > VariantMap
T get_value_or(VariantMap const &vals, std::string const &name, T const &default_)
Get a value from a VariantMap by name, or return a default value if it does not exist.
T mpi_reduce_sum(boost::mpi::communicator const &comm, T const &result)
Reduce object by sum on the head node.
make_recursive_variant< ObjectRef > Variant
Possible types for parameters.
T reduce_optional(boost::mpi::communicator const &comm, std::optional< T > const &result)
Reduce an optional on the head node.
ResourceObserver get_mpi_cart_comm_observer()
Get an observer on waLBerla's MPI Cartesian communicator status.
Checkpoint data for a LB node.
std::vector< double > populations
void update_collision_model()
void reset()
Remove the LB solver.
Recursive variant implementation.
Matrix representation with static size.