def diagonal_block(context,layers,layer_id,impedance): """Create a diagonal block associated with a given layer_id """ plc = layers[layer_id]['spaces']['l'] pwc = layers[layer_id]['spaces']['c'] k = layers[layer_id]['k'] kappa = layers[layer_id]['kappa'] if layer_id == 0: I_00 = lib.createIdentityOperator(context,plc,pwc,plc,label="I00") I_01 = lib.createIdentityOperator(context,pwc,pwc,plc,label="I01") I_10 = lib.createIdentityOperator(context,plc,plc,pwc,label="I10") K = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,plc,plc,pwc,k,label="K10") S = 1./kappa*lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,pwc,plc,pwc,k,label="S11") return lib.createBlockedBoundaryOperator(context,[[I_00,impedance*I_01],[-.5*I_10-K,S]]) else: kf = layers[layers[layer_id]['father']]['k'] kappaf = layers[layers[layer_id]['father']]['kappa'] DD = (-kappaf*lib.createModifiedHelmholtz3dHypersingularBoundaryOperator(context,plc,pwc,plc,kf,label="Df"+str(layer_id)+"_"+str(layer_id)) -kappa*lib.createModifiedHelmholtz3dHypersingularBoundaryOperator(context,plc,pwc,plc,k,label="D"+str(layer_id)+"_"+str(layer_id))) TT = (-lib.createModifiedHelmholtz3dAdjointDoubleLayerBoundaryOperator(context,pwc,pwc,plc,kf,label="Tf"+str(layer_id)+"_"+str(layer_id)) -lib.createModifiedHelmholtz3dAdjointDoubleLayerBoundaryOperator(context,pwc,pwc,plc,k,label="T"+str(layer_id)+"_"+str(layer_id))) KK = (lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,plc,plc,pwc,kf,label="Kf"+str(layer_id)+"_"+str(layer_id)) +lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,plc,plc,pwc,k,label="K"+str(layer_id)+"_"+str(layer_id))) SS = (-1./kappaf*lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,pwc,plc,pwc,kf,label="Sf"+str(layer_id)+"_"+str(layer_id)) -1./kappa*lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,pwc,plc,pwc,k,label="S"+str(layer_id)+"_"+str(layer_id))) return lib.createBlockedBoundaryOperator(context,[[DD,TT],[KK,SS]])
def initialize(self,evaluation_points): accuracy_options = _bempplib.createAccuracyOptions() accuracy_options.doubleRegular.setRelativeQuadratureOrder(self._relative_regular_quadrature_order) accuracy_options.doubleSingular.setRelativeQuadratureOrder(self._relative_singular_quadrature_order) accuracy_options.singleRegular.setRelativeQuadratureOrder(self._relative_regular_quadrature_order) assembly_options = _bempplib.createAssemblyOptions() assembly_options.setVerbosityLevel('low') if self._use_aca: aca_options = _bempplib.createAcaOptions() aca_options.maximumBlockSize = 2000 aca_options.maximumRank = 100 aca_options.eps = self._aca_epsilon assembly_options.switchToAca(aca_options) quad_strategy = _bempplib.createNumericalQuadratureStrategy("float64","complex128",accuracy_options) self._quad_strategy = quad_strategy self._context = _bempplib.createContext(quad_strategy,assembly_options) pconsts = _bempplib.createPiecewiseConstantScalarSpace(self._context,self._mesh) self._spaces = [pconsts,pconsts,pconsts] self._mass_matrix = _bempplib.createIdentityOperator(self._context,pconsts,pconsts,pconsts).weakForm() self._boundary_operator_cache = _tools.OperatorCache(self._operator_cache_tol) self._potential_operator_cache = _tools.OperatorCache(self._operator_cache_tol) self._residuals = {} self._evaluation_points = evaluation_points
"triangular", "../../meshes/sphere-h-0.1.msh") # Create a space of piecewise constant basis functions over the grid. pwiseConstants = lib.createPiecewiseConstantScalarSpace(context, grid) # We now initialize the boundary operators. # A boundary operator always takes three space arguments: a domain space, # a range space, and the test space (dual to the range). # Here, we just use L^2 projections. Hence, all spaces are identical. slpOp = lib.createHelmholtz3dSingleLayerBoundaryOperator( context, pwiseConstants, pwiseConstants, pwiseConstants, k) 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)
def diagonal_block(context, layers, layer_id, impedance): """Create a diagonal block associated with a given layer_id """ plc = layers[layer_id]['spaces']['l'] pwc = layers[layer_id]['spaces']['c'] k = layers[layer_id]['k'] kappa = layers[layer_id]['kappa'] if layer_id == 0: I_00 = lib.createIdentityOperator(context, plc, pwc, plc, label="I00") I_01 = lib.createIdentityOperator(context, pwc, pwc, plc, label="I01") I_10 = lib.createIdentityOperator(context, plc, plc, pwc, label="I10") K = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, plc, plc, pwc, k, label="K10") S = 1. / kappa * lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, pwc, plc, pwc, k, label="S11") return lib.createBlockedBoundaryOperator( context, [[I_00, impedance * I_01], [-.5 * I_10 - K, S]]) else: kf = layers[layers[layer_id]['father']]['k'] kappaf = layers[layers[layer_id]['father']]['kappa'] DD = ( -kappaf * lib.createModifiedHelmholtz3dHypersingularBoundaryOperator( context, plc, pwc, plc, kf, label="Df" + str(layer_id) + "_" + str(layer_id)) - kappa * lib.createModifiedHelmholtz3dHypersingularBoundaryOperator( context, plc, pwc, plc, k, label="D" + str(layer_id) + "_" + str(layer_id))) TT = (-lib.createModifiedHelmholtz3dAdjointDoubleLayerBoundaryOperator( context, pwc, pwc, plc, kf, label="Tf" + str(layer_id) + "_" + str(layer_id)) - lib.createModifiedHelmholtz3dAdjointDoubleLayerBoundaryOperator( context, pwc, pwc, plc, k, label="T" + str(layer_id) + "_" + str(layer_id))) KK = (lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, plc, plc, pwc, kf, label="Kf" + str(layer_id) + "_" + str(layer_id)) + lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, plc, plc, pwc, k, label="K" + str(layer_id) + "_" + str(layer_id))) SS = (-1. / kappaf * lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, pwc, plc, pwc, kf, label="Sf" + str(layer_id) + "_" + str(layer_id)) - 1. / kappa * lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, pwc, plc, pwc, k, label="S" + str(layer_id) + "_" + str(layer_id))) return lib.createBlockedBoundaryOperator(context, [[DD, TT], [KK, SS]])
aca_options.eps = 1E-5 options.switchToAca(aca_options) context = blib.createContext(strategy, options) # Create the spaces sphere1_plc = blib.createPiecewiseLinearContinuousScalarSpace(context, sphere1) sphere2_plc = blib.createPiecewiseLinearContinuousScalarSpace(context, sphere2) sphere3_plc = blib.createPiecewiseLinearContinuousScalarSpace(context, sphere3) # Now create the operators slp11 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, sphere1_plc, sphere1_plc, sphere1_plc, w1) dlp11 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, sphere1_plc, sphere1_plc, sphere1_plc, w1) id11 = blib.createIdentityOperator(context, sphere1_plc, sphere1_plc, sphere1_plc) slp22_w1 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, sphere2_plc, sphere2_plc, sphere2_plc, w1) dlp22_w1 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, sphere2_plc, sphere2_plc, sphere2_plc, w1) slp22_w2 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, sphere2_plc, sphere2_plc, sphere2_plc, w2) dlp22_w2 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, sphere2_plc, sphere2_plc, sphere2_plc, w2) id22 = blib.createIdentityOperator(context, sphere2_plc, sphere2_plc, sphere2_plc) slp12 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, sphere2_plc, sphere1_plc, sphere1_plc, w1) dlp12 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(
rhoInt = 2. rhoExt = 1. kInt = 1. kExt = 5. # Create boundary operators slpOpInt = lib.createHelmholtz3dSingleLayerBoundaryOperator( context, pconsts, pconsts, pconsts, kInt, "SLP_int") slpOpExt = lib.createHelmholtz3dSingleLayerBoundaryOperator( context, pconsts, pconsts, pconsts, kExt, "SLP_ext") dlpOpInt = lib.createHelmholtz3dDoubleLayerBoundaryOperator( context, pconsts, pconsts, pconsts, kInt, "DLP_int") dlpOpExt = lib.createHelmholtz3dDoubleLayerBoundaryOperator( context, pconsts, pconsts, pconsts, kExt, "DLP_ext") idOp = lib.createIdentityOperator( context, pconsts, pconsts, pconsts, "Id") # Create blocks of the operator on the lhs of the equation... lhsOp00 = 0.5 * idOp - dlpOpExt lhsOp01 = slpOpExt 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
aca_options = blib.createAcaOptions() aca_options.eps=1E-5 options.switchToAca(aca_options) context = blib.createContext(strategy, options) # Create the spaces sphere1_plc = blib.createPiecewiseLinearContinuousScalarSpace(context,sphere1) sphere2_plc = blib.createPiecewiseLinearContinuousScalarSpace(context,sphere2) sphere3_plc = blib.createPiecewiseLinearContinuousScalarSpace(context,sphere3) # Now create the operators slp11 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,sphere1_plc,sphere1_plc,sphere1_plc,w1) dlp11 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,sphere1_plc,sphere1_plc,sphere1_plc,w1) id11 = blib.createIdentityOperator(context,sphere1_plc,sphere1_plc,sphere1_plc) slp22_w1 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,sphere2_plc,sphere2_plc,sphere2_plc,w1) dlp22_w1 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,sphere2_plc,sphere2_plc,sphere2_plc,w1) slp22_w2 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,sphere2_plc,sphere2_plc,sphere2_plc,w2) dlp22_w2 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,sphere2_plc,sphere2_plc,sphere2_plc,w2) id22 = blib.createIdentityOperator(context,sphere2_plc,sphere2_plc,sphere2_plc) slp12 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,sphere2_plc,sphere1_plc,sphere1_plc,w1) dlp12 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,sphere2_plc,sphere1_plc,sphere1_plc,w1) slp21 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,sphere1_plc,sphere2_plc,sphere2_plc,w1) dlp21 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,sphere1_plc,sphere2_plc,sphere2_plc,w1) slp23 = blib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,sphere3_plc,sphere2_plc,sphere2_plc,w2) dlp23 = blib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,sphere3_plc,sphere2_plc,sphere2_plc,w2)
"triangular", "../../examples/meshes/sphere-h-0.1.msh") # Create a space of piecewise constant basis functions over the grid. pwiseConstants = lib.createPiecewiseConstantScalarSpace(context, grid) # We now initialize the boundary operators. # A boundary operator always takes three space arguments: a domain space, # a range space, and the test space (dual to the range). # Here, we just use L^2 projections. Hence, all spaces are identical. slpOp = lib.createHelmholtz3dSingleLayerBoundaryOperator( context, pwiseConstants, pwiseConstants, pwiseConstants, k) 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)