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)
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 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)