def communicate_f(self): """ Used in communicating the values at the boundary zones for each of the local vectors among all procs. This routine is called to take care of communication (and periodic B.C's) procedures for the distribution function array. """ if(self.performance_test_flag == True): tic = af.time() # Transfer data from af.Array to PETSc.Vec af_to_petsc_glob_array(self, self.f, self._glob_f_array) # The following function takes care of interzonal communications # Additionally, it also automatically applies periodic BCs when necessary self._da_f.globalToLocal(self._glob_f, self._local_f) # Converting back from PETSc.Vec to af.Array: self.f = petsc_local_array_to_af(self, self.N_p1*self.N_p2*self.N_p3, self.N_species, self._local_f_array ) if(self.performance_test_flag == True): af.sync() toc = af.time() self.time_communicate_f += toc - tic return
def dump_distribution_function(self, file_name): """ This function is used to dump distribution function to a file for later usage.This dumps the complete 5D distribution function which can be used for restarting / post-processing Parameters ---------- file_name : The distribution_function array will be dumped to this provided file name. Returns ------- This function returns None. However it creates a file 'file_name.h5', containing the data of the distribution function Examples -------- >> solver.dump_distribution_function('distribution_function') The above statement will create a HDF5 file which contains the distribution function. The data is always stored with the key 'distribution_function' This can later be accessed using >> import h5py >> h5f = h5py.File('distribution_function.h5', 'r') >> f = h5f['distribution_function'][:] >> h5f.close() Alternatively, it can also be used with the load function to resume a long-running calculation. >> solver.load_distribution_function('distribution_function') """ af_to_petsc_glob_array(self, self.f, self._glob_f_array) viewer = PETSc.Viewer().createBinary(file_name + '.bin', 'w', comm=self._comm) viewer(self._glob_f) return
def check_maxwells_contraint_equations(self, rho): PETSc.Sys.Print("Initial Maxwell's Constraints:") divB_error = af.abs(self.compute_divB()) af_to_petsc_glob_array(self, divB_error, self._glob_divB_error_array) PETSc.Sys.Print('MAX(|divB|) =', self._glob_divB_error.max()) # TODO: What the is going on here? rho_b?? rho_by_eps = rho #/ self.params.dielectric_epsilon rho_b = af.mean(rho_by_eps) # background divE_error = self.compute_divE() - rho_by_eps + rho_b af_to_petsc_glob_array(self, divE_error, self._glob_divE_error_array) PETSc.Sys.Print('MAX(|divE-rho|) =', self._glob_divE_error.max())
def communicate_fields(self, on_fdtd_grid = False): """ Used in communicating the values at the boundary zones for each of the local vectors among all procs.This routine is called to take care of communication(and periodic B.C's) procedures for the EM field arrays. The function is used for communicating the EM field values on the cell centered grid which is used by default. Additionally,it can also be used to communicate the values on the Yee-grid which is used by the FDTD solver. """ if(self.performance_test_flag == True): tic = af.time() # Assigning the values of the af.Array # fields quantities to the PETSc.Vec: if(on_fdtd_grid is True): tmp_array = self.yee_grid_EM_fields else: tmp_array = self.cell_centered_EM_fields af_to_petsc_glob_array(self, tmp_array, self._glob_fields_array) # Takes care of boundary conditions and interzonal communications: self._da_fields.globalToLocal(self._glob_fields, self._local_fields) # Converting back to af.Array tmp_array = petsc_local_array_to_af(self, 6, 1, self._local_fields_array) if(on_fdtd_grid is True): self.yee_grid_EM_fields = tmp_array else: self.cell_centered_EM_fields = tmp_array if(self.performance_test_flag == True): af.sync() toc = af.time() self.time_communicate_fields += toc - tic return
def dump_moments(self, file_name): """ This function is used to dump moment variables to a file for later usage. Parameters ---------- file_name : str The variables will be dumped to this provided file name. Returns ------- This function returns None. However it creates a file 'file_name.h5', containing all the moments that were defined under moments_defs in physical_system. Examples -------- >> solver.dump_variables('boltzmann_moments_dump') The above set of statements will create a HDF5 file which contains the all the moments which have been defined in the physical_system object. The data is always stored with the key 'moments' inside the HDF5 file. Suppose 'density', 'mom_v1_bulk' and 'energy' are the 3 functions defined. Then the moments get stored in alphabetical order, ie. 'density', 'energy'...: These variables can then be accessed from the file using >> import h5py >> h5f = h5py.File('boltzmann_moments_dump.h5', 'r') >> n = h5f['moments'][:][:, :, 0] >> energy = h5f['moments'][:][:, :, 1] >> mom_v1 = h5f['moments'][:][:, :, 2] >> h5f.close() However, in the case of multiple species, the following holds: >> n_species_1 = h5f['moments'][:][:, :, 0] >> n_species_2 = h5f['moments'][:][:, :, 1] >> energy_species_1 = h5f['moments'][:][:, :, 2] >> energy_species_2 = h5f['moments'][:][:, :, 3] >> mom_v1_species_1 = h5f['moments'][:][:, :, 4] >> mom_v1_species_2 = h5f['moments'][:][:, :, 5] """ N_g = self.N_ghost attributes = [ a for a in dir(self.physical_system.moments) if not a.startswith('_') ] # Removing utility functions and imported modules: if ('integral_over_p' in attributes): attributes.remove('integral_over_p') if ('params' in attributes): attributes.remove('params') for i in range(len(attributes)): #print("i = ", i, attributes[i]) if (i == 0): array_to_dump = self.compute_moments(attributes[i]) else: array_to_dump = af.join(1, array_to_dump, self.compute_moments(attributes[i])) af.eval(array_to_dump) af_to_petsc_glob_array(self, array_to_dump, self._glob_moments_array) viewer = PETSc.Viewer().createBinary(file_name + '.bin', 'w', comm=self._comm) viewer(self._glob_moments)
def dump_EM_fields(self, file_name): """ This function is used to EM fields to a file for later usage. This dumps all the EM fields quantities E1, E2, E3, B1, B2, B3 which can then be used later for post-processing Parameters ---------- file_name : The EM_fields array will be dumped to this provided file name. Returns ------- This function returns None. However it creates a file 'file_name.h5', containing the data of the EM fields. Examples -------- >> solver.dump_EM_fields('data_EM_fields') The above statement will create a HDF5 file which contains the EM fields data. The data is always stored with the key 'EM_fields' This can later be accessed using >> import h5py >> h5f = h5py.File('data_EM_fields.h5', 'r') >> EM_fields = h5f['EM_fields'][:] >> E1 = EM_fields[:, :, 0] >> E2 = EM_fields[:, :, 1] >> E3 = EM_fields[:, :, 2] >> B1 = EM_fields[:, :, 3] >> B2 = EM_fields[:, :, 4] >> B3 = EM_fields[:, :, 5] >> h5f.close() Alternatively, it can also be used with the load function to resume a long-running calculation. >> solver.load_EM_fields('data_EM_fields') """ af_to_petsc_glob_array(self, self.fields_solver.yee_grid_EM_fields, self.fields_solver._glob_fields_array) viewer = PETSc.Viewer().createBinary(file_name + '.bin', 'w', comm=self._comm) viewer(self.fields_solver._glob_fields) return