def save_output(context, layers, x, fname): """Create vtk files from the result""" ndofc = sum([layers[i]['spaces']['ndof'] for i in range(len(layers))]) tmp = x.ExtractView().T xc = tmp[:ndofc, :] + 1j * tmp[ndofc:, :] if Epetra.PyComm().MyPID() == 0: n = 0 for i in range(len(layers)): plc = layers[i]['spaces']['l'] pwc = layers[i]['spaces']['c'] nplc = plc.globalDofCount() npwc = pwc.globalDofCount() ndof = nplc + npwc coeff_dirichlet = xc[n:n + nplc, 0] coeff_neumann = xc[n + nplc:n + nplc + npwc, 0] n = n + ndof ufun = lib.createGridFunction(context, plc, pwc, coefficients=coeff_dirichlet) vfun = lib.createGridFunction(context, pwc, plc, coefficients=coeff_neumann) ufun.exportToVtk("vertex_data", "dirichlet_data", fname + "_u" + str(i)) vfun.exportToVtk("cell_data", "neumann_data", fname + "_v" + str(i))
def save_output(context,layers,x,fname): """Create vtk files from the result""" ndofc = sum([layers[i]['spaces']['ndof'] for i in range(len(layers))]) tmp = x.ExtractView().T xc = tmp[:ndofc,:]+1j*tmp[ndofc:,:] if Epetra.PyComm().MyPID()==0: n = 0 for i in range(len(layers)): plc = layers[i]['spaces']['l'] pwc = layers[i]['spaces']['c'] nplc = plc.globalDofCount() npwc = pwc.globalDofCount() ndof = nplc+npwc coeff_dirichlet = xc[n:n+nplc,0] coeff_neumann = xc[n+nplc:n+nplc+npwc,0] n = n+ndof ufun = lib.createGridFunction(context,plc,pwc,coefficients=coeff_dirichlet) vfun = lib.createGridFunction(context,pwc,plc,coefficients=coeff_neumann) ufun.exportToVtk("vertex_data","dirichlet_data",fname+"_u"+str(i)) vfun.exportToVtk("cell_data","neumann_data",fname+"_v"+str(i))
def project_incident_field(self,fun,time,space_index=0): if space_index==0: f = lambda x,normal:fun.dirichlet_trace(x,time,normal) gridFun = _bempplib.createGridFunction(self._context,self._space,self._space,f,surfaceNormalDependent=True) return gridFun.coefficients() else: f = lambda x,normal: fun.neumann_trace(x,time,normal) gridFun = _bempplib.createGridFunction(self._context,self._space,self._space,f,surfaceNormalDependent=True) return gridFun.coefficients()
def evaluate_potential(self,wave_number,density): if self._evaluation_options is None: raise Exception("Error. 'evaluation_options' must be defined") if self._evaluation_quadrature_strategy is None: raise Exception("Error. 'evaluation_quadrature_options' must be defined") op_found_in_cache = False if self._operator_cache: try: potential = self._potential_operator_cache.get(wave_number) op_found_in_cache = True except: pass if not op_found_in_cache: potential = _bempplib.createMaxwell3dSingleLayerPotentialOperator(self._context,1.0j*wave_number).assemble(self._space, self._evaluation_points, self._evaluation_quadrature_strategy, self._evaluation_options) if self._operator_cache: self._potential_operator_cache.insert(wave_number,potential) n = len(density[0]) gridFun = _bempplib.createGridFunction(self._context,self._space,coefficients=density[0]) return potential.apply(gridFun)
def initialize_rhs(context, layers, evalFun, process_maps): """Generate the rhs vector""" pwc = layers[0]['spaces']['c'] plc = layers[0]['spaces']['l'] ndof = plc.globalDofCount() total_dofs = sum([layers[i]['spaces']['ndof'] for i in range(len(layers))]) rhs_data = Epetra.MultiVector(process_maps.single_proc_map, 1) if Epetra.PyComm().MyPID() == 0: pwc = layers[0]['spaces']['c'] plc = layers[0]['spaces']['l'] fun = lib.createGridFunction(context, pwc, plc, evalFun) data = fun.projections() rhs_data[0, :ndof] = np.real(data) rhs_data[0, total_dofs:total_dofs + ndof] = np.imag(data) return rhs_data
def initialize_rhs(context,layers,evalFun,process_maps): """Generate the rhs vector""" pwc = layers[0]['spaces']['c'] plc = layers[0]['spaces']['l'] ndof = plc.globalDofCount() total_dofs = sum([layers[i]['spaces']['ndof'] for i in range(len(layers))]) rhs_data = Epetra.MultiVector(process_maps.single_proc_map,1) if Epetra.PyComm().MyPID()==0: pwc = layers[0]['spaces']['c'] plc = layers[0]['spaces']['l'] fun = lib.createGridFunction(context,pwc,plc,evalFun) data = fun.projections() rhs_data[0,:ndof] = np.real(data) rhs_data[0,total_dofs:total_dofs+ndof]=np.imag(data) return rhs_data
adlpOp = lib.createHelmholtz3dAdjointDoubleLayerBoundaryOperator( context, pwiseConstants, pwiseConstants, pwiseConstants, k) idOp = lib.createIdentityOperator( context, pwiseConstants, pwiseConstants, pwiseConstants) # Standard arithmetic operators can be used to create linear combinations of # boundary operators. lhsOp = idOp + 2 * adlpOp - 2j * k * slpOp # Use the rhsData() Python function defined earlier to initialize the grid # function that represents the right-hand side. The spaces are the domain space # and the test space (in this case they are identical). rhsData() takes the # surface normal as a parameter, so we set surfaceNormalDependent to True. fun = lib.createGridFunction( context, pwiseConstants, pwiseConstants, rhsData, surfaceNormalDependent=True) # We will now use GMRES to solve the problem. # The default iterative solver supports several Krylov space methods. solver = lib.createDefaultIterativeSolver(lhsOp) # Create an initialization list for GMRES with tolerance 1e-5. # A CG parameter list is also available for symmetric problems. params = lib.defaultGmresParameterList(1e-5) solver.initializeSolver(params) # Solve...
def _save_slice(self,data,fname): gridFun = _bempplib.createGridFunction(self._context,self._spaces[0],self._spaces[0],coefficients=data) gridFun.exportToVtk("cell_data","solution_data",fname)
structure.setBlock(2, 1, lhs_k32) structure.setBlock(2, 2, lhs_k33) structure.setBlock(2, 3, lhs_k34) structure.setBlock(2, 4, lhs_k35) structure.setBlock(3, 1, lhs_k42) structure.setBlock(3, 2, lhs_k43) structure.setBlock(3, 3, lhs_k44) structure.setBlock(3, 4, lhs_k45) structure.setBlock(4, 3, lhs_k54) structure.setBlock(4, 4, lhs_k55) blockedOp = blib.createBlockedBoundaryOperator(context, structure) rhs1 = scale * slp11 rhs2 = scale * slp21 boundaryData1 = rhs1 * blib.createGridFunction(context, sphere1_plc, sphere1_plc, evalBoundaryData) boundaryData2 = rhs2 * blib.createGridFunction(context, sphere1_plc, sphere1_plc, evalBoundaryData) boundaryData3 = blib.createGridFunction(context, sphere2_plc, sphere2_plc, evalNullData) boundaryData4 = blib.createGridFunction(context, sphere3_plc, sphere3_plc, evalNullData) boundaryData5 = blib.createGridFunction(context, sphere3_plc, sphere3_plc, evalNullData) rhs = [ boundaryData1, boundaryData2, boundaryData3, boundaryData4, boundaryData5 ] solver = blib.createDefaultIterativeSolver(blockedOp) params = blib.defaultGmresParameterList(1e-10)
x, y, z = point res = 0.0*x + 0.0j*y + 0*z for pt in range(0,x.size): res[pt] = np.exp(1j*k*x[pt]) return res def evalInc(point): x, y, z = point if x.size == 1: return uIncData(point) res = 0.0*x + 0.0j*y + 0.0*z for pt in range(0,x.size): res[pt] = uIncData([x[pt], y[pt], z[pt] ]) return res uInc = lib.createGridFunction(context, pconsts, pconsts, evalInc) rhs = -uInc # PART 4: Discretize and solve the equations ################################### solver = lib.createDefaultIterativeSolver(lhsOp) params = lib.defaultGmresParameterList(1e-8) solver.initializeSolver(params) # Solve the equation solution = solver.solve(rhs) print solution.solverMessage() # PART 5: Extract the solution ################################################# sol = solution.gridFunction() print "************** k = ", k, " **********************"
lhsOp10 = 0.5 * idOp + dlpOpInt lhsOp11 = -rhoInt / rhoExt * slpOpInt # ... and combine them into a blocked operator lhsOp = lib.createBlockedBoundaryOperator( context, [[lhsOp00, lhsOp01], [lhsOp10, lhsOp11]]) # Create a grid function representing the Dirichlet trace of the incident wave def uIncData(point): x, y, z = point r = np.sqrt(x**2 + y**2 + z**2) return np.exp(1j * kExt * x) uInc = lib.createGridFunction(context, pconsts, pconsts, uIncData) # Create a grid function representing the Neumann trace of the incident wave def uIncDerivData(point, normal): x, y, z = point nx, ny, nz = normal r = np.sqrt(x**2 + y**2 + z**2) return 1j * kExt * np.exp(1j * kExt * x) * nx uIncDeriv = lib.createGridFunction(context, pconsts, pconsts, uIncDerivData, surfaceNormalDependent=True) # Create elements of the right hand side of the equation rhs = [uInc, None]
def evaluate_potential(self,wave_number,density): if self._evaluation_options is None: raise Exception("Error. 'evaluation_options' must be defined") if self._evaluation_quadrature_strategy is None: raise Exception("Error. 'evaluation_quadrature_options' must be defined") op_found_in_cache = False if self._operator_cache: try: pot_ext_single,pot_ext_double,pot_int_single,pot_int_double = self._potential_operator_cache.get(wave_number) op_found_in_cache = True except: pass if not op_found_in_cache: k_ext = 1.0j*wave_number * _np.sqrt(self._eps_ext * self._mu_ext) k_int = 1.0j*wave_number * _np.sqrt(self._eps_int * self._mu_int) rho = (k_int * self._mu_ext) / (k_ext * self._mu_int) pot_ext_single = _bempplib.createMaxwell3dSingleLayerPotentialOperator(self._context,k_ext).assemble(self._space, self._evaluation_points[:,self._outside], self._evaluation_quadrature_strategy, self._evaluation_options) pot_ext_double = _bempplib.createMaxwell3dDoubleLayerPotentialOperator(self._context,k_ext).assemble(self._space, self._evaluation_points[:,self._outside], self._evaluation_quadrature_strategy, self._evaluation_options) pot_int_single = _bempplib.createMaxwell3dSingleLayerPotentialOperator(self._context,k_int).assemble(self._space, self._evaluation_points[:,self._inside], self._evaluation_quadrature_strategy, self._evaluation_options) pot_int_double = _bempplib.createMaxwell3dDoubleLayerPotentialOperator(self._context,k_int).assemble(self._space, self._evaluation_points[:,self._inside], self._evaluation_quadrature_strategy, self._evaluation_options) if self._operator_cache: self._potential_operator_cache.insert(wave_number,pot_int_single,pot_int_double, pot_ext_single,pot_ext_double) dirichlet_ext = density[0] dirichlet_int = dirichlet_ext neumann_ext = density[1] neumann_int = density[1]/rho dirichlet_ext_fun = _bempplib.createGridFunction(self._context,self._space,self._space,coefficients=dirichlet_ext) dirichlet_int_fun = _bempplib.createGridFunction(self._context,self._space,self._space,coefficients=dirichlet_int) neumann_ext_fun = _bempplib.createGridFunction(self._context,self._space,self._space,coefficients=neumann_ext) neumann_int_fun = _bempplib.createGridFunction(self._context,self._space,self._space,coefficients=neumann_int) scatt_dirichlet_ext_fun = dirichlet_ext_fun - self._inc_dirichlet_traces[wave_number] print "Eval Dirichlet Error "+str(scatt_dirichlet_ext_fun.L2Norm()/dirichlet_ext_fun.L2Norm()) scatt_neumann_ext_fun = neumann_ext_fun - self._inc_neumann_traces[wave_number] print "Eval Neumann Error "+str(scatt_neumann_ext_fun.L2Norm()/dirichlet_ext_fun.L2Norm()) valsExt = pot_ext_single.apply(scatt_neumann_ext_fun) + pot_ext_double.apply(scatt_dirichlet_ext_fun) valsInt = pot_int_single.apply(neumann_int_fun) + pot_int_double.apply(dirichlet_int_fun) vals = _np.zeros((3,self._evaluation_points.shape[1]), dtype='complex128') vals[:,self._inside] = valsInt vals[:,self._outside] = valsExt return vals
def solve_bvp(self,wave_number,rhs): self._residuals[wave_number] = [] def evaluate_residual(res): self._residuals[wave_number].append(res) k_ext = 1.0j*wave_number * _np.sqrt(self._eps_ext * self._mu_ext) k_int = 1.0j*wave_number * _np.sqrt(self._eps_int * self._mu_int) rho = (k_int * self._mu_ext) / (k_ext * self._mu_int) op_found_in_cache = False if self._operator_cache: try: op,prec = self._boundary_operator_cache(wave_number) op_found_in_cache = True except: pass if not op_found_in_cache: context = self._context space = self._space slpOpExt = _bempplib.createMaxwell3dSingleLayerBoundaryOperator( context, space, space, space, k_ext, "SLP_ext") dlpOpExt = _bempplib.createMaxwell3dDoubleLayerBoundaryOperator( context, space, space, space, k_ext, "DLP_ext") slpOpInt = _bempplib.createMaxwell3dSingleLayerBoundaryOperator( context, space, space, space, k_int, "SLP_int") dlpOpInt = _bempplib.createMaxwell3dDoubleLayerBoundaryOperator( context, space, space, space, k_int, "DLP_int") idOp = _bempplib.createMaxwell3dIdentityOperator( context, space, space, space, "Id") # Form the left- and right-hand-side operators lhsOp00 = -(slpOpExt + rho * slpOpInt) lhsOp01 = lhsOp10 = dlpOpExt + dlpOpInt lhsOp11 = slpOpExt + (1. / rho) * slpOpInt lhsOp = _bempplib.createBlockedBoundaryOperator( context, [[lhsOp00, lhsOp01], [lhsOp10, lhsOp11]]) precTol = self._aca_lu_delta invLhsOp00 = _bempplib.acaOperatorApproximateLuInverse( lhsOp00.weakForm().asDiscreteAcaBoundaryOperator(), precTol) invLhsOp11 = _bempplib.acaOperatorApproximateLuInverse( lhsOp11.weakForm().asDiscreteAcaBoundaryOperator(), precTol) prec = _bempplib.discreteBlockDiagonalPreconditioner([invLhsOp00, invLhsOp11]) op = lhsOp # Construct the grid functions representing the traces of the incident field incDirichletTrace = _bempplib.createGridFunction( context, space, space, coefficients=rhs[0]) incNeumannTrace = 1./(1j*k_ext)*_bempplib.createGridFunction( context, space, space, coefficients=rhs[1]) self._inc_dirichlet_traces[wave_number] = incDirichletTrace self._inc_neumann_traces[wave_number] = incNeumannTrace # Construct the right-hand-side grid function rhs = [idOp * incNeumannTrace, idOp * incDirichletTrace] solver = _bempplib.createDefaultIterativeSolver(op) solver.initializeSolver(_bempplib.defaultGmresParameterList(self._gmres_tol), prec) # Solve the equation solution = solver.solve(rhs) print solution.solverMessage() # Extract the solution components in the form of grid functions extDirichletTrace = solution.gridFunction(0) extNeumannTrace = solution.gridFunction(1) if self._operator_cache: self._boundary_operator_cache.insert(wave_number,(op,prec)) scatt_dirichlet_ext_fun = extDirichletTrace - self._inc_dirichlet_traces[wave_number] print "Dirichlet Error "+str(scatt_dirichlet_ext_fun.L2Norm()/extDirichletTrace.L2Norm()) scatt_neumann_ext_fun = extNeumannTrace - self._inc_neumann_traces[wave_number] print "Neumann Error "+str(scatt_neumann_ext_fun.L2Norm()/extNeumannTrace.L2Norm()) return [extDirichletTrace.coefficients(),extNeumannTrace.coefficients()]
structure.setBlock(2, 1, lhs_k32); structure.setBlock(2, 2, lhs_k33); structure.setBlock(2, 3, lhs_k34); structure.setBlock(2, 4, lhs_k35); structure.setBlock(3, 1, lhs_k42); structure.setBlock(3, 2, lhs_k43); structure.setBlock(3, 3, lhs_k44); structure.setBlock(3, 4, lhs_k45); structure.setBlock(4, 3, lhs_k54); structure.setBlock(4, 4, lhs_k55); blockedOp = blib.createBlockedBoundaryOperator(context,structure) rhs1 = scale*slp11 rhs2 = scale*slp21 boundaryData1 = rhs1 * blib.createGridFunction( context, sphere1_plc, sphere1_plc, evalBoundaryData) boundaryData2 = rhs2 * blib.createGridFunction( context, sphere1_plc, sphere1_plc, evalBoundaryData) boundaryData3 = blib.createGridFunction( context, sphere2_plc, sphere2_plc, evalNullData) boundaryData4 = blib.createGridFunction( context, sphere3_plc, sphere3_plc, evalNullData) boundaryData5 = blib.createGridFunction( context, sphere3_plc, sphere3_plc, evalNullData) rhs = [boundaryData1, boundaryData2, boundaryData3, boundaryData4, boundaryData5] solver = blib.createDefaultIterativeSolver(blockedOp) params = blib.defaultGmresParameterList(1e-10) solver.initializeSolver(params) solution = solver.solve(rhs)
for pt in range(0, x.size): res[pt] = np.exp(1j * k * x[pt]) return res def evalInc(point): x, y, z = point if x.size == 1: return uIncData(point) res = 0.0 * x + 0.0j * y + 0.0 * z for pt in range(0, x.size): res[pt] = uIncData([x[pt], y[pt], z[pt]]) return res uInc = lib.createGridFunction(context, pconsts, pconsts, evalInc) rhs = -uInc # PART 4: Discretize and solve the equations ################################### solver = lib.createDefaultIterativeSolver(lhsOp) params = lib.defaultGmresParameterList(1e-8) solver.initializeSolver(params) # Solve the equation solution = solver.solve(rhs) print solution.solverMessage() # PART 5: Extract the solution ################################################# sol = solution.gridFunction() print "************** k = ", k, " **********************" slPot = lib.createHelmholtz3dSingleLayerPotentialOperator(context, k)
def project_incident_field(self,fun,time,space_index=0): f = lambda x:fun.dirichlet_trace(x,time) gridFun = _bempplib.createGridFunction(self._context,self._spaces[0],self._spaces[0],f) return gridFun.coefficients()