56#ifdef ESPRESSO_WALBERLA_FFT
57 std::shared_ptr<EKFFT>,
59 std::shared_ptr<EKFFTGPU>,
62 std::shared_ptr<EKNone>>
65 std::shared_ptr<EKReactions> m_ek_reactions;
66 std::shared_ptr<::EK::EKWalberla> m_ek_instance;
67 std::shared_ptr<::EK::EKWalberla::ek_container_type> m_ek_container;
70 auto get_precision(
decltype(m_poisson_solver)
const &solver)
const {
71 std::optional<bool> result = std::nullopt;
73 [&](
auto const &ptr) {
75 if (ptr
and not std::is_same_v<SolverType, EKNone>) {
87 auto get_precision(std::vector<value_type>
const &
species_list)
const {
88 std::optional<bool> result = std::nullopt;
90 result = get_precision(
species);
96 return m_ek_container->contains(
obj_ptr->get_ekinstance());
99 context()->parallel_try_catch([
this, &
obj_ptr]() {
102 auto const prec_solver = get_precision(m_poisson_solver);
105 throw std::runtime_error(
106 "Cannot mix single and double precision kernels");
108 m_ek_container->add(
obj_ptr->get_ekinstance());
112 m_ek_container->remove(
obj_ptr->get_ekinstance());
115 struct GetPoissonSolverAsVariant {
116 template <
typename T>
117 auto operator()(std::shared_ptr<T>
const &solver)
const {
123 return std::visit(GetPoissonSolverAsVariant(), m_poisson_solver);
126 struct GetPoissonSolverCoreInstance {
127 template <
typename T>
128 std::shared_ptr<::walberla::PoissonSolver>
129 operator()(std::shared_ptr<T>
const &solver)
const {
130 return solver->get_instance();
134 auto extract_solver(
Variant const &v) {
135 std::optional<
decltype(m_poisson_solver)> solver;
137 if (
auto ptr = std::dynamic_pointer_cast<EKNone>(
so_ptr)) {
138 solver = std::move(ptr);
140#ifdef ESPRESSO_WALBERLA_FFT
142 else if (
auto ptr = std::dynamic_pointer_cast<EKFFTGPU>(
so_ptr)) {
143 solver = std::move(ptr);
146 else if (
auto ptr = std::dynamic_pointer_cast<EKFFT>(
so_ptr)) {
147 solver = std::move(ptr);
150 assert(solver.has_value());
154 void set_solver(
Variant const &v) {
157 context()->parallel_try_catch([&]() {
161 throw std::runtime_error(
162 "Cannot mix single and double precision kernels");
164 m_ek_container->set_poisson_solver(
handle);
173 [
this]() {
return m_ek_container->get_tau(); }},
174 {
"solver", [
this](
Variant const &v) { set_solver(v); },
175 [
this]() {
return get_solver(); }},
177 [
this]() {
return m_ek_reactions; }},
179 [
this]() {
return m_is_active; }},
188 context()->parallel_try_catch([tau]() {
190 throw std::domain_error(
"Parameter 'tau' must be > 0");
193 m_poisson_solver = extract_solver(
195 m_ek_container = std::make_shared<::EK::EKWalberla::ek_container_type>(
196 tau, std::visit(GetPoissonSolverCoreInstance{}, m_poisson_solver));
198 m_ek_instance = std::make_shared<::EK::EKWalberla>(
199 m_ek_container, m_ek_reactions->get_handle());
207 if (
method ==
"activate") {
208 context()->parallel_try_catch([
this]() {
214 if (
method ==
"deactivate") {