Exemplo n.º 1
0
    def __init__(self,
                 velocity_func,
                 t_min,
                 t_max,
                 num_of_traj=None,
                 initial_values=None,
                 **integrator_kwargs):

        self.spatial_dimension = 3
        # Let's generate this kind of format automatically from grid etc. for the sake of generalization
        self.traj_data_file_name_format = 'rho-%.3f-theta-%.3f-phi-%.3f.dat'

        assert callable(velocity_func)
        self.velocity_func = velocity_func

        for arg in [t_min, t_max]:
            assert is_real_number(arg)
        assert t_min < t_max
        self.t_min, self.t_max = t_min, t_max

        self.num_of_traj = None
        if num_of_traj is not None:
            assert is_integer_valued_real(num_of_traj)
            self.num_of_traj = int(num_of_traj)

        self.initial_values = None
        self.initial_values_are_set = False
        if initial_values is not None: self.set_initial_values(initial_values)

        self.integrator_kwargs = integrator_kwargs

        self.shape = None
        self.traj_array = None
        if self.initial_values_are_set: self.construct_array_of_trajectory()
Exemplo n.º 2
0
def eigenfunction_spherical_box(rho, theta, phi, t, n, l, m, R0):
    """Return eigenfunction of an spherical box

    The radius of the spherical box is specfied as 'R0'.
    The returned eigenfunction is not normalized.

    ## Arguments ##
    # n (integer)
    - index (starting from 1) of radial function
    # l (integer)
    - order (starting from 0) of spherical radial bessel function
    - one of the index of spherical harmonics
    # m (integer)
    - -l <= m <= l
    # R0 (float)
    - R0 > 0
    """

    ## [180310 NOTE] Following checking procedure
    ## .. may be omitted for performance in future implementation
    for arg in [n, l, m]:
        assert is_integer_valued_real(arg)
    assert (n > 0) and (l >= 0) and (-l <= m) and (m <= l)
    assert R0 > 0

    zero_point = spherical_jn_zeros(l, n)
    energy = 0.5 * (zero_point / R0)**2
    time_independent_part = \
        special.spherical_jn(l, zero_point / R0 * rho) \
        * special.sph_harm(m, l, phi, theta)
    time_dependent_part = np.exp(-1.0j * energy * t)
    return time_independent_part * time_dependent_part
Exemplo n.º 3
0
def cut_range_to_be_dividable_by_delta(min_val, max_val, delta, cut_min,
                                       cut_max):
    ## Check input arguments
    #
    # Check real-ness and sign
    for arg in [min_val, max_val, delta]:
        assert is_real_number(arg)
    assert delta > 0
    #
    # check 'exclusive or' of cut_min and cut_max
    assert check_xor(cut_min, cut_max)

    ## Determine if the range is dividable by 'delta'
    divided = (max_val - min_val) / delta
    num_of_delta = int(divided)
    range_is_dividable_by_delta = is_integer_valued_real(divided)

    ## Cut range if the range (='max_val'-'min_val') is not dividable by 'delta'
    cut_min_val, cut_max_val = None, None
    if range_is_dividable_by_delta:
        cut_min_val, cut_max_val = min_val, max_val
    else:
        if cut_min:
            cut_min_val = max_val - num_of_delta * delta
            cut_max_val = max_val
        elif cut_max:
            cut_min_val = min_val
            cut_max_val = min_val + num_of_delta * delta
        else:
            raise Exception("Either 'cut_min' or 'cut_max' should be true")

    ## Return
    return cut_min_val, cut_max_val
Exemplo n.º 4
0
    def check_whether_index_is_in_supported_range(self, i, j, k):
        """Check whether an index is in the supported range"""

        grid_polar = self.grid

        for arg in [i, j, k]:
            assert is_integer_valued_real(arg)
        # Because of the boundary condition,
        # .. when i == grid_polar.rho.N, it means out of spaital region
        # .. and velocity vector is set to zero at this region.
        assert (0 < (i + 1)) and (i < (grid_polar.rho.N + 1)
                                  )  # i = 0, 1, ..., grid_polar.rho.N

        # When j == grid_polar.phi.N - 1, then the unit_cell's vertices' 'j'
        # .. ranges from (grid_polar.phi.N - 1 to grid_polar.phi.N)
        # .. where 'grid_polar.phi.N' is turned into '0' accordingin to the periodic boundary condition.
        assert (0 < (j + 1)) and (j < grid_polar.phi.N
                                  )  # j = 0, 1, ..., grid_polar.phi.N - 1

        assert (0 < (k + 1)) and (k < grid_polar.t.N)
Exemplo n.º 5
0
    def __getitem__(self, index_exp):
        """
        Return coordinate value in (\rho, \phi, time) coordinate system,
        corresponding to given array slice
        """
        #ndim = 3
        #assert len(index_exp) == 3:
        index_exp = process_index_exp(index_exp, self.ndim)

        A, B, C = np.meshgrid(self.rho[index_exp[0]],
                              self.phi[index_exp[1]],
                              self.t[index_exp[2]],
                              indexing='ij')

        result = []
        for arr in [A, B, C]:
            arr = np.squeeze(arr)
            if arr.ndim == 0:
                arr = float(arr)
                if is_integer_valued_real(arr):
                    arr = int(arr)
            result.append(arr)

        return result
Exemplo n.º 6
0
    def __init__(self,
                 ndim=None,
                 dydt=None,
                 initial_value=None,
                 t0=None,
                 t_max=None,
                 integrator='dopri5',
                 **integrator_kwargs):
        """
        ## Arguments
        #
        # ndim
        : the number of independent variables
        - 'ndim' is same as the number of elements in 'initial_value'
        - 'ndim' is same as the number of elements 
        .. in the returned array(or list) from 'dydt'
        - Although the default value of this argument is None,
        .. it should not be None and given by the caller.
        .. The default value is set to None in order to
        .. allow pure keyword argument syntax
        #
        # initial_value
        : initial values of independent variables (i.e. except time)
        - Type: array-like, scalar
        """

        ## Check input arguments and assign it to member variables if needed.
        assert ndim is not None
        assert is_integer_valued_real(ndim)
        self.ndim = int(ndim)

        if dydt is not None: assert callable(dydt)
        self.dydt = dydt

        assert type(integrator) is str
        self.initial_value = None
        if initial_value is not None:
            if np.iterable(initial_value):
                self.initial_value = initial_value
            elif is_real_number(initial_value):
                self.initial_value = [initial_value
                                      ]  # Make a scalar into a list
            else:
                raise TypeError(
                    "'initial_value' should be of type either iterable or scalar numerics"
                )

        for arg in [t0, t_max]:
            if arg is not None: assert is_real_number(arg)

        self.t0 = t0
        self.t_max = t_max

        self.integrator_name = integrator

        if self.dydt is not None:
            super().__init__(self.dydt)
            self.set_integrator(self.integrator_name, **integrator_kwargs)
            self.sol = []
            self.set_solout(lambda t, y: self.sol.append([t, *y]))

            self.initial_value_is_set = False
            if (self.initial_value is not None) and (self.t0 is not None):
                self.set_initial_value(self.initial_value, t=self.t0)
                self.initial_value_is_set = True

        self.array = None

        self.data_file_path = None
Exemplo n.º 7
0
    def __init__(self,
                 delta,
                 min_val,
                 max_val,
                 zero_at_min,
                 zero_at_max,
                 fix_delta,
                 periodic,
                 cut_min=None,
                 cut_max=None,
                 name=''):

        ## Check assign input arguments into member variables
        #
        # Check real-ness and sign
        for arg in [min_val, max_val, delta]:
            assert is_real_number(arg)
        assert min_val < max_val
        assert delta > 0
        #
        # Check booleans
        for arg in [zero_at_min, zero_at_min, fix_delta, periodic]:
            assert type(arg) is bool
        self.zero_at_min, self.zero_at_max = zero_at_min, zero_at_max
        self.fix_delta = fix_delta
        self.periodic = periodic
        if fix_delta is True:
            for arg in [cut_min, cut_max]:
                assert type(arg) is bool
            assert check_xor(cut_min, cut_max)
        self.cut_min, self.cut_max = cut_min, cut_max
        #
        # Check other parameter
        assert type(name) is str
        self.name = name

        ## Initialize member variables of parent class such as 'ndim'
        ndim = 1
        super().__init__(ndim)

        ## Cut range so that the range (='self.max'-'self.max') becomes a multiple of delta
        self.min, self.max = None, None
        self.delta = None
        if self.fix_delta:
            self.delta = delta
            self.min, self.max = cut_range_to_be_dividable_by_delta(
                min_val, max_val, self.delta, self.cut_min, self.cut_max)
        else:
            # If 'delta' isn't fixed, min and max value are fixed instead.
            self.min, self.max = min_val, max_val
            # Make the grid slightly denser if range is not dividable by given 'delta'
            divided = (self.max - self.min) / delta
            if is_integer_valued_real(divided):
                num_of_delta_to_fill_range = int(divided)
            else:
                num_of_delta_to_fill_range = int(divided) + 1
            self.delta = (self.max - self.min) / num_of_delta_to_fill_range

        ## Determine N, first value, last value
        if self.periodic:
            assert (self.zero_at_min is False) and (self.zero_at_max is False)
        self.N = int(np.round((self.max - self.min) / self.delta) + 1)

        self.first_val, self.last_val = None, None
        if self.periodic:
            self.N -= 1
            self.last_val = self.max - self.delta
        else:
            if self.zero_at_min:
                self.N -= 1
                self.first_val = self.min + self.delta
            #else: self.first_val = self.min

            if self.zero_at_max:
                self.N -= 1
                self.last_val = self.max - self.delta
            #else: self.last_val = self.max
        if self.first_val is None: self.first_val = self.min
        if self.last_val is None: self.last_val = self.max

        self.array = self.first_val + np.arange(self.N) * self.delta
        #print("max: ",self.max, "min:",self.min,"N:",self.N)
        #print("first: ",self.first_val,"delta",self.delta)
        # Check consistency
        #print("self.array[-1], self.last_val",self.array[-1], self.last_val )
        assert abs(self.array[-1] - self.last_val) < 1e-6
Exemplo n.º 8
0
 def indices_are_in_supported_range(self, *indices):
     all_in_range = True
     for idx, index in enumerate(indices):
         assert is_integer_valued_real(index)
         all_in_range &= (0 < (index + 1)) and (index < self.shape[idx])
     return all_in_range
Exemplo n.º 9
0
 def __init__(self, ndim):
     assert is_integer_valued_real(ndim)
     self.ndim = int(ndim)