def generate_local_block_operator(context, my_proc, graph, layers, alpha):
    """Generate the local system matrix.
    """
    def copy_to_structure(brow, bcol, block, structure):
        """Small helper routine to copy a 2x2 block at the right position into a structure
        """
        structure.setBlock(2 * brow, 2 * bcol, block.block(0, 0))
        structure.setBlock(2 * brow, 2 * bcol + 1, block.block(0, 1))
        structure.setBlock(2 * brow + 1, 2 * bcol, block.block(1, 0))
        structure.setBlock(2 * brow + 1, 2 * bcol + 1, block.block(1, 1))

    nproc = Epetra.PyComm().NumProc()

    process_map = procmap(blockmap(graph), nproc)
    scheduler = partition(process_map)

    # Initialize structure of local system matrix

    nb = process_map.shape[0]  # Block-dimension of global matrix
    structure = lib.createBlockedOperatorStructure(context)
    for i in range(nb):
        plc = layers[i]['spaces']['l']
        pwc = layers[i]['spaces']['c']
        null_op_00 = lib.createNullOperator(context, plc, pwc, plc)
        null_op_11 = lib.createNullOperator(context, pwc, plc, pwc)
        structure.setBlock(2 * i, 2 * i, null_op_00)
        structure.setBlock(2 * i + 1, 2 * i + 1, null_op_11)

    # Iterate through elements from scheduler and fill up local system matrix

    if not scheduler.has_key(my_proc + 1):
        A = lib.createBlockedBoundaryOperator(context, structure)
        return A

    for elem in scheduler[my_proc + 1]:
        if elem[0] == elem[1]:
            # Diagonal Block
            block = diagonal_block(context, layers, elem[0], alpha)
            copy_to_structure(elem[0], elem[1], block, structure)
        else:
            if layers[elem[0]]['sons'].count(elem[1]):
                # elem[1] is a son of elem[0]
                block1, block2 = off_diagonal_block_father_son(
                    context, layers, elem[0], elem[1])
            else:
                # elements must be on the same level
                block1, block2 = off_diagonal_block_same_layer(
                    context, layers, elem[0], elem[1])
            copy_to_structure(elem[0], elem[1], block1, structure)
            copy_to_structure(elem[1], elem[0], block2, structure)
    A = lib.createBlockedBoundaryOperator(context, structure)
    return A
def generate_local_block_operator(context,my_proc,graph,layers,alpha):
    """Generate the local system matrix.
    """

    def copy_to_structure(brow,bcol,block,structure):
        """Small helper routine to copy a 2x2 block at the right position into a structure
        """
        structure.setBlock(2*brow,2*bcol,block.block(0,0))
        structure.setBlock(2*brow,2*bcol+1,block.block(0,1))
        structure.setBlock(2*brow+1,2*bcol,block.block(1,0))
        structure.setBlock(2*brow+1,2*bcol+1,block.block(1,1))

    nproc = Epetra.PyComm().NumProc()

    process_map = procmap(blockmap(graph),nproc)
    scheduler = partition(process_map)

    # Initialize structure of local system matrix

    nb = process_map.shape[0] # Block-dimension of global matrix
    structure = lib.createBlockedOperatorStructure(context)
    for i in range(nb):
        plc = layers[i]['spaces']['l']
        pwc = layers[i]['spaces']['c']
        null_op_00 = lib.createNullOperator(context,plc,pwc,plc)
        null_op_11 = lib.createNullOperator(context,pwc,plc,pwc)
        structure.setBlock(2*i,2*i,null_op_00)
        structure.setBlock(2*i+1,2*i+1,null_op_11)

    # Iterate through elements from scheduler and fill up local system matrix

    if not scheduler.has_key(my_proc+1):
        A = lib.createBlockedBoundaryOperator(context,structure)
        return A
        
    for elem in scheduler[my_proc+1]:
        if elem[0]==elem[1]:
            # Diagonal Block
            block = diagonal_block(context,layers,elem[0],alpha)
            copy_to_structure(elem[0],elem[1],block,structure)
        else:
            if layers[elem[0]]['sons'].count(elem[1]):
                # elem[1] is a son of elem[0]
                block1,block2 = off_diagonal_block_father_son(context,layers,elem[0],elem[1])
            else:
                # elements must be on the same level
                block1,block2 = off_diagonal_block_same_layer(context,layers,elem[0],elem[1])
            copy_to_structure(elem[0],elem[1],block1,structure)
            copy_to_structure(elem[1],elem[0],block2,structure)
    A = lib.createBlockedBoundaryOperator(context,structure)
    return A
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)
Exemple #4
0
def createList(Context, Shape=(0, 0)):

    context, spaces, doms = Context

    Mat = []
    for ii in range(Shape[0]):
        Mat.append([ 0 for jj in range(Shape[1])])

    MyZeros_symbol = deepcopy(Mat)

    row = 0
    MyZeros = deepcopy(Mat) ## could be better with append instead of assign
    for dom in doms:
        myname = dom['name']
        for my in dom['union']:
            Ni = len(dom['union'])
            itest = abs(my)
            test = spaces[itest]
            col = 0
            for odom in doms:
                oname = odom['name']
                for other in odom['union']:
                    ni = len(odom['union'])
                    itrial = abs(other)
                    trial = spaces[itrial]

                    sz = 'Z_' + myname+oname + '_{}{}'.format(itest, itrial)
                    Zd = createNullOperator(
                        context, trial, trial, test, sz)

                    # print(row, col, 'd-'+sz, ni)
                    MyZeros_symbol[row][col] = sz
                    MyZeros[row][col] = Zd

                    # print(row, col+ni, 'n-'+sz)
                    MyZeros_symbol[row][col+ni] = sz
                    MyZeros[row][col+ni] = Zd

                    # print(row+Ni, col, 'n-'+sz, ni)
                    MyZeros_symbol[row+Ni][col] = sz
                    MyZeros[row+Ni][col] = Zd

                    # print(row+Ni, col+ni, 'd-'+sz)
                    MyZeros_symbol[row+Ni][col+ni] = sz
                    MyZeros[row+Ni][col+ni] = Zd

                    col += 1
                col += ni
            row += 1
        row += Ni
    return MyZeros_symbol, MyZeros
Exemple #5
0
def createList(Context, Shape=(0, 0)):

    context, spaces, doms = Context

    Mat = []
    for ii in range(Shape[0]):
        Mat.append([0 for jj in range(Shape[1])])

    MyZeros_symbol = deepcopy(Mat)

    row = 0
    MyZeros = deepcopy(Mat)  ## could be better with append instead of assign
    for dom in doms:
        myname = dom['name']
        for my in dom['union']:
            Ni = len(dom['union'])
            itest = abs(my)
            test = spaces[itest]
            col = 0
            for odom in doms:
                oname = odom['name']
                for other in odom['union']:
                    ni = len(odom['union'])
                    itrial = abs(other)
                    trial = spaces[itrial]

                    sz = 'Z_' + myname + oname + '_{}{}'.format(itest, itrial)
                    Zd = createNullOperator(context, trial, trial, test, sz)

                    # print(row, col, 'd-'+sz, ni)
                    MyZeros_symbol[row][col] = sz
                    MyZeros[row][col] = Zd

                    # print(row, col+ni, 'n-'+sz)
                    MyZeros_symbol[row][col + ni] = sz
                    MyZeros[row][col + ni] = Zd

                    # print(row+Ni, col, 'n-'+sz, ni)
                    MyZeros_symbol[row + Ni][col] = sz
                    MyZeros[row + Ni][col] = Zd

                    # print(row+Ni, col+ni, 'd-'+sz)
                    MyZeros_symbol[row + Ni][col + ni] = sz
                    MyZeros[row + Ni][col + ni] = Zd

                    col += 1
                col += ni
            row += 1
        row += Ni
    return MyZeros_symbol, MyZeros
def generate_local_block_operator(context,my_proc,process_map,layers,impedance):
    """Generate the local system matrix.
    """

    nproc = Epetra.PyComm().NumProc()
    total_time = 0

    scheduler = process_map.scheduler

    # Initialize structure of local system matrix

    nb = process_map.block_matrix_layout.shape[0] # Block-dimension of global matrix
    structure = lib.createBlockedOperatorStructure(context)
    for i in range(nb):
        plc = layers[i]['spaces']['l']
        pwc = layers[i]['spaces']['c']
        null_op_00 = lib.createNullOperator(context,plc,pwc,plc)
        null_op_11 = lib.createNullOperator(context,pwc,plc,pwc)
        structure.setBlock(2*i,2*i,null_op_00)
        structure.setBlock(2*i+1,2*i+1,null_op_11)

    # Iterate through elements from scheduler and fill up local system matrix

    if not scheduler.has_key(my_proc+1):
        A = lib.createBlockedBoundaryOperator(context,structure)
        return (A,total_time)
        
    for elem in scheduler[my_proc+1]:
        if elem[0]==elem[1]:
            # Diagonal Block
            print "Generating block element [%(e0)i,%(e1)i] on process %(my_proc)i... " % {'e0':elem[0],
                                                                                        'e1':elem[1],
                                                                                        'my_proc':my_proc}

            tstart=time()
            block = diagonal_block(context,layers,elem[0],impedance)
            block.weakForm()
            copy_to_structure(elem[0],elem[1],block,structure)
            tend=time()
            print "Block element [%(e0)i,%(e1)i] on process %(my_proc)i generated in %(tval)f seconds" % {'e0':elem[0],
                                                                                                          'e1':elem[1],
                                                                                                          'my_proc':my_proc,
                                                                                                          'tval':tend-tstart}
            total_time +=tend-tstart
        else:
            print "Generating block elements [%(e0)i,%(e1)i] and [%(e1)i,%(e0)i] on process %(my_proc)i... " % {'e0':elem[0],
                                                                                                           'e1':elem[1],
                                                                                                           'my_proc':my_proc}
            tstart=time()
            if layers[elem[0]]['sons'].count(elem[1]):
                # elem[1] is a son of elem[0]
                block1,block2 = off_diagonal_block_father_son(context,layers,elem[0],elem[1])
            else:
                # elements must be on the same level
                block1,block2 = off_diagonal_block_same_layer(context,layers,elem[0],elem[1])
            block1.weakForm()
            block2.weakForm()
            copy_to_structure(elem[0],elem[1],block1,structure)
            copy_to_structure(elem[1],elem[0],block2,structure)
            tend = time()
            print "Block elements [%(e0)i,%(e1)i] and [%(e1)i,%(e0)i] on process %(my_proc)i generated in %(tval)f seconds " % {'e0':elem[0],
                                                                                                                                'e1':elem[1],
                                                                                                                                'my_proc':my_proc,
                                                                                                                                'tval':tend-tstart
                                                                                                                                }
            total_time +=tend-tstart

    A = lib.createBlockedBoundaryOperator(context,structure)
    return (A,total_time)
def generate_local_block_operator(context, my_proc, process_map, layers,
                                  impedance):
    """Generate the local system matrix.
    """

    nproc = Epetra.PyComm().NumProc()
    total_time = 0

    scheduler = process_map.scheduler

    # Initialize structure of local system matrix

    nb = process_map.block_matrix_layout.shape[
        0]  # Block-dimension of global matrix
    structure = lib.createBlockedOperatorStructure(context)
    for i in range(nb):
        plc = layers[i]['spaces']['l']
        pwc = layers[i]['spaces']['c']
        null_op_00 = lib.createNullOperator(context, plc, pwc, plc)
        null_op_11 = lib.createNullOperator(context, pwc, plc, pwc)
        structure.setBlock(2 * i, 2 * i, null_op_00)
        structure.setBlock(2 * i + 1, 2 * i + 1, null_op_11)

    # Iterate through elements from scheduler and fill up local system matrix

    if not scheduler.has_key(my_proc + 1):
        A = lib.createBlockedBoundaryOperator(context, structure)
        return (A, total_time)

    for elem in scheduler[my_proc + 1]:
        if elem[0] == elem[1]:
            # Diagonal Block
            print "Generating block element [%(e0)i,%(e1)i] on process %(my_proc)i... " % {
                'e0': elem[0],
                'e1': elem[1],
                'my_proc': my_proc
            }

            tstart = time()
            block = diagonal_block(context, layers, elem[0], impedance)
            block.weakForm()
            copy_to_structure(elem[0], elem[1], block, structure)
            tend = time()
            print "Block element [%(e0)i,%(e1)i] on process %(my_proc)i generated in %(tval)f seconds" % {
                'e0': elem[0],
                'e1': elem[1],
                'my_proc': my_proc,
                'tval': tend - tstart
            }
            total_time += tend - tstart
        else:
            print "Generating block elements [%(e0)i,%(e1)i] and [%(e1)i,%(e0)i] on process %(my_proc)i... " % {
                'e0': elem[0],
                'e1': elem[1],
                'my_proc': my_proc
            }
            tstart = time()
            if layers[elem[0]]['sons'].count(elem[1]):
                # elem[1] is a son of elem[0]
                block1, block2 = off_diagonal_block_father_son(
                    context, layers, elem[0], elem[1])
            else:
                # elements must be on the same level
                block1, block2 = off_diagonal_block_same_layer(
                    context, layers, elem[0], elem[1])
            block1.weakForm()
            block2.weakForm()
            copy_to_structure(elem[0], elem[1], block1, structure)
            copy_to_structure(elem[1], elem[0], block2, structure)
            tend = time()
            print "Block elements [%(e0)i,%(e1)i] and [%(e1)i,%(e0)i] on process %(my_proc)i generated in %(tval)f seconds " % {
                'e0': elem[0],
                'e1': elem[1],
                'my_proc': my_proc,
                'tval': tend - tstart
            }
            total_time += tend - tstart

    A = lib.createBlockedBoundaryOperator(context, structure)
    return (A, total_time)
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)