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 off_diagonal_block_same_layer(context,layers,id1,id2): """Off-diagonal interaction between two different layers. Returns a tuple of two operators. """ pwc_id1 = layers[id1]['spaces']['c'] plc_id1 = layers[id1]['spaces']['l'] pwc_id2 = layers[id2]['spaces']['c'] plc_id2 = layers[id2]['spaces']['l'] k = layers[layers[id1]['father']]['k'] kappa = layers[layers[id1]['father']]['kappa'] D = kappa*lib.createModifiedHelmholtz3dHypersingularBoundaryOperator(context,plc_id2,pwc_id1,plc_id1,k) T = lib.createModifiedHelmholtz3dAdjointDoubleLayerBoundaryOperator(context,pwc_id2,pwc_id1,plc_id1,k) K = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,plc_id2,plc_id1,pwc_id1,k) S = 1./kappa*lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,pwc_id2,plc_id1,pwc_id1,k) D2 = lib.adjoint(D,pwc_id2) T2 = lib.adjoint(K,pwc_id2) K2 = lib.adjoint(T,plc_id2) S2 = lib.adjoint(S,plc_id2) op1 = lib.createBlockedBoundaryOperator(context,[[-D,-T],[K,-S]]) op2 = lib.createBlockedBoundaryOperator(context,[[-D2,-T2],[K2,-S2]]) return (op1,op2)
def off_diagonal_block_same_layer(context, layers, id1, id2): """Off-diagonal interaction between two different layers. Returns a tuple of two operators. """ pwc_id1 = layers[id1]['spaces']['c'] plc_id1 = layers[id1]['spaces']['l'] pwc_id2 = layers[id2]['spaces']['c'] plc_id2 = layers[id2]['spaces']['l'] k = layers[layers[id1]['father']]['k'] kappa = layers[layers[id1]['father']]['kappa'] D = kappa * lib.createModifiedHelmholtz3dHypersingularBoundaryOperator( context, plc_id2, pwc_id1, plc_id1, k) T = lib.createModifiedHelmholtz3dAdjointDoubleLayerBoundaryOperator( context, pwc_id2, pwc_id1, plc_id1, k) K = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, plc_id2, plc_id1, pwc_id1, k) S = 1. / kappa * lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, pwc_id2, plc_id1, pwc_id1, k) D2 = lib.adjoint(D, pwc_id2) T2 = lib.adjoint(K, pwc_id2) K2 = lib.adjoint(T, plc_id2) S2 = lib.adjoint(S, plc_id2) op1 = lib.createBlockedBoundaryOperator(context, [[-D, -T], [K, -S]]) op2 = lib.createBlockedBoundaryOperator(context, [[-D2, -T2], [K2, -S2]]) return (op1, op2)
def off_diagonal_block_father_son(context,layers,father_id,son_id): """Off-diagonal interaction between two different layers. Returns a tuple of two operators. """ plc_father = layers[father_id]['spaces']['l'] pwc_father = layers[father_id]['spaces']['c'] plc_son = layers[son_id]['spaces']['l'] pwc_son = layers[son_id]['spaces']['c'] kf = layers[father_id]['k'] kappaf = layers[father_id]['kappa'] if father_id==0: null_00 = lib.createNullOperator(context,plc_son,pwc_father,plc_father,label="Null_00") null_01 = lib.createNullOperator(context,pwc_son,pwc_father,plc_father,label="Null_01") Kf = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,plc_son,plc_father,pwc_father,kf,label="Kf0_"+str(son_id)) Sf = 1./kappaf*lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator(context,pwc_son,plc_father,pwc_father,kf,label="Sf0_"+str(son_id)) op_father_son = lib.createBlockedBoundaryOperator(context,[[null_00,null_01],[Kf,-Sf]]) Ds = kappaf*lib.createModifiedHelmholtz3dHypersingularBoundaryOperator(context,plc_father,pwc_son,plc_son,kf,label="Ds"+str(son_id)+"_0") Ts = lib.adjoint(Kf,pwc_son) Ks = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,plc_father,plc_son,pwc_son,kf,label="Ks"+str(son_id)+"_0") Ss = lib.adjoint(Sf,plc_son) op_son_father = lib.createBlockedBoundaryOperator(context,[[Ds,Ts],[-Ks,Ss]]) else: Df = kappaf*lib.createModifiedHelmholtz3dHypersingularBoundaryOperator(context,plc_son,pwc_father,plc_father,kf) Tf = lib.createModifiedHelmholtz3dAdjointDoubleLayerBoundaryOperator(context,pwc_son,pwc_father,plc_father,kf) Kf = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,plc_son,plc_father,pwc_father,kf) Sf = 1./kappaf*lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,pwc_son,plc_father,pwc_father,kf) op_father_son = lib.createBlockedBoundaryOperator(context,[[Df,Tf],[-Kf,Sf]]) Ds = lib.adjoint(Df,pwc_son) Ts = lib.adjoint(Kf,pwc_son) Ks = lib.adjoint(Tf,plc_son) Ss = lib.adjoint(Sf,plc_son) op_son_father = lib.createBlockedBoundaryOperator(context,[[Ds,Ts],[-Ks,Ss]]) return (op_father_son,op_son_father)
def solve_bvp(self,wavenumber,rhs): from scipy.sparse.linalg import gmres from bempp.tools import RealOperator self._residuals[wavenumber] = [] def evaluate_residual(res): self._residuals[wavenumber].append(res) n = len(rhs[0]) rhs_dual = (self._mass_matrix*rhs[0].reshape(n,1)).ravel() op_found_in_cache = False if self._use_cache: try: op = self._boundary_operator_cache(wavenumber) op_found_in_cache = True except: pass if not op_found_in_cache: pconsts = self._spaces[0] context = self._context op = (_bempplib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator(context,pconsts,pconsts,pconsts,wavenumber).weakForm()+ .5*self._mass_matrix) #prec = _bempplib.acaOperatorApproximateLuInverse(op,self._aca_lu_epsilon) op = RealOperator(op) #prec = RealOperator(prec) if self._use_cache: self._boundary_operator_cache.insert(wavenumber,op) rhs_dual_real = _np.hstack([_np.real(rhs_dual),_np.imag(rhs_dual)]) sol_real,info = gmres(op,rhs_dual_real,tol=self._gmres_tol,maxiter=self._gmres_max_iter,callback=evaluate_residual) if info != 0: raise Exception('GMRES did not converge for wavenumber '+str(wavenumber)+'.') sol = sol_real[:n]+1j*sol_real[n:] return [sol.ravel()]
def off_diagonal_block_father_son(context, layers, father_id, son_id): """Off-diagonal interaction between two different layers. Returns a tuple of two operators. """ plc_father = layers[father_id]['spaces']['l'] pwc_father = layers[father_id]['spaces']['c'] plc_son = layers[son_id]['spaces']['l'] pwc_son = layers[son_id]['spaces']['c'] kf = layers[father_id]['k'] kappaf = layers[father_id]['kappa'] if father_id == 0: null_00 = lib.createNullOperator(context, plc_son, pwc_father, plc_father, label="Null_00") null_01 = lib.createNullOperator(context, pwc_son, pwc_father, plc_father, label="Null_01") Kf = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, plc_son, plc_father, pwc_father, kf, label="Kf0_" + str(son_id)) Sf = 1. / kappaf * lib.createModifiedHelmholtz3dSingleLayerBoundaryOperator( context, pwc_son, plc_father, pwc_father, kf, label="Sf0_" + str(son_id)) op_father_son = lib.createBlockedBoundaryOperator( context, [[null_00, null_01], [Kf, -Sf]]) Ds = kappaf * lib.createModifiedHelmholtz3dHypersingularBoundaryOperator( context, plc_father, pwc_son, plc_son, kf, label="Ds" + str(son_id) + "_0") Ts = lib.adjoint(Kf, pwc_son) Ks = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, plc_father, plc_son, pwc_son, kf, label="Ks" + str(son_id) + "_0") Ss = lib.adjoint(Sf, plc_son) op_son_father = lib.createBlockedBoundaryOperator( context, [[Ds, Ts], [-Ks, Ss]]) else: Df = kappaf * lib.createModifiedHelmholtz3dHypersingularBoundaryOperator( context, plc_son, pwc_father, plc_father, kf) Tf = lib.createModifiedHelmholtz3dAdjointDoubleLayerBoundaryOperator( context, pwc_son, pwc_father, plc_father, kf) Kf = lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, plc_son, plc_father, pwc_father, kf) Sf = 1. / kappaf * lib.createModifiedHelmholtz3dDoubleLayerBoundaryOperator( context, pwc_son, plc_father, pwc_father, kf) op_father_son = lib.createBlockedBoundaryOperator( context, [[Df, Tf], [-Kf, Sf]]) Ds = lib.adjoint(Df, pwc_son) Ts = lib.adjoint(Kf, pwc_son) Ks = lib.adjoint(Tf, plc_son) Ss = lib.adjoint(Sf, plc_son) op_son_father = lib.createBlockedBoundaryOperator( context, [[Ds, Ts], [-Ks, Ss]]) return (op_father_son, op_son_father)
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]])
options = blib.createAssemblyOptions() 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(
options = blib.createAssemblyOptions() 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)