mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() # 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 ode_solver_type == 1: ode_solver = BackwardEulerSolver() elif ode_solver_type == 2: ode_solver = mfem.SDIRK23Solver(2) elif ode_solver_type == 3: ode_solver = mfem.SDIRK33Solver() elif ode_solver_type == 11: ode_solver = ForwardEulerSolver() elif ode_solver_type == 12: ode_solver = mfem.RK2Solver(0.5) elif ode_solver_type == 13: ode_solver = mfem.RK3SSPSolver() elif ode_solver_type == 14: ode_solver = mfem.RK4Solver() elif ode_solver_type == 22: ode_solver = mfem.ImplicitMidpointSolver() elif ode_solver_type == 23: ode_solver = mfem.SDIRK23Solver() elif ode_solver_type == 24: ode_solver = mfem.SDIRK34Solver() else: print("Unknown ODE solver type: " + str(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(ser_ref_levels): 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. pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh for x in range(par_ref_levels):
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)