diff options
author | 2019-12-20 06:00:47 -0800 | |
---|---|---|
committer | 2019-12-20 06:00:47 -0800 | |
commit | 3bafba4f532c06df8eac1f896415aba9be47f98c (patch) | |
tree | 150ed3abf4a54959b6ae4266ac54b09f52359a3b /Python | |
parent | 000a6b27ff59f3ef9c97f0e5324433e20f06b7a9 (diff) | |
parent | f225e540585be9fdde0f0520215f5f01a5efe38d (diff) | |
download | WarpX-3bafba4f532c06df8eac1f896415aba9be47f98c.tar.gz WarpX-3bafba4f532c06df8eac1f896415aba9be47f98c.tar.zst WarpX-3bafba4f532c06df8eac1f896415aba9be47f98c.zip |
Merge pull request #568 from dpgrote/pml_python
Adds Python wrapper of PML fields
Diffstat (limited to 'Python')
-rwxr-xr-x | Python/pywarpx/_libwarpx.py | 341 | ||||
-rw-r--r-- | Python/pywarpx/fields.py | 151 |
2 files changed, 489 insertions, 3 deletions
diff --git a/Python/pywarpx/_libwarpx.py b/Python/pywarpx/_libwarpx.py index 6c3e54619..0444140e4 100755 --- a/Python/pywarpx/_libwarpx.py +++ b/Python/pywarpx/_libwarpx.py @@ -130,18 +130,30 @@ libwarpx.warpx_getEfieldCP.restype = _LP_LP_c_real libwarpx.warpx_getEfieldCPLoVects.restype = _LP_c_int libwarpx.warpx_getEfieldFP.restype = _LP_LP_c_real libwarpx.warpx_getEfieldFPLoVects.restype = _LP_c_int +libwarpx.warpx_getEfieldCP_PML.restype = _LP_LP_c_real +libwarpx.warpx_getEfieldCPLoVects_PML.restype = _LP_c_int +libwarpx.warpx_getEfieldFP_PML.restype = _LP_LP_c_real +libwarpx.warpx_getEfieldFPLoVects_PML.restype = _LP_c_int libwarpx.warpx_getBfield.restype = _LP_LP_c_real libwarpx.warpx_getBfieldLoVects.restype = _LP_c_int libwarpx.warpx_getBfieldCP.restype = _LP_LP_c_real libwarpx.warpx_getBfieldCPLoVects.restype = _LP_c_int libwarpx.warpx_getBfieldFP.restype = _LP_LP_c_real libwarpx.warpx_getBfieldFPLoVects.restype = _LP_c_int +libwarpx.warpx_getBfieldCP_PML.restype = _LP_LP_c_real +libwarpx.warpx_getBfieldCPLoVects_PML.restype = _LP_c_int +libwarpx.warpx_getBfieldFP_PML.restype = _LP_LP_c_real +libwarpx.warpx_getBfieldFPLoVects_PML.restype = _LP_c_int libwarpx.warpx_getCurrentDensity.restype = _LP_LP_c_real libwarpx.warpx_getCurrentDensityLoVects.restype = _LP_c_int libwarpx.warpx_getCurrentDensityCP.restype = _LP_LP_c_real libwarpx.warpx_getCurrentDensityCPLoVects.restype = _LP_c_int libwarpx.warpx_getCurrentDensityFP.restype = _LP_LP_c_real libwarpx.warpx_getCurrentDensityFPLoVects.restype = _LP_c_int +libwarpx.warpx_getCurrentDensityCP_PML.restype = _LP_LP_c_real +libwarpx.warpx_getCurrentDensityCPLoVects_PML.restype = _LP_c_int +libwarpx.warpx_getCurrentDensityFP_PML.restype = _LP_LP_c_real +libwarpx.warpx_getCurrentDensityFPLoVects_PML.restype = _LP_c_int #libwarpx.warpx_getPMLSigma.restype = _LP_c_real #libwarpx.warpx_getPMLSigmaStar.restype = _LP_c_real @@ -747,6 +759,66 @@ def get_mesh_electric_field_fp(level, direction, include_ghosts=True): return _get_mesh_field_list(libwarpx.warpx_getEfieldFP, level, direction, include_ghosts) +def get_mesh_electric_field_cp_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of numpy arrays containing the mesh electric field + data on each grid for this process. This version returns the field on + the coarse patch for the PML for the given level. + + The data for the numpy arrays are not copied, but share the underlying + memory buffer with WarpX. The numpy arrays are fully writeable. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A List of numpy arrays. + + ''' + + try: + return _get_mesh_field_list(libwarpx.warpx_getEfieldCP_PML, level, direction, include_ghosts) + except ValueError: + raise Exception('PML not initialized') + + +def get_mesh_electric_field_fp_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of numpy arrays containing the mesh electric field + data on each grid for this process. This version returns the field on + the fine patch for the PML for the given level. + + The data for the numpy arrays are not copied, but share the underlying + memory buffer with WarpX. The numpy arrays are fully writeable. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A List of numpy arrays. + + ''' + + try: + return _get_mesh_field_list(libwarpx.warpx_getEfieldFP_PML, level, direction, include_ghosts) + except ValueError: + raise Exception('PML not initialized') + + def get_mesh_magnetic_field(level, direction, include_ghosts=True): ''' @@ -829,6 +901,66 @@ def get_mesh_magnetic_field_fp(level, direction, include_ghosts=True): return _get_mesh_field_list(libwarpx.warpx_getBfieldFP, level, direction, include_ghosts) +def get_mesh_magnetic_field_cp_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of numpy arrays containing the mesh magnetic field + data on each grid for this process. This version returns the field on + the coarse patch for the PML for the given level. + + The data for the numpy arrays are not copied, but share the underlying + memory buffer with WarpX. The numpy arrays are fully writeable. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A List of numpy arrays. + + ''' + + try: + return _get_mesh_field_list(libwarpx.warpx_getBfieldCP_PML, level, direction, include_ghosts) + except ValueError: + raise Exception('PML not initialized') + + +def get_mesh_magnetic_field_fp_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of numpy arrays containing the mesh magnetic field + data on each grid for this process. This version returns the field on + the fine patch for the PML for the given level. + + The data for the numpy arrays are not copied, but share the underlying + memory buffer with WarpX. The numpy arrays are fully writeable. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A List of numpy arrays. + + ''' + + try: + return _get_mesh_field_list(libwarpx.warpx_getBfieldFP_PML, level, direction, include_ghosts) + except ValueError: + raise Exception('PML not initialized') + + def get_mesh_current_density(level, direction, include_ghosts=True): ''' @@ -909,6 +1041,66 @@ def get_mesh_current_density_fp(level, direction, include_ghosts=True): return _get_mesh_field_list(libwarpx.warpx_getCurrentDensityFP, level, direction, include_ghosts) +def get_mesh_current_density_cp_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of numpy arrays containing the mesh current density + data on each grid for this process. This version returns the density for + the coarse patch for the PML for the given level. + + The data for the numpy arrays are not copied, but share the underlying + memory buffer with WarpX. The numpy arrays are fully writeable. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A List of numpy arrays. + + ''' + + try: + return _get_mesh_field_list(libwarpx.warpx_getCurrentDensityCP_PML, level, direction, include_ghosts) + except ValueError: + raise Exception('PML not initialized') + + +def get_mesh_current_density_fp_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of numpy arrays containing the mesh current density + data on each grid for this process. This version returns the density on + the fine patch for the PML for the given level. + + The data for the numpy arrays are not copied, but share the underlying + memory buffer with WarpX. The numpy arrays are fully writeable. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A List of numpy arrays. + + ''' + + try: + return _get_mesh_field_list(libwarpx.warpx_getCurrentDensityFP_PML, level, direction, include_ghosts) + except ValueError: + raise Exception('PML not initialized') + + def _get_mesh_array_lovects(level, direction, include_ghosts=True, getarrayfunc=None): assert(0 <= level and level <= libwarpx.warpx_finestLevel()) @@ -998,6 +1190,56 @@ def get_mesh_electric_field_fp_lovects(level, direction, include_ghosts=True): return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getEfieldFPLoVects) +def get_mesh_electric_field_cp_lovects_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of the lo vectors of the arrays containing the mesh electric field + data on each PML grid for this process. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A 2d numpy array of the lo vector for each grid with the shape (dims, number of grids) + + ''' + try: + return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getEfieldCPLoVects_PML) + except ValueError: + raise Exception('PML not initialized') + + +def get_mesh_electric_field_fp_lovects_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of the lo vectors of the arrays containing the mesh electric field + data on each PML grid for this process. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A 2d numpy array of the lo vector for each grid with the shape (dims, number of grids) + + ''' + try: + return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getEfieldFPLoVects_PML) + except ValueError: + raise Exception('PML not initialized') + + def get_mesh_magnetic_field_lovects(level, direction, include_ghosts=True): ''' @@ -1066,6 +1308,56 @@ def get_mesh_magnetic_field_fp_lovects(level, direction, include_ghosts=True): return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getBfieldFPLoVects) +def get_mesh_magnetic_field_cp_lovects_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of the lo vectors of the arrays containing the mesh electric field + data on each PML grid for this process. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A 2d numpy array of the lo vector for each grid with the shape (dims, number of grids) + + ''' + try: + return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getBfieldCPLoVects_PML) + except ValueError: + raise Exception('PML not initialized') + + +def get_mesh_magnetic_field_fp_lovects_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of the lo vectors of the arrays containing the mesh electric field + data on each PML grid for this process. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A 2d numpy array of the lo vector for each grid with the shape (dims, number of grids) + + ''' + try: + return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getBfieldFPLoVects_PML) + except ValueError: + raise Exception('PML not initialized') + + def get_mesh_current_density_lovects(level, direction, include_ghosts=True): ''' @@ -1129,3 +1421,52 @@ def get_mesh_current_density_fp_lovects(level, direction, include_ghosts=True): ''' return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getCurrentDensityFPLoVects) + + +def get_mesh_current_density_cp_lovects_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of the lo vectors of the arrays containing the mesh electric field + data on each PML grid for this process. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A 2d numpy array of the lo vector for each grid with the shape (dims, number of grids) + + ''' + try: + return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getCurrentDensityCPLoVects_PML) + except ValueError: + raise Exception('PML not initialized') + +def get_mesh_current_density_fp_lovects_pml(level, direction, include_ghosts=True): + ''' + + This returns a list of the lo vectors of the arrays containing the mesh electric field + data on each PML grid for this process. + + Parameters + ---------- + + level : the AMR level to get the data for + direction : the component of the data you want + include_ghosts : whether to include ghost zones or not + + Returns + ------- + + A 2d numpy array of the lo vector for each grid with the shape (dims, number of grids) + + ''' + try: + return _get_mesh_array_lovects(level, direction, include_ghosts, libwarpx.warpx_getCurrentDensityFPLoVects_PML) + except ValueError: + raise Exception('PML not initialized') diff --git a/Python/pywarpx/fields.py b/Python/pywarpx/fields.py index fa247db07..920c109d6 100644 --- a/Python/pywarpx/fields.py +++ b/Python/pywarpx/fields.py @@ -87,14 +87,28 @@ class _MultiFABWrapper(object): def _getitem3d(self, index): """Returns slices of a 3D decomposed array, """ - ix = index[0] - iy = index[1] - iz = index[2] lovects = self._getlovects() hivects = self._gethivects() fields = self._getfields() + ix = index[0] + iy = index[1] + iz = index[2] + + if len(fields[0].shape) > self.dim: + ncomps = fields[0].shape[-1] + else: + ncomps = 1 + + if len(index) > self.dim: + if ncomps > 1: + ic = index[-1] + else: + raise Exception('Too many indices given') + else: + ic = None + nx = hivects[0,:].max() - self.nghosts ny = hivects[1,:].max() - self.nghosts nz = hivects[2,:].max() - self.nghosts @@ -124,9 +138,12 @@ class _MultiFABWrapper(object): izstop = iz + 1 # --- Setup the size of the array to be returned and create it. + # --- Space is added for multiple components if needed. sss = (max(0, ixstop - ixstart), max(0, iystop - iystart), max(0, izstop - izstart)) + if ncomps > 1 and ic is None: + sss = tuple(list(sss) + [ncomps]) resultglobal = np.zeros(sss, dtype=_libwarpx._numpy_real_dtype) datalist = [] @@ -145,6 +162,8 @@ class _MultiFABWrapper(object): sss = (slice(ix1 - lovects[0,i], ix2 - lovects[0,i]), slice(iy1 - lovects[1,i], iy2 - lovects[1,i]), slice(iz1 - lovects[2,i], iz2 - lovects[2,i])) + if ic is not None: + sss = tuple(list(sss) + [ic]) vslice = (slice(ix1 - ixstart, ix2 - ixstart), slice(iy1 - iystart, iy2 - iystart), @@ -295,6 +314,14 @@ class _MultiFABWrapper(object): hivects = self._gethivects() fields = self._getfields() + if len(index) > self.dim: + if ncomps > 1: + ic = index[-1] + else: + raise Exception('Too many indices given') + else: + ic = None + nx = hivects[0,:].max() - self.nghosts ny = hivects[1,:].max() - self.nghosts nz = hivects[2,:].max() - self.nghosts @@ -343,6 +370,8 @@ class _MultiFABWrapper(object): sss = (slice(ix1 - lovects[0,i], ix2 - lovects[0,i]), slice(iy1 - lovects[1,i], iy2 - lovects[1,i]), slice(iz1 - lovects[2,i], iz2 - lovects[2,i])) + if ic is not None: + sss = tuple(list(sss) + [ic]) if isinstance(value, np.ndarray): vslice = (slice(ix1 - ixstart, ix2 - ixstart), @@ -593,3 +622,119 @@ def JzFPWrapper(level=0, include_ghosts=False): get_lovects=_libwarpx.get_mesh_current_density_fp_lovects, get_fabs=_libwarpx.get_mesh_current_density_fp, level=level, include_ghosts=include_ghosts) +def ExCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=0, overlaps=[0,1,1], + get_lovects=_libwarpx.get_mesh_electric_field_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_electric_field_cp_pml, + level=level, include_ghosts=include_ghosts) + +def EyCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=1, overlaps=[1,0,1], + get_lovects=_libwarpx.get_mesh_electric_field_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_electric_field_cp_pml, + level=level, include_ghosts=include_ghosts) + +def EzCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=2, overlaps=[1,1,0], + get_lovects=_libwarpx.get_mesh_electric_field_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_electric_field_cp_pml, + level=level, include_ghosts=include_ghosts) + +def BxCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=0, overlaps=[1,0,0], + get_lovects=_libwarpx.get_mesh_magnetic_field_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_magnetic_field_cp_pml, + level=level, include_ghosts=include_ghosts) + +def ByCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=1, overlaps=[0,1,0], + get_lovects=_libwarpx.get_mesh_magnetic_field_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_magnetic_field_cp_pml, + level=level, include_ghosts=include_ghosts) + +def BzCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=2, overlaps=[0,0,1], + get_lovects=_libwarpx.get_mesh_magnetic_field_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_magnetic_field_cp_pml, + level=level, include_ghosts=include_ghosts) + +def JxCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=0, overlaps=[0,1,1], + get_lovects=_libwarpx.get_mesh_current_density_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_current_density_cp_pml, + level=level, include_ghosts=include_ghosts) + +def JyCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=1, overlaps=[1,0,1], + get_lovects=_libwarpx.get_mesh_current_density_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_current_density_cp_pml, + level=level, include_ghosts=include_ghosts) + +def JzCPPMLWrapper(level=1, include_ghosts=False): + assert level>0, Exception('Coarse patch only available on levels > 0') + return _MultiFABWrapper(direction=2, overlaps=[1,1,0], + get_lovects=_libwarpx.get_mesh_current_density_cp_lovects_pml, + get_fabs=_libwarpx.get_mesh_current_density_cp_pml, + level=level, include_ghosts=include_ghosts) + +def ExFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=0, overlaps=[0,1,1], + get_lovects=_libwarpx.get_mesh_electric_field_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_electric_field_fp_pml, + level=level, include_ghosts=include_ghosts) + +def EyFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=1, overlaps=[1,0,1], + get_lovects=_libwarpx.get_mesh_electric_field_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_electric_field_fp_pml, + level=level, include_ghosts=include_ghosts) + +def EzFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=2, overlaps=[1,1,0], + get_lovects=_libwarpx.get_mesh_electric_field_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_electric_field_fp_pml, + level=level, include_ghosts=include_ghosts) + +def BxFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=0, overlaps=[1,0,0], + get_lovects=_libwarpx.get_mesh_magnetic_field_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_magnetic_field_fp_pml, + level=level, include_ghosts=include_ghosts) + +def ByFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=1, overlaps=[0,1,0], + get_lovects=_libwarpx.get_mesh_magnetic_field_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_magnetic_field_fp_pml, + level=level, include_ghosts=include_ghosts) + +def BzFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=2, overlaps=[0,0,1], + get_lovects=_libwarpx.get_mesh_magnetic_field_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_magnetic_field_fp_pml, + level=level, include_ghosts=include_ghosts) + +def JxFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=0, overlaps=[0,1,1], + get_lovects=_libwarpx.get_mesh_current_density_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_current_density_fp_pml, + level=level, include_ghosts=include_ghosts) + +def JyFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=1, overlaps=[1,0,1], + get_lovects=_libwarpx.get_mesh_current_density_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_current_density_fp_pml, + level=level, include_ghosts=include_ghosts) + +def JzFPPMLWrapper(level=0, include_ghosts=False): + return _MultiFABWrapper(direction=2, overlaps=[1,1,0], + get_lovects=_libwarpx.get_mesh_current_density_fp_lovects_pml, + get_fabs=_libwarpx.get_mesh_current_density_fp_pml, + level=level, include_ghosts=include_ghosts) |