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... solution = solver.solve(fun) print solution.solverMessage() # Trilinos solver summary message # ... and extract the solution. It is the normal derivative of the total field. solfun = solution.gridFunction()
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) u0 = solution.gridFunction(0) u1 = solution.gridFunction(1) v1 = solution.gridFunction(2) u2 = solution.gridFunction(3) v2 = solution.gridFunction(4) # write out VTK files u0.exportToVtk("vertex_data", "u0", "u0") u1.exportToVtk("vertex_data", "u1", "u1") v1.exportToVtk("vertex_data", "v1", "v1") u2.exportToVtk("vertex_data", "u2", "u2") v2.exportToVtk("vertex_data", "v2", "v2")
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) u0 = solution.gridFunction(0) u1 = solution.gridFunction(1) v1 = solution.gridFunction(2) u2 = solution.gridFunction(3) v2 = solution.gridFunction(4) # write out VTK files u0.exportToVtk("vertex_data", "u0", "u0") u1.exportToVtk("vertex_data", "u1", "u1") v1.exportToVtk("vertex_data", "v1", "v1") u2.exportToVtk("vertex_data", "u2", "u2") v2.exportToVtk("vertex_data", "v2", "v2")
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()]
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) dlPot = lib.createHelmholtz3dDoubleLayerPotentialOperator(context, k) evalOptions = lib.createEvaluationOptions() endpl = 0.5