29#include <boost/mpi.hpp>
30#include <boost/mpi/collectives/all_reduce.hpp>
31#include <boost/mpi/collectives/broadcast.hpp>
45std::unordered_map<std::string, int>
const EKVTKHandle::obs_map = {
51 if (method ==
"update_flux_boundary_from_shape") {
52 auto values = get_value<std::vector<double>>(parameters,
"values");
53 std::transform(values.begin(), values.end(), values.begin(),
54 [
this](
double v) { return v * m_conv_flux; });
57 get_value<std::vector<int>>(parameters,
"raster"), values);
60 if (method ==
"update_density_boundary_from_shape") {
61 auto values = get_value<std::vector<double>>(parameters,
"values");
62 std::transform(values.begin(), values.end(), values.begin(),
63 [
this](
double v) { return v * m_conv_density; });
64 m_instance->update_density_boundary_from_shape(
65 get_value<std::vector<int>>(parameters,
"raster"), values);
68 if (method ==
"clear_flux_boundaries") {
72 if (method ==
"clear_density_boundaries") {
76 if (method ==
"save_checkpoint") {
77 auto const path = get_value<std::string>(parameters,
"path");
78 auto const mode = get_value<int>(parameters,
"mode");
79 save_checkpoint(path, mode);
82 if (method ==
"load_checkpoint") {
83 auto const path = get_value<std::string>(parameters,
"path");
84 auto const mode = get_value<int>(parameters,
"mode");
85 load_checkpoint(path, mode);
92 auto const diffusion = get_value<double>(
params,
"diffusion");
93 auto const ext_efield = get_value<Utils::Vector3d>(
params,
"ext_efield");
95 auto const kT = get_value<double>(
params,
"kT");
96 auto const precision = get_value<bool>(
params,
"single_precision");
102 m_lattice->lattice(), ek_diffusion, ek_kT,
103 get_value<double>(
params,
"valency"), ek_ext_efield, ek_density,
104 get_value<bool>(
params,
"advection"),
105 get_value<bool>(
params,
"friction_coupling"), precision);
109 m_lattice = get_value<std::shared_ptr<LatticeWalberla>>(
params,
"lattice");
111 get_value_or<decltype(m_vtk_writers)>(
params,
"vtk_writers", {});
112 auto const agrid = get_value<double>(
m_lattice->get_parameter(
"agrid"));
114 auto const kT = get_value<double>(
params,
"kT");
115 auto const tau =
m_tau = get_value<double>(
params,
"tau");
118 throw std::domain_error(
"Parameter 'tau' must be > 0");
121 throw std::domain_error(
"Parameter 'kT' must be >= 0");
124 throw std::domain_error(
"Parameter 'density' must be >= 0");
126 m_conv_energy = Utils::int_pow<2>(tau) / Utils::int_pow<2>(agrid);
139void EKSpecies::load_checkpoint(std::string
const &filename,
int mode) {
143 auto const expected_grid_size = ek_obj.get_lattice().get_grid_dimensions();
145 cpfile.read(read_grid_size);
146 if (read_grid_size != expected_grid_size) {
147 std::stringstream message;
148 message <<
"grid dimensions mismatch, read [" << read_grid_size <<
"], "
149 <<
"expected [" << expected_grid_size <<
"].";
150 throw std::runtime_error(message.str());
154 auto const read_data = [&ek_obj](CheckpointFile &cpfile) {
155 auto const grid_size = ek_obj.get_lattice().get_grid_dimensions();
156 auto const i_max = grid_size[0];
157 auto const j_max = grid_size[1];
158 auto const k_max = grid_size[2];
160 for (
int i = 0; i < i_max; i++) {
161 for (
int j = 0; j < j_max; j++) {
162 for (
int k = 0; k < k_max; k++) {
173 ek_obj.set_node_density(ind, cpnode.
density);
185 auto const on_success = [&ek_obj]() { ek_obj.ghost_communication(); };
188 read_data, on_success);
191void EKSpecies::save_checkpoint(std::string
const &filename,
int mode) {
194 auto const write_metadata = [&ek_obj,
195 mode](std::shared_ptr<CheckpointFile> cpfile_ptr,
197 auto const grid_size = ek_obj.get_lattice().get_grid_dimensions();
199 cpfile_ptr->write(grid_size);
204 auto const on_failure = [](std::shared_ptr<CheckpointFile>
const &,
212 auto const write_data = [&ek_obj,
213 mode](std::shared_ptr<CheckpointFile> cpfile_ptr,
215 auto const get_node_checkpoint =
216 [&](
Utils::Vector3i const &ind) -> std::optional<EKWalberlaNodeState> {
217 auto const density = ek_obj.get_node_density(ind);
218 auto const is_b_d = ek_obj.get_node_is_density_boundary(ind);
219 auto const dens_b = ek_obj.get_node_density_at_boundary(ind);
220 auto const is_b_f = ek_obj.get_node_is_flux_boundary(ind);
221 auto const flux_b = ek_obj.get_node_flux_at_boundary(ind);
222 if (
density and is_b_d and is_b_f and
223 ((*is_b_d) ? dens_b.has_value() :
true) and
224 ((*is_b_f) ? flux_b.has_value() :
true)) {
240 auto failure =
false;
243 auto const unit_test_mode = (mode !=
static_cast<int>(
CptMode::ascii)) and
245 auto const grid_size = ek_obj.get_lattice().get_grid_dimensions();
250 for (
int i = 0; i < i_max; i++) {
251 for (
int j = 0; j < j_max; j++) {
252 for (
int k = 0; k < k_max; k++) {
254 auto const result = get_node_checkpoint(ind);
255 if (!unit_test_mode) {
256 assert(1 == boost::mpi::all_reduce(comm,
static_cast<int>(!!result),
258 "Incorrect number of return values");
264 comm.recv(boost::mpi::any_source, 42, cpnode);
266 auto &cpfile = *cpfile_ptr;
276 boost::mpi::broadcast(comm, failure, 0);
279 comm.send(0, 42, *result);
281 boost::mpi::broadcast(comm, failure, 0);
292 write_data, on_failure);
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.
Handle for a checkpoint file.
void make_instance(VariantMap const ¶ms) override
Variant do_call_method(std::string const &method, VariantMap const ¶meters) override
::LatticeModel::units_map get_latice_to_md_units_conversion() const override
void do_construct(VariantMap const ¶ms) override
std::shared_ptr< ::EKinWalberlaBase > m_instance
Variant do_call_method(std::string const &method_name, VariantMap const ¶ms) override
std::vector< std::shared_ptr< EKVTKHandle > > m_vtk_writers
std::shared_ptr< LatticeWalberla > m_lattice
This file contains the defaults for ESPResSo.
void save_checkpoint_common(Context const &context, std::string const classname, std::string const &filename, int mode, F1 const write_metadata, F2 const write_data, F3 const on_failure)
void unit_test_handle(int mode)
Inject code for unit tests.
void load_checkpoint_common(Context const &context, std::string const classname, std::string const &filename, 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
boost::make_recursive_variant< None, bool, int, std::size_t, double, std::string, ObjectRef, Utils::Vector3b, Utils::Vector3i, Utils::Vector2d, Utils::Vector3d, Utils::Vector4d, std::vector< int >, std::vector< double >, std::vector< boost::recursive_variant_ >, std::unordered_map< int, boost::recursive_variant_ >, std::unordered_map< std::string, boost::recursive_variant_ > >::type Variant
Possible types for parameters.
static FUNC_PREFIX double *RESTRICT int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const double grid_size
std::shared_ptr< EKinWalberlaBase > new_ek_walberla(std::shared_ptr< LatticeWalberla > const &lattice, double diffusion, double kT, double valency, Utils::Vector3d ext_efield, double density, bool advection, bool friction_coupling, bool single_precision)
static SteepestDescentParameters params
Currently active steepest descent instance.
Checkpoint data for a EK node.
Utils::Vector3d flux_boundary