filename = "t=00000096.343750.bin" dump_file = filepath + '/dump_moments/' + filename moments = io.readBinaryFile(dump_file) moments = moments[0].reshape(N_q2, N_q1, 3) dump_file = filepath + '/dump_lagrange_multipliers/' + filename lagrange_multipliers = io.readBinaryFile(dump_file) lagrange_multipliers = lagrange_multipliers[0].reshape(N_q2, N_q1, 5) density = moments[:, :, 0] vel_drift_x = lagrange_multipliers[:, :, 3] vel_drift_y = lagrange_multipliers[:, :, 4] size = N_q1 * N_q2 density_array[:] = density.flatten() vel_drift_x_array[:] = vel_drift_x.flatten() vel_drift_y_array[:] = vel_drift_y.flatten() vel_drift_array[::3] = vel_drift_x.flatten() vel_drift_array[1::3] = vel_drift_y.flatten() # third component is zero; do nothing viewer = PETSc.Viewer().createVTK('ballistic_rectifier.vts', 'w') density_vec.view(viewer) vel_drift_x_vec.view(viewer) vel_drift_y_vec.view(viewer) vel_drift_vec.view(viewer)
def evalMatDiffRel(mat1, mat2, diffTol=1e-16): # the relative error is computed as # (mat1-mat2)/mat1 # read mat 1 jacMat1 = PETSc.Mat().create(PETSc.COMM_WORLD) viewer = PETSc.Viewer().createBinary(mat1, comm=PETSc.COMM_WORLD) jacMat1.load(viewer) # read mat 2 jacMat2 = PETSc.Mat().create(PETSc.COMM_WORLD) viewer = PETSc.Viewer().createBinary(mat2, comm=PETSc.COMM_WORLD) jacMat2.load(viewer) Istart, Iend = jacMat1.getOwnershipRange() # absolute error jacMatDiff = PETSc.Mat().create(PETSc.COMM_WORLD) viewer = PETSc.Viewer().createBinary(mat1, comm=PETSc.COMM_WORLD) jacMatDiff.load(viewer) jacMatDiff.axpy(-1.0, jacMat2, structure=jacMatDiff.Structure.DIFFERENT_NONZERO_PATTERN) maxDiff = -1.0e12 maxVal1 = -1.0e12 maxVal2 = -1.0e12 maxRowI = -1.0e12 maxColI = -1.0e12 l2norm = 0.0 foundDiff = 0 for i in xrange(Istart, Iend): rowVals = jacMatDiff.getRow(i) nCols = len(rowVals[0]) for j in range(nCols): colI = rowVals[0][j] valDiff = abs(rowVals[1][j]) valRef = abs(jacMat1[i, colI]) valRelError = valDiff / (valRef + diffTol) l2norm = l2norm + valRelError**2 if valRelError > diffTol: if valRelError > maxDiff: foundDiff = 1 maxDiff = valRelError maxRowI = i maxColI = colI maxVal1 = jacMat1.getValue(i, colI) maxVal2 = jacMat2.getValue(i, colI) l2norm = l2norm**0.5 if foundDiff == 1: print('L2Norm: %20.16e' % l2norm) print('MaxDRel: %20.16e' % maxDiff) print('MaxVal1: %20.16e' % maxVal1) print('MaxVal2: %20.16e' % maxVal2) print('MaxrowI: %d' % maxRowI) print('MaxcolI: %d' % maxColI) return maxDiff else: print('Two matrices are exactly same with tolerance: %e' % diffTol) return 0.0, 0.0
def _vector_load(directory, filename): if _file_exists(directory, filename + ".dat"): viewer = PETSc.Viewer().createBinary(os.path.join(str(directory), filename + ".dat"), "r") return PETSc.Vec().load(viewer) else: raise OSError
Created on Aug 15, 2012 @author: nullas ''' from cp.surfaces.MeshWrapper import MeshWrapper from mayavi import mlab as pl import scipy as sp import petsc4py petsc4py.init() from petsc4py import PETSc def initialu(cp): rlt = sp.ones(cp.shape[0]) (ind,) = sp.where(2.3*cp[:,0]+cp[:,2] > 0) rlt[ind] = 0 return rlt if __name__ == '__main__': surface = MeshWrapper('eight.ply') pl.figure(bgcolor=(1,1,1),fgcolor=(0.5,0.5,0.5)) pl.triangular_mesh(surface.v[:,0],surface.v[:,1],surface.v[:,2],surface.f,scalars=initialu(surface.v)) # pl.points3d(surface.v[:,0],surface.v[:,1],surface.v[:,2],initialu(surface.v),mode='point') pl.colorbar() vv=PETSc.Viewer().createBinary('gv.dat','r') cv = PETSc.Vec().load(vv) cv = cv.getArray() pl.figure(bgcolor=(1,1,1),fgcolor=(0.5,0.5,0.5)) pl.triangular_mesh(surface.v[:,0],surface.v[:,1],surface.v[:,2],surface.f,scalars=cv) pl.colorbar() pl.show()
import time comm = MPI.COMM_WORLD myid = comm.Get_rank() OptDB = P.Options() fname_mat = OptDB.getString('-mat', 'mat.bin') fname_b = OptDB.getString('-b', 'b.bin') check_matrows = OptDB.getBool('-check_matrows', False) info = OptDB.getBool('-info', False) if myid == 0: print("Loading Matrix File: {}".format(fname_mat)) viewer = P.Viewer().createBinary(fname_mat, 'r') A = P.Mat().load(viewer) A = A.setUp() if check_matrows: if myid == 0: print("Building Transpose...") At = A.duplicate() A.transpose(At) if myid == 0: print("Building Transpose... done") rStart, rEnd = At.getOwnershipRange() for i in range(rStart, rEnd): col_idx, coeff = At.getRow(i) if np.sum(coeff) < -1e-8:
def _matrix_load(directory, filename, mpi_comm): if _file_exists(directory, filename + ".dat", mpi_comm): viewer = PETSc.Viewer().createBinary(os.path.join(str(directory), filename + ".dat"), "r", mpi_comm) return PETSc.Mat().load(viewer) else: raise OSError
def dump_moments(self, file_name): """ This function is used to dump 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' and 'energy' are two these moments, and are declared the first and second in the moment_exponents object: These variables can then be accessed from the file using >> import h5py >> h5f = h5py.File('boltzmann_moments_dump.h5', 'r') >> rho = h5f['moments'][:][:, :, 0] >> energy = h5f['moments'][:][:, :, 1] >> h5f.close() However, in the case of multiple species, the following holds: >> rho_species_1 = h5f['moments'][:][:, :, 0] >> rho_species_2 = h5f['moments'][:][:, :, 1] >> energy_species_1 = h5f['moments'][:][:, :, 2] >> energy_species_2 = h5f['moments'][:][:, :, 3] """ 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') for i in range(len(attributes)): 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.flat(array_to_dump).to_ndarray(self._glob_moments_array) viewer = PETSc.Viewer().createHDF5(file_name + '.h5', 'w') viewer(self._glob_moments)
def run_SDC_variant(variant=None, inexact=False, cwd=''): """ Routine to run particular SDC variant Args: variant (str): string describing the variant inexact (bool): flag to use inexact nonlinear solve (or nor) cwd (str): current working directory Returns: timing (float) niter (float) """ # load (incomplete) default parameters description, controller_params = setup_parameters() # add stuff based on variant if variant == 'fully-implicit': description['problem_class'] = petsc_grayscott_fullyimplicit description['sweeper_class'] = generic_implicit elif variant == 'semi-implicit': description['problem_class'] = petsc_grayscott_semiimplicit description['sweeper_class'] = imex_1st_order elif variant == 'multi-implicit': description['problem_class'] = petsc_grayscott_multiimplicit description['sweeper_class'] = multi_implicit else: raise NotImplemented('Wrong variant specified, got %s' % variant) if inexact: description['problem_params']['lsol_maxiter'] = 2 description['problem_params']['nlsol_maxiter'] = 1 out = 'Working on inexact %s variant...' % variant else: out = 'Working on exact %s variant...' % variant print(out) # set time parameters t0 = 0.0 Tend = 2000.0 # instantiate controller controller = controller_nonMPI(num_procs=1, controller_params=controller_params, description=description) # get initial values on finest level P = controller.MS[0].levels[0].prob uinit = P.u_exact(t0) # call main function to get things done... uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend) #VecGetArrays neu = uend.values.getArray() np.savez_compressed(file=str(Tend) + 'petsc.npz', uend=neu) #neu = uend.values.VecGetArray() print("abw afw", abs(uend - uinit)) plt.imshow(neu.reshape([32, 32, 2])[:, :, 0], interpolation='bilinear') plt.savefig(str(Tend) + 'mesh.pdf') exit() fname = 'ref_24.npz' np.savez_compressed(file=fname, uend=uend.values) # load reference solution to compare with fname = cwd + 'data/GS_reference.dat' viewer = PETSc.Viewer().createBinary(fname, 'r') uex = P.u_exact(t0) uex.values = PETSc.Vec().load(viewer) err = abs(uex - uend) # filter statistics by variant (number of iterations) filtered_stats = filter_stats(stats, type='niter') # convert filtered statistics to list of iterations count, sorted by process iter_counts = sort_stats(filtered_stats, sortby='time') # compute and print statistics niters = np.array([item[1] for item in iter_counts]) out = ' Mean number of iterations: %4.2f' % np.mean(niters) print(out) out = ' Range of values for number of iterations: %2i ' % np.ptp(niters) print(out) out = ' Position of max/min number of iterations: %2i -- %2i' % \ (int(np.argmax(niters)), int(np.argmin(niters))) print(out) out = ' Std and var for number of iterations: %4.2f -- %4.2f' % (float( np.std(niters)), float(np.var(niters))) print(out) print('Iteration count (nonlinear/linear): %i / %i' % (P.snes_itercount, P.ksp_itercount)) print('Mean Iteration count per call: %4.2f / %4.2f' % (P.snes_itercount / max(P.snes_ncalls, 1), P.ksp_itercount / max(P.ksp_ncalls, 1))) timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time') print('Time to solution: %6.4f sec.' % timing[0][1]) print('Error vs. reference solution: %6.4e' % err) print() assert err < 3E-06, 'ERROR: variant %s did not match error tolerance, got %s' % ( variant, err) assert np.mean( niters ) <= 10, 'ERROR: number of iterations is too high, got %s' % np.mean( niters) return timing[0][1], np.mean(niters)
A[I,I] = 4 i = I//n if i>0 : J = I-n; A[I,J] = -1 if i<m-1: J = I+n; A[I,J] = -1 j = I-i*n if j>0 : J = I-1; A[I,J] = -1 if j<n-1: J = I+1; A[I,J] = -1 A.assemblyBegin() A.assemblyEnd() x, y = A.getVecs() x.set(1) A.mult(x,y) # save viewer = PETSc.Viewer().createBinary('matrix-A.dat', 'w') viewer(A) viewer = PETSc.Viewer().createBinary('vector-x.dat', 'w') viewer(x) viewer = PETSc.Viewer().createBinary('vector-y.dat', 'w') viewer(y) # load viewer = PETSc.Viewer().createBinary('matrix-A.dat', 'r') B = PETSc.Mat().load(viewer) viewer = PETSc.Viewer().createBinary('vector-x.dat', 'r') u = PETSc.Vec().load(viewer) viewer = PETSc.Viewer().createBinary('vector-y.dat', 'r') v = PETSc.Vec().load(viewer) # check
# Set metric parameters h_min = 1.0e-10 # Minimum tolerated metric magnitude ~ cell size h_max = 1.0e-01 # Maximum tolerated metric magnitude ~ cell size a_max = 1.0e+05 # Maximum tolerated anisotropy targetComplexity = 10000.0 # Analogous to number of vertices in adapted mesh p = 1.0 # Lᵖ normalization order # Create a uniform mesh OptDB = PETSc.Options() dim = OptDB.getInt('dim', 2) numEdges = 10 simplex = True plex = PETSc.DMPlex().createBoxMesh([numEdges] * dim, simplex=simplex) plex.distribute() plex.view() viewer = PETSc.Viewer().createVTK('base_mesh.vtk', 'w') viewer(plex) # Do four mesh adaptation iterations for i in range(4): vStart, vEnd = plex.getDepthStratum(0) # Create a P1 sensor function comm = plex.getComm() fe = PETSc.FE().createLagrange(dim, 1, simplex, 1, -1, comm=comm) plex.setField(0, fe) plex.createDS() f = plex.createLocalVector() csec = plex.getCoordinateSection() coords = plex.getCoordinatesLocal() pf = f.getArray()
def run_reference(): """ Helper routine to create a reference solution using very high order SDC and small time-steps """ description, controller_params = setup_parameters() description['problem_class'] = petsc_grayscott_semiimplicit description['sweeper_class'] = imex_1st_order description['sweeper_params']['num_nodes'] = 9 description['level_params']['dt'] = 0.01 # set time parameters t0 = 0.0 Tend = 1.0 # instantiate controller controller = controller_nonMPI(num_procs=1, controller_params=controller_params, description=description) # get initial values on finest level P = controller.MS[0].levels[0].prob uinit = P.u_exact(t0) # call main function to get things done... uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend) # filter statistics by variant (number of iterations) filtered_stats = filter_stats(stats, type='niter') # convert filtered statistics to list of iterations count, sorted by process iter_counts = sort_stats(filtered_stats, sortby='time') # compute and print statistics niters = np.array([item[1] for item in iter_counts]) out = ' Mean number of iterations: %4.2f' % np.mean(niters) print(out) out = ' Range of values for number of iterations: %2i ' % np.ptp(niters) print(out) out = ' Position of max/min number of iterations: %2i -- %2i' % \ (int(np.argmax(niters)), int(np.argmin(niters))) print(out) out = ' Std and var for number of iterations: %4.2f -- %4.2f' % (float( np.std(niters)), float(np.var(niters))) print(out) print('Iteration count (nonlinear/linear): %i / %i' % (P.snes_itercount, P.ksp_itercount)) print('Mean Iteration count per call: %4.2f / %4.2f' % (P.snes_itercount / max(P.snes_ncalls, 1), P.ksp_itercount / max(P.ksp_ncalls, 1))) timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time') print('Time to solution: %6.4f sec.' % timing[0][1]) fname = 'data/GS_reference.dat' viewer = PETSc.Viewer().createBinary(fname, 'w') viewer.view(uend.values) assert os.path.isfile(fname), 'ERROR: PETSc did not create file' return None
# GRAPHENE if args.type == "gr": tag = "gr_%d" % (args.xdim) tagham = "gr_%d" % (args.xdim) rnp = 3.01 dim = args.xdim CK = Chebcoeffs(args.kbt, args.mu, args.fhchebdeg) Mat, coords = Make_graphene_ham_coo(dim, args.p, rnp, 0.0, -1) print "<< Matrix generated" if args.V: Vx = Velx_gr(dim, 1, 0.0) Velx = Create_petsc_mat(Vx, 3.01) velxname = "velxgr_%d" % (dim) viewer = PETSc.Viewer().createBinary(velxname, 'w') viewer(Velx) # print_mat(Vx.todense()) tmpMat, tmpcoords = Make_graphene_ham_coo(50, args.p, rnp) Jx = Make_Jx_op(dim, args.p, rnp - 1) # Jx = Make_Jx_id_op(G_mat.size,p,1.01) Jxname = "jxgr_%d" % (dim) t = -2. eps = -t / 16. JX = Create_petsc_mat(Jx, -1.0j / rnp) #print Mat.todense()
moments = io.readBinaryFile(dump_file) moments = moments[0].reshape(N_q2, N_q1, 3) dump_file = filepath + '/dump_lagrange_multipliers/' + filename lagrange_multipliers = io.readBinaryFile(dump_file) lagrange_multipliers = lagrange_multipliers[0].reshape(N_q2, N_q1, 5) density = moments[:, :, 0] #vel_drift_x = lagrange_multipliers[:, :, 3] #vel_drift_y = lagrange_multipliers[:, :, 4] vel_drift_x = moments[:, :, 1] # This is j_x vel_drift_y = moments[:, :, 2] # This is j_y size = N_q1 * N_q2 density_array[:] = density.flatten() vel_drift_x_array[:] = vel_drift_x.flatten() vel_drift_y_array[:] = vel_drift_y.flatten() vel_drift_array[::3] = vel_drift_x.flatten() vel_drift_array[1::3] = vel_drift_y.flatten() # third component is zero; do nothing viewer = PETSc.Viewer().createVTK('circular_domain.vts', 'w') density_vec.view(viewer) vel_drift_x_vec.view(viewer) vel_drift_y_vec.view(viewer) vel_drift_vec.view(viewer)
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 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') """ N_g_q = self.N_ghost_q N_g_p = self.N_ghost_p N_q1_local = self.f.shape[2] N_q2_local = self.f.shape[3] # The dumped array shouldn't be inclusive of velocity ghost zones: if (N_g_p != 0): array_to_dump = self._convert_to_p_expanded(self.f)[N_g_p:-N_g_p, N_g_p:-N_g_p, N_g_p:-N_g_p] array_to_dump = af.moddims(array_to_dump, self.N_p1 * self.N_p2 * self.N_p3, self.N_species, N_q1_local, N_q2_local) else: array_to_dump = self.f array_to_dump = af.flat(array_to_dump[:, :, N_g_q:-N_g_q, N_g_q:-N_g_q]) array_to_dump.to_ndarray(self._glob_dump_f_array) viewer = PETSc.Viewer().createHDF5(file_name + '.h5', 'w', comm=self._comm) viewer(self._glob_dump_f) return
def write_petsc(solution,frame,path='./',file_prefix='claw',write_aux=False,options={},write_p=False): r""" Write out pickle and PETSc data files representing the solution. Common data is written from process 0 in pickle files. Shared data is written from all processes into PETSc data files. :Input: - *solution* - (:class:`~pyclaw.solution.Solution`) pyclaw object to be output - *frame* - (int) Frame number - *path* - (string) Root path - *file_prefix* - (string) Prefix for the file name. ``default = 'claw'`` - *write_aux* - (bool) Boolean controlling whether the associated auxiliary array should be written out. ``default = False`` - *options* - (dict) Optional argument dictionary, see `PETScIO Option Table`_ .. _`PETScIO Option Table`: format : one of 'ascii' or 'binary' clobber : if True (Default), files will be overwritten """ # Option parsing option_defaults = {'format':'binary','clobber':True} for k in option_defaults.iterkeys(): if options.has_key(k): pass else: options[k] = option_defaults[k] clobber = options['clobber'] pickle_filename = os.path.join(path, '%s.pkl' % file_prefix) + str(frame).zfill(4) if options['format']=='vtk': viewer_filename = os.path.join(path, file_prefix+str(frame).zfill(4)+'.vtk') else: viewer_filename = os.path.join(path, '%s.ptc' % file_prefix) + str(frame).zfill(4) if solution.num_aux > 0 and write_aux: write_aux = True aux_filename = os.path.join(path, '%s_aux.ptc' % file_prefix) else: write_aux = False if not clobber: if os.path.exists(pickle_filename): raise IOError('Cowardly refusing to clobber %s!' % pickle_filename) if os.path.exists(viewer_filename): raise IOError('Cowardly refusing to clobber %s!' % viewer_filename) if write_aux and os.path.exists(aux_filename): raise IOError('Cowardly refusing to clobber %s!' % aux_filename) rank = PETSc.Comm.getRank(PETSc.COMM_WORLD) if rank==0: pickle_file = open(pickle_filename,'wb') # explicitly dumping a dictionary here to help out anybody trying to read the pickle file if write_p: pickle.dump({'t':solution.t,'num_eqn':solution.mp,'nstates':len(solution.states), 'num_aux':solution.num_aux,'num_dim':solution.num_dim,'write_aux':write_aux, 'problem_data' : solution.problem_data}, pickle_file) else: pickle.dump({'t':solution.t,'num_eqn':solution.num_eqn,'nstates':len(solution.states), 'num_aux':solution.num_aux,'num_dim':solution.domain.num_dim,'write_aux':write_aux, 'problem_data' : solution.problem_data}, pickle_file) # now set up the PETSc viewers if options['format'] == 'ascii': viewer = PETSc.Viewer().createASCII(viewer_filename, PETSc.Viewer.Mode.WRITE) if write_aux: aux_viewer = PETSc.Viewer().createASCII(aux_filename, PETSc.Viewer.Mode.WRITE) elif options['format'] == 'binary': if hasattr(PETSc.Viewer,'createMPIIO'): viewer = PETSc.Viewer().createMPIIO(viewer_filename, PETSc.Viewer.Mode.WRITE) else: viewer = PETSc.Viewer().createBinary(viewer_filename, PETSc.Viewer.Mode.WRITE) if write_aux: if hasattr(PETSc.Viewer,'createMPIIO'): aux_viewer = PETSc.Viewer().createMPIIO(aux_filename, PETSc.Viewer.Mode.WRITE) else: aux_viewer = PETSc.Viewer().createBinary(aux_filename, PETSc.Viewer.Mode.WRITE) elif options['format'] == 'vtk': viewer = PETSc.Viewer().createASCII(viewer_filename, PETSc.Viewer.Mode.WRITE, format=PETSc.Viewer.Format.ASCII_VTK) if write_aux: aux_viewer = PETSc.Viewer().createASCII(aux_filename, PETSc.Viewer.Mode.WRITE) else: raise IOError('format type %s not supported' % options['format']) for state in solution.states: patch = state.patch if rank==0: pickle.dump({'level':patch.level, 'names':patch.name,'lower':patch.lower_global, 'num_cells':patch.num_cells_global,'delta':patch.delta}, pickle_file) # we will reenable this bad boy when we switch over to petsc-dev # state.q_da.view(viewer) if write_p: state.gpVec.view(viewer) else: state.gqVec.view(viewer) if write_aux: state.gauxVec.view(aux_viewer) viewer.flush() viewer.destroy() if rank==0: pickle_file.close()
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 read_petsc(self): if hasattr(self, 'frame'): frame = self.frame if hasattr(self, 'file_prefix'): file_prefix = self.file_prefix if hasattr(self, 'path'): path = self.path if hasattr(self, 'write_aux'): write_aux = self.write_aux if hasattr(self, 'write_aux'): read_aux = self.read_aux if hasattr(self, 'write_p'): write_p = self.write_p pickle_filename = os.path.join( path, '%s.pkl' % file_prefix) + str(frame).zfill(4) viewer_filename = os.path.join( path, '%s.ptc' % file_prefix) + str(frame).zfill(4) aux_viewer_filename1 = os.path.join( path, '%s_aux.ptc' % file_prefix) + str(frame).zfill(4) aux_viewer_filename2 = os.path.join( path, '%s_aux.ptc' % file_prefix) + str(0).zfill(4) if os.path.exists(aux_viewer_filename1): aux_viewer_filename = aux_viewer_filename1 else: aux_viewer_filename = aux_viewer_filename2 pickle_file = open(pickle_filename, 'rb') # this dictionary is mostly holding debugging information, only nstates is needed # most of this information is explicitly saved in the individual patches value_dict = pickle.load(pickle_file) nstates = value_dict['nstates'] num_dim = value_dict['num_dim'] num_aux = value_dict['num_aux'] num_eqn = value_dict['num_eqn'] self.__setattr__('num_dim', num_dim) self.__setattr__('num_aux', num_aux) self.__setattr__('num_eqn', num_eqn) # now set up the PETSc viewer (assuming binary) viewer = PETSc.Viewer().createBinary(viewer_filename, PETSc.Viewer.Mode.READ) if read_aux: aux_viewer = PETSc.Viewer().createBinary(aux_viewer_filename, PETSc.Viewer.Mode.READ) patches = [] for m in xrange(nstates): patch_dict = pickle.load(pickle_file) level = patch_dict['level'] names = patch_dict['names'] lower = patch_dict['lower'] n = patch_dict['num_cells'] d = patch_dict['delta'] from clawpack import petclaw dimensions = [] for i in xrange(num_dim): dimensions.append( petclaw.Dimension(names[i], lower[i], lower[i] + n[i] * d[i], n[i])) patch = petclaw.Patch(dimensions) self.__setattr__('_patch', patch) if num_dim == 1: self.__setattr__('x', patch.x) elif num_dim == 2: self.__setattr__('x', patch.x) self.__setattr__('y', patch.y) elif num_dim == 3: self.__setattr__('y', patch.y) self.__setattr__('z', path.z) self.__setattr__('num_cells', patch.num_cells_global) claw = petclaw.State(patch, num_eqn, num_aux) ## self.__setattr__('_claw', claw) self.t = value_dict['t'] self.problem_data = value_dict['problem_data'] self.nstates = value_dict['nstates'] self._claw.gqVec.load(viewer) if read_aux: self._claw.gauxVec.load(aux_viewer) self.__setattr__('aux', self._claw.aux) self.__setattr__('q', self._claw.q) self.__setattr__('frame', frame) self.__setattr__('file_prefix', file_prefix) self.__setattr__('read_aux', read_aux) self.__setattr__('write_aux', write_aux) self.__setattr__('write_p', write_p) self.__setattr__('path', path) return self
def test_j_design(ssarun): grid = ssarun.grid S = 250 d_viewer = PETSc.Viewer().createDraw(title="d", size=S) drhs_viewer = PETSc.Viewer().createDraw(title="drhs", size=S) drhs_fd_viewer = PETSc.Viewer().createDraw(title="drhs_fd", size=S) d_drhs_viewer = PETSc.Viewer().createDraw(title="d_drhs", size=S) ssarun.ssa.linearize_at(zeta1) u1 = PISM.IceModelVec2V() u1.create(grid, "", PISM.WITH_GHOSTS) u1.copy_from(ssarun.ssa.solution()) for (i, j) in grid.points(): d = PISM.IceModelVec2S() d.create(grid, "", PISM.WITH_GHOSTS) d.set(0) with PISM.vec.Access(comm=d): d[i, j] = 1 ssarun.ssa.linearize_at(zeta1) rhs1 = PISM.IceModelVec2V() rhs1.create(grid, "", PISM.WITHOUT_GHOSTS) ssarun.ssa.assemble_residual(u1, rhs1) eps = 1e-8 zeta2 = PISM.IceModelVec2S() zeta2.create(grid, "zeta_prior", PISM.WITH_GHOSTS) zeta2.copy_from(d) zeta2.scale(eps) zeta2.add(1, zeta1) ssarun.ssa.set_design(zeta2) rhs2 = PISM.IceModelVec2V() rhs2.create(grid, "", PISM.WITHOUT_GHOSTS) ssarun.ssa.assemble_residual(u1, rhs2) drhs_fd = PISM.IceModelVec2V() drhs_fd.create(grid, "", PISM.WITHOUT_GHOSTS) drhs_fd.copy_from(rhs2) drhs_fd.add(-1, rhs1) drhs_fd.scale(1. / eps) drhs = PISM.IceModelVec2V() drhs.create(grid, "", PISM.WITHOUT_GHOSTS) ssarun.ssa.apply_jacobian_design(u1, d, drhs) d_drhs = PISM.IceModelVec2V() d_drhs.create(grid, "", PISM.WITHOUT_GHOSTS) d_drhs.copy_from(drhs) d_drhs.add(-1, drhs_fd) n_drhs_fd = drhs_fd.norm(PETSc.NormType.NORM_2) n_drhs_l2 = drhs.norm(PETSc.NormType.NORM_2) n_drhs_l1 = drhs.norm(PETSc.NormType.NORM_1) n_drhs_linf = drhs.norm(PETSc.NormType.NORM_INFINITY) n_d_drhs_l2 = d_drhs.norm(PETSc.NormType.NORM_2) n_d_drhs_l1 = d_drhs.norm(PETSc.NormType.NORM_1) n_d_drhs_linf = d_drhs.norm(PETSc.NormType.NORM_INFINITY) PISM.verbPrintf( 1, grid.com, "\nTest Jacobian Design (Comparison with finite differences):\n") PISM.verbPrintf( 1, grid.com, "jacobian_design(d): l2 norm %.10g; finite difference %.10g\n" % (n_drhs_l2, n_drhs_fd)) if n_drhs_linf == 0: PISM.verbPrintf( 1, grid.com, "difference: l2 norm %.10g l1 norm %.10g linf norm %.10g\n" % (n_d_drhs_l2, n_d_drhs_l1, n_d_drhs_linf)) else: PISM.verbPrintf( 1, grid.com, "relative difference: l2 norm %.10g l1 norm %.10g linf norm %.10g\n" % (n_d_drhs_l2 / n_drhs_l2, n_d_drhs_l1 / n_drhs_l1, n_d_drhs_linf / n_drhs_linf)) view(d, d_viewer) view(drhs, drhs_viewer) view(drhs_fd, drhs_fd_viewer) view(d_drhs, d_drhs_viewer) PISM.logging.pause()
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') """ array_to_dump = 0.5 * self.N_q2 * self.N_q1 * af.real( ifft2(self.fields_solver.fields_hat)) array_to_dump.to_ndarray(self.fields_solver._glob_fields_array) viewer = PETSc.Viewer().createHDF5(file_name + '.h5', 'w') viewer(self.fields_solver._glob_fields) return
def test_linearization_transpose(ssarun): grid = ssarun.grid S = 250 r_viewer = PETSc.Viewer().createDraw(title="r", size=S) TStarR_viewer = PETSc.Viewer().createDraw(title="TStarR", size=S) TStarR_indirect_viewer = PETSc.Viewer().createDraw(title="TStarR (ind)", size=S) d_TStarR_viewer = PETSc.Viewer().createDraw(title="d_TStarR_fd", size=S) ssarun.ssa.linearize_at(zeta1) u = PISM.IceModelVec2V() u.create(grid, "", PISM.WITH_GHOSTS) u.copy_from(ssarun.ssa.solution()) Td = PISM.IceModelVec2V() Td.create(grid, "", PISM.WITHOUT_GHOSTS) TStarR = PISM.IceModelVec2S() TStarR.create(grid, "", PISM.WITHOUT_GHOSTS) TStarR_indirect = PISM.IceModelVec2S() TStarR_indirect.create(grid, "", PISM.WITHOUT_GHOSTS) for (i, j) in grid.points(): for k in range(2): r = PISM.IceModelVec2V() r.create(grid, "", PISM.WITH_GHOSTS) r.set(0) with PISM.vec.Access(comm=r): if k == 0: r[i, j].u = 1 else: r[i, j].v = 1 ssarun.ssa.apply_linearization_transpose(r, TStarR) r_global = PISM.IceModelVec2V() r_global.create(grid, "", PISM.WITHOUT_GHOSTS) r_global.copy_from(r) for (k, l) in grid.points(): with PISM.vec.Access(nocomm=TStarR_indirect): d = PISM.IceModelVec2S() d.create(grid, "", PISM.WITH_GHOSTS) d.set(0) with PISM.vec.Access(comm=d): d[k, l] = 1 ssarun.ssa.apply_linearization(d, Td) TStarR_indirect[k, l] = Td.get_vec().dot(r_global.get_vec()) d_TStarR = PISM.IceModelVec2S() d_TStarR.create(grid, "", PISM.WITHOUT_GHOSTS) d_TStarR.copy_from(TStarR) d_TStarR.add(-1, TStarR_indirect) PISM.verbPrintf( 1, grid.com, "\nTest Linearization Transpose (%d,%d):\n" % (i, j)) view(r_global, r_viewer) view(TStarR, TStarR_viewer) view(TStarR_indirect, TStarR_indirect_viewer) view(d_TStarR, d_TStarR_viewer) PISM.logging.pause()
def __init__(self, cfgfile): ''' Constructor ''' # stencil = 1 stencil = 2 # load run config file cfg = Config(cfgfile) # set some PETSc options OptDB = PETSc.Options() OptDB.setValue('snes_rtol', 1E-20) # OptDB.setValue('snes_atol', 1E-12) # OptDB.setValue('snes_atol', 1E-1) # OptDB.setValue('snes_atol', 1E-3) # OptDB.setValue('snes_atol', 1E-4) # OptDB.setValue('snes_atol', 1E-5) # OptDB.setValue('snes_atol', 1E-6) OptDB.setValue('snes_atol', 1E-13) # OptDB.setValue('snes_atol', 1E-12) OptDB.setValue('snes_stol', 1E-14) OptDB.setValue('snes_max_it', 100) # OptDB.setValue('ksp_monitor', '') OptDB.setValue('snes_monitor', '') # OptDB.setValue('log_info', '') # OptDB.setValue('log_summary', '') # timestep setup self.ht = cfg['grid']['ht'] # timestep size self.nt = cfg['grid']['nt'] # number of timesteps self.nsave = cfg['io']['nsave'] # save only every nsave'th timestep # grid setup nx = cfg['grid']['nx'] # number of points in x ny = cfg['grid']['ny'] # number of points in y Lx = cfg['grid']['Lx'] # spatial domain in x x1 = cfg['grid']['x1'] # x2 = cfg['grid']['x2'] # Ly = cfg['grid']['Ly'] # spatial domain in y y1 = cfg['grid']['y1'] # y2 = cfg['grid']['y2'] # self.nx = nx self.ny = ny if x1 != x2: Lx = x2-x1 else: x1 = 0.0 x2 = Lx if y1 != y2: Ly = y2-y1 else: y1 = 0.0 y2 = Ly self.hx = Lx / nx # gridstep size in x self.hy = Ly / ny # gridstep size in y if PETSc.COMM_WORLD.getRank() == 0: print() print("nt = %i" % (self.nt)) print("nx = %i" % (self.nx)) print("ny = %i" % (self.ny)) print() print("ht = %e" % (self.ht)) print("hx = %e" % (self.hx)) print("hy = %e" % (self.hy)) print() print("Lx = %e" % (Lx)) print("Ly = %e" % (Ly)) print() self.time = PETSc.Vec().createMPI(1, PETSc.DECIDE, comm=PETSc.COMM_WORLD) self.time.setName('t') if PETSc.COMM_WORLD.getRank() == 0: self.time.setValue(0, 0.0) # create DA with single dof self.da1 = PETSc.DA().create(dim=2, dof=1, sizes=[nx, ny], proc_sizes=[PETSc.DECIDE, PETSc.DECIDE], boundary_type=('periodic', 'periodic'), stencil_width=stencil, stencil_type='box') # create DA (dof = 4 for Bx, By, Vx, Vy) self.da4 = PETSc.DA().create(dim=2, dof=4, sizes=[nx, ny], proc_sizes=[PETSc.DECIDE, PETSc.DECIDE], boundary_type=('periodic', 'periodic'), stencil_width=stencil, stencil_type='box') # create DA (dof = 5 for Bx, By, Vx, Vy, P) self.da5 = PETSc.DA().create(dim=2, dof=5, sizes=[nx, ny], proc_sizes=[PETSc.DECIDE, PETSc.DECIDE], boundary_type=('periodic', 'periodic'), stencil_width=stencil, stencil_type='box') # create DA for x grid self.dax = PETSc.DA().create(dim=1, dof=1, sizes=[nx], proc_sizes=[PETSc.DECIDE], boundary_type=('periodic')) # create DA for y grid self.day = PETSc.DA().create(dim=1, dof=1, sizes=[ny], proc_sizes=[PETSc.DECIDE], boundary_type=('periodic')) # initialise grid self.da1.setUniformCoordinates(xmin=x1, xmax=x2, ymin=y1, ymax=y2) self.da4.setUniformCoordinates(xmin=x1, xmax=x2, ymin=y1, ymax=y2) self.da5.setUniformCoordinates(xmin=x1, xmax=x2, ymin=y1, ymax=y2) self.dax.setUniformCoordinates(xmin=x1, xmax=x2) self.day.setUniformCoordinates(xmin=y1, xmax=y2) # create solution and RHS vector self.f = self.da5.createGlobalVec() self.x = self.da5.createGlobalVec() self.b = self.da5.createGlobalVec() # create global RK4 vectors self.Y = self.da5.createGlobalVec() self.X0 = self.da5.createGlobalVec() self.X1 = self.da5.createGlobalVec() self.X2 = self.da5.createGlobalVec() self.X3 = self.da5.createGlobalVec() self.X4 = self.da5.createGlobalVec() # create local RK4 vectors self.localX0 = self.da5.createLocalVec() self.localX1 = self.da5.createLocalVec() self.localX2 = self.da5.createLocalVec() self.localX3 = self.da5.createLocalVec() self.localX4 = self.da5.createLocalVec() # self.localP = self.da1.createLocalVec() # create vectors for magnetic and velocity field self.Bx = self.da1.createGlobalVec() self.By = self.da1.createGlobalVec() self.Vx = self.da1.createGlobalVec() self.Vy = self.da1.createGlobalVec() self.P = self.da1.createGlobalVec() # create local vectors for initialisation of pressure self.localBx = self.da1.createLocalVec() self.localBy = self.da1.createLocalVec() self.localVx = self.da1.createLocalVec() self.localVy = self.da1.createLocalVec() # set variable names self.Bx.setName('Bx') self.By.setName('By') self.Vx.setName('Vx') self.Vy.setName('Vy') self.P.setName('P') # create Matrix object self.petsc_matrix = PETScMatrix (self.da1, self.da5, nx, ny, self.ht, self.hx, self.hy) self.petsc_jacobian = PETScJacobian(self.da1, self.da5, nx, ny, self.ht, self.hx, self.hy) self.petsc_function = PETScFunction(self.da1, self.da5, nx, ny, self.ht, self.hx, self.hy) # self.petsc_jacobian_4d = PETSc_MHD_NL_Jacobian_Matrix.PETScJacobian(self.da1, self.da5, nx, ny, self.ht, self.hx, self.hy) # initialise matrix self.A = self.da5.createMat() self.A.setOption(self.A.Option.NEW_NONZERO_ALLOCATION_ERR, False) self.A.setUp() # create jacobian self.J = self.da5.createMat() self.J.setOption(self.J.Option.NEW_NONZERO_ALLOCATION_ERR, False) self.J.setUp() # create nonlinear solver self.snes = PETSc.SNES().create() self.snes.setFunction(self.petsc_function.snes_mult, self.f) self.snes.setJacobian(self.updateJacobian, self.J) # self.snes.setUseMF() self.snes.setFromOptions() self.snes.getKSP().setType('preonly') self.snes.getKSP().getPC().setType('lu') # self.snes.getKSP().getPC().setFactorSolverPackage('superlu_dist') self.snes.getKSP().getPC().setFactorSolverPackage('mumps') print(self.snes.getTolerances()) self.ksp = None # set initial data (xs, xe), (ys, ye) = self.da1.getRanges() coords = self.da1.getCoordinateDA().getVecArray(self.da1.getCoordinates()) Bx_arr = self.da1.getVecArray(self.Bx) By_arr = self.da1.getVecArray(self.By) Vx_arr = self.da1.getVecArray(self.Vx) Vy_arr = self.da1.getVecArray(self.Vy) if cfg['initial_data']['magnetic_python'] != None: init_data = __import__("runs." + cfg['initial_data']['magnetic_python'], globals(), locals(), ['magnetic_x', 'magnetic_y'], 0) for i in range(xs, xe): for j in range(ys, ye): Bx_arr[i,j] = init_data.magnetic_x(coords[i,j][0], coords[i,j][1] + 0.5 * self.hy, Lx, Ly) By_arr[i,j] = init_data.magnetic_y(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1], Lx, Ly) else: Bx_arr[xs:xe, ys:ye] = cfg['initial_data']['magnetic'] By_arr[xs:xe, ys:ye] = cfg['initial_data']['magnetic'] if cfg['initial_data']['velocity_python'] != None: init_data = __import__("runs." + cfg['initial_data']['velocity_python'], globals(), locals(), ['velocity_x', 'velocity_y'], 0) for i in range(xs, xe): for j in range(ys, ye): Vx_arr[i,j] = init_data.velocity_x(coords[i,j][0], coords[i,j][1] + 0.5 * self.hy, Lx, Ly) Vy_arr[i,j] = init_data.velocity_y(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1], Lx, Ly) else: Vx_arr[xs:xe, ys:ye] = cfg['initial_data']['velocity'] Vy_arr[xs:xe, ys:ye] = cfg['initial_data']['velocity'] if cfg['initial_data']['pressure_python'] != None: init_data = __import__("runs." + cfg['initial_data']['pressure_python'], globals(), locals(), ['pressure', ''], 0) x_arr = self.da5.getVecArray(self.x) x_arr[xs:xe, ys:ye, 0] = Vx_arr[xs:xe, ys:ye] x_arr[xs:xe, ys:ye, 1] = Vy_arr[xs:xe, ys:ye] x_arr[xs:xe, ys:ye, 2] = Bx_arr[xs:xe, ys:ye] x_arr[xs:xe, ys:ye, 3] = By_arr[xs:xe, ys:ye] self.da1.globalToLocal(self.Bx, self.localBx) self.da1.globalToLocal(self.By, self.localBy) self.da1.globalToLocal(self.Vx, self.localVx) self.da1.globalToLocal(self.Vy, self.localVy) Bx_arr = self.da1.getVecArray(self.localBx) By_arr = self.da1.getVecArray(self.localBy) Vx_arr = self.da1.getVecArray(self.localVx) Vy_arr = self.da1.getVecArray(self.localVy) P_arr = self.da1.getVecArray(self.P) for i in range(xs, xe): for j in range(ys, ye): P_arr[i,j] = init_data.pressure(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1] + 0.5 * self.hy, Lx, Ly) # P_arr[i,j] = init_data.pressure(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1] + 0.5 * self.hy, Lx, Ly) \ # + 0.5 * (0.25 * (Bx_arr[i,j] + Bx_arr[i+1,j])**2 + 0.25 * (By_arr[i,j] + By_arr[i,j+1])**2) # P_arr[i,j] = init_data.pressure(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1] + 0.5 * self.hy, Lx, Ly) \ # + 0.5 * (0.25 * (Vx_arr[i,j] + Vx_arr[i+1,j])**2 + 0.25 * (Vy_arr[i,j] + Vy_arr[i,j+1])**2) # P_arr[i,j] = init_data.pressure(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1] + 0.5 * self.hy, Lx, Ly) \ # + 0.5 * (0.25 * (Vx_arr[i,j] + Vx_arr[i+1,j])**2 + 0.25 * (Vy_arr[i,j] + Vy_arr[i,j+1])**2) \ # - 1.0 * (0.25 * (Bx_arr[i,j] + Bx_arr[i+1,j])**2 + 0.25 * (By_arr[i,j] + By_arr[i,j+1])**2) # copy distribution function to solution vector x_arr = self.da5.getVecArray(self.x) x_arr[xs:xe, ys:ye, 4] = P_arr [xs:xe, ys:ye] # update solution history self.petsc_matrix.update_history(self.x) self.petsc_jacobian.update_history(self.x) self.petsc_function.update_history(self.x) # create HDF5 output file self.hdf5_viewer = PETSc.Viewer().createHDF5(cfg['io']['hdf5_output'], mode=PETSc.Viewer.Mode.WRITE, comm=PETSc.COMM_WORLD) self.hdf5_viewer.HDF5PushGroup("/") # write grid data to hdf5 file coords_x = self.dax.getCoordinates() coords_y = self.day.getCoordinates() coords_x.setName('x') coords_y.setName('y') self.hdf5_viewer(coords_x) self.hdf5_viewer(coords_y) # write initial data to hdf5 file self.hdf5_viewer.HDF5SetTimestep(0) self.save_hdf5_vectors()
def test_lin(ssarun): grid = ssarun.grid PISM.verbPrintf( 1, grid.com, "\nTest Linearization (Comparison with finite differences):\n") S = 250 d_viewer = PETSc.Viewer().createDraw(title="d", size=S) Td_viewer = PETSc.Viewer().createDraw(title="Td", size=S) Td_fd_viewer = PETSc.Viewer().createDraw(title="Td_fd", size=S) d_Td_viewer = PETSc.Viewer().createDraw(title="d_Td", size=S) for (i, j) in grid.points(): d = PISM.IceModelVec2S() d.create(grid, "", PISM.WITH_GHOSTS) d.set(0) with PISM.vec.Access(comm=d): d[i, j] = 1 ssarun.ssa.linearize_at(zeta1) u1 = PISM.IceModelVec2V() u1.create(grid, "", PISM.WITH_GHOSTS) u1.copy_from(ssarun.ssa.solution()) Td = PISM.IceModelVec2V() Td.create(grid, "", PISM.WITH_GHOSTS) ssarun.ssa.apply_linearization(d, Td) eps = 1e-8 zeta2 = PISM.IceModelVec2S() zeta2.create(grid, "", PISM.WITH_GHOSTS) zeta2.copy_from(d) zeta2.scale(eps) zeta2.add(1, zeta1) ssarun.ssa.linearize_at(zeta2) u2 = PISM.IceModelVec2V() u2.create(grid, "", PISM.WITH_GHOSTS) u2.copy_from(ssarun.ssa.solution()) Td_fd = PISM.IceModelVec2V() Td_fd.create(grid, "", PISM.WITH_GHOSTS) Td_fd.copy_from(u2) Td_fd.add(-1, u1) Td_fd.scale(1. / eps) d_Td = PISM.IceModelVec2V() d_Td.create(grid, "", PISM.WITH_GHOSTS) d_Td.copy_from(Td_fd) d_Td.add(-1, Td) n_Td_fd = Td_fd.norm(PETSc.NormType.NORM_2) n_Td_l2 = Td.norm(PETSc.NormType.NORM_2) n_Td_l1 = Td.norm(PETSc.NormType.NORM_1) n_Td_linf = Td.norm(PETSc.NormType.NORM_INFINITY) n_d_Td_l2 = d_Td.norm(PETSc.NormType.NORM_2) n_d_Td_l1 = d_Td.norm(PETSc.NormType.NORM_1) n_d_Td_linf = d_Td.norm(PETSc.NormType.NORM_INFINITY) PISM.verbPrintf(1, grid.com, "(i,j)=(%d,%d)\n" % (i, j)) PISM.verbPrintf( 1, grid.com, "apply_linearization(d): l2 norm %.10g; finite difference %.10g\n" % (n_Td_l2, n_Td_fd)) r_d_l2 = 0 if n_Td_l2 != 0: r_d_l2 = n_d_Td_l2 / n_Td_l2 r_d_l1 = 0 if n_Td_l1 != 0: r_d_l1 = n_d_Td_l1 / n_Td_l1 r_d_linf = 0 if n_Td_linf != 0: r_d_linf = n_d_Td_linf / n_Td_linf PISM.verbPrintf( 1, grid.com, "relative difference: l2 norm %.10g l1 norm %.10g linf norm %.10g\n" % (r_d_l2, r_d_l1, r_d_linf)) PISM.verbPrintf(1, grid.com, "\n") d_global = PISM.IceModelVec2S() d_global.create(grid, "", PISM.WITHOUT_GHOSTS) d_global.copy_from(d) d_global.get_vec().view(d_viewer) Td_global = PISM.IceModelVec2V() Td_global.create(grid, "", PISM.WITHOUT_GHOSTS) Td_global.copy_from(Td) # if n_Td_linf > 0: # Td_global.scale(1./n_Td_linf) Td_global.get_vec().view(Td_viewer) Td_fd_global = PISM.IceModelVec2V() Td_fd_global.create(grid, "", PISM.WITHOUT_GHOSTS) Td_fd_global.copy_from(Td_fd) # if n_Td_fd_linf > 0: # Td_fd_global.scale(1./n_Td_linf) Td_fd_global.get_vec().view(Td_fd_viewer) d_Td_global = PISM.IceModelVec2V() d_Td_global.create(grid, "", PISM.WITHOUT_GHOSTS) d_Td_global.copy_from(d_Td) # if n_Td_linf > 0: # d_Td_global.scale(1./n_Td_linf) d_Td_global.get_vec().view(d_Td_viewer) PISM.logging.pause()
def save_matrix(self, Mat, name): if name[-3:] == 'txt': viewer = PETSc.Viewer().createASCII(name, 'w') else: viewer = PETSc.Viewer().createBinary(name, 'w') Mat.view(viewer) print('saved matrix in ', name)
ksp.setOperators(A) ksp.setType(ksp.Type.PYTHON) pyKSP = KSP_AMPCG(pcbnn) pyKSP.callback = callback(da) ksp.setPythonContext(pyKSP) ksp.setFromOptions() ksp.setInitialGuessNonzero(True) ksp.solve(b, x) def write_simu_info(da, viewer): lamb_petsc = da.createGlobalVec() lamb_a = da.getVecArray(lamb_petsc) coords = da.getCoordinates() coords_a = da.getVecArray(coords) E = lame_coeff(coords_a[:, :, 0], coords_a[:, :, 1], E1, E2) nu = lame_coeff(coords_a[:, :, 0], coords_a[:, :, 1], nu1, nu2) lamb_a[:, :, 0] = (nu * E) / ((1 + nu) * (1 - 2 * nu)) lamb_a[:, :, 1] = mpi.COMM_WORLD.rank lamb_petsc.view(viewer) viewer = PETSc.Viewer().createVTK(path + 'solution_2d.vts', 'w', comm=PETSc.COMM_WORLD) x.view(viewer) write_simu_info(da, viewer) viewer.destroy()
x = da.createGlobalVec() b = buildRHS(da, [hx, hy], rhs) A = buildElasticityMatrix(da, [hx, hy], lamb, mu) A.assemble() bcApplyWest(da, A, b) #Setup the preconditioner (or multipreconditioner) and the coarse space pcbnn = PCBNN(A) # Set initial guess x.setRandom() xnorm = b.dot(x) / x.dot(A * x) x *= xnorm ksp = PETSc.KSP().create() ksp.setOperators(A) ksp.setType(ksp.Type.PYTHON) pyKSP = KSP_AMPCG(pcbnn) pyKSP.callback = callback(da) ksp.setPythonContext(pyKSP) ksp.setFromOptions() ksp.setInitialGuessNonzero(True) ksp.solve(b, x) viewer = PETSc.Viewer().createVTK('solution_2d_asm.vts', 'w', comm=PETSc.COMM_WORLD) x.view(viewer)
def setUp(self): self.txtvwr = PETSc.Viewer()
def __init__(self, cfgfile): ''' Constructor ''' # load run config file cfg = Config(cfgfile) # timestep setup self.ht = cfg['grid']['ht'] # timestep size self.nt = cfg['grid']['nt'] # number of timesteps self.nsave = cfg['io']['nsave'] # save only every nsave'th timestep # grid setup nx = cfg['grid']['nx'] # number of points in x ny = cfg['grid']['ny'] # number of points in y Lx = cfg['grid']['Lx'] # spatial domain in x x1 = cfg['grid']['x1'] # x2 = cfg['grid']['x2'] # Ly = cfg['grid']['Ly'] # spatial domain in y y1 = cfg['grid']['y1'] # y2 = cfg['grid']['y2'] # if x1 != x2: Lx = x2-x1 else: x1 = 0.0 x2 = Lx if y1 != y2: Ly = y2-y1 else: y1 = 0.0 y2 = Ly self.hx = Lx / nx # gridstep size in x self.hy = Ly / ny # gridstep size in y self.time = PETSc.Vec().createMPI(1, PETSc.DECIDE, comm=PETSc.COMM_WORLD) self.time.setName('t') if PETSc.COMM_WORLD.getRank() == 0: self.time.setValue(0, 0.0) # set some PETSc options OptDB = PETSc.Options() OptDB.setValue('ksp_rtol', cfg['solver']['petsc_residual']) # OptDB.setValue('snes_rtol', 1E-2) # OptDB.setValue('ksp_max_it', 100) OptDB.setValue('ksp_max_it', 200) # OptDB.setValue('ksp_max_it', 1000) # OptDB.setValue('ksp_max_it', 2000) # OptDB.setValue('ksp_monitor', '') # OptDB.setValue('log_info', '') # OptDB.setValue('log_summary', '') # create DA with single dof self.da1 = PETSc.DA().create(dim=2, dof=1, sizes=[nx, ny], proc_sizes=[PETSc.DECIDE, PETSc.DECIDE], boundary_type=('periodic', 'periodic'), stencil_width=1, stencil_type='box') # create DA (dof = 5 for Bx, By, Vx, Vy, P) self.da4 = PETSc.DA().create(dim=2, dof=5, sizes=[nx, ny], proc_sizes=[PETSc.DECIDE, PETSc.DECIDE], boundary_type=('periodic', 'periodic'), stencil_width=1, stencil_type='box') # create DA for x grid self.dax = PETSc.DA().create(dim=1, dof=1, sizes=[nx], proc_sizes=[PETSc.DECIDE], boundary_type=('periodic')) # create DA for y grid self.day = PETSc.DA().create(dim=1, dof=1, sizes=[ny], proc_sizes=[PETSc.DECIDE], boundary_type=('periodic')) # initialise grid self.da1.setUniformCoordinates(xmin=x1, xmax=x2, ymin=y1, ymax=y2) self.da4.setUniformCoordinates(xmin=x1, xmax=x2, ymin=y1, ymax=y2) self.dax.setUniformCoordinates(xmin=x1, xmax=x2) self.day.setUniformCoordinates(xmin=y1, xmax=y2) # create solution and RHS vector self.dx = self.da4.createGlobalVec() self.x = self.da4.createGlobalVec() self.b = self.da4.createGlobalVec() self.f = self.da4.createGlobalVec() self.Pb = self.da1.createGlobalVec() self.localX = self.da4.createLocalVec() # create global RK4 vectors self.X1 = self.da4.createGlobalVec() self.X2 = self.da4.createGlobalVec() self.X3 = self.da4.createGlobalVec() self.X4 = self.da4.createGlobalVec() # create local RK4 vectors self.localX1 = self.da4.createLocalVec() self.localX2 = self.da4.createLocalVec() self.localX3 = self.da4.createLocalVec() self.localX4 = self.da4.createLocalVec() # create vectors for magnetic and velocity field self.Bx = self.da1.createGlobalVec() self.By = self.da1.createGlobalVec() self.Vx = self.da1.createGlobalVec() self.Vy = self.da1.createGlobalVec() self.P = self.da1.createGlobalVec() # set variable names self.x.setName('solver_x') self.b.setName('solver_b') self.Bx.setName('Bx') self.By.setName('By') self.Vx.setName('Vx') self.Vy.setName('Vy') self.P.setName('P') # create Matrix object self.petsc_matrix = PETScSolver (self.da1, self.da4, nx, ny, self.ht, self.hx, self.hy) self.petsc_function = PETScFunction(self.da1, self.da4, nx, ny, self.ht, self.hx, self.hy) self.petsc_jacobian = PETScJacobian(self.da1, self.da4, nx, ny, self.ht, self.hx, self.hy) # create sparse matrix self.J = PETSc.Mat().createPython([self.dx.getSizes(), self.b.getSizes()], comm=PETSc.COMM_WORLD) self.J.setPythonContext(self.petsc_jacobian) self.J.setUp() # create nonlinear solver self.snes = PETSc.SNES().create() self.snes.setFunction(self.petsc_function.snes_mult, self.f) self.snes.setJacobian(self.updateJacobian, self.J) # self.snes.setUseMF() self.snes.setFromOptions() self.snes.getKSP().setType('gmres') self.snes.getKSP().getPC().setType('none') # create Preconditioner matrix and solver self.pc_mat = PETScPreconditioner(self.da1, self.da4, self.P, nx, ny, self.ht, self.hx, self.hy) # create sparse matrix self.pc_A = PETSc.Mat().createPython([self.x.getSizes(), self.b.getSizes()], comm=PETSc.COMM_WORLD) self.pc_A.setPythonContext(self.pc_mat) self.pc_A.setUp() # create linear solver and preconditioner self.pc_ksp = PETSc.KSP().create() self.pc_ksp.setFromOptions() self.pc_ksp.setOperators(self.pc_A) self.pc_ksp.setType(cfg['solver']['petsc_ksp_type']) self.pc_ksp.setInitialGuessNonzero(True) self.pc_pc = self.pc_ksp.getPC() self.pc_pc.setType('none') # create Poisson matrix and solver self.poisson_mat = PETScPoissonSolver(self.da1, self.da4, self.x, nx, ny, self.ht, self.hx, self.hy) self.poisson_A = PETSc.Mat().createPython([self.P.getSizes(), self.Pb.getSizes()], comm=PETSc.COMM_WORLD) self.poisson_A.setPythonContext(self.poisson_mat) self.poisson_A.setUp() self.poisson_ksp = PETSc.KSP().create() self.poisson_ksp.setFromOptions() self.poisson_ksp.setOperators(self.poisson_A) self.poisson_ksp.setType(cfg['solver']['petsc_ksp_type']) # self.poisson_ksp.setInitialGuessNonzero(True) self.poisson_pc = self.poisson_ksp.getPC() self.poisson_pc.setType('none') # create Arakawa solver object # self.mhd_rk4 = PETScRK4(self.da4, nx, ny, self.ht, self.hx, self.hy) # set initial data (xs, xe), (ys, ye) = self.da1.getRanges() coords = self.da1.getCoordinateDA().getVecArray(self.da1.getCoordinates()) # print # print(self.hx) # print(coords[1,0][0] - coords[0,0][0]) # print # print(self.hy) # print(coords[0,1][1] - coords[0,0][1]) # print # print(Lx) # print(coords[-1,0][0]+self.hx) # print # print(Ly) # print(coords[0,-1][1]+self.hy) # print x_arr = self.da4.getVecArray(self.x) Bx_arr = self.da1.getVecArray(self.Bx) By_arr = self.da1.getVecArray(self.By) Vx_arr = self.da1.getVecArray(self.Vx) Vy_arr = self.da1.getVecArray(self.Vy) P_arr = self.da1.getVecArray(self.P) if cfg['initial_data']['magnetic_python'] != None: init_data = __import__("runs." + cfg['initial_data']['magnetic_python'], globals(), locals(), ['magnetic_x', 'magnetic_y'], 0) for i in range(xs, xe): for j in range(ys, ye): Bx_arr[i,j] = init_data.magnetic_x(coords[i,j][0], coords[i,j][1], Lx, Ly) By_arr[i,j] = init_data.magnetic_y(coords[i,j][0], coords[i,j][1], Lx, Ly) else: Bx_arr[xs:xe, ys:ye] = cfg['initial_data']['magnetic'] By_arr[xs:xe, ys:ye] = cfg['initial_data']['magnetic'] if cfg['initial_data']['velocity_python'] != None: init_data = __import__("runs." + cfg['initial_data']['velocity_python'], globals(), locals(), ['velocity_x', 'velocity_y'], 0) for i in range(xs, xe): for j in range(ys, ye): Vx_arr[i,j] = init_data.velocity_x(coords[i,j][0], coords[i,j][1], Lx, Ly) Vy_arr[i,j] = init_data.velocity_y(coords[i,j][0], coords[i,j][1], Lx, Ly) else: Vx_arr[xs:xe, ys:ye] = cfg['initial_data']['velocity'] Vy_arr[xs:xe, ys:ye] = cfg['initial_data']['velocity'] if cfg['initial_data']['pressure_python'] != None: init_data = __import__("runs." + cfg['initial_data']['pressure_python'], globals(), locals(), ['pressure', ''], 0) for i in range(xs, xe): for j in range(ys, ye): P_arr[i,j] = init_data.pressure(coords[i,j][0], coords[i,j][1], Lx, Ly) #+ 0.5 * (Bx_arr[i,j]**2 + By_arr[i,j]**2) # copy distribution function to solution vector x_arr[xs:xe, ys:ye, 0] = Bx_arr[xs:xe, ys:ye] x_arr[xs:xe, ys:ye, 1] = By_arr[xs:xe, ys:ye] x_arr[xs:xe, ys:ye, 2] = Vx_arr[xs:xe, ys:ye] x_arr[xs:xe, ys:ye, 3] = Vy_arr[xs:xe, ys:ye] x_arr[xs:xe, ys:ye, 4] = P_arr [xs:xe, ys:ye] # update solution history self.petsc_matrix.update_history(self.x) self.petsc_function.update_history(self.x) self.petsc_jacobian.update_history(self.x) # create HDF5 output file self.hdf5_viewer = PETSc.Viewer().createHDF5(cfg['io']['hdf5_output'], mode=PETSc.Viewer.Mode.WRITE, comm=PETSc.COMM_WORLD) self.hdf5_viewer.HDF5PushGroup("/") # write grid data to hdf5 file coords_x = self.dax.getCoordinates() coords_y = self.day.getCoordinates() coords_x.setName('x') coords_y.setName('y') self.hdf5_viewer(coords_x) self.hdf5_viewer(coords_y) # write initial data to hdf5 file self.hdf5_viewer.HDF5SetTimestep(0) self.hdf5_viewer(self.time) # self.hdf5_viewer(self.x) # self.hdf5_viewer(self.b) self.hdf5_viewer(self.Bx) self.hdf5_viewer(self.By) self.hdf5_viewer(self.Vx) self.hdf5_viewer(self.Vy) self.hdf5_viewer(self.P)
def read_petsc(solution,frame,path='./',file_prefix='claw',read_aux=False,options={}): r""" Read in pickles and PETSc data files representing the solution :Input: - *solution* - (:class:`~pyclaw.solution.Solution`) Solution object to read the data into. - *frame* - (int) Frame number to be read in - *path* - (string) Path to the current directory of the file - *file_prefix* - (string) Prefix of the files to be read in. ``default = 'fort'`` - *read_aux* (bool) Whether or not an auxiliary file will try to be read in. ``default = False`` - *options* - (dict) Optional argument dictionary, see `PETScIO Option Table`_ .. _`PETScIO Option Table`: format : one of 'ascii' or 'binary' """ # Option parsing option_defaults = {'format':'binary'} for k in option_defaults.iterkeys(): if options.has_key(k): pass else: options[k] = option_defaults[k] pickle_filename = os.path.join(path, '%s.pkl' % file_prefix) + str(frame).zfill(4) viewer_filename = os.path.join(path, '%s.ptc' % file_prefix) + str(frame).zfill(4) aux_viewer_filename = os.path.join(path, '%s_aux.ptc' % file_prefix) if frame < 0: # Don't construct file names with negative frameno values. raise IOError("Frame " + str(frame) + " does not exist ***") pickle_file = open(pickle_filename,'rb') # this dictionary is mostly holding debugging information, only nstates is needed # most of this information is explicitly saved in the individual patches value_dict = pickle.load(pickle_file) nstates = value_dict['nstates'] num_dim = value_dict['num_dim'] num_aux = value_dict['num_aux'] num_eqn = value_dict['num_eqn'] # now set up the PETSc viewer if options['format'] == 'ascii': viewer = PETSc.Viewer().createASCII(viewer_filename, PETSc.Viewer.Mode.READ) if read_aux: aux_viewer = PETSc.Viewer().createASCII(aux_viewer_filename, PETSc.Viewer.Mode.READ) elif options['format'] == 'binary': if hasattr(PETSc.Viewer,'createMPIIO'): viewer = PETSc.Viewer().createMPIIO(viewer_filename, PETSc.Viewer.Mode.READ) else: viewer = PETSc.Viewer().createBinary(viewer_filename, PETSc.Viewer.Mode.READ) if read_aux: if os.path.exists(aux_viewer_filename): if hasattr(PETSc.Viewer,'createMPIIO'): aux_viewer = PETSc.Viewer().createMPIIO(aux_viewer_filename, PETSc.Viewer.Mode.READ) else: aux_viewer = PETSc.Viewer().createBinary(aux_viewer_filename, PETSc.Viewer.Mode.READ) else: from warnings import warn aux_file_path = os.path.join(path,aux_viewer_filename) warn('read_aux=True but aux file %s does not exist' % aux_file_path) read_aux=False else: raise IOError('format type %s not supported' % options['format']) patches = [] for m in xrange(nstates): patch_dict = pickle.load(pickle_file) level = patch_dict['level'] names = patch_dict['names'] lower = patch_dict['lower'] n = patch_dict['num_cells'] d = patch_dict['delta'] import petclaw dimensions = [] for i in xrange(num_dim): dimensions.append( #pyclaw.solution.Dimension(names[i],lower[i],lower[i] + n[i]*d[i],n[i])) petclaw.Dimension(names[i],lower[i],lower[i] + n[i]*d[i],n[i])) #patch = pyclaw.solution.Patch(dimensions) patch = petclaw.Patch(dimensions) patch.level = level #state = pyclaw.state.State(patch) state = petclaw.State(patch,num_eqn,num_aux) ## state.t = value_dict['t'] state.problem_data = value_dict['problem_data'] # DA View/Load is broken in Petsc-3.1.8, we can load/view the DA if needed in petsc-3.2 # state.q_da.load(viewer) state.gqVec.load(viewer) if read_aux: state.gauxVec.load(aux_viewer) solution.states.append(state) patches.append(state.patch) solution.domain = petclaw.geometry.Domain(patches) pickle_file.close() viewer.destroy() if read_aux: aux_viewer.destroy()
def read_petsc(solution, frame, path='./', file_prefix='claw', read_aux=False, options={}): r""" Read in pickles and PETSc data files representing the solution :Input: - *solution* - (:class:`~pyclaw.solution.Solution`) Solution object to read the data into. - *frame* - (int) Frame number to be read in - *path* - (string) Path to the current directory of the file - *file_prefix* - (string) Prefix of the files to be read in. ``default = 'fort'`` - *read_aux* (bool) Whether or not an auxillary file will try to be read in. ``default = False`` - *options* - (dict) Optional argument dictionary, see `PETScIO Option Table`_ .. _`PETScIO Option Table`: format : one of 'ascii' or 'binary' """ # Option parsing option_defaults = {'format': 'binary'} for (k, v) in option_defaults.iteritems(): if options.has_key(k): pass else: options[k] = option_defaults[k] pickle_filename = os.path.join( path, '%s.pkl' % file_prefix) + str(frame).zfill(4) viewer_filename = os.path.join( path, '%s.ptc' % file_prefix) + str(frame).zfill(4) aux_filename = os.path.join( path, '%s_aux.ptc' % file_prefix) + str(frame).zfill(4) if frame < 0: # Don't construct file names with negative frameno values. raise IOError("Frame " + str(frame) + " does not exist ***") pickle_file = open(pickle_filename, 'rb') # this dictionary is mostly holding debugging information, only ngrids is needed # most of this information is explicitly saved in the individual grids value_dict = pickle.load(pickle_file) ngrids = value_dict['ngrids'] read_aux = value_dict['write_aux'] ndim = value_dict['ndim'] # now set up the PETSc viewer if options['format'] == 'ascii': viewer = PETSc.Viewer().createASCII(viewer_filename, PETSc.Viewer.Mode.READ) if read_aux: aux_viewer = PETSc.Viewer().createASCII(aux_viewer_filename, PETSc.Viewer.Mode.READ) elif options['format'] == 'binary': viewer = PETSc.Viewer().createBinary(viewer_filename, PETSc.Viewer.Mode.READ) if read_aux: aux_viewer = PETSc.Viewer().createBinary(aux_viewer_filename, PETSc.Viewer.Mode.READ) else: raise IOError('format type %s not supported' % options['format']) for m in xrange(ngrids): grid_dict = pickle.load(pickle_file) gridno = grid_dict['gridno'] level = grid_dict['level'] names = grid_dict['names'] lower = grid_dict['lower'] n = grid_dict['n'] d = grid_dict['d'] dimensions = [] for i in xrange(ndim): dimensions.append( pyclaw.solution.Dimension(names[i], lower[i], lower[i] + n[i] * d[i], n[i])) grid = pyclaw.solution.Grid(dimensions) grid.t = value_dict['t'] grid.meqn = value_dict['meqn'] nbc = [x + (2 * grid.mbc) for x in grid.n] grid.q_da = PETSc.DA().create( dim=grid.ndim, dof=grid.meqn, # should be modified to reflect the update sizes=nbc, #periodic_type = PETSc.DA.PeriodicType.X, #periodic_type=grid.PERIODIC, #stencil_type=grid.STENCIL, stencil_width=grid.mbc, comm=PETSc.COMM_WORLD) grid.gqVec = PETSc.Vec().load(viewer) grid.q = grid.gqVec.getArray().copy() grid.q.shape = (grid.q.size / grid.meqn, grid.meqn) if read_aux: nbc = [x + (2 * grid.mbc) for x in grid.n] grid.aux_da = PETSc.DA().create( dim=grid.ndim, dof=maux, # should be modified to reflect the update sizes=nbc, #Amal: what about for 2D, 3D #periodic_type = PETSc.DA.PeriodicType.X, #periodic_type=grid.PERIODIC, #stencil_type=grid.STENCIL, stencil_width=grid.mbc, comm=PETSc.COMM_WORLD) grid.gauxVec = PETSc.Vec().load(aux_viewer) grid.aux = grid.gauxVec.getArray().copy() grid.aux.shape = (grid.aux.size / grid.meqn, grid.meqn) # Add AMR attributes: grid.gridno = gridno grid.level = level solution.grids.append(grid) pickle_file.close() viewer.destroy() if read_aux: aux_viewer.destroy()
def determine_min_max(name, time_array): """ Determines the minimum and maximum of the quantity of interest over the entire time_array. This is needed when we want to make movies showing evolution in time. By using this function we avoid the problem of shifting limits in y axis / changing colorbar limits. Parameters ---------- name : str Pass the name of the quantity that needs to be plotted. time_array: np.ndarray The time array over which the maximum and minimum of the quantity need to be determined. """ # Declaring an initial value for the max and minimum for the quantity plotted: q_max = 0 q_min = 1e10 for time_index, t0 in enumerate(time_array): if (name in ['E1', 'E2', 'E3', 'B1', 'B2', 'B3']): fields_file = 'dump_fields/t=%.6f' % (t0) + '.bin' # Load fields viewer = PETSc.Viewer().createBinary( fields_file, PETSc.Viewer.Mode.READ, ) fields_vec.load(viewer) fields = da_fields.getVecArray( fields_vec) # [N_q1, N_q2, N_fields] array = return_field_to_be_plotted(name, fields) else: moments_file = 'dump_moments/t=%.6f' % (t0) + '.bin' # Load moments viewer = PETSc.Viewer().createBinary( moments_file, PETSc.Viewer.Mode.READ, ) moments_vec.load(viewer) moments = da_moments.getVecArray( moments_vec) # [N_q1, N_q2, N_moments] array = return_moment_to_be_plotted(name, moments) if (np.max(array) > q_max): q_max = np.max(array) if (np.min(array) < q_min): q_min = np.min(array) return (q_min, q_max)