18 Inform m(
"FieldSolver::initSolverWithParams");
19 this->getSolver().template emplace<Solver>();
20 Solver& solver = std::get<Solver>(this->getSolver());
21 solver.mergeParameters(sp);
22 m << level3 <<
"Initialized solver with params: " << this->getStype() << endl;
26 throw OpalException(
"FieldSolver::initSolverWithParams",
"rho_m is not initialized.");
29 solver.setRhs(*rho_m);
30 m << level5 <<
"Set solver RHS." << endl;
32 if constexpr ((std::is_same_v<Solver, CGSolver_t<T, Dim>>)
37 "FieldSolver::initSolverWithParams",
38 "Cannot use CGSolver yet, not fully implemented.");
41 solver.setLhs(*phi_m);
42 solver.setGradient(*E_m);
43 m << level5 <<
"Set gradient for CG." << endl;
50 m << level4 <<
"Set solver RHS+LHS." << endl;
60 Inform m(
"FieldSolver::dumpVectorField");
64 if (ippl::Comm->size() > 1 || call_counter_m < 2) {
65 m << level5 <<
"Skipping vector field dump for multiple ranks or first call." << endl;
84 std::string dirname =
"data/";
96 auto localIdx = field->getOwned();
97 auto mesh_mp = &(field->get_mesh());
98 auto spacing = mesh_mp->getMeshSpacing();
99 auto origin = mesh_mp->getOrigin();
100 int nghost = field->getNghost();
102 auto fieldV = field->getView();
103 auto field_hostV = field->getHostMirror();
104 Kokkos::deep_copy(field_hostV, fieldV);
106 std::filesystem::path file(dirname);
108 std::ostringstream oss;
109 oss << basename <<
"-" << (what + std::string(
"_") + type) <<
"-" << std::setfill(
'0')
110 << std::setw(6) << call_counter_m <<
".dat";
111 std::string filename = oss.str();
113 std::ofstream fout(file.string(), std::ios::out);
115 fout << std::setprecision(9);
117 fout <<
"# " <<
Util::toUpper(what) <<
" " << type <<
" data on grid" << std::endl
118 <<
"# origin= " << std::fixed << origin <<
" h= " << std::fixed << spacing << std::endl
119 <<
"#" << std::setw(4) <<
"i" << std::setw(5) <<
"j" << std::setw(5) <<
"k"
120 << std::setw(17) <<
"x [m]" << std::setw(17) <<
"y [m]" << std::setw(17) <<
"z [m]";
122 fout << std::setw(10) << what <<
"x [" << unit <<
"]" << std::setw(10) << what <<
"y [" << unit
123 <<
"]" << std::setw(10) << what <<
"z [" << unit <<
"]";
127 for (
int i = localIdx[0].first() + nghost; i <= localIdx[0].last() + nghost; i++) {
128 for (
int j = localIdx[1].first() + nghost; j <= localIdx[1].last() + nghost; j++) {
129 for (
int k = localIdx[2].first() + nghost; k <= localIdx[2].last() + nghost; k++) {
131 double x = (i - nghost) * spacing[0] + origin[0];
132 double y = (j - nghost) * spacing[1] + origin[1];
133 double z = (k - nghost) * spacing[2] + origin[2];
135 fout << std::setw(5) << i << std::setw(5) << j << std::setw(5) << k << std::setw(17)
136 << x << std::setw(17) << y << std::setw(17) << z << std::scientific <<
"\t"
137 << field_hostV(i, j, k)[0] <<
"\t" << field_hostV(i, j, k)[1] <<
"\t"
138 << field_hostV(i, j, k)[2] << std::endl;
143 m << level5 <<
"*** FINISHED DUMPING " +
Util::toUpper(what) +
" FIELD *** to " << file.string()
153 Inform m(
"FS::dumpScalField() ");
154 m << level5 <<
"Dumping scalar field: " << what << endl;
156 if (ippl::Comm->size() > 1 ) {
157 m << level5 <<
"Skipping scalar field dump for multiple ranks or first call." << endl;
177 std::string dirname =
"data/";
181 bool isVectorField =
false;
197 ippl::NDIndex<3> localIdx = field->getLayout().getLocalNDIndex();
198 int nghost = field->getNghost();
200 auto mesh_mp = &(field->get_mesh());
201 auto spacing = mesh_mp->getMeshSpacing();
202 auto origin = mesh_mp->getOrigin();
206 Kokkos::deep_copy(field_hostV, fieldV);
208 std::filesystem::path file(dirname);
210 std::ostringstream oss;
211 oss << basename <<
"-" << (what + std::string(
"_") + type) <<
"-" << std::setfill(
'0')
212 << std::setw(6) << call_counter_m <<
".dat";
213 std::string filename = oss.str();
215 std::ofstream fout(file.string(), std::ios::out);
217 fout << std::setprecision(9);
219 fout <<
"# " <<
Util::toUpper(what) <<
" " << type <<
" data on grid" << std::endl
220 <<
"# origin= " << std::fixed << origin <<
" h= " << std::fixed << spacing
221 <<
" nghosts=" << nghost << std::endl
222 <<
"#" << std::setw(4) <<
"i" << std::setw(5) <<
"j" << std::setw(5) <<
"k"
223 << std::setw(17) <<
"x [m]" << std::setw(17) <<
"y [m]" << std::setw(17) <<
"z [m]";
226 fout << std::setw(10) << what <<
"x [" << unit <<
"]" << std::setw(10) << what <<
"y ["
227 << unit <<
"]" << std::setw(10) << what <<
"z [" << unit <<
"]";
229 fout << std::setw(13) << what <<
" [" << unit <<
"]";
235 for (
int i = localIdx[0].first() + nghost; i <= localIdx[0].last() + nghost; i++) {
236 for (
int j = localIdx[1].first() + nghost; j <= localIdx[1].last() + nghost; j++) {
237 for (
int k = localIdx[2].first() + nghost; k <= localIdx[2].last() + nghost; k++) {
239 double x = (i - nghost) * spacing[0] + origin[0];
240 double y = (j - nghost) * spacing[1] + origin[1];
241 double z = (k - nghost) * spacing[2] + origin[2];
243 fout << std::setw(5) << i << std::setw(5) << j << std::setw(5) << k
244 << std::setw(17) << x << std::setw(17) << y << std::setw(17) << z
245 << std::scientific <<
"\t" << field_hostV(i, j, k) << std::endl;
250 for (
int i = localIdx[0].first() + nghost; i <= localIdx[0].last() + nghost; i++) {
251 for (
int j = localIdx[1].first() + nghost; j <= localIdx[1].last() + nghost; j++) {
252 for (
int k = localIdx[2].first() + nghost; k <= localIdx[2].last() + nghost; k++) {
254 double x = (i - nghost) * spacing[0] + origin[0];
255 double y = (j - nghost) * spacing[1] + origin[1];
256 double z = (k - nghost) * spacing[2] + origin[2];
259 fout << std::setw(5) << i << std::setw(5) << j << std::setw(5) << k
260 << std::setw(17) << x << std::setw(17) << y << std::setw(17) << z
261 << std::scientific <<
"\t" << field_hostV(i, j, k) << std::endl;
267 m << level5 <<
"*** FINISHED DUMPING " +
Util::toUpper(what) +
" FIELD *** to " << file.string()
363 constexpr int Dim = 3;
364 Inform m(
"FieldSolver::runSolver");
370 m << level3 <<
"Running solver with type: " << this->getStype()
371 <<
". Force skip field dump: " << force_skip_field_dump << endl;
373 if (this->getStype() ==
"CG") {
374 CGSolver_t<double, 3>& solver = std::get<CGSolver_t<double, 3>>(this->getSolver());
375#ifdef OPALX_FIELD_DEBUG
376 if (!force_skip_field_dump) this->dumpScalField(
"rho");
380#ifdef OPALX_FIELD_DEBUG
381 if (!force_skip_field_dump) this->dumpScalField(
"phi");
402 int iterations = solver.getIterationCount();
403 int residue = solver.getResidue();
404 m << level4 <<
"CG solver finished. Iterations: " << iterations <<
", Residue: " << residue
406 }
else if (this->getStype() ==
"FFT") {
407 if constexpr (
Dim == 2 ||
Dim == 3) {
408#ifdef OPALX_FIELD_DEBUG
409 if (!force_skip_field_dump) this->dumpScalField(
"rho");
412 std::get<FFTSolver_t<double, 3>>(this->getSolver()).solve();
413#ifdef OPALX_FIELD_DEBUG
415 if (!force_skip_field_dump) this->dumpScalField(
"phi");
416 if (!force_skip_field_dump) this->dumpVectField(
"ef");
419 }
else if (this->getStype() ==
"P3M") {
420 if constexpr (
Dim == 3) {
421 std::get<FFTTruncatedGreenSolver_t<double, 3>>(this->getSolver()).solve();
423 }
else if (this->getStype() ==
"OPEN") {
424 if constexpr (
Dim == 3) {
425#ifdef OPALX_FIELD_DEBUG
426 if (!force_skip_field_dump) this->dumpScalField(
"rho");
428 std::get<OpenSolver_t<double, 3>>(this->getSolver()).solve();
429#ifdef OPALX_FIELD_DEBUG
430 if (!force_skip_field_dump) this->dumpScalField(
"phi");
431 if (!force_skip_field_dump) this->dumpVectField(
"ef");
434 }
else if (this->getStype() ==
"NONE") {
435 std::get<NullSolver_t<T, Dim>>(this->getSolver()).solve();
438 "FieldSolver::runSolver",
439 "No known solver matches the argument: " + this->getStype());