6#include <boost/filesystem.hpp>
7#include <boost/format.hpp>
15template <
typename Solver>
17 Inform m (
"initSolverWithParams ");
18 this->getSolver().template emplace<Solver>();
19 Solver& solver = std::get<Solver>(this->getSolver());
20 solver.mergeParameters(sp);
22 if constexpr (std::is_same_v<Solver, CGSolver_t<T, Dim>>) {
25 throw OpalException(
"FieldSolver<double,3>::initSolverWithParams",
"Cannot use CGSolver yet, not implemented.");
28 m <<
"CG solver used " <<
endl;
29 solver.setLhs(*phi_m);
30 solver.setGradient(*E_m);
31 }
else if constexpr (std::is_same_v<Solver, OpenSolver_t<T, Dim>>) {
34 m <<
"OpenSolver used" <<
endl;
35 solver.setRhs(*rho_m);
36 m <<
"Set RHS for OpenSolver" <<
endl;
38 m <<
"Set LHS for OpenSolver" <<
endl;
40 m <<
"Set GradFD for OpenSolver" <<
endl;
41 }
else if constexpr (std::is_same_v<Solver, FFTSolver_t<T, Dim>>) {
43 m <<
"FFTSolver used" <<
endl;
44 solver.setRhs(*rho_m);
46 }
else if constexpr (std::is_same_v<Solver, NullSolver_t<T, Dim>>) {
47 m <<
"NullSolver used" <<
endl;
48 solver.setRhs(*rho_m);
64 Inform m(
"FS::dumpVectorField() ");
68 if (
ippl::Comm->size() > 1 || call_counter_m<2) {
87 std::string dirname =
"data/";
100 auto mesh_mp = &(field->
get_mesh());
101 auto spacing = mesh_mp->getMeshSpacing();
102 auto origin = mesh_mp->getOrigin();
104 auto fieldV = field->
getView();
106 Kokkos::deep_copy(field_hostV, fieldV);
108 boost::filesystem::path file(dirname);
109 boost::format filename(
"%1%-%2%-%|3$06|.dat");
111 filename % basename % (what + std::string(
"_") + type) % call_counter_m;
112 file /= filename.str();
113 std::ofstream fout(file.string(), std::ios::out);
115 fout << std::setprecision(9);
118 <<
"# origin= " << std::fixed << origin <<
" h= " << std::fixed << spacing <<
std::endl
119 << std::setw(5) <<
"i"
120 << std::setw(5) <<
"j"
121 << std::setw(5) <<
"k"
122 << std::setw(17) <<
"x [m]"
123 << std::setw(17) <<
"y [m]"
124 << std::setw(17) <<
"z [m]";
126 fout << std::setw(10) << what <<
"x [" << unit <<
"]"
127 << std::setw(10) << what <<
"y [" << unit <<
"]"
128 << std::setw(10) << what <<
"z [" << unit <<
"]";
132 for (
int i = localIdx[0].
first() + 1; i <= localIdx[0].last() +1 ; i++) {
133 for (
int j = localIdx[1].
first() + 1 ; j <= localIdx[1].last() +1 ; j++) {
134 for (
int k = localIdx[2].
first() + 1 ; k <= localIdx[2].last() +1 ; k++) {
137 double x = i * spacing[0] + origin[0];
138 double y = j * spacing[1] + origin[1];
139 double z = k * spacing[2] + origin[2];
141 fout << std::setw(5) << i-1
142 << std::setw(5) << j-1
143 << std::setw(5) << k-1
144 << std::setw(17) << x
145 << std::setw(17) << y
146 << std::setw(17) << z
148 <<
"\t" << field_hostV(i,j,k)[0]
149 <<
"\t" << field_hostV(i,j,k)[1]
150 <<
"\t" << field_hostV(i,j,k)[2]
156 m <<
"*** FINISHED DUMPING " +
Util::toUpper(what) +
" FIELD *** to " << file.string() <<
endl;
166 Inform m(
"FS::dumpScalField() ");
168 if (
ippl::Comm->size() > 1 || call_counter_m<2) {
188 std::string dirname =
"data/";
192 bool isVectorField =
false;
206 auto mesh_mp = &(field->
get_mesh());
207 auto spacing = mesh_mp->getMeshSpacing();
208 auto origin = mesh_mp->getOrigin();
210 auto fieldV = field->
getView();
212 Kokkos::deep_copy(field_hostV, fieldV);
214 boost::filesystem::path file(dirname);
215 boost::format filename(
"%1%-%2%-%|3$06|.dat");
217 filename % basename % (what + std::string(
"_") + type) % call_counter_m;
218 file /= filename.str();
219 std::ofstream fout(file.string(), std::ios::out);
221 fout << std::setprecision(9);
224 <<
"# origin= " << std::fixed << origin <<
" h= " << std::fixed << spacing <<
std::endl
225 << std::setw(5) <<
"i"
226 << std::setw(5) <<
"j"
227 << std::setw(5) <<
"k"
228 << std::setw(17) <<
"x [m]"
229 << std::setw(17) <<
"y [m]"
230 << std::setw(17) <<
"z [m]";
233 fout << std::setw(10) << what <<
"x [" << unit <<
"]"
234 << std::setw(10) << what <<
"y [" << unit <<
"]"
235 << std::setw(10) << what <<
"z [" << unit <<
"]";
237 fout << std::setw(13) << what <<
" [" << unit <<
"]";
243 for (
int i = localIdx[0].
first(); i <= localIdx[0].last(); i++) {
244 for (
int j = localIdx[1].
first(); j <= localIdx[1].last(); j++) {
245 for (
int k = localIdx[2].
first(); k <= localIdx[2].last(); k++) {
248 double x = i * spacing[0] + origin[0];
249 double y = j * spacing[1] + origin[1];
250 double z = k * spacing[2] + origin[2];
252 fout << std::setw(5) << i
255 << std::setw(17) << x
256 << std::setw(17) << y
257 << std::setw(17) << z
258 << std::scientific <<
"\t" << field_hostV(i,j,k)
265 for (
int i = localIdx[0].
first() + 1; i <= localIdx[0].last() +1 ; i++) {
266 for (
int j = localIdx[1].
first() + 1 ; j <= localIdx[1].last() +1 ; j++) {
267 for (
int k = localIdx[2].
first() + 1 ; k <= localIdx[2].last() +1 ; k++) {
270 double x = i * spacing[0] + origin[0];
271 double y = j * spacing[1] + origin[1];
272 double z = k * spacing[2] + origin[2];
274 fout << std::setw(5) << i-1
275 << std::setw(5) << j-1
276 << std::setw(5) << k-1
277 << std::setw(17) << x
278 << std::setw(17) << y
279 << std::setw(17) << z
280 << std::scientific <<
"\t" << field_hostV(i,j,k)
287 m <<
"*** FINISHED DUMPING " +
Util::toUpper(what) +
" FIELD *** to " << file.string() <<
endl;
294 sp.
add(
"use_heffte_defaults",
false);
295 sp.
add(
"use_pencils",
true);
296 sp.
add(
"use_reorder",
false);
297 sp.
add(
"use_gpu_aware",
true);
299 sp.
add(
"r2c_direction", 0);
301 initSolverWithParams<OpenSolver_t<double, 3>>(sp);
306 if constexpr (
Dim == 2 ||
Dim == 3) {
310 sp.
add(
"use_heffte_defaults",
false);
311 sp.
add(
"use_pencils",
true);
312 sp.
add(
"use_reorder",
false);
313 sp.
add(
"use_gpu_aware",
true);
315 sp.
add(
"r2c_direction", 0);
316 initSolverWithParams<FFTSolver_t<double, 3>>(sp);
327 if (this->getStype() ==
"FFT") {
329 }
else if (this->getStype() ==
"OPEN") {
331 }
else if (this->getStype() ==
"NONE") {
335 m <<
"No solver matches the argument: " << this->getStype() <<
endl;
336 throw std::runtime_error(
"No solver match");
344 if (this->getStype() ==
"CG") {
347 for (
unsigned int i = 0; i < 2 * 3; ++i) {
348 allPeriodic[i] = std::make_shared<ippl::PeriodicFace<Field<double, 3>>>(i);
350 phi_m->setFieldBC(allPeriodic);
356 constexpr int Dim = 3;
358 if (this->getStype() ==
"CG") {
363 std::stringstream fname;
371 if (iterations == 0) {
372 log <<
"residue,iterations" <<
endl;
375 if (iterations > 0) {
380 }
else if (this->getStype() ==
"FFT") {
381 if constexpr (
Dim == 2 ||
Dim == 3) {
382#ifdef OPALX_FIELD_DEBUG
383 this->dumpScalField(
"rho");
387 std::get<FFTSolver_t<double, 3>>(this->getSolver()).
solve();
388#ifdef OPALX_FIELD_DEBUG
389 this->dumpScalField(
"phi");
390 this->dumpVectField(
"ef");
394 }
else if (this->getStype() ==
"P3M") {
395 if constexpr (
Dim == 3) {
396 std::get<FFTTruncatedGreenSolver_t<double, 3>>(this->getSolver()).
solve();
398 }
else if (this->getStype() ==
"OPEN") {
399 if constexpr (
Dim == 3) {
400#ifdef OPALX_FIELD_DEBUG
401 this->dumpScalField(
"rho");
404 std::get<OpenSolver_t<double, 3>>(this->getSolver()).
solve();
405#ifdef OPALX_FIELD_DEBUG
406 this->dumpScalField(
"phi");
407 this->dumpVectField(
"ef");
411 }
else if (this->getStype() ==
"NONE") {
412 std::get<NullSolver_t<T, Dim>>(this->getSolver()).
solve();
414 throw std::runtime_error(
"Unknown solver type");
421 if constexpr (
Dim == 2 ||
Dim == 3) {
422 initSolverWithParams<NullSolver_t<T, Dim>>(sp);
424 throw std::runtime_error(
"Unsupported dimensionality for Null solver");
ConditionalType< Dim==2||Dim==3, ippl::FFTPeriodicPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > FFTSolver_t
ConditionalType< Dim==3, ippl::FFTOpenPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > OpenSolver_t
constexpr KOKKOS_INLINE_FUNCTION auto first()
Inform & endl(Inform &inf)
void solve(double *Matrix, double *Solution, double *rightHandSide, const int &M, const int &N)
std::string toUpper(const std::string &str)
std::unique_ptr< mpi::Communicator > Comm
std::string getInputBasename()
get input file name without extension
static OpalData * getInstance()
void dumpVectField(std::string what)
void initSolver() override
void runSolver() override
void initSolverWithParams(const ippl::ParameterList &sp)
void dumpScalField(std::string what)
The base class for all OPAL exceptions.
HostMirror getHostMirror() const
const Domain_t & getOwned() const
KOKKOS_INLINE_FUNCTION Mesh_t & get_mesh() const
void add(const std::string &key, const T &value)