Ejemplo n.º 1
0
 def initialize(self,evaluation_points=None):
     
     self._evaluation_points = evaluation_points
     self._space = _bempplib.createRaviartThomas0VectorSpace(self._context,self._grid)
     self._identity = _bempplib.createMaxwell3dIdentityOperator(self._context,self._space,self._space,self._space).weakForm()
     if self._operator_cache:
         self._boundary_operator_cache = _tools.OperatorCache(self._operator_cache_tol)
         self._potential_operator_cache = _tools.OperatorCache(self._operator_cache_tol)
Ejemplo n.º 2
0
    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()]