S0 = mfem.BilinearForm(x0_space) S0.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) S0.Assemble() S0.EliminateEssentialBC(ess_bdr) S0.Finalize() matB0 = B0.SpMat() matBhat = Bhat.SpMat() matSinv = Sinv.SpMat() matS0 = S0.SpMat() # 8. Set up the 1x2 block Least Squares DPG operator, B = [B0 Bhat], # the normal equation operator, A = B^t Sinv B, and # the normal equation right-hand-size, b = B^t Sinv F. B = mfem.BlockOperator(offsets_test, offsets) B.SetBlock(0, 0, matB0) B.SetBlock(0, 1, matBhat) A = mfem.RAPOperator(B, matSinv, B) SinvF = mfem.Vector(s_test) matSinv.Mult(F,SinvF) B.MultTranspose(SinvF, b) # 9. Set up a block-diagonal preconditioner for the 2x2 normal equation # # [ S0^{-1} 0 ] # [ 0 Shat^{-1} ] Shat = (Bhat^T Sinv Bhat) # # corresponding to the primal (x0) and interfacial (xhat) unknowns.
mVarf = mfem.BilinearForm(R_space) bVarf = mfem.MixedBilinearForm(R_space, W_space) mVarf.AddDomainIntegrator(mfem.VectorFEMassIntegrator(k)) mVarf.Assemble() mVarf.Finalize() M = mVarf.SpMat() bVarf.AddDomainIntegrator(mfem.VectorFEDivergenceIntegrator()) bVarf.Assemble() bVarf.Finalize() B = bVarf.SpMat() B *= -1 BT = mfem.Transpose(B) darcyOp = mfem.BlockOperator(block_offsets) darcyOp.SetBlock(0, 0, M) darcyOp.SetBlock(0, 1, BT) darcyOp.SetBlock(1, 0, B) MinvBt = mfem.Transpose(B) Md = mfem.Vector(M.Height()) M.GetDiag(Md) for i in range(Md.Size()): MinvBt.ScaleRow(i, 1 / Md[i]) S = mfem.Mult(B, MinvBt) invM = mfem.DSmoother(M) invS = mfem.GSSmoother(S) invM.iterative_mode = False invS.iterative_mode = False
from scipy.sparse import csr_matrix if len(sys.argv) < 2: import mfem.ser as mfem elif sys.argv[1] == 'par': import mfem.par as mfem smat = csr_matrix([[1,2,3,], [0, 0, 1], [2, 0, 0]]) mmat = mfem.SparseMatrix(smat) offset1 = mfem.intArray([0, 3, 6]) offset2 = mfem.intArray([0, 3, 6]) print('BlockOperator') m = mfem.BlockOperator(offset1, offset2) m.SetBlock(0, 0, mmat) print(m._offsets[0].ToList()) print(m._offsets[1].ToList()) print(m._linked_op) print('BlockOperator') m = mfem.BlockOperator(offset1) m.SetBlock(0, 1, mmat) m.SetDiagonalBlock(1, mmat) print(m._offsets.ToList()) print(m._linked_op) print('BlockDiagonalPreconditioner') m = mfem.BlockDiagonalPreconditioner(offset1) m.SetDiagonalBlock(1, mmat)