Exemple #1
0
    def Mult(self, x, y):
        globals()['max_char_speed'] = 0.;
        num_equation = globals()['num_equation']
        # 1. Create the vector z with the face terms -<F.n(u), [w]>.
        self.A.Mult(x, self.z);

        # 2. Add the element terms.
        # i.  computing the flux approximately as a grid function by interpolating
        #     at the solution nodes.
        # ii. multiplying this grid function by a (constant) mixed bilinear form for
        #     each of the num_equation, computing (F(u), grad(w)) for each equation.

        xmat = mfem.DenseMatrix(x.GetData(), self.vfes.GetNDofs(), num_equation)
        self.GetFlux(xmat, self.flux)

        for k in range(num_equation):
           fk = mfem.Vector(self.flux[k].GetData(), self.dim * self.vfes.GetNDofs())
           o = k * self.vfes.GetNDofs()
           zk = self.z[o: o+self.vfes.GetNDofs()]
           self.Aflux.AddMult(fk, zk)

        # 3. Multiply element-wise by the inverse mass matrices.
        zval = mfem.Vector()
        vdofs = mfem.intArray()
        dof = self.vfes.GetFE(0).GetDof()
        zmat = mfem.DenseMatrix()
        ymat = mfem.DenseMatrix(dof, num_equation)        

        for i in range(self.vfes.GetNE()):
            # Return the vdofs ordered byNODES
            vdofs = mfem.intArray(self.vfes.GetElementVDofs(i))
            self.z.GetSubVector(vdofs, zval)
            zmat.UseExternalData(zval.GetData(), dof, num_equation)
            mfem.Mult(self.Me_inv[i], zmat, ymat);
            y.SetSubVector(vdofs, ymat.GetData())
Exemple #2
0
def make_mask(values, X, Y, Z, mask_start=0, logfile=None):
    '''
    mask for interpolation
    '''
    mask = np.zeros(len(X.flatten()), dtype=int) - 1

    for kk, data in enumerate(values):
        ptx, ret, gfr = data

        xmax = np.max(ptx[:, 0])
        xmin = np.min(ptx[:, 0])
        ymax = np.max(ptx[:, 1])
        ymin = np.min(ptx[:, 1])
        zmax = np.max(ptx[:, 2])
        zmin = np.min(ptx[:, 2])

        i1 = np.logical_and(xmax >= X.flatten(), xmin <= X.flatten())
        i2 = np.logical_and(ymax >= Y.flatten(), ymin <= Y.flatten())
        i3 = np.logical_and(zmax >= Z.flatten(), zmin <= Z.flatten())
        ii = np.logical_and(np.logical_and(i1, i2), i3)

        mesh = gfr.FESpace().GetMesh()

        XX = X.flatten()[ii]
        YY = Y.flatten()[ii]
        ZZ = Z.flatten()[ii]
        size = len(XX)

        m = mfem.DenseMatrix(3, size)
        ptx = np.vstack([XX, YY, ZZ])

        if logfile is not None:
            txt = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
            logfile.write(txt + "\n")
            logfile.write("calling FindPoints : size = " + str(XX.shape) +
                          " " + str(kk + 1) + '/' + str(len(values)) + "\n")

        m.Assign(ptx)
        ips = mfem.IntegrationPointArray()
        elem_ids = mfem.intArray()

        pts_found = mesh.FindPoints(m, elem_ids, ips)

        ii = np.where(ii)[0][np.array(elem_ids.ToList()) != -1]
        mask[ii] = kk + mask_start
        if logfile is not None:
            logfile.write("done\n")

    return mask
Exemple #3
0
    def __init__(self, fespace, alpha, kappa, u):
        mfem.PyTimeDependentOperator.__init__(self, fespace.GetTrueVSize(),
                                              0.0)
        rel_tol = 1e-8
        self.alpha = alpha
        self.kappa = kappa
        self.T = None
        self.K = None
        self.M = None
        self.fespace = fespace

        self.ess_tdof_list = intArray()
        self.Mmat = mfem.SparseMatrix()
        self.Kmat = mfem.SparseMatrix()
        self.M_solver = mfem.CGSolver()
        self.M_prec = mfem.DSmoother()
        self.T_solver = mfem.CGSolver()
        self.T_prec = mfem.DSmoother()
        self.z = mfem.Vector(self.Height())

        self.M = mfem.BilinearForm(fespace)
        self.M.AddDomainIntegrator(mfem.MassIntegrator())
        self.M.Assemble()
        self.M.FormSystemMatrix(self.ess_tdof_list, self.Mmat)

        self.M_solver.iterative_mode = False
        self.M_solver.SetRelTol(rel_tol)
        self.M_solver.SetAbsTol(0.0)
        self.M_solver.SetMaxIter(30)
        self.M_solver.SetPrintLevel(0)
        self.M_solver.SetPreconditioner(self.M_prec)
        self.M_solver.SetOperator(self.Mmat)

        self.T_solver.iterative_mode = False
        self.T_solver.SetRelTol(rel_tol)
        self.T_solver.SetAbsTol(0.0)
        self.T_solver.SetMaxIter(100)
        self.T_solver.SetPrintLevel(0)
        self.T_solver.SetPreconditioner(self.T_prec)

        self.SetParameters(u)
Exemple #4
0
if (mesh.NURBSext):  mesh.SetCurvature(order)

# 4. Define a DG vector finite element space on the mesh. Here, we use
#    Gauss-Lobatto nodal basis because it gives rise to a sparser matrix
#    compared to the default Gauss-Legendre nodal basis.
fec = mfem.DG_FECollection(order, dim, mfem.BasisType.GaussLobatto)
fespace = mfem.FiniteElementSpace(mesh, fec, dim)
print('Number of finite element unknowns: '+ str(fespace.GetVSize()))
print('Assembling:')

# 5. In this example, the Dirichlet boundary conditions are defined by
#    marking boundary attributes 1 and 2 in the marker Array 'dir_bdr'.
#    These b.c. are imposed weakly, by adding the appropriate boundary
#    integrators over the marked 'dir_bdr' to the bilinear and linear forms.
#    With this DG formulation, there are no essential boundary conditions.
ess_tdof_list = intArray()
dir_bdr = intArray(mesh.bdr_attributes.Max())
dir_bdr.Assign(0)
dir_bdr[0] = 1 # boundary attribute 1 is Dirichlet
dir_bdr[1] = 1 # boundary attribute 2 is Dirichlet

# 6. Define the DG solution vector 'x' as a finite element grid function
#    corresponding to fespace. Initialize 'x' using the 'InitDisplacement'
#    function.
x = mfem.GridFunction(fespace) 
init_x = InitDisplacement(dim)
x.ProjectCoefficient(init_x)

# 7. Set up the Lame constants for the two materials. They are defined as
#    piece-wise (with respect to the element attributes) constant
#    coefficients, i.e. type PWConstCoefficient.
Exemple #5
0
mesh.ReorientTetMesh();

#  4. Define a finite element space on the mesh. Here we use the Nedelec
#     finite elements of the specified order.

fec = mfem.ND_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 = intArray();
if mesh.bdr_attributes.Size():
    ess_bdr = intArray(mesh.bdr_attributes.Max())
    ess_bdr = intArray([1]*mesh.bdr_attributes.Max())
    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 (f,phi_i) where f is
#    given by the function f_exact and phi_i are the basis functions in the
#    finite element fespace.

b = mfem.LinearForm(fespace);
f = f_exact()
dd = mfem.VectorFEDomainLFIntegrator(f);
b.AddDomainIntegrator(dd)
b.Assemble();
Exemple #6
0
#   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.
Exemple #7
0
hdiv_coll = mfem.RT_FECollection(order, dim)
l2_coll = mfem.L2_FECollection(order, dim)

R_space = mfem.FiniteElementSpace(mesh, hdiv_coll)
W_space = mfem.FiniteElementSpace(mesh, l2_coll)

dimR = R_space.GetVSize()
dimW = W_space.GetVSize()

print("***********************************************************")
print("dim(R) = " + str(dimR))
print("dim(W) = " + str(dimW))
print("dim(R+W) = " + str(dimR + dimW))
print("***********************************************************")

block_offsets = intArray([0, dimR, dimW])
block_offsets.PartialSum()

k = mfem.ConstantCoefficient(1.0)

fcoeff = fFunc(dim)
fnatcoeff = f_natural()
gcoeff = gFunc()
ucoeff = uFunc_ex(dim)
pcoeff = pFunc_ex()

x = mfem.BlockVector(block_offsets)
rhs = mfem.BlockVector(block_offsets)

fform = mfem.LinearForm()
fform.Update(R_space, rhs.GetBlock(0), 0)
Exemple #8
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)
Exemple #9
0
import sys
import numpy as np
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])

m = mfem.BlockMatrix(offset1, offset2)
m.SetBlock(0, 0, mmat)

print m._offsets
print m._linked_mat

m = mfem.BlockMatrix(offset1)
m.SetBlock(0, 1, mmat)
m.SetBlock(1, 0, mmat)
print m._offsets
print m._linked_mat
Exemple #10
0
def ex19_main(args):
    ref_levels = args.refine
    order = args.order
    visualization = args.visualization
    mu = args.shear_modulus
    newton_rel_tol = args.relative_tolerance
    newton_abs_tol = args.absolute_tolerance
    newton_iter = args.newton_iterations

    parser.print_options(args)

    meshfile = expanduser(join(path, 'data', args.mesh))
    mesh = mfem.Mesh(meshfile, 1, 1)
    dim = mesh.Dimension()

    for lev in range(ref_levels):
        mesh.UniformRefinement()

    #  4. Define the shear modulus for the incompressible Neo-Hookean material
    c_mu = mfem.ConstantCoefficient(mu)

    #  5. Define the finite element spaces for displacement and pressure
    #     (Taylor-Hood elements). By default, the displacement (u/x) is a second
    #     order vector field, while the pressure (p) is a linear scalar function.
    quad_coll = mfem.H1_FECollection(order, dim)
    lin_coll = mfem.H1_FECollection(order - 1, dim)

    R_space = mfem.FiniteElementSpace(mesh, quad_coll, dim,
                                      mfem.Ordering.byVDIM)
    W_space = mfem.FiniteElementSpace(mesh, lin_coll)

    spaces = [R_space, W_space]
    R_size = R_space.GetVSize()
    W_size = W_space.GetVSize()

    #   6. Define the Dirichlet conditions (set to boundary attribute 1 and 2)
    ess_bdr_u = mfem.intArray(R_space.GetMesh().bdr_attributes.Max())
    ess_bdr_p = mfem.intArray(W_space.GetMesh().bdr_attributes.Max())
    ess_bdr_u.Assign(0)
    ess_bdr_u[0] = 1
    ess_bdr_u[1] = 1
    ess_bdr_p.Assign(0)
    ess_bdr = [ess_bdr_u, ess_bdr_p]

    print("***********************************************************")
    print("dim(u) = " + str(R_size))
    print("dim(p) = " + str(W_size))
    print("dim(u+p) = " + str(R_size + W_size))
    print("***********************************************************")

    block_offsets = intArray([0, R_size, W_size])
    block_offsets.PartialSum()

    xp = mfem.BlockVector(block_offsets)

    #  9. Define grid functions for the current configuration, reference
    #     configuration, final deformation, and pressure
    x_gf = mfem.GridFunction(R_space)
    x_ref = mfem.GridFunction(R_space)
    x_def = mfem.GridFunction(R_space)
    p_gf = mfem.GridFunction(W_space)

    x_gf.MakeRef(R_space, xp.GetBlock(0), 0)
    p_gf.MakeRef(W_space, xp.GetBlock(1), 0)

    deform = InitialDeformation(dim)
    refconfig = ReferenceConfiguration(dim)

    x_gf.ProjectCoefficient(deform)
    x_ref.ProjectCoefficient(refconfig)
    p_gf.Assign(0.0)

    #  10. Initialize the incompressible neo-Hookean operator
    oper = RubberOperator(spaces, ess_bdr, block_offsets, newton_rel_tol,
                          newton_abs_tol, newton_iter, mu)
    #  11. Solve the Newton system
    oper.Solve(xp)

    #  12. Compute the final deformation
    mfem.subtract_vector(x_gf, x_ref, x_def)

    #  13. Visualize the results if requested
    if (visualization):
        vis_u = mfem.socketstream("localhost", 19916)
        visualize(vis_u, mesh, x_gf, x_def, "Deformation", True)
        vis_p = mfem.socketstream("localhost", 19916)
        visualize(vis_p, mesh, x_gf, p_gf, "Deformation", True)

    #  14. Save the displaced mesh, the final deformation, and the pressure
    nodes = x_gf
    owns_nodes = 0
    nodes, owns_nodes = mesh.SwapNodes(nodes, owns_nodes)

    mesh.Print('deformed.mesh', 8)
    p_gf.Save('pressure.sol', 8)
    x_def.Save("deformation.sol", 8)
Exemple #11
0
fes = mfem.FiniteElementSpace(mesh, fec)
# Finite element space for a mesh-dim vector quantity (momentum)
dfes = mfem.FiniteElementSpace(mesh, fec, dim, mfem.Ordering.byNODES)
# Finite element space for all variables together (total thermodynamic state)
vfes = mfem.FiniteElementSpace(mesh, fec, num_equation, mfem.Ordering.byNODES)

assert fes.GetOrdering() == mfem.Ordering.byNODES, "Ordering must be byNODES"
print("Number of unknowns: " + str(vfes.GetVSize()))

# 6. Define the initial conditions, save the corresponding mesh and grid
#    functions to a file. This can be opened with GLVis with the -gc option.
#    The solution u has components {density, x-momentum, y-momentum, energy}.
#    These are stored contiguously in the BlockVector u_block.

offsets = [k * vfes.GetNDofs() for k in range(num_equation + 1)]
offsets = mfem.intArray(offsets)
u_block = mfem.BlockVector(offsets)
mom = mfem.GridFunction(dfes, u_block, offsets[1])

#
#  Define coefficient using VecotrPyCoefficient and PyCoefficient
#  A user needs to define EvalValue method
#
u0 = InitialCondition(num_equation)
sol = mfem.GridFunction(vfes, u_block.GetData())
sol.ProjectCoefficient(u0)

mesh.PrintToFile("vortex.mesh", 8)
for k in range(num_equation):
    uk = mfem.GridFunction(fes, u_block.GetBlock(k).GetData())
    sol_name = "vortex-" + str(k) + "-init.gf"
Exemple #12
0
#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.
fec = mfem.H1_FECollection(order, dim)
fespace = mfem.FiniteElementSpace(mesh, fec, dim)

print("Number of finite element unknowns: " + str(fespace.GetTrueVSize()))

# 6. Determine the list of true (i.e. conforming) essential boundary dofs.
#    In this example, the boundary conditions are defined by marking only
#    boundary attribute 1 from the mesh as essential and converting it to a
#    list of true dofs.
ess_tdof_list = intArray()
ess_bdr = intArray([1] + [0] * (mesh.bdr_attributes.Max() - 1))
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list)
# 7. Set up the linear form b(.) which corresponds to the right-hand side of
#    the FEM linear system. In this case, b_i equals the boundary integral
#    of f*phi_i where f represents a "pull down" force on the Neumann part
#    of the boundary and phi_i are the basis functions in the finite element
#    fespace. The force is defined by the VectorArrayCoefficient object f,
#    which is a vector of Coefficient objects. The fact that f is non-zero
#    on boundary attribute 2 is indicated by the use of piece-wise constants
#    coefficient for its last component.
f = mfem.VectorArrayCoefficient(dim)
for i in range(dim - 1):
    f.Set(i, mfem.ConstantCoefficient(0.0))

pull_force = mfem.Vector([0] * mesh.bdr_attributes.Max())
Exemple #13
0
for lev in range(ref_levels):
    mesh.UniformRefinement()

# 5. Define the vector finite element spaces representing the mesh
#    deformation x, the velocity v, and the initial configuration, x_ref.
#    Define also the elastic energy density, w, which is in a discontinuous
#    higher-order space. Since x and v are integrated in time as a system,
#    we group them together in block vector vx, with offsets given by the
#    fe_offset array.
fec = mfem.H1_FECollection(order, dim)
fespace = mfem.FiniteElementSpace(mesh, fec, dim)

fe_size = fespace.GetVSize()
print("Number of velocity/deformation unknowns: " + str(fe_size))
fe_offset = intArray([0, fe_size, 2 * fe_size])

vx = mfem.BlockVector(fe_offset)
x = mfem.GridFunction()
v = mfem.GridFunction()
v.MakeRef(fespace, vx.GetBlock(0), 0)
x.MakeRef(fespace, vx.GetBlock(1), 0)

x_ref = mfem.GridFunction(fespace)
mesh.GetNodes(x_ref)

w_fec = mfem.L2_FECollection(order + 1, dim)
w_fespace = mfem.FiniteElementSpace(mesh, w_fec)
w = mfem.GridFunction(w_fespace)

Exemple #14
0
    
x0_space   = mfem.FiniteElementSpace(mesh, x0_fec)
xhat_space = mfem.FiniteElementSpace(mesh, xhat_fec)
test_space = mfem.FiniteElementSpace(mesh, test_fec)

# 5. Define the block structure of the problem, by creating the offset
#    variables. Also allocate two BlockVector objects to store the solution
#    and rhs.

x0_var = 0;  xhat_var = 1;  NVAR = 2

s0 = x0_space.GetVSize()
s1 = xhat_space.GetVSize()
s_test = test_space.GetVSize()

offsets = mfem.intArray([0, s0, s0+s1])
offsets_test = mfem.intArray([0, s_test])

print('\n'.join(["nNumber of Unknowns", 
                 " Trial space,     X0   : " + str(s0) +
                 " (order " + str(trial_order) + ")",
                 " Interface space, Xhat : " + str(s1) +
                 " (order " + str(trace_order) + ")",
                 " Test space,      Y    : " + str(s_test) +
                 " (order " + str(test_order) + ")"]))
x = mfem.BlockVector(offsets)
b = mfem.BlockVector(offsets)
x.Assign(0.0)

# 6. Set up the linear form F(.) which corresponds to the right-hand side of
#    the FEM linear system, which in this case is (f,phi_i) where f=1.0 and
Exemple #15
0
#     corresponding to fespace. Initialize x with initial guess of zero.
x = mfem.GridFunction(fespace)
x.Assign(0.0)

#  7. Set up the bilinear form a(.,.) on the finite element space
#     corresponding to the Laplacian operator -Delta, by adding the Diffusion
#     and Mass domain integrators.
a = mfem.BilinearForm(fespace)
a.AddDomainIntegrator(mfem.DiffusionIntegrator(one))
a.AddDomainIntegrator(mfem.MassIntegrator(one))

#  8. Assemble the linear system, apply conforming constraints, etc.
a.Assemble()
A = mfem.SparseMatrix()
B = mfem.Vector()
X = mfem.Vector()
empty_tdof_list = mfem.intArray()
a.FormLinearSystem(empty_tdof_list, x, b, A, X, B)

M = mfem.GSSmoother(A)
mfem.PCG(A, M, B, X, 1, 200, 1e-12, 0.0)

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

# 12. Compute and print the L^2 norm of the error.
print("L2 norm of error = " + str(x.ComputeL2Error(sol_coef)))

mesh.PrintToFile('sphere_refined.mesh', 8)
x.SaveToFile('sol.gf', 8)
Exemple #16
0
    def RequestData(self, request, inInfo, outInfo):
        output = dsa.WrapDataObject(vtkUnstructuredGrid.GetData(outInfo))

        import os
        import json
        import mfem.ser as mfem

        _, ext = os.path.splitext(self._filename)
        cwd = os.path.dirname(self._filename)

        if ext == ".mfem_root":
            with open(self._filename) as f:
                root = json.load(f)
                cycle = int(root['dsets']['main']['cycle'])
                mesh_filename = root['dsets']['main']['mesh']['path']
                mesh_filename = format(mesh_filename % cycle)
                mesh_filename = os.path.join(cwd, mesh_filename)
        else:
            mesh_filename = self._filename

        mesh = mfem.Mesh(mesh_filename)
        dim = mesh.SpaceDimension()
        nelem = mesh.GetNE()

        # Points
        mesh_fes = mesh.GetNodalFESpace()
        nodes = mesh.GetNodes()
        if nodes is None:
            nnode = mesh.GetNV()
            points = np.array(mesh.GetVertexArray())
        else:
            nnode = mesh.GetNodes().Size() // dim
            points = np.array(mesh.GetNodes().GetDataArray())
            if mesh_fes.GetOrdering() == 0:
                points = points.reshape((dim, nnode)).T
            elif mesh_fes.GetOrdering() == 1:
                points = points.reshape((nnode, dim))
            else:
                raise NotImplementedError
        if dim == 1:
            points = np.hstack([points, np.zeros((nnode, 2))])
        elif dim == 2:
            points = np.hstack([points, np.zeros((nnode, 1))])
        output.SetPoints(points)

        # Cells
        cell_attributes = np.empty((nelem), dtype=int)
        cell_types = np.empty((nelem), dtype=np.ubyte)
        cell_offsets = np.empty((nelem), dtype=int)
        cell_conn = []

        offset = 0
        if nodes is None:
            for i in range(nelem):
                v = mesh.GetElementVertices(i)
                geom = mesh.GetElementBaseGeometry(i)
                perm = VTKGeometry_VertexPermutation[geom]
                if perm: v = [v[i] for i in perm]
                cell_types[i] = VTKGeometry_Map[geom]
                cell_offsets[i] = offset
                offset += len(v) + 1
                cell_conn.append(len(v))
                cell_conn.extend(v)
        else:
            for i in range(nelem):
                v = mesh_fes.GetElementDofs(i)
                geom = mesh.GetElementBaseGeometry(i)
                order = mesh_fes.GetOrder(i)
                if order == 1:
                    perm = VTKGeometry_VertexPermutation[geom]
                    cell_types[i] = VTKGeometry_Map[geom]
                elif order == 2:
                    perm = VTKGeometry_QuadraticVertexPermutation[geom]
                    cell_types[i] = VTKGeometry_QuadraticMap[geom]
                else:
                    # FIXME: this needs more work...
                    # See CreateVTKMesh for reading VTK Lagrange elements and
                    # invert that process to create VTK Lagrange elements.
                    # https://github.com/mfem/mfem/blob/master/mesh/mesh_readers.cpp
                    parray = mfem.intArray()
                    mfem.CreateVTKElementConnectivity(parray, geom, order)
                    perm = parray.ToList()
                    cell_types[i] = VTKGeometry_HighOrderMap[geom]
                if perm: v = [v[i] for i in perm]
                cell_offsets[i] = offset
                offset += len(v) + 1
                cell_conn.append(len(v))
                cell_conn.extend(v)

        output.SetCells(cell_types, cell_offsets, cell_conn)

        # Attributes
        for i in range(nelem):
            cell_attributes[i] = mesh.GetAttribute(i)
        output.CellData.append(cell_attributes, "attribute")

        # Read fields
        if ext == ".mfem_root":
            fields = root['dsets']['main']['fields']
            for name, prop in fields.items():
                filename = prop['path']
                filename = format(filename % cycle)
                filename = os.path.join(cwd, filename)
                gf = mfem.GridFunction(mesh, filename)
                gf_fes = gf.FESpace()
                gf_vdim = gf.VectorDim()
                gf_nnode = gf_fes.GetNDofs() // gf_vdim
                gf_nelem = gf_fes.GetNBE()
                data = np.array(gf.GetDataArray())
                if prop['tags']['assoc'] == 'nodes':
                    assert gf_nnode == nnode, "Mesh and grid function have different number of nodes"
                    if gf_fes.GetOrdering() == 0:
                        data = data.reshape((gf_vdim, gf_nnode)).T
                    elif gf_fes.GetOrdering() == 1:
                        data = data.reshape((gf_nnode, gf_vdim))
                    else:
                        raise NotImplementedError
                    output.PointData.append(data, name)
                elif prop['tags']['assoc'] == 'elements':
                    assert gf_nelem == nelem, "Mesh and grid function have different number of elements"
                    if gf_fes.GetOrdering() == 0:
                        data = data.reshape((gf_vdim, gf_nelem)).T
                    elif gf_fes.GetOrdering() == 1:
                        data = data.reshape((gf_nelem, gf_vdim))
                    else:
                        raise NotImplementedError
                    output.CellData.append(data, name)
                else:
                    raise NotImplementedError("assoc: '{}'".format(
                        prop['tags']['assoc']))

        return 1