def solve_petsc(self, solver_data_list, rhs_list, nu, *args, **kwargs): #try catch for the petsc4py use in multiple rhs solve try: import petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc from pysit.util.wrappers.petsc import PetscWrapper except ImportError: raise ImportError( 'petsc4py is not installed, please install it and try again') flag = 'petsc' in kwargs if flag == 0: petsc = None else: petsc = kwargs['petsc'] if petsc is not None: if len(solver_data_list) != len(rhs_list): raise ValueError( 'solver and right hand side list must be the same size') else: #Building the Helmholtz operator for petsc H = self._build_helmholtz_operator(nu) ndof = H.shape[1] nshot = len(rhs_list) # creating the B rhs Matrix B = PETSc.Mat().createDense([ndof, nshot]) B.setUp() for i in range(nshot): # added by zhilong [0:ndof] B.setValues(list(range(0, ndof)), [i], rhs_list[i][0:ndof]) B.assemblyBegin() B.assemblyEnd() # call the wrapper to solve the system wrapper = PetscWrapper() try: linear_solver = wrapper.factorize(H, petsc, PETSc.COMM_WORLD) Uhat = linear_solver(B.getDenseArray()) except: raise SyntaxError( 'petsc = ' + str(petsc) + ' is not a correct solver you can only use \'superlu_dist\', \'mumps\' or \'mkl_pardiso\' ' ) numb = 0 for solver_data in solver_data_list: u = Uhat[:, numb] u = np.append( u, np.zeros(2 * ndof) ) # added by zhilong, assume that we do not need the auxiliary wavefields u.shape = solver_data.k.data.shape solver_data.k.data = u numb += 1
def solve_petsc_uhat(self, solver, rhs_list, frequency, petsc='mumps', *args, **kwargs): #try catch for the petsc4py use in multiple rhs solve #use only in the data generation where we do not need to compute #the system for the whole auxiliary fields try: import petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc from pysit.util.wrappers.petsc import PetscWrapper except ImportError: raise ImportError( 'petsc4py is not installed, please install it and try again') #Building the Helmholtz operator for petsc H = self._build_helmholtz_operator(frequency) ndof = H.shape[1] nshot = len(rhs_list) # if the compact operator is used we do not need to slice the solution if self.compact: usize = ndof else: nwfield = len(self.WavefieldVector.aux_names) + 1 usize = ndof / nwfield # creating the B rhs Matrix B = PETSc.Mat().createDense([ndof, nshot]) B.setUp() for i in range(nshot): B.setValues(list(range(0, ndof)), [i], rhs_list[i][0:ndof]) # added by zhilong [0:ndof] B.assemblyBegin() B.assemblyEnd() # call the wrapper to solve the system wrapper = PetscWrapper() try: linear_solver = wrapper.factorize(H, petsc, PETSc.COMM_WORLD) Uhat = linear_solver(B.getDenseArray()) except: raise SyntaxError( 'petsc = ' + str(petsc) + ' is not a correct solver you can only use \'superlu_dist\', \'mumps\' or \'mkl_pardiso\' ' ) Uhat = Uhat[range(usize), :] return Uhat
def solve_petsc(self, solver_data_list, rhs_list, nu, *args, **kwargs ): #try catch for the petsc4py use in multiple rhs solve try: import petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc from pysit.util.wrappers.petsc import PetscWrapper except ImportError: raise ImportError('petsc4py is not installed, please install it and try again') petsc = kwargs['petsc'] if petsc is not None: if len(solver_data_list) != len(rhs_list): raise ValueError('solver and right hand side list must be the same size') else: #Building the Helmholtz operator for petsc H = self._build_helmholtz_operator(nu) ndof = H.shape[1] nshot = len(rhs_list) # creating the B rhs Matrix B = PETSc.Mat().createDense([ndof, nshot]) B.setUp() for i in range(nshot): # added by zhilong [0:ndof] B.setValues(list(range(0, ndof)), [i], rhs_list[i][0:ndof]) B.assemblyBegin() B.assemblyEnd() # call the wrapper to solve the system wrapper = PetscWrapper() try: linear_solver = wrapper.factorize(H, petsc, PETSc.COMM_WORLD) Uhat = linear_solver(B.getDenseArray()) except: raise SyntaxError('petsc = '+str(petsc)+' is not a correct solver you can only use \'superlu_dist\', \'mumps\' or \'mkl_pardiso\' ') numb = 0 for solver_data in solver_data_list: u = Uhat[:,numb] u = np.append(u, np.zeros(2*ndof)) # added by zhilong, assume that we do not need the auxiliary wavefields u.shape = solver_data.k.data.shape solver_data.k.data = u numb += 1
def solve_petsc_uhat(self, solver, rhs_list, frequency, petsc='mumps', *args, **kwargs): #try catch for the petsc4py use in multiple rhs solve #use only in the data generation where we do not need to compute #the system for the whole auxiliary fields try: import petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc from pysit.util.wrappers.petsc import PetscWrapper except ImportError: raise ImportError('petsc4py is not installed, please install it and try again') #Building the Helmholtz operator for petsc H = self._build_helmholtz_operator(frequency) ndof = H.shape[1] nshot = len(rhs_list) # if the compact operator is used we do not need to slice the solution if self.compact: usize = ndof else: nwfield = len(self.WavefieldVector.aux_names) + 1 usize = ndof/nwfield # creating the B rhs Matrix B = PETSc.Mat().createDense([ndof, nshot]) B.setUp() for i in range(nshot): B.setValues(range(0, ndof), [i], rhs_list[i]) B.assemblyBegin() B.assemblyEnd() # call the wrapper to solve the system wrapper = PetscWrapper() try: linear_solver = wrapper.factorize(H, petsc, PETSc.COMM_WORLD) Uhat = linear_solver(B.getDenseArray()) except: raise SyntaxError('petsc = '+str(petsc)+' is not a correct solver you can only use \'superlu_dist\', \'mumps\' or \'mkl_pardiso\' ') Uhat = Uhat[xrange(usize),:] return Uhat
def factorize_at_freq(self, freq): #This function follows the same idea as the 'factorized' routine of scipy.sparse.linalg.dsolve.linsolve if self.petscdict is None: #umfdict contains the umf objects for every frequency. self.petscdict = dict() #The matrix A = self.solver.linear_operators[freq] print "Factorizing matrix" wrapper = PetscWrapper() linear_solver = wrapper.factorize(A, self.petsc, PETSc.COMM_WORLD) self.petscdict[freq] = linear_solver def solve(b): warnings.warn( 'Right now only solving for one shot at a time. Petsc can take many RHS at the same time. Need to change code...' ) #b is a complex128 vector. The solve routine of umfpack expects a vector with real and imaginary part (two float64 vectors). if b.dtype != "complex128": raise Exception( "Efficient only for complex128 systems. Need to write more optimal routines for other dtypes." ) ndof = b.size #Assuming b is length of single shot RHS vector # creating the B rhs Matrix. Borrowed from the standard CDA solver, its petsc solve routine B = PETSc.Mat().createDense( [ndof, 1]) #right now 1 refers to us passing only 1 shot at a time B.setUp() B.setValues(range(0, ndof), [0], b) #only set up one shot for now B.assemblyBegin() B.assemblyEnd() x = self.petscdict[freq](B.getDenseArray()) return x.flatten( ) #NOW THAT I AM USING ONE SHOT AT A TIME I AM STILL EXPECTING A FLAT RETURN VECTOR return solve
def _build_petsc_mkl_pardiso_solver(self, nu): dummy_wrapper = PetscWrapper() return dummy_wrapper.factorize(self.linear_operators[nu], 'mkl_pardiso')
def _build_petsc_superlu_dist_solver(self, nu): dummy_wrapper = PetscWrapper() return dummy_wrapper.factorize(self.linear_operators[nu], 'superlu_dist')
def _build_petsc_mumps_solver(self, nu): dummy_wrapper = PetscWrapper() return dummy_wrapper.factorize(self.linear_operators[nu], 'mumps')