Example #1
0
    def __init__(self):

        self.q1_start = 0
        self.q2_start = 0

        self.q1_end = 1
        self.q2_end = 1

        self.N_q1 = 1024
        self.N_q2 = 1024

        self.dq1 = (self.q1_end - self.q1_start) / self.N_q1
        self.dq2 = (self.q2_end - self.q2_start) / self.N_q2

        self.N_ghost = self.N_g = np.random.randint(3, 5)

        self.q1_center, self.q2_center = \
            calculate_q_center(self.q1_start, self.q2_start,
                               self.N_q1, self.N_q2, self.N_ghost,
                               self.dq1, self.dq2
                              )

        self.params = type('obj', (object, ), {'eps':1})

        self.cell_centered_EM_fields = af.constant(0, 6, 1, 
                                                   self.q1_center.shape[2],
                                                   self.q1_center.shape[3],
                                                   dtype=af.Dtype.f64
                                                  )

        self._comm   = PETSc.COMM_WORLD.tompi4py()

        self.performance_test_flag = False
Example #2
0
    def __init__(self, physical_system, rho_hat_initial):
        """
        Constructor for the fields_solver object, which takes in the physical system
        object and the FT of the initial charge density as the input. 

        Parameters:
        -----------
        physical_system: The defined physical system object which holds
                         all the simulation information

        rho_hat_initial: af.Array
                         The FT of the initial charge density array that's passed to 
                         an electrostatic solver for initialization
        """

        self.N_q1 = physical_system.N_q1
        self.N_q2 = physical_system.N_q2
        self.dq1 = physical_system.dq1
        self.dq2 = physical_system.dq2
        self.params = physical_system.params

        self.initialize = physical_system.initial_conditions

        self.q1_center, self.q2_center = \
            calculate_q_center(physical_system.q1_start,
                               physical_system.q2_start,
                               self.N_q1, self.N_q2, 0,
                               self.dq1, self.dq2
                              )

        self.k_q1, self.k_q2 = calculate_k(self.N_q1, self.N_q2,
                                           physical_system.dq1,
                                           physical_system.dq2)

        self._initialize(rho_hat_initial)
Example #3
0
    def __init__(self):
        self.physical_system = type('obj', (object, ), {'moments': moments})
        self.p1_start = [-10]
        self.p2_start = [-10]
        self.p3_start = [-10]

        self.N_p1 = 32
        self.N_p2 = 32
        self.N_p3 = 32

        self.dp1 = (-2 * self.p1_start[0]) / self.N_p1
        self.dp2 = (-2 * self.p2_start[0]) / self.N_p2
        self.dp3 = (-2 * self.p3_start[0]) / self.N_p3

        self.q1_start = 0
        self.q2_start = 0
        self.q1_end = 1
        self.q2_end = 1

        self.N_q1 = 16
        self.N_q2 = 16

        self.dq1 = (self.q1_end - self.q1_start) / self.N_q1
        self.dq2 = (self.q2_end - self.q2_start) / self.N_q2

        self.q1_center, self.q2_center = \
            calculate_q_center(self.q1_start, self.q2_start,
                               self.N_q1, self.N_q2, 0,
                               self.dq1, self.dq2
                              )

        self.p1_center, self.p2_center, self.p3_center = \
            calculate_p_center(self.p1_start, self.p2_start, self.p3_start,
                               self.N_p1, self.N_p2, self.N_p3,
                               [self.dp1], [self.dp2], [self.dp3]
                              )

        rho = (1 + 0.01 *
               af.sin(2 * np.pi * self.q1_center + 4 * np.pi * self.q2_center))

        T = (1 + 0.01 *
             af.cos(2 * np.pi * self.q1_center + 4 * np.pi * self.q2_center))

        p1_b = 0.01 * af.exp(-10 * self.q1_center**2 - 10 * self.q2_center**2)
        p2_b = 0.01 * af.exp(-10 * self.q1_center**2 - 10 * self.q2_center**2)
        p3_b = 0.01 * af.exp(-10 * self.q1_center**2 - 10 * self.q2_center**2)

        self.f = maxwell_boltzmann(rho, T, p1_b, p2_b, p3_b, self.p1_center,
                                   self.p2_center, self.p3_center)
def test_check_maxwells_constraints():

    params = params_check_maxwells_contraints
    system = physical_system(domain,
                             boundary_conditions,
                             params,
                             initialize_check_maxwells_contraints,
                             advection_terms,
                             collision_operator.BGK,
                             moments
                            )

    dq1 = (domain.q1_end - domain.q1_start) / domain.N_q1
    dq2 = (domain.q2_end - domain.q2_start) / domain.N_q2
    
    q1, q2 = calculate_q_center(domain.q1_start, domain.q2_start,
                                domain.N_q1, domain.N_q2, domain.N_ghost,
                                dq1, dq2
                               )
    
    rho = (  params.pert_real * af.cos(  params.k_q1 * q1 
                                       + params.k_q2 * q2
                                      )
           - params.pert_imag * af.sin(  params.k_q1 * q1 
                                       + params.k_q2 * q2
                                      )
          )

    obj = fields_solver(system, 
                        rho, 
                        False
                       )

    # Checking for ∇.E = rho / epsilon
    rho_left_bot = 0.25 * (  rho 
                           + af.shift(rho, 0, 0, 0, 1)
                           + af.shift(rho, 0, 0, 1, 0)
                           + af.shift(rho, 0, 0, 1, 1)
                          ) 

    N_g = obj.N_g
    assert(af.mean(af.abs(obj.compute_divB()[:, :, N_g:-N_g, N_g:-N_g]))<1e-14)

    divE  = obj.compute_divE()
    rho_b = af.mean(rho_left_bot) # background

    assert(af.mean(af.abs(divE - rho_left_bot + rho_b)[:, :, N_g:-N_g, N_g:-N_g])<1e-6)
Example #5
0
    def __init__(self, physical_system):
        """
        Constructor for the linear_solver object. It takes the physical
        system object as an argument and uses it in intialization and
        evolution of the system in consideration.

        Parameters
        ----------
        
        physical_system: The defined physical system object which holds
                         all the simulation information such as the initial
                         conditions, and the domain info is passed as an
                         argument in defining an instance of the linear_solver.
                         This system is then evolved, and monitored using the
                         various methods under the linear_solver class.
        """
        self.physical_system = physical_system

        # Storing Domain Information:
        self.q1_start, self.q1_end = physical_system.q1_start,\
                                     physical_system.q1_end
        self.q2_start, self.q2_end = physical_system.q2_start,\
                                     physical_system.q2_end
        self.p1_start, self.p1_end = physical_system.p1_start,\
                                     physical_system.p1_end
        self.p2_start, self.p2_end = physical_system.p2_start,\
                                     physical_system.p2_end
        self.p3_start, self.p3_end = physical_system.p3_start,\
                                     physical_system.p3_end

        # Getting Domain Resolution
        self.N_q1, self.dq1 = physical_system.N_q1, physical_system.dq1
        self.N_q2, self.dq2 = physical_system.N_q2, physical_system.dq2
        self.N_p1, self.dp1 = physical_system.N_p1, physical_system.dp1
        self.N_p2, self.dp2 = physical_system.N_p2, physical_system.dp2
        self.N_p3, self.dp3 = physical_system.N_p3, physical_system.dp3
        
        # Getting number of species:
        N_s = self.N_species = len(physical_system.params.mass)

        if(type(physical_system.params.mass) == list):
            # Having a temporary copy of the lists to copy to af.Array:
            list_mass   = physical_system.params.mass.copy()
            list_charge = physical_system.params.charge.copy()

            # Initializing af.Arrays for mass and charge:
            # Having the mass and charge along axis 1:
            self.physical_system.params.mass   = af.constant(0, 1, N_s, dtype = af.Dtype.f64)
            self.physical_system.params.charge = af.constant(0, 1, N_s, dtype = af.Dtype.f64)

            for i in range(N_s):
                self.physical_system.params.mass[0, i]   = list_mass[i]
                self.physical_system.params.charge[0, i] = list_charge[i]

        # Initializing variable to hold time elapsed:
        self.time_elapsed = 0

        # Checking that periodic B.C's are utilized:
        if(    physical_system.boundary_conditions.in_q1_left   != 'periodic' 
           and physical_system.boundary_conditions.in_q1_right  != 'periodic'
           and physical_system.boundary_conditions.in_q2_bottom != 'periodic'
           and physical_system.boundary_conditions.in_q2_top    != 'periodic'
          ):
            raise Exception('Only systems with periodic boundary conditions \
                             can be solved using the linear solver'
                           )

        # Initializing DAs which will be used in file-writing:
        # This is done so that the output format used by the linear solver matches
        # with the output format of the nonlinear solver:
        self._da_dump_f = PETSc.DMDA().create([self.N_q1, self.N_q2],
                                              dof=(  self.N_species
                                                   * self.N_p1 
                                                   * self.N_p2 
                                                   * self.N_p3
                                                  )
                                             )

        # Getting the number of definitions in moments:
        attributes = [a for a in dir(self.physical_system.moments) if not a.startswith('_')]

        # Removing utility functions:
        if('integral_over_v' in attributes):
            attributes.remove('integral_over_v')

        self._da_dump_moments = PETSc.DMDA().create([self.N_q1, self.N_q2],
                                                    dof = self.N_species * len(attributes)
                                                   )

        # Printing backend details:
        PETSc.Sys.Print('\nBackend Details for Linear Solver:')
        PETSc.Sys.Print(indent('On Node: '+ socket.gethostname()))
        PETSc.Sys.Print(indent('Device Details:'))
        PETSc.Sys.Print(indent(af.info_str(), 2))
        PETSc.Sys.Print(indent('Device Bandwidth = ' + str(bandwidth_test(100)) + ' GB / sec'))
        PETSc.Sys.Print()

        # Creating PETSc Vecs which are used in dumping to file:
        self._glob_f       = self._da_dump_f.createGlobalVec()
        self._glob_f_array = self._glob_f.getArray()

        self._glob_moments       = self._da_dump_moments.createGlobalVec()
        self._glob_moments_array = self._glob_moments.getArray()

        # Setting names for the objects which will then be
        # used as the key identifiers for the HDF5 files:
        PETSc.Object.setName(self._glob_f, 'distribution_function')
        PETSc.Object.setName(self._glob_moments, 'moments')

        # Intializing position, velocity and wave number arrays:
        self.q1_center, self.q2_center = \
            calculate_q_center(self.q1_start, self.q2_start,
                               self.N_q1, self.N_q2, 0,
                               self.dq1, self.dq2
                              )

        self.p1_center, self.p2_center, self.p3_center = \
            calculate_p_center(self.p1_start, self.p2_start, self.p3_start,
                               self.N_p1, self.N_p2, self.N_p3,
                               self.dp1, self.dp2, self.dp3, 
                              )
        
        # Converting dp1, dp2, dp3 to af.Array:
        self.dp1 = af.moddims(af.to_array(self.dp1), 1, self.N_species)
        self.dp2 = af.moddims(af.to_array(self.dp2), 1, self.N_species)
        self.dp3 = af.moddims(af.to_array(self.dp3), 1, self.N_species)

        self.k_q1, self.k_q2 = calculate_k(self.N_q1, self.N_q2,
                                           self.physical_system.dq1, 
                                           self.physical_system.dq2
                                          )

        # Assigning the function objects to methods of the solver:
        self._A_q    = self.physical_system.A_q
        self._A_p    = self.physical_system.A_p
        self._source = self.physical_system.source

        # Initializing f, f_hat and the other EM field quantities:
        self._initialize(physical_system.params)