56#ifdef ESPRESSO_WALBERLA_FFT
57 std::shared_ptr<EKFFT>,
59 std::shared_ptr<EKNone>>
62 std::shared_ptr<EKReactions> m_ek_reactions;
63 std::shared_ptr<::EK::EKWalberla> m_ek_instance;
64 std::shared_ptr<::EK::EKWalberla::ek_container_type> m_ek_container;
67 auto get_precision(
decltype(m_poisson_solver)
const &solver)
const {
68 std::optional<bool> result = std::nullopt;
70 [&](
auto const &ptr) {
72 if (ptr
and not std::is_same_v<SolverType, EKNone>) {
84 auto get_precision(std::vector<value_type>
const &
species_list)
const {
85 std::optional<bool> result = std::nullopt;
87 result = get_precision(
species);
93 return m_ek_container->contains(
obj_ptr->get_ekinstance());
96 context()->parallel_try_catch([
this, &
obj_ptr]() {
99 auto const prec_solver = get_precision(m_poisson_solver);
102 throw std::runtime_error(
103 "Cannot mix single and double precision kernels");
106 m_ek_container->add(
obj_ptr->get_ekinstance());
110 m_ek_container->remove(
obj_ptr->get_ekinstance());
113 struct GetPoissonSolverAsVariant {
114 template <
typename T>
115 auto operator()(std::shared_ptr<T>
const &solver)
const {
121 return std::visit(GetPoissonSolverAsVariant(), m_poisson_solver);
124 struct GetPoissonSolverCoreInstance {
125 template <
typename T>
126 std::shared_ptr<::walberla::PoissonSolver>
127 operator()(std::shared_ptr<T>
const &solver)
const {
128 return solver->get_instance();
132 auto extract_solver(
Variant const &v) {
133 std::optional<
decltype(m_poisson_solver)> solver;
135 if (
auto ptr = std::dynamic_pointer_cast<EKNone>(
so_ptr)) {
136 solver = std::move(ptr);
138#ifdef ESPRESSO_WALBERLA_FFT
139 else if (
auto ptr = std::dynamic_pointer_cast<EKFFT>(
so_ptr)) {
140 solver = std::move(ptr);
143 assert(solver.has_value());
147 void set_solver(
Variant const &v) {
150 context()->parallel_try_catch([&]() {
154 throw std::runtime_error(
155 "Cannot mix single and double precision kernels");
157 m_ek_container->set_poisson_solver(
handle);
166 [
this]() {
return m_ek_container->get_tau(); }},
167 {
"solver", [
this](
Variant const &v) { set_solver(v); },
168 [
this]() {
return get_solver(); }},
170 [
this]() {
return m_ek_reactions; }},
172 [
this]() {
return m_is_active; }},
181 context()->parallel_try_catch([tau]() {
183 throw std::domain_error(
"Parameter 'tau' must be > 0");
186 m_poisson_solver = extract_solver(
187 params.contains(
"solver") ? params.at(
"solver") :
Variant{
none});
188 m_ek_container = std::make_shared<::EK::EKWalberla::ek_container_type>(
189 tau, std::visit(GetPoissonSolverCoreInstance{}, m_poisson_solver));
191 m_ek_instance = std::make_shared<::EK::EKWalberla>(
192 m_ek_container, m_ek_reactions->get_handle());
200 if (
method ==
"activate") {
205 if (
method ==
"deactivate") {