diff options
author | 2023-04-23 23:49:57 -0700 | |
---|---|---|
committer | 2023-04-23 23:49:57 -0700 | |
commit | 2b68ee9f2897ade6ba85cf10cc2add6f72fb848b (patch) | |
tree | 7314f4771b332ba7a274878d6309b2e6913f5823 /Source/Initialization/WarpXInitData.cpp | |
parent | 402c30da6dd8db998b78f1fcc75bc4b511447c86 (diff) | |
download | WarpX-2b68ee9f2897ade6ba85cf10cc2add6f72fb848b.tar.gz WarpX-2b68ee9f2897ade6ba85cf10cc2add6f72fb848b.tar.zst WarpX-2b68ee9f2897ade6ba85cf10cc2add6f72fb848b.zip |
Import external E/B fields from openPMD files (#3584)
* Squashed commit of the following:
commit 5452b0a818e952fc8ac989a306b0ea83738243f1
Merge: a21dda0f 90b72e80
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Fri Sep 23 13:22:03 2022 -0700
Merge branch 'development' of https://github.com/ECP-WarpX/WarpX into add_external_fields
commit a21dda0f1bad8ee8601104c3322631d5f385ffdd
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Fri Sep 23 13:13:23 2022 -0700
Update
commit 3394416cc0f7dc1e4742249b469957bedbfd5e84
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Wed Aug 24 13:37:30 2022 -0700
Update Examples/Tests/LoadExternalField/*
commit f0650b02e2f2d8d9719163ed5d4fd932a9d62a5b
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Wed Aug 24 12:41:11 2022 -0700
parameters.rst added
commit a96a3eb3a181d6e1a649a43bc9eb2e00e4e0ef57
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Thu Aug 18 15:15:43 2022 -0700
Add 3D test
commit caf213cdff02213cf0ff7389b399898bc76951b5
Merge: e85a7105 2b60afe8
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Thu Aug 18 12:02:35 2022 -0700
Merge branch 'add_external_fields' of https://github.com/Yin-YinjianZhao/WarpX into add_external_fields
commit e85a7105dceb80bc8769062a306248f57ac0939d
Merge: d00ce279 642f6c0f
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Thu Aug 18 12:01:59 2022 -0700
Merge branch 'development' of https://github.com/ECP-WarpX/WarpX into add_external_fields
commit 2b60afe876b6e4400e9f2676824ec94a4728c468
Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Thu Aug 18 19:01:58 2022 +0000
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
commit d00ce2790ae56148bd717baa7c8e074a2d12a6bf
Merge: fbaf5226 c21244d1
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Thu Aug 18 12:01:42 2022 -0700
minor
commit fbaf5226ee92444b618029ad56722f8e54918448
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Thu Aug 18 11:57:46 2022 -0700
The automated test of RZ passed, cleaning up needed.
commit c21244d103e3eb245ebb1d3b9d2c4b016afd8671
Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Wed Aug 17 20:51:59 2022 +0000
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
commit 0a52f2976b58cdbb48673387decce61aabf61561
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Wed Aug 17 13:51:40 2022 -0700
Add RZ test, but has a bug.
commit 2c6e1537e9fa1f630134e64800b2d509088481b8
Merge: d3b6b0cd b4686616
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Wed Aug 10 13:37:01 2022 -0700
Merge branch 'development' of https://github.com/ECP-WarpX/WarpX into add_external_fields
commit d3b6b0cd8eb34a5832bc8b439e96744f7a01a2ce
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Wed Aug 10 13:36:36 2022 -0700
Do not use WARPX_EXTERNAL_FIELD
commit a32207ab2c4476feab0cb4b1e9a65a6181c7bf81
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Wed Aug 10 10:50:18 2022 -0700
In the middle of clean up.
commit dcfcb02b9e053391c59cef50c692e84cf379fb8a
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Tue Aug 9 11:08:42 2022 -0700
RZ OpenPMD bug fixed, but code is messy, and chunk load is not done.
commit dec17c35d025ac4d40dcaca4b68853959e176782
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Tue Aug 9 10:43:58 2022 -0700
Has bug using RZ OpenMPD
commit b32e6efdd766f5986d66b213479d7c84587fca7e
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Fri Aug 5 13:17:04 2022 -0700
Add OpenPMD 3D.
commit 7b7f48e2ae751d0393703c912116f5cb4d4dffbc
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Thu Aug 4 15:50:00 2022 -0700
Revert "minor"
This reverts commit 01e022958bad3057737e57fda4ecfaed22778b51.
commit 01e022958bad3057737e57fda4ecfaed22778b51
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Tue Aug 2 15:03:24 2022 -0700
minor
commit 774e591959fce76f94dcb96ae17f43c71ee7b931
Author: Yin-YinjianZhao <yinjianzhao@lbl.gov>
Date: Fri Jul 29 11:13:14 2022 -0700
Make 1d work
commit 5db4e862104459e5511dad9869764866dc88e62d
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Fri Jul 29 10:27:03 2022 -0700
Make xz working
commit 03c3d0062e301c1dd525a50f7ea84c2ccad6d679
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Fri Jul 29 09:38:43 2022 -0700
Make rz workiong
commit 8864a1780606bfa68e842d6902d28a34da659dc8
Merge: 0c1c7b7b a514e793
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Wed Jun 22 14:02:05 2022 -0700
Merge branch 'add_external_fields' of https://github.com/Yin-YinjianZhao/WarpX into add_external_fields
commit 0c1c7b7bda98549559d44125bb48e78ac6af24aa
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Wed Jun 22 14:01:42 2022 -0700
Fix a bug.
commit a514e793cb5e30591debc475082cc48f9172ee25
Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Wed Jun 15 19:47:43 2022 +0000
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
commit dd3c3749e2793c8c489652a8152c166def995514
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Wed Jun 15 12:47:23 2022 -0700
Use txt file.
commit 61fb96d9219598d10dab6a729eb4db7278583d2e
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Thu May 26 13:51:58 2022 -0700
Now the loaded external field does not match the provided external field data.
commit 7354a1abcd3b36e97d2145eff0c4b1da0a3aca27
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Wed May 18 15:21:15 2022 -0700
Try to add new arguments in the doGatherShapeN function, such that external fields can be added.
commit 3a0db5fcbaf4298c7cf59ba4443f3cdf7a21094b
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Tue May 10 14:35:53 2022 -0700
Changed to mfi.growntilebox() to include the guard cells.
commit 33e3393eb6bf769a2d92043c1012796b8212e653
Merge: 53201644 32fe8aac
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local.dhcp.lbl.gov>
Date: Thu May 5 13:37:24 2022 -0700
A bug needs to be fixed related to the growth of cells.
commit 53201644322ae2a65c121a6f0559cda874edd98d
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local.dhcp.lbl.gov>
Date: Thu May 5 13:35:39 2022 -0700
A bug needs to be fixed related to the growth of cells.
commit 32fe8aacc16a749910956e28120e31f1807f3bc1
Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Tue May 3 22:54:42 2022 +0000
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
commit f434bff0e12643ba03fc76b1693c4875ef799fc6
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Tue May 3 15:54:25 2022 -0700
In the middle.
commit 698e8f3e69dac5945b332c67570272bf2f4ae168
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local.dhcp.lbl.gov>
Date: Tue May 3 09:32:54 2022 -0700
In the middle.
commit 9d9f88d59820e00eed0e962c8c8905d3f1964083
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Wed Apr 27 14:07:31 2022 -0700
In the middle of reading data.
commit 3640e134fa0970b6b4ec0bf7f1c7f779c730b9a1
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Thu Apr 21 09:43:06 2022 -0700
Draft.
commit 85e16cafbf65cf502b82943d5bae98c4e1d750df
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Mon Apr 18 15:15:22 2022 -0700
Minor: change tag.
commit 0b7d2723c225cc4eed09eb58ad7f049d6baa650a
Author: Yinjian Zhao <yin@Yinjians-MacBook-Air.local>
Date: Mon Apr 18 15:04:19 2022 -0700
Allocate MultiFabs for the external E and B fields.
* Conditionalize compilation on openPMD support
* Switch bit-flag integer configuration to separate booleans
* Clean up and modernize allocation and reading logic
* Roll back addition of external fields in all calls down to doGatherShapeN
* Do away with separate MultiFABs for file-read field values, and just read into the main ones
* Check that solved and externally-prescribed fields are mutually exclusive
* Clean up compilation issues
* Support GPUs
* Correct data sets URLs
* Fix compilation for 1D
* Fix some GPU issues
* Extract elements of various random little types that aren't GPU-friendly
* Run RZ test along with the others, not with the 2D tests
* Fix complaint about unused variable
* Fix complaints about unused variable from 1D
* Clean up 1D warning issues harder
* Clone the example dataset repository directly, like warpx-data
* Allow composition of external and internal fields
* Go back to reading external field into a separate MultiFAB
* Vaguely working for lab frame electrostatic case
* Fix copy-paste errors
* Replace magic constants by enumerators
* Get indexing order right for RZ
* Put external field contribution in the right place
* Fix GPU and unused variable issues
* Match renamed input variable
* Update input parameters
* reset benchmark for LoadExternalField3D because data actually get loaded now
* reset benchmark for LoadExternalFieldRZ because data actually get loaded now
* Drop unused includes
* Read data once for all boxes
* Guard against unimplemented mesh refinement support
* Rename function to slightly better reflect substance
* Use existing linear interpolation routines
* Specify type argument for interpolation to avoid mixture
* Account for Array4 indexing in Fortran order
* Address Edoardo's review comments
* Support load balancing
* Add assertions of assumptions about input file format
* Move assertion about max levels to earlier in initialization
* Error in XZ case since it's untested
* Don't pretend implementation covers XZ
* Name variables to correspond to dimensionality
* Reword comment per request
* Correct typos
* Add issue numbers for different unimplemented bits, and guard 1D case
* Fix comment about RZ ParallelFor
* Fix reStructuredText syntax
* Shift 2D case to the unimplemented path to avoid unused parameter/variable warnings
* Use 2020+ Curl Command
* Support older curl
---------
Co-authored-by: Tools <warpx@lbl.gov>
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
Diffstat (limited to 'Source/Initialization/WarpXInitData.cpp')
-rw-r--r-- | Source/Initialization/WarpXInitData.cpp | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/Source/Initialization/WarpXInitData.cpp b/Source/Initialization/WarpXInitData.cpp index cc2225375..062f8a83b 100644 --- a/Source/Initialization/WarpXInitData.cpp +++ b/Source/Initialization/WarpXInitData.cpp @@ -20,6 +20,7 @@ #include "Filter/BilinearFilter.H" #include "Filter/NCIGodfreyFilter.H" #include "Particles/MultiParticleContainer.H" +#include "Utils/Algorithms/LinearInterpolation.H" #include "Utils/Logo/GetLogo.H" #include "Utils/MPIInitHelpers.H" #include "Utils/Parser/ParserUtils.H" @@ -72,6 +73,10 @@ #include <string> #include <utility> +#ifdef WARPX_USE_OPENPMD +# include <openPMD/openPMD.hpp> +#endif + #include "FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H" using namespace amrex; @@ -435,6 +440,12 @@ WarpX::InitData () if (electrostatic_solver_id == ElectrostaticSolverAlgo::LabFrameElectroMagnetostatic) ComputeMagnetostaticField(); + // Set up an invariant condition through the rest of + // execution, that any code besides the field solver that + // looks at field values will see the composite of the field + // solution and any external field + AddExternalFields(); + // Write full diagnostics before the first iteration. multi_diags->FilterComputePackFlush( -1 ); @@ -452,6 +463,23 @@ WarpX::InitData () } void +WarpX::AddExternalFields () { + for (int lev = 0; lev <= finest_level; ++lev) { + // FIXME: RZ multimode has more than one component for all these + if (add_external_E_field) { + amrex::MultiFab::Add(*Efield_fp[lev][0], *Efield_fp_external[lev][0], 0, 0, 1, guard_cells.ng_alloc_EB); + amrex::MultiFab::Add(*Efield_fp[lev][1], *Efield_fp_external[lev][1], 0, 0, 1, guard_cells.ng_alloc_EB); + amrex::MultiFab::Add(*Efield_fp[lev][2], *Efield_fp_external[lev][2], 0, 0, 1, guard_cells.ng_alloc_EB); + } + if (add_external_B_field) { + amrex::MultiFab::Add(*Bfield_fp[lev][0], *Bfield_fp_external[lev][0], 0, 0, 1, guard_cells.ng_alloc_EB); + amrex::MultiFab::Add(*Bfield_fp[lev][1], *Bfield_fp_external[lev][1], 0, 0, 1, guard_cells.ng_alloc_EB); + amrex::MultiFab::Add(*Bfield_fp[lev][2], *Bfield_fp_external[lev][2], 0, 0, 1, guard_cells.ng_alloc_EB); + } + } +} + +void WarpX::InitDiagnostics () { multi_diags->InitData(); reduced_diags->InitData(); @@ -870,6 +898,38 @@ WarpX::InitLevelData (int lev, Real /*time*/) } } + // Reading external fields from data file + if (add_external_B_field) { + std::string read_fields_from_path="./"; + pp_warpx.query("read_fields_from_path", read_fields_from_path); +#if defined(WARPX_DIM_RZ) + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(n_rz_azimuthal_modes == 1, + "External field reading is not implemented for more than one RZ mode (see #3829)"); + ReadExternalFieldFromFile(read_fields_from_path, Bfield_fp_external[lev][0].get(), "B", "r"); + ReadExternalFieldFromFile(read_fields_from_path, Bfield_fp_external[lev][1].get(), "B", "t"); + ReadExternalFieldFromFile(read_fields_from_path, Bfield_fp_external[lev][2].get(), "B", "z"); +#else + ReadExternalFieldFromFile(read_fields_from_path, Bfield_fp_external[lev][0].get(), "B", "x"); + ReadExternalFieldFromFile(read_fields_from_path, Bfield_fp_external[lev][1].get(), "B", "y"); + ReadExternalFieldFromFile(read_fields_from_path, Bfield_fp_external[lev][2].get(), "B", "z"); +#endif + } + if (add_external_E_field) { + std::string read_fields_from_path="./"; + pp_warpx.query("read_fields_from_path", read_fields_from_path); +#if defined(WARPX_DIM_RZ) + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(n_rz_azimuthal_modes == 1, + "External field reading is not implemented for more than one RZ mode (see #3829)"); + ReadExternalFieldFromFile(read_fields_from_path, Efield_fp_external[lev][0].get(), "E", "r"); + ReadExternalFieldFromFile(read_fields_from_path, Efield_fp_external[lev][1].get(), "E", "t"); + ReadExternalFieldFromFile(read_fields_from_path, Efield_fp_external[lev][2].get(), "E", "z"); +#else + ReadExternalFieldFromFile(read_fields_from_path, Efield_fp_external[lev][0].get(), "E", "x"); + ReadExternalFieldFromFile(read_fields_from_path, Efield_fp_external[lev][1].get(), "E", "y"); + ReadExternalFieldFromFile(read_fields_from_path, Efield_fp_external[lev][2].get(), "E", "z"); +#endif + } + if (costs[lev]) { const auto iarr = costs[lev]->IndexArray(); for (int i : iarr) { @@ -1242,3 +1302,195 @@ void WarpX::CheckKnownIssues() ablastr::warn_manager::WarnPriority::low); } } + +#if defined(WARPX_USE_OPENPMD) && !defined(WARPX_DIM_1D_Z) && !defined(WARPX_DIM_XZ) +void +WarpX::ReadExternalFieldFromFile ( + std::string read_fields_from_path, amrex::MultiFab* mf, + std::string F_name, std::string F_component) +{ + // Get WarpX domain info + auto& warpx = WarpX::GetInstance(); + amrex::Geometry const& geom0 = warpx.Geom(0); + const amrex::RealBox& real_box = geom0.ProbDomain(); + const auto dx = geom0.CellSizeArray(); + amrex::IntVect nodal_flag = mf->ixType().toIntVect(); + + // Read external field openPMD data + auto series = openPMD::Series(read_fields_from_path, openPMD::Access::READ_ONLY); + auto iseries = series.iterations.begin()->second; + auto F = iseries.meshes[F_name]; + + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(F.getAttribute("dataOrder").get<std::string>() == "C", + "Reading from files with non-C dataOrder is not implemented"); + + auto axisLabels = F.getAttribute("axisLabels").get<std::vector<std::string>>(); + auto fileGeom = F.getAttribute("geometry").get<std::string>(); + +#if defined(WARPX_DIM_3D) + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(fileGeom == "cartesian", "3D can only read from files with cartesian geometry"); + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(axisLabels[0] == "x" && axisLabels[1] == "y" && axisLabels[2] == "z", + "3D expects axisLabels {x, y, z}"); +#elif defined(WARPX_DIM_XZ) + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(fileGeom == "cartesian", "XZ can only read from files with cartesian geometry"); + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(axisLabels[0] == "x" && axisLabels[1] == "z", + "XZ expects axisLabels {x, z}"); +#elif defined(WARPX_DIM_1D_Z) + amrex::Abort(Utils::TextMsg::Err( + "Reading from openPMD for external fields is not known to work with 1D3V (see #3830)")); + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(fileGeom == "cartesian", "1D3V can only read from files with cartesian geometry"); + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(axisLabels[0] == "z"); +#elif defined(WARPX_DIM_RZ) + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(fileGeom == "thetaMode", "RZ can only read from files with 'thetaMode' geometry"); + WARPX_ALWAYS_ASSERT_WITH_MESSAGE(axisLabels[0] == "r" && axisLabels[1] == "z", + "RZ expects axisLabels {r, z}"); +#endif + + auto offset = F.gridGlobalOffset(); + amrex::Real offset0 = offset[0]; + amrex::Real offset1 = offset[1]; +#if defined(WARPX_DIM_3D) + amrex::Real offset2 = offset[2]; +#endif + auto d = F.gridSpacing<long double>(); + +#if defined(WARPX_DIM_RZ) + amrex::Real file_dr = d[0]; + amrex::Real file_dz = d[1]; +#elif defined(WARPX_DIM_3D) + amrex::Real file_dx = d[0]; + amrex::Real file_dy = d[1]; + amrex::Real file_dz = d[2]; +#endif + + auto FC = F[F_component]; + auto extent = FC.getExtent(); + int extent0 = extent[0]; + int extent1 = extent[1]; + int extent2 = extent[2]; + + // Determine the chunk data that will be loaded. + // Now, the full range of data is loaded. + // Loading chunk data can speed up the process. + // Thus, `chunk_offset` and `chunk_extent` should be modified accordingly in another PR. + openPMD::Offset chunk_offset = {0,0,0}; + openPMD::Extent chunk_extent = {extent[0], extent[1], extent[2]}; + + auto FC_chunk_data = FC.loadChunk<double>(chunk_offset,chunk_extent); + series.flush(); + auto FC_data_host = FC_chunk_data.get(); + + // Load data to GPU + size_t total_extent = size_t(extent[0]) * extent[1] * extent[2]; + amrex::Gpu::DeviceVector<double> FC_data_gpu(total_extent); + auto FC_data = FC_data_gpu.data(); + amrex::Gpu::copy(amrex::Gpu::hostToDevice, FC_data_host, FC_data_host + total_extent, FC_data); + + // Loop over boxes + for (MFIter mfi(*mf, TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + amrex::Box box = mfi.growntilebox(); + amrex::Box tb = mfi.tilebox(nodal_flag, mf->nGrowVect()); + auto const& mffab = mf->array(mfi); + + // Start ParallelFor + amrex::ParallelFor (tb, + [=] AMREX_GPU_DEVICE (int i, int j, int k) { + // i,j,k denote x,y,z indices in 3D xyz. + // i,j denote r,z indices in 2D rz; k is just 0 + + // ii is used for 2D RZ mode + int ii = i; +#if defined(WARPX_DIM_RZ) + // In 2D RZ, i denoting r can be < 0 + // but mirrored values should be assigned. + // Namely, mffab(i) = FC_data[-i] when i<0. + if (i<0) {ii = -i;} +#endif + + // Physical coordinates of the grid point + // 0,1,2 denote x,y,z in 3D xyz. + // 0,1 denote r,z in 2D rz. + amrex::Real x0, x1; + if ( box.type(0)==amrex::IndexType::CellIndex::NODE ) + { x0 = real_box.lo(0) + ii*dx[0]; } + else { x0 = real_box.lo(0) + ii*dx[0] + 0.5*dx[0]; } + if ( box.type(1)==amrex::IndexType::CellIndex::NODE ) + { x1 = real_box.lo(1) + j*dx[1]; } + else { x1 = real_box.lo(1) + j*dx[1] + 0.5*dx[1]; } + +#if defined(WARPX_DIM_RZ) + // Get index of the external field array + int const ir = floor( (x0-offset0)/file_dr ); + int const iz = floor( (x1-offset1)/file_dz ); + + // Get coordinates of external grid point + amrex::Real const xx0 = offset0 + ir * file_dr; + amrex::Real const xx1 = offset1 + iz * file_dz; + +#elif defined(WARPX_DIM_3D) + amrex::Real x2; + if ( box.type(2)==amrex::IndexType::CellIndex::NODE ) + { x2 = real_box.lo(2) + k*dx[2]; } + else { x2 = real_box.lo(2) + k*dx[2] + 0.5*dx[2]; } + + // Get index of the external field array + int const ix = floor( (x0-offset0)/file_dx ); + int const iy = floor( (x1-offset1)/file_dy ); + int const iz = floor( (x2-offset2)/file_dz ); + + // Get coordinates of external grid point + amrex::Real const xx0 = offset0 + ix * file_dx; + amrex::Real const xx1 = offset1 + iy * file_dy; + amrex::Real const xx2 = offset2 + iz * file_dz; +#endif + +#if defined(WARPX_DIM_RZ) + amrex::Array4<double> fc_array(FC_data, {0,0,0}, {extent0, extent2, extent1}, 1); + double + f00 = fc_array(0, iz , ir ), + f01 = fc_array(0, iz , ir+1), + f10 = fc_array(0, iz+1, ir ), + f11 = fc_array(0, iz+1, ir+1); + mffab(i,j,k) = utils::algorithms::bilinear_interp<double> + (xx0, xx0+file_dr, xx1, xx1+file_dz, + f00, f01, f10, f11, + x0, x1); +#elif defined(WARPX_DIM_3D) + amrex::Array4<double> fc_array(FC_data, {0,0,0}, {extent2, extent1, extent0}, 1); + double + f000 = fc_array(iz , iy , ix ), + f001 = fc_array(iz+1, iy , ix ), + f010 = fc_array(iz , iy+1, ix ), + f011 = fc_array(iz+1, iy+1, ix ), + f100 = fc_array(iz , iy , ix+1), + f101 = fc_array(iz+1, iy , ix+1), + f110 = fc_array(iz , iy+1, ix+1), + f111 = fc_array(iz+1, iy+1, ix+1); + mffab(i,j,k) = utils::algorithms::trilinear_interp<double> + (xx0, xx0+file_dx, xx1, xx1+file_dy, xx2, xx2+file_dz, + f000, f001, f010, f011, f100, f101, f110, f111, + x0, x1, x2); +#endif + + } + + ); // End ParallelFor + + } // End loop over boxes. + +} // End function WarpX::ReadExternalFieldFromFile +#else // WARPX_USE_OPENPMD && !WARPX_DIM_1D_Z && !defined(WARPX_DIM_XZ) +void +WarpX::ReadExternalFieldFromFile (std::string , amrex::MultiFab* ,std::string, std::string) +{ +#if defined(WARPX_DIM_1D) + Abort(Utils::TextMsg::Err("Reading fields from openPMD files is not supported in 1D"); +#elif defined(WARPX_DIM_XZ) + Abort(Utils::TextMsg::Err( + "Reading from openPMD for external fields is not known to work with XZ (see #3828)")); +#elif !defined(WARPX_USE_OPENPMD) + Abort(Utils::TextMsg::Err("OpenPMD field reading requires OpenPMD support to be enabled")); +#endif +} +#endif // WARPX_USE_OPENPMD |