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 darcyPrec = mfem.BlockDiagonalPreconditioner(block_offsets) darcyPrec.SetDiagonalBlock(0, invM) darcyPrec.SetDiagonalBlock(1, invS) maxIter = 500 rtol = 1e-6 atol = 1e-10 stime = clock() solver = mfem.MINRESSolver() solver.SetAbsTol(atol) solver.SetRelTol(rtol) solver.SetMaxIter(maxIter) solver.SetOperator(darcyOp) solver.SetPreconditioner(darcyPrec) solver.SetPrintLevel(1)
S0inv.SetOperator(matS0) S0inv.SetPrintLevel(-1) S0inv.SetRelTol(prec_rtol) S0inv.SetMaxIter(prec_maxit) Shatinv = mfem.CGSolver() Shatinv.SetOperator(Shat) Shatinv.SetPrintLevel(-1) Shatinv.SetRelTol(prec_rtol) Shatinv.SetMaxIter(prec_maxit) # Disable 'iterative_mode' when using CGSolver (or any IterativeSolver) as # a preconditioner: S0inv.iterative_mode = False Shatinv.iterative_mode = False P = mfem.BlockDiagonalPreconditioner(offsets) P.SetDiagonalBlock(0, S0inv) P.SetDiagonalBlock(1, Shatinv) # 10. Solve the normal equation system using the PCG iterative solver. # Check the weighted norm of residual for the DPG least square problem. # Wrap the primal variable in a GridFunction for visualization purposes. mfem.PCG(A, P, b, x, 1, 200, 1e-12, 0.0) LSres = mfem.Vector(s_test) B.Mult(x, LSres) LSres -= F res = sqrt(matSinv.InnerProduct(LSres, LSres)) print("|| B0*x0 + Bhat*xhat - F ||_{S^-1} = " + str(res))