rg_space.py 8.69 KB
 Ultima committed Sep 10, 2015 1 2 # NIFTY (Numerical Information Field Theory) has been developed at the # Max-Planck-Institute for Astrophysics.  Marco Selig committed Jan 30, 2015 3 ##  Ultima committed Sep 10, 2015 4 # Copyright (C) 2015 Max-Planck-Society  Marco Selig committed Jan 30, 2015 5 ##  Ultima committed Sep 10, 2015 6 7 # Author: Marco Selig # Project homepage:  Marco Selig committed Jan 30, 2015 8 ##  Ultima committed Sep 10, 2015 9 10 11 12 # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version.  Marco Selig committed Jan 30, 2015 13 ##  Ultima committed Sep 10, 2015 14 15 16 17 # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details.  Marco Selig committed Jan 30, 2015 18 ##  Ultima committed Sep 10, 2015 19 20 # You should have received a copy of the GNU General Public License # along with this program. If not, see .  Marco Selig committed Jan 30, 2015 21 22 23 24 25 26 27 28 29 30  """ .. __ ____ __ .. /__/ / _/ / /_ .. __ ___ __ / /_ / _/ __ __ .. / _ | / / / _/ / / / / / / .. / / / / / / / / / /_ / /_/ / .. /__/ /__/ /__/ /__/ \___/ \___ / rg .. /______/  Marco Selig committed Feb 03, 2015 31  NIFTY submodule for regular Cartesian grids.  Marco Selig committed Jan 30, 2015 32 33 34  """ from __future__ import division  Ultimanet committed Jun 29, 2015 35   Marco Selig committed Jan 30, 2015 36 import numpy as np  Ultimanet committed Jun 11, 2015 37   theos committed Jul 22, 2016 38 39 from d2o import distributed_data_object,\ STRATEGIES as DISTRIBUTION_STRATEGIES  theos committed May 26, 2016 40   theos committed Jul 23, 2016 41 from nifty.spaces.space import Space  csongor committed May 27, 2016 42   theos committed Aug 19, 2016 43 from nifty.config import about  Ultima committed Sep 10, 2015 44   theos committed Aug 19, 2016 45 from rg_space_paradict import RGSpaceParadict  Ultimanet committed Jun 11, 2015 46   Marco Selig committed Jan 30, 2015 47   theos committed Jul 04, 2016 48 class RGSpace(Space):  Marco Selig committed Jan 30, 2015 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95  """ .. _____ _______ .. / __/ / _ / .. / / / /_/ / .. /__/ \____ / space class .. /______/ NIFTY subclass for spaces of regular Cartesian grids. Parameters ---------- num : {int, numpy.ndarray} Number of gridpoints or numbers of gridpoints along each axis. naxes : int, *optional* Number of axes (default: None). zerocenter : {bool, numpy.ndarray}, *optional* Whether the Fourier zero-mode is located in the center of the grid (or the center of each axis speparately) or not (default: True). hermitian : bool, *optional* Whether the fields living in the space follow hermitian symmetry or not (default: True). purelyreal : bool, *optional* Whether the field values are purely real (default: True). dist : {float, numpy.ndarray}, *optional* Distance between two grid points along each axis (default: None). fourier : bool, *optional* Whether the space represents a Fourier or a position grid (default: False). Notes ----- Only even numbers of grid points per axis are supported. The basis transformations between position x and Fourier mode k rely on (inverse) fast Fourier transformations using the :math:exp(2 \pi i k^\dagger x)-formulation. Attributes ---------- para : numpy.ndarray One-dimensional array containing information on the axes of the space in the following form: The first entries give the grid-points along each axis in reverse order; the next entry is 0 if the fields defined on the space are purely real-valued, 1 if they are hermitian and complex, and 2 if they are not hermitian, but complex-valued; the last entries hold the information on whether the axes are centered on zero or not, containing a one for each zero-centered axis and a zero for each other one, in reverse order.  Ultima committed Sep 17, 2015 96  dtype : numpy.dtype  Marco Selig committed Jan 30, 2015 97 98 99 100 101 102 103 104 105 106 107 108 109  Data type of the field values for a field defined on this space, either numpy.float64 or numpy.complex128. discrete : bool Whether or not the underlying space is discrete, always False for regular grids. vol : numpy.ndarray One-dimensional array containing the distances between two grid points along each axis, in reverse order. By default, the total length of each axis is assumed to be one. fourier : bool Whether or not the grid represents a Fourier basis. """  theos committed Jul 22, 2016 110  def __init__(self, shape=(1,), zerocenter=False, distances=None,  theos committed Aug 19, 2016 111  harmonic=False, dtype=np.dtype('float')):  Marco Selig committed Jan 30, 2015 112 113 114 115 116 117 118 119 120 121 122 123  """ Sets the attributes for an rg_space class instance. Parameters ---------- num : {int, numpy.ndarray} Number of gridpoints or numbers of gridpoints along each axis. naxes : int, *optional* Number of axes (default: None). zerocenter : {bool, numpy.ndarray}, *optional* Whether the Fourier zero-mode is located in the center of the grid (or the center of each axis speparately) or not  Ultimanet committed Jun 11, 2015 124  (default: False).  Marco Selig committed Jan 30, 2015 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140  hermitian : bool, *optional* Whether the fields living in the space follow hermitian symmetry or not (default: True). purelyreal : bool, *optional* Whether the field values are purely real (default: True). dist : {float, numpy.ndarray}, *optional* Distance between two grid points along each axis (default: None). fourier : bool, *optional* Whether the space represents a Fourier or a position grid (default: False). Returns ------- None """  Ultima committed Sep 10, 2015 141   theos committed Jul 23, 2016 142 143 144 145  self.paradict = RGSpaceParadict(shape=shape, zerocenter=zerocenter, distances=distances, harmonic=harmonic)  theos committed Aug 19, 2016 146  self.dtype = np.dtype(dtype)  theos committed Jul 22, 2016 147 148 149 150  @property def harmonic(self): return self.paradict['harmonic']  Ultima committed Sep 17, 2015 151   Ultima committed Aug 05, 2015 152  def copy(self):  theos committed Jul 22, 2016 153 154  return RGSpace(dtype=self.dtype, harmonic=self.harmonic, **self.paradict.parameters)  Ultima committed Aug 05, 2015 155   theos committed Jun 24, 2016 156 157  @property def shape(self):  theos committed Jul 22, 2016 158  return self.paradict['shape']  Marco Selig committed Jan 30, 2015 159   theos committed Jul 22, 2016 160 161 162  @property def dim(self): return reduce(lambda x, y: x*y, self.shape)  Ultima committed Sep 10, 2015 163   theos committed Jul 22, 2016 164 165 166  @property def total_volume(self): return self.dim * reduce(lambda x, y: x*y, self.paradict['distances'])  Marco Selig committed Jan 30, 2015 167   theos committed Jul 23, 2016 168  def weight(self, x, power=1, axes=None, inplace=False):  theos committed Jul 22, 2016 169  weight = reduce(lambda x, y: x*y, self.paradict['distances'])**power  theos committed Jul 23, 2016 170 171 172 173 174 175  if inplace: x *= weight result_x = x else: result_x = x*weight return result_x  Marco Selig committed Jan 30, 2015 176   theos committed Jul 22, 2016 177  def compute_k_array(self, distribution_strategy):  Marco Selig committed Jan 30, 2015 178  """  theos committed Jul 22, 2016 179 180  Calculates an n-dimensional array with its entries being the lengths of the k-vectors from the zero point of the grid.  Marco Selig committed Jan 30, 2015 181 182 183  Parameters ----------  theos committed Jul 22, 2016 184  None : All information is taken from the parent object.  Marco Selig committed Jan 30, 2015 185 186 187  Returns -------  theos committed Jul 22, 2016 188  nkdict : distributed_data_object  Marco Selig committed Jan 30, 2015 189  """  theos committed Jul 22, 2016 190 191 192 193 194 195 196 197 198 199 200 201 202  shape = self.shape # prepare the distributed_data_object nkdict = distributed_data_object( global_shape=shape, dtype=np.float128, distribution_strategy=distribution_strategy) if distribution_strategy in DISTRIBUTION_STRATEGIES['slicing']: # get the node's individual slice of the first dimension slice_of_first_dimension = slice( *nkdict.distributor.local_slice[0:2]) elif distribution_strategy in DISTRIBUTION_STRATEGIES['not']: slice_of_first_dimension = slice(0, shape[0])  Ultimanet committed Jun 11, 2015 203  else:  ultimanet committed Apr 27, 2015 204  raise ValueError(about._errors.cstring(  theos committed Jul 22, 2016 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233  "ERROR: Unsupported distribution strategy")) dists = self._compute_k_array_helper(slice_of_first_dimension) nkdict.set_local_data(dists) return nkdict def _compute_k_array_helper(self, slice_of_first_dimension): dk = self.paradict['distances'] shape = self.shape inds = [] for a in shape: inds += [slice(0, a)] cords = np.ogrid[inds] dists = ((np.float128(0) + cords[0] - shape[0] // 2) * dk[0])**2 # apply zerocenterQ shift if self.paradict['zerocenter'][0] == False: dists = np.fft.fftshift(dists) # only save the individual slice dists = dists[slice_of_first_dimension] for ii in range(1, len(shape)): temp = ((cords[ii] - shape[ii] // 2) * dk[ii])**2 if self.paradict['zerocenter'][ii] == False: temp = np.fft.fftshift(temp) dists = dists + temp dists = np.sqrt(dists) return dists