def solve(self, update_operator=True): engine = self.engine phys_target = self.get_phys() phys_range = self.get_phys_range() engine.access_idx = 0 name0 = phys_target[0].dep_vars[0] r_x = engine.r_x[engine.r_ifes(name0)] if len(phys_target[0].dep_vars) > 1: name1 = phys_target[0].dep_vars[1] dr_x = engine.r_x[engine.r_ifes(name1)] do_vector = True else: do_vector = False import mfem.par as mfem pfes_s = r_x.ParFESpace() pmesh = pfes_s.GetParMesh() filt_gf = mfem.ParGridFunction(pfes_s) # run heat solver if self.gui.solver_type == "heat flow": t_param = self.gui.heat_flow_t dx = mfem.dist_solver.AvgElementSize(pmesh) ds = mfem.dist_solver.HeatDistanceSolver(t_param * dx * dx) ds.smooth_steps = 0 ds.vis_glvis = False ls_coeff = mfem.GridFunctionCoefficient(r_x) filt_gf.ProjectCoefficient(ls_coeff) ls_filt_coeff = mfem.GridFunctionCoefficient(filt_gf) ds.ComputeScalarDistance(ls_filt_coeff, r_x) if do_vector: ds.ComputeVectorDistance(ls_filt_coeff, dr_x) else: p = self.gui.p_lap_p newton_iter = self.gui.p_lap_iter ds = mfem.dist_solver.PLapDistanceSolver(p, newton_iter) ls_coeff = mfem.GridFunctionCoefficient(r_x) filt_gf.ProjectCoefficient(ls_coeff) ls_filt_coeff = mfem.GridFunctionCoefficient(filt_gf) ds.print_level = self.gui.log_level ds.ComputeScalarDistance(ls_filt_coeff, r_x) if do_vector: ds.ComputeVectorDistance(ls_filt_coeff, dr_x) return True '''
def SetParameters(self, u): u_alpha_gf = mfem.ParGridFunction(self.fespace) u_alpha_gf.SetFromTrueDofs(u) for i in range(u_alpha_gf.Size()): u_alpha_gf[i] = self.kappa + self.alpha * u_alpha_gf[i] self.K = mfem.ParBilinearForm(self.fespace) u_coeff = mfem.GridFunctionCoefficient(u_alpha_gf) self.K.AddDomainIntegrator(mfem.DiffusionIntegrator(u_coeff)) self.K.Assemble(0) self.K.FormSystemMatrix(self.ess_tdof_list, self.Kmat) self.T = None
mfem.BoundaryFlowIntegrator(inflow, velocity, -1.0, -0.5)) m.Assemble() m.Finalize() skip_zeros = 0 k.Assemble(skip_zeros) k.Finalize(skip_zeros) b.Assemble() M = m.ParallelAssemble() K = k.ParallelAssemble() B = b.ParallelAssemble() # 7. Define the initial conditions, save the corresponding grid function to # a file u = mfem.ParGridFunction(fes) u.ProjectCoefficient(u0) U = u.GetTrueDofs() smyid = '{:0>6d}'.format(myid) mesh_name = "ex9-mesh." + smyid sol_name = "ex9-init." + smyid pmesh.Print(mesh_name, 8) u.Save(sol_name, 8) class FE_Evolution(mfem.PyTimeDependentOperator): def __init__(self, M, K, b): mfem.PyTimeDependentOperator.__init__(self, M.Height()) self.M_prec = mfem.HypreSmoother()
# the Laplace problem -\Delta u = 1. We don't assemble the discrete # problem yet, this will be done in the inner loop. a = mfem.ParBilinearForm(fespace) b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) bdr = BdrCoefficient() rhs = RhsCoefficient() integ = mfem.DiffusionIntegrator(one) a.AddDomainIntegrator(integ) b.AddDomainIntegrator(mfem.DomainLFIntegrator(rhs)) # 8. The solution vector x and the associated finite element grid function # will be maintained over the AMR iterations. x = mfem.ParGridFunction(fespace) # 9. Connect to GLVis. if visualization: sout = mfem.socketstream("localhost", 19916) sout.precision(8) # 10. As in Example 6p, we set up a Zienkiewicz-Zhu estimator that will be # used to obtain element error indicators. The integrator needs to # provide the method ComputeElementFlux. We supply an L2 space for the # discontinuous flux and an H(div) space for the smoothed flux. flux_fec = mfem.L2_FECollection(order, dim) flux_fes = mfem.ParFiniteElementSpace(pmesh, flux_fec, sdim) smooth_flux_fec = mfem.RT_FECollection(order - 1, dim) smooth_flux_fes = mfem.ParFiniteElementSpace(pmesh, smooth_flux_fec) estimator = mfem.L2ZienkiewiczZhuEstimator(integ, x, flux_fes, smooth_flux_fes)
"nNumber of Unknowns", " Trial space, X0 : " + str(glob_true_s0) + " (order " + str(trial_order) + ")", " Interface space, Xhat : " + str(glob_true_s1) + " (order " + str(trace_order) + ")", " Test space, Y : " + str(glob_true_s_test) + " (order " + str(test_order) + ")" ])) # 7. 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 # phi_i are the basis functions in the test finite element fespace. one = mfem.ConstantCoefficient(1.0) F = mfem.ParLinearForm(test_space) F.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) F.Assemble() x0 = mfem.ParGridFunction(x0_space) x0.Assign(0.0) # 8. Set up the mixed bilinear form for the primal trial unknowns, B0, # the mixed bilinear form for the interfacial unknowns, Bhat, # the inverse stiffness matrix on the discontinuous test space, Sinv, # and the stiffness matrix on the continuous trial space, S0. ess_bdr = mfem.intArray(pmesh.bdr_attributes.Max()) ess_bdr.Assign(1) ess_dof = mfem.intArray() x0_space.GetEssentialVDofs(ess_bdr, ess_dof) B0 = mfem.ParMixedBilinearForm(x0_space, test_space) B0.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) B0.Assemble() B0.EliminateEssentialBCFromTrialDofs(ess_dof, x0, F)
trueX.Assign(0.0) solver.Mult(trueRhs, trueX) solve_time = time.clock() - stime if verbose: if solver.GetConverged(): print("MINRES converged in " + str(solver.GetNumIterations()) + " iterations with a residual norm of " + str(solver.GetFinalNorm())) else: print("MINRES did not converge in " + str(solver.GetNumIterations()) + " iterations. Residual norm is " + str(solver.GetFinalNorm())) print("MINRES solver took " + str(solve_time) + "s.") u = mfem.ParGridFunction() p = mfem.ParGridFunction() u.MakeRef(R_space, x.GetBlock(0), 0) p.MakeRef(W_space, x.GetBlock(1), 0) u.Distribute(trueX.GetBlock(0)) p.Distribute(trueX.GetBlock(1)) order_quad = max(2, 2 * order + 1) irs = [mfem.IntRules.Get(i, order_quad) for i in range(mfem.Geometry.NumGeom)] err_u = u.ComputeL2Error(ucoeff, irs) norm_u = mfem.ComputeGlobalLpNorm(2, ucoeff, pmesh, irs) err_p = p.ComputeL2Error(pcoeff, irs) norm_p = mfem.ComputeGlobalLpNorm(2, pcoeff, pmesh, irs) if verbose:
fec = mfem.H1_FECollection(order, dim) fespace = mfem.ParFiniteElementSpace(pmesh, fec, dim) glob_size = fespace.GlobalTrueVSize() if (myid == 0): print('Number of velocity/deformation unknowns: ' + str(glob_size)) true_size = fespace.TrueVSize() true_offset = mfem.intArray(3) true_offset[0] = 0 true_offset[1] = true_size true_offset[2] = 2 * true_size vx = mfem.BlockVector(true_offset) v_gf = mfem.ParGridFunction(fespace) x_gf = mfem.ParGridFunction(fespace) x_ref = mfem.ParGridFunction(fespace) pmesh.GetNodes(x_ref) w_fec = mfem.L2_FECollection(order + 1, dim) w_fespace = mfem.ParFiniteElementSpace(pmesh, w_fec) w_gf = mfem.ParGridFunction(w_fespace) # 8. Set the initial conditions for v_gf, x_gf and vx, and define the # boundary conditions on a beam-like mesh (see description above). class InitialVelocity(mfem.VectorPyCoefficient): def EvalValue(self, x): dim = len(x)
def ex19_main(args): ser_ref_levels = args.refine_serial par_ref_levels = args.refine_parallel 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 if myid == 0: parser.print_options(args) meshfile = expanduser(join(path, 'data', args.mesh)) mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() for lev in range(ser_ref_levels): mesh.UniformRefinement() pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh for lev in range(par_ref_levels): pmesh.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.ParFiniteElementSpace(pmesh, quad_coll, dim, mfem.Ordering.byVDIM) W_space = mfem.ParFiniteElementSpace(pmesh, lin_coll) spaces = [R_space, W_space] glob_R_size = R_space.GlobalTrueVSize() glob_W_size = W_space.GlobalTrueVSize() # 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] if myid == 0: print("***********************************************************") print("dim(u) = " + str(glob_R_size)) print("dim(p) = " + str(glob_W_size)) print("dim(u+p) = " + str(glob_R_size + glob_W_size)) print("***********************************************************") block_offsets = intArray([0, R_space.TrueVSize(), W_space.TrueVSize()]) 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.ParGridFunction(R_space) x_ref = mfem.ParGridFunction(R_space) x_def = mfem.ParGridFunction(R_space) p_gf = mfem.ParGridFunction(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) # 12. Set up the block solution vectors x_gf.GetTrueDofs(xp.GetBlock(0)) p_gf.GetTrueDofs(xp.GetBlock(1)) # 13. Initialize the incompressible neo-Hookean operator oper = RubberOperator(spaces, ess_bdr, block_offsets, newton_rel_tol, newton_abs_tol, newton_iter, mu) # 14. Solve the Newton system oper.Solve(xp) # 15. Distribute the shared degrees of freedom x_gf.Distribute(xp.GetBlock(0)) p_gf.Distribute(xp.GetBlock(1)) # 16. Compute the final deformation mfem.subtract_vector(x_gf, x_ref, x_def) # 17. Visualize the results if requested if (visualization): vis_u = mfem.socketstream("localhost", 19916) visualize(vis_u, pmesh, x_gf, x_def, "Deformation", True) MPI.COMM_WORLD.Barrier() vis_p = mfem.socketstream("localhost", 19916) visualize(vis_p, pmesh, 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 = pmesh.SwapNodes(nodes, owns_nodes) smyid = '.' + '{:0>6d}'.format(myid) pmesh.PrintToFile('deformed.mesh' + smyid, 8) p_gf.SaveToFile('pressure.sol' + smyid, 8) x_def.SaveToFile("deformation.sol" + smyid, 8)
def run(order = 1, static_cond = False, meshfile = def_meshfile, visualization = False, use_strumpack = False): mesh = mfem.Mesh(meshfile, 1,1) dim = mesh.Dimension() ref_levels = int(np.floor(np.log(10000./mesh.GetNE())/np.log(2.)/dim)) for x in range(ref_levels): mesh.UniformRefinement(); mesh.ReorientTetMesh(); pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh par_ref_levels = 2 for l in range(par_ref_levels): pmesh.UniformRefinement(); if order > 0: fec = mfem.H1_FECollection(order, dim) elif mesh.GetNodes(): fec = mesh.GetNodes().OwnFEC() print( "Using isoparametric FEs: " + str(fec.Name())); else: order = 1 fec = mfem.H1_FECollection(order, dim) fespace =mfem.ParFiniteElementSpace(pmesh, fec) fe_size = fespace.GlobalTrueVSize() if (myid == 0): print('Number of finite element unknowns: '+ str(fe_size)) ess_tdof_list = mfem.intArray() if pmesh.bdr_attributes.Size()>0: ess_bdr = mfem.intArray(pmesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # the basis functions in the finite element fespace. b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble(); x = mfem.ParGridFunction(fespace); x.Assign(0.0) a = mfem.ParBilinearForm(fespace); a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) if static_cond: a.EnableStaticCondensation() a.Assemble(); A = mfem.HypreParMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) if (myid == 0): print("Size of linear system: " + str(x.Size())) print("Size of linear system: " + str(A.GetGlobalNumRows())) if use_strumpack: import mfem.par.strumpack as strmpk Arow = strmpk.STRUMPACKRowLocMatrix(A) args = ["--sp_hss_min_sep_size", "128", "--sp_enable_hss"] strumpack = strmpk.STRUMPACKSolver(args, MPI.COMM_WORLD) strumpack.SetPrintFactorStatistics(True) strumpack.SetPrintSolveStatistics(False) strumpack.SetKrylovSolver(strmpk.KrylovSolver_DIRECT); strumpack.SetReorderingStrategy(strmpk.ReorderingStrategy_METIS) strumpack.SetMC64Job(strmpk.MC64Job_NONE) # strumpack.SetSymmetricPattern(True) strumpack.SetOperator(Arow) strumpack.SetFromCommandLine() strumpack.Mult(B, X); else: amg = mfem.HypreBoomerAMG(A) cg = mfem.CGSolver(MPI.COMM_WORLD) cg.SetRelTol(1e-12) cg.SetMaxIter(200) cg.SetPrintLevel(1) cg.SetPreconditioner(amg) cg.SetOperator(A) cg.Mult(B, X); a.RecoverFEMSolution(X, b, x) smyid = '{:0>6d}'.format(myid) mesh_name = "mesh."+smyid sol_name = "sol."+smyid pmesh.Print(mesh_name, 8) x.Save(sol_name, 8)
def run(order = 1, static_cond = False, meshfile = def_meshfile, visualization = False): mesh = mfem.Mesh(meshfile, 1,1) dim = mesh.Dimension() ref_levels = int(np.floor(np.log(10000./mesh.GetNE())/np.log(2.)/dim)) for x in range(ref_levels): mesh.UniformRefinement(); mesh.ReorientTetMesh(); pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh par_ref_levels = 2 for l in range(par_ref_levels): pmesh.UniformRefinement(); 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.ParFiniteElementSpace(pmesh, fec) fe_size = fespace.GlobalTrueVSize() if (myid == 0): print('Number of finite element unknowns: '+ str(fe_size)) ess_tdof_list = mfem.intArray() if pmesh.bdr_attributes.Size()>0: ess_bdr = mfem.intArray(pmesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # the basis functions in the finite element fespace. b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble(); x = mfem.ParGridFunction(fespace); x.Assign(0.0) a = mfem.ParBilinearForm(fespace); a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) if static_cond: a.EnableStaticCondensation() a.Assemble(); A = mfem.HypreParMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) if (myid == 0): print("Size of linear system: " + str(x.Size())) print("Size of linear system: " + str(A.GetGlobalNumRows())) amg = mfem.HypreBoomerAMG(A) pcg = mfem.HyprePCG(A) pcg.SetTol(1e-12) pcg.SetMaxIter(200) pcg.SetPrintLevel(2) pcg.SetPreconditioner(amg) pcg.Mult(B, X); a.RecoverFEMSolution(X, b, x) smyid = '{:0>6d}'.format(myid) mesh_name = "mesh."+smyid sol_name = "sol."+smyid pmesh.PrintToFile(mesh_name, 8) x.SaveToFile(sol_name, 8)
# 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 = mfem.intArray() dir_bdr = mfem.intArray(pmesh.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.ParGridFunction(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. lamb = mfem.Vector(pmesh.attributes.Max()) # lambda is not possible in python lamb.Assign(1.0) lamb[0] = 50. lambda_c = mfem.PWConstCoefficient(lamb) mu = mfem.Vector(pmesh.attributes.Max()) mu.Assign(1.0) mu[0] = 50.0 mu_c = mfem.PWConstCoefficient(mu)
solver.SetPrintLevel(1) trueX.Assign(0.0) solver.Mult(trueRhs, trueX) solve_time = clock() - stime if verbose: if solver.GetConverged(): print("MINRES converged in " + str(solver.GetNumIterations()) + " iterations with a residual norm of " + str(solver.GetFinalNorm())) else: print("MINRES did not converge in " + str(solver.GetNumIterations()) + " iterations. Residual norm is " + str(solver.GetFinalNorm())) print("MINRES solver took " + str(solve_time) + "s.") u = mfem.ParGridFunction(); p = mfem.ParGridFunction() u.MakeRef(R_space, x.GetBlock(0), 0) p.MakeRef(W_space, x.GetBlock(1), 0) u.Distribute(trueX.GetBlock(0)) p.Distribute(trueX.GetBlock(1)) order_quad = max(2, 2*order+1); irs = [mfem.IntRules.Get(i, order_quad) for i in range(mfem.Geometry.NumGeom)] err_u = u.ComputeL2Error(ucoeff, irs); norm_u = mfem.ComputeGlobalLpNorm(2, ucoeff, pmesh, irs) err_p = p.ComputeL2Error(pcoeff, irs); norm_p = mfem.ComputeGlobalLpNorm(2, pcoeff, pmesh, irs); if verbose:
assert fes.GetOrdering() == mfem.Ordering.byNODES, "Ordering must be byNODES" glob_size = vfes.GlobalTrueVSize(); if myid==0: print("Number of unknowns: " + str(glob_size)) # 8. 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) # Momentum grid function on dfes for visualization. mom = mfem.ParGridFunction(dfes, u_block, offsets[1]) # Initialize the state. u0 = InitialCondition(num_equation) sol = mfem.ParGridFunction(vfes, u_block.GetData()) sol.ProjectCoefficient(u0) smyid = '{:0>6d}'.format(myid) pmesh.PrintToFile("vortex-mesh."+smyid, 8) for k in range(num_equation): uk = mfem.ParGridFunction(fes, u_block.GetBlock(k).GetData()) sol_name = "vortex-" + str(k) + "-init."+smyid uk.SaveToFile(sol_name, 8) # 9. Set up the nonlinear form corresponding to the DG discretization of the # flux divergence, and assemble the corresponding mass matrix.
def initialize(self, inMeshObj=None, inMeshFile=None): # 2. Problem initialization self.parser = ArgParser(description='Based on MFEM Ex16p') self.parser.add_argument('-m', '--mesh', default='beam-tet.mesh', action='store', type=str, help='Mesh file to use.') self.parser.add_argument('-rs', '--refine-serial', action='store', default=1, type=int, help="Number of times to refine the mesh \ uniformly in serial") self.parser.add_argument('-rp', '--refine-parallel', action='store', default=0, type=int, help="Number of times to refine the mesh \ uniformly in parallel") self.parser.add_argument('-o', '--order', action='store', default=1, type=int, help="Finite element order (polynomial \ degree)") self.parser.add_argument( '-s', '--ode-solver', action='store', default=3, type=int, help='\n'.join([ "ODE solver: 1 - Backward Euler, 2 - SDIRK2, \ 3 - SDIRK3", "\t\t 11 - Forward Euler, \ 12 - RK2, 13 - RK3 SSP, 14 - RK4." ])) self.parser.add_argument('-t', '--t-final', action='store', default=20., type=float, help="Final time; start time is 0.") self.parser.add_argument("-dt", "--time-step", action='store', default=5e-3, type=float, help="Time step.") self.parser.add_argument("-v", "--viscosity", action='store', default=0.00, type=float, help="Viscosity coefficient.") self.parser.add_argument('-L', '--lmbda', action='store', default=1.e0, type=float, help='Lambda of Hooks law') self.parser.add_argument('-mu', '--shear-modulus', action='store', default=1.e0, type=float, help='Shear modulus for Hooks law') self.parser.add_argument('-rho', '--density', action='store', default=1.0, type=float, help='mass density') self.parser.add_argument('-vis', '--visualization', action='store_true', help='Enable GLVis visualization') self.parser.add_argument('-vs', '--visualization-steps', action='store', default=25, type=int, help="Visualize every n-th timestep.") args = self.parser.parse_args() self.ser_ref_levels = args.refine_serial self.par_ref_levels = args.refine_parallel self.order = args.order self.dt = args.time_step self.visc = args.viscosity self.t_final = args.t_final self.lmbda = args.lmbda self.mu = args.shear_modulus self.rho = args.density self.visualization = args.visualization self.ti = 1 self.vis_steps = args.visualization_steps self.ode_solver_type = args.ode_solver self.t = 0.0 self.last_step = False if self.myId == 0: self.parser.print_options(args) # 3. Reading mesh if inMeshObj is None: self.meshFile = inMeshFile if self.meshFile is None: self.meshFile = args.mesh self.mesh = mfem.Mesh(self.meshFile, 1, 1) else: self.mesh = inMeshObj self.dim = self.mesh.Dimension() print("Mesh dimension: %d" % self.dim) print("Number of vertices in the mesh: %d " % self.mesh.GetNV()) print("Number of elements in the mesh: %d " % self.mesh.GetNE()) # 4. Define the ODE solver used for time integration. # Several implicit singly diagonal implicit # Runge-Kutta (SDIRK) methods, as well as # explicit Runge-Kutta methods are available. if self.ode_solver_type == 1: self.ode_solver = BackwardEulerSolver() elif self.ode_solver_type == 2: self.ode_solver = mfem.SDIRK23Solver(2) elif self.ode_solver_type == 3: self.ode_solver = mfem.SDIRK33Solver() elif self.ode_solver_type == 11: self.ode_solver = ForwardEulerSolver() elif self.ode_solver_type == 12: self.ode_solver = mfem.RK2Solver(0.5) elif self.ode_solver_type == 13: self.ode_solver = mfem.RK3SSPSolver() elif self.ode_solver_type == 14: self.ode_solver = mfem.RK4Solver() elif self.ode_solver_type == 22: self.ode_solver = mfem.ImplicitMidpointSolver() elif self.ode_solver_type == 23: self.ode_solver = mfem.SDIRK23Solver() elif self.ode_solver_type == 24: self.ode_solver = mfem.SDIRK34Solver() else: print("Unknown ODE solver type: " + str(self.ode_solver_type)) exit # 5. Refine the mesh in serial to increase the # resolution. In this example we do # 'ser_ref_levels' of uniform refinement, where # 'ser_ref_levels' is a command-line parameter. for lev in range(self.ser_ref_levels): self.mesh.UniformRefinement() # 6. Define a parallel mesh by a partitioning of # the serial mesh. Refine this mesh further # in parallel to increase the resolution. Once the # parallel mesh is defined, the serial mesh can # be deleted. self.pmesh = mfem.ParMesh(MPI.COMM_WORLD, self.mesh) for lev in range(self.par_ref_levels): self.pmesh.UniformRefinement() # 7. Define the vector finite element space # representing the current and the # initial temperature, u_ref. self.fe_coll = mfem.H1_FECollection(self.order, self.dim) self.fespace = mfem.ParFiniteElementSpace(self.pmesh, self.fe_coll, self.dim) self.fe_size = self.fespace.GlobalTrueVSize() if self.myId == 0: print("FE Number of unknowns: " + str(self.fe_size)) true_size = self.fespace.TrueVSize() self.true_offset = mfem.intArray(3) self.true_offset[0] = 0 self.true_offset[1] = true_size self.true_offset[2] = 2 * true_size self.vx = mfem.BlockVector(self.true_offset) self.v_gf = mfem.ParGridFunction(self.fespace) self.v_gfbnd = mfem.ParGridFunction(self.fespace) self.x_gf = mfem.ParGridFunction(self.fespace) self.x_gfbnd = mfem.ParGridFunction(self.fespace) self.x_ref = mfem.ParGridFunction(self.fespace) self.pmesh.GetNodes(self.x_ref) # 8. Set the initial conditions for u. #self.velo = InitialVelocity(self.dim) self.velo = velBCs(self.dim) #self.deform = InitialDeformation(self.dim) self.deform = defBCs(self.dim) self.v_gf.ProjectCoefficient(self.velo) self.v_gfbnd.ProjectCoefficient(self.velo) self.x_gf.ProjectCoefficient(self.deform) self.x_gfbnd.ProjectCoefficient(self.deform) #self.v_gf.GetTrueDofs(self.vx.GetBlock(0)); #self.x_gf.GetTrueDofs(self.vx.GetBlock(1)); # setup boundary-conditions self.xess_bdr = mfem.intArray( self.fespace.GetMesh().bdr_attributes.Max()) self.xess_bdr.Assign(0) self.xess_bdr[0] = 1 self.xess_bdr[1] = 1 self.xess_tdof_list = intArray() self.fespace.GetEssentialTrueDofs(self.xess_bdr, self.xess_tdof_list) #print('True x essential BCs are') #self.xess_tdof_list.Print() self.vess_bdr = mfem.intArray( self.fespace.GetMesh().bdr_attributes.Max()) self.vess_bdr.Assign(0) self.vess_bdr[0] = 1 self.vess_bdr[1] = 1 self.vess_tdof_list = intArray() self.fespace.GetEssentialTrueDofs(self.vess_bdr, self.vess_tdof_list) #print('True v essential BCs are') #self.vess_tdof_list.Print() # 9. Initialize the stiffness operator self.oper = StiffnessOperator(self.fespace, self.lmbda, self.mu, self.rho, self.visc, self.vess_tdof_list, self.vess_bdr, self.xess_tdof_list, self.xess_bdr, self.v_gfbnd, self.x_gfbnd, self.deform, self.velo, self.vx) # 10. Setting up file output self.smyid = '{:0>2d}'.format(self.myId) # initializing ode solver self.ode_solver.Init(self.oper)