Beispiel #1
0
    def __init__(self, spaces, mass, offsets):
        self.pressure_mass = mass
        self.block_offsets = offsets
        super(JacobianPreconditioner, self).__init__(offsets[2])

        self.gamma = 0.00001

        # The mass matrix and preconditioner do not change every Newton cycle, so we
        # only need to define them once
        self.mass_prec = mfem.GSSmoother(mass)

        mass_pcg = mfem.CGSolver()
        mass_pcg.SetRelTol(1e-12)
        mass_pcg.SetAbsTol(1e-12)
        mass_pcg.SetMaxIter(200)
        mass_pcg.SetPrintLevel(0)
        mass_pcg.SetPreconditioner(self.mass_prec)
        mass_pcg.SetOperator(self.pressure_mass)
        mass_pcg.iterative_mode = False
        self.mass_pcg = mass_pcg

        # The stiffness matrix does change every Newton cycle, so we will define it
        # during SetOperator
        self.stiff_pcg = None
        self.stiff_prec = None
Beispiel #2
0
    def SetOperator(self, op):
        self.jacobian = mfem.Opr2BlockOpr(op)
        if (self.stiff_prec == None):
            # Initialize the stiffness preconditioner and solver
            stiff_prec_gs = mfem.GSSmoother()
            self.stiff_prec = stiff_prec_gs

            stiff_pcg_iter = mfem.GMRESSolver()
            stiff_pcg_iter.SetRelTol(1e-8)
            stiff_pcg_iter.SetAbsTol(1e-8)
            stiff_pcg_iter.SetMaxIter(200)
            stiff_pcg_iter.SetPrintLevel(0)
            stiff_pcg_iter.SetPreconditioner(self.stiff_prec)
            stiff_pcg_iter.iterative_mode = False

            self.stiff_pcg = stiff_pcg_iter

        #  At each Newton cycle, compute the new stiffness preconditioner by updating
        #  the iterative solver which, in turn, updates its preconditioner
        self.stiff_pcg.SetOperator(self.jacobian.GetBlock(0, 0))
Beispiel #3
0
a.AddBdrFaceIntegrator(mfem.DGElasticityIntegrator(lambda_c, mu_c, alpha, kappa), dir_bdr)
print('matrix ...')
a.Assemble()

A = mfem.SparseMatrix()
B = mfem.Vector()
X = mfem.Vector()
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B);
print('...done')

A.PrintInfo(sys.stdout)

# 11. Define a simple symmetric Gauss-Seidel preconditioner and use it to
#     solve the system Ax=b with PCG for the symmetric formulation, or GMRES
#     for the non-symmetric.
M = mfem.GSSmoother(A)
rtol = 1e-6
if (alpha == -1.0):
    mfem.PCG(A, M, B, X, 3, 5000, rtol*rtol, 0.0)
else:
    mfem.GMRES(A, M, B, X, 3, 5000, 50, rtol*rtol, 0.0)

# 12. Recover the solution as a finite element grid function 'x'.
a.RecoverFEMSolution(X, b, x)

# 13. Use the DG solution space as the mesh nodal space. This allows us to
#     save the displaced mesh as a curved DG mesh.
mesh.SetNodalFESpace(fespace)
reference_nodes = mfem.Vector()
if (visualization):
    reference_nodes.Assign(mesh.GetNodes())
Beispiel #4
0
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

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)
Beispiel #5
0
def run(order=1,
        static_cond=False,
        meshfile=def_meshfile,
        visualization=False):

    mesh = mfem.Mesh(meshfile, 1, 1)
    dim = mesh.Dimension()

    #   3. Refine the mesh to increase the resolution. In this example we do
    #      'ref_levels' of uniform refinement. We choose 'ref_levels' to be the
    #      largest number that gives a final mesh with no more than 50,000
    #      elements.
    ref_levels = int(np.floor(
        np.log(50000. / mesh.GetNE()) / np.log(2.) / dim))
    for x in range(ref_levels):
        mesh.UniformRefinement()

    #5. Define a finite element space on the mesh. Here we use vector finite
    #   elements, i.e. dim copies of a scalar finite element space. The vector
    #   dimension is specified by the last argument of the FiniteElementSpace
    #   constructor. For NURBS meshes, we use the (degree elevated) NURBS space
    #   associated with the mesh nodes.
    if order > 0:
        fec = mfem.H1_FECollection(order, dim)
    elif mesh.GetNodes():
        fec = mesh.GetNodes().OwnFEC()
        prinr("Using isoparametric FEs: " + str(fec.Name()))
    else:
        order = 1
        fec = mfem.H1_FECollection(order, dim)
    fespace = mfem.FiniteElementSpace(mesh, fec)
    print('Number of finite element unknowns: ' + str(fespace.GetTrueVSize()))
    # 5. Determine the list of true (i.e. conforming) essential boundary dofs.
    #    In this example, the boundary conditions are defined by marking all
    #    the boundary attributes from the mesh as essential (Dirichlet) and
    #    converting them to a list of true dofs.
    ess_tdof_list = mfem.intArray()
    if mesh.bdr_attributes.Size() > 0:
        ess_bdr = mfem.intArray([1] * mesh.bdr_attributes.Max())
        ess_bdr = mfem.intArray(mesh.bdr_attributes.Max())
        ess_bdr.Assign(1)
        fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list)
    #6. Set up the linear form b(.) which corresponds to the right-hand side of
    #   the FEM linear system, which in this case is (1,phi_i) where phi_i are
    #   the basis functions in the finite element fespace.
    b = mfem.LinearForm(fespace)
    one = mfem.ConstantCoefficient(1.0)
    b.AddDomainIntegrator(mfem.DomainLFIntegrator(one))
    b.Assemble()
    #7. Define the solution vector x as a finite element grid function
    #   corresponding to fespace. Initialize x with initial guess of zero,
    #   which satisfies the boundary conditions.
    x = mfem.GridFunction(fespace)
    x.Assign(0.0)
    #8. Set up the bilinear form a(.,.) on the finite element space
    #   corresponding to the Laplacian operator -Delta, by adding the Diffusion
    #   domain integrator.
    a = mfem.BilinearForm(fespace)
    a.AddDomainIntegrator(mfem.DiffusionIntegrator(one))
    #9. Assemble the bilinear form and the corresponding linear system,
    #   applying any necessary transformations such as: eliminating boundary
    #   conditions, applying conforming constraints for non-conforming AMR,
    #   static condensation, etc.
    if static_cond: a.EnableStaticCondensation()
    a.Assemble()

    A = mfem.OperatorPtr()
    B = mfem.Vector()
    X = mfem.Vector()

    a.FormLinearSystem(ess_tdof_list, x, b, A, X, B)
    print("Size of linear system: " + str(A.Height()))

    # 10. Solve
    AA = mfem.OperatorHandle2SparseMatrix(A)
    M = mfem.GSSmoother(AA)
    mfem.PCG(AA, M, B, X, 1, 200, 1e-12, 0.0)

    # 11. Recover the solution as a finite element grid function.
    a.RecoverFEMSolution(X, b, x)
    # 12. Save the refined mesh and the solution. This output can be viewed later
    #     using GLVis: "glvis -m refined.mesh -g sol.gf".
    mesh.Print('refined.mesh', 8)
    x.Save('sol.gf', 8)

    #13. Send the solution by socket to a GLVis server.
    if (visualization):
        sol_sock = mfem.socketstream("localhost", 19916)
        sol_sock.precision(8)
        sol_sock.send_solution(mesh, x)