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)
Esempio n. 5
0
 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(
Esempio n. 9
0
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)