def test_Min(): """ Test of Min subclass of the Field base class and of the use of set_background_mesh function with a list of fields as input. #* Test OK """ name = "test_Min" model.add(name) rect_vtcs = [geo.Point(np.array(c)) for c in [(-4, -2), (4, -2), (4, 2), (-4, 2)]] rect_ll = geo.LineLoop(rect_vtcs, False) rect_s = geo.PlaneSurface(rect_ll) rect_s.add_gmsh() h1 = msh.MathEvalField("0.1") h2 = msh.MathEvalField("(x*x)+0.02") h1.add_gmsh() h2.add_gmsh() msh.set_background_mesh([h1, h2]) factory.synchronize() model.mesh.generate(2) gmsh.write("%s.msh" % name) os.system("gmsh %s.msh &" % name)
def test_fctn_restrict(): """ Test of the function that has been designed to quickly specify a refinement constraint with a restriction to a given surface. #* Test OK """ name = "test_Restrict_with_fctn" model.add(name) vtcs_1 = [geo.Point(np.array(c)) for c in [(-1, -1), (1, -1), (1, 1), (-1, 1)]] vtcs_2 = [geo.Point(np.array(c)) for c in [(0, 0), (2, 0), (2, 2), (0, 2)]] ll_1 = geo.LineLoop(vtcs_1, explicit=False) ll_2 = geo.LineLoop(vtcs_2, explicit=False) surf_1 = geo.PlaneSurface(ll_1) surf_2 = geo.PlaneSurface(ll_2) surf_1.add_gmsh() surf_2.add_gmsh() f = msh.MathEvalField("0.1") g = msh.MathEvalField("(x-0.25)*(x-0.25)+0.02") h = msh.MathEvalField("(y-0.25)*(y-0.25)+0.02") gr = msh.RestrictField(g, surfaces=[surf_1], curves=surf_1.ext_contour.sides) hr = msh.RestrictField( h, surfaces=[surf_2], curves=surf_2.ext_contour.sides + surf_1.ext_contour.sides ) msh.set_background_mesh([f, gr, hr]) factory.synchronize() model.mesh.generate(2) gmsh.write("%s.msh" % name) os.system("gmsh %s.msh &" % name)
def test_Restrict(): """ Test of the Restrict subclass of the Field base class. #* Test OK! """ name = "test_Restrict" model.add(name) vtcs_1 = [geo.Point(np.array(c)) for c in [(-1, -1), (1, -1), (1, 1), (-1, 1)]] vtcs_2 = [geo.Point(np.array(c)) for c in [(0, 0), (2, 0), (2, 2), (0, 2)]] ll_1 = geo.LineLoop(vtcs_1, explicit=False) ll_2 = geo.LineLoop(vtcs_2, explicit=False) surf_1 = geo.PlaneSurface(ll_1) surf_2 = geo.PlaneSurface(ll_2) surf_1.add_gmsh() surf_2.add_gmsh() f = msh.MathEvalField("0.1") g = msh.MathEvalField("(x-0.25)*(x-0.25)+0.02") h = msh.RestrictField(g, surfaces=[surf_1]) msh.set_background_mesh([f, h]) factory.synchronize() model.mesh.generate(2) gmsh.write("%s.msh" % name) os.system("gmsh %s.msh &" % name)
def test_MathEval(): """ Test of MathEval subclass of the Field base class. #* Test OK """ name = "test_MathEval" model.add(name) rect_vtcs = [geo.Point(np.array(c)) for c in [(-4, -2), (4, -2), (4, 2), (-4, 2)]] rect_ll = geo.LineLoop(rect_vtcs, False) rect_s = geo.PlaneSurface(rect_ll) rect_s.add_gmsh() f = msh.MathEvalField("(Cos(3.14*x) * Sin(3.14*y)+1)*0.1+0.005") f.add_gmsh() # Optional msh.set_background_mesh(f) factory.synchronize() model.mesh.generate(2) gmsh.write("%s.msh" % name) os.system("gmsh %s.msh &" % name)
def test_get_domains_gmsh(plots=False): """ Get subdomains and partition of the boundary from a .msh file. """ name = "test_domains" local_dir = Path(__file__).parent mesh_file = local_dir.joinpath(name + ".msh") gmsh.model.add(name) L_x, L_y = 2.0, 2.0 H = 1.0 vertices = [(0.0, 0.0), (0.0, L_y), (L_x, L_y), (L_x, 0.0)] contour = geo.LineLoop([geo.Point(np.array(c)) for c in vertices], False) surface = geo.PlaneSurface(contour) inclusion_vertices = list() for coord in [ (H / 2, -H / 2, 0.0), (H / 2, H / 2, 0.0), (-H / 2, H / 2, 0.0), (-H / 2, -H / 2, 0.0), ]: vertex = geo.translation(geo.Point((L_x / 2, L_y / 2)), coord) inclusion_vertices.append(vertex) inclusion = geo.PlaneSurface(geo.LineLoop(inclusion_vertices, False)) for s in [surface, inclusion]: s.add_gmsh() factory.synchronize() (stiff_s, ) = geo.surface_bool_cut(surface, inclusion) factory.synchronize() (soft_s, ) = geo.surface_bool_cut(surface, stiff_s) factory.synchronize() domains = { "stiff": geo.PhysicalGroup(stiff_s, 2), "soft": geo.PhysicalGroup(soft_s, 2), } boundaries = { "S": geo.PhysicalGroup(surface.ext_contour.sides[0], 1), "W": geo.PhysicalGroup(surface.ext_contour.sides[1], 1), "N": geo.PhysicalGroup(surface.ext_contour.sides[2], 1), "E": geo.PhysicalGroup(surface.ext_contour.sides[3], 1), } for group in domains.values(): group.add_gmsh() for group in boundaries.values(): group.add_gmsh() charact_field = mesh_tools.MathEvalField("0.05") mesh_tools.set_background_mesh(charact_field) geo.set_gmsh_option("Mesh.SaveAll", 0) model.mesh.generate(1) model.mesh.generate(2) gmsh.model.mesh.removeDuplicateNodes() gmsh.write(str(mesh_file)) E_1, E_2, nu = 1, 3, 0.3 materials = { domains["soft"].tag: mat.Material(E_1, nu, "cp"), domains["stiff"].tag: mat.Material(E_1, nu, "cp"), } test_part = part.FenicsPart.part_from_file(mesh_file, materials, subdomains_import=True) assert test_part.mat_area == approx(L_x * L_y) elem_type = "CG" degree = 2 V = fe.VectorFunctionSpace(test_part.mesh, elem_type, degree) W = fe.FunctionSpace( test_part.mesh, fe.VectorElement(elem_type, test_part.mesh.ufl_cell(), degree, dim=3), ) boundary_conditions = { boundaries["N"].tag: fe.Expression(("x[0]-1", "1"), degree=1), boundaries["S"].tag: fe.Expression(("x[0]-1", "-1"), degree=1), boundaries["E"].tag: fe.Expression(("1", "x[1]-1"), degree=1), boundaries["W"].tag: fe.Expression(("-1", "x[1]-1"), degree=1), } bcs = list() for tag, val in boundary_conditions.items(): bcs.append(fe.DirichletBC(V, val, test_part.facet_regions, tag)) ds = fe.Measure("ds", domain=test_part.mesh, subdomain_data=test_part.facet_regions) v = fe.TestFunctions(V) u = fe.TrialFunctions(V) F = (fe.inner(mat.sigma(test_part.elasticity_tensor, mat.epsilon(u)), mat.epsilon(v)) * fe.dx) a, L = fe.lhs(F), fe.rhs(F) u_sol = fe.Function(V) fe.solve(a == L, u_sol, bcs) strain = fe.project(mat.epsilon(u_sol), W) if plots: import matplotlib.pyplot as plt plt.figure() plot = fe.plot(u_sol) plt.colorbar(plot) plt.figure() plot = fe.plot(strain[0]) plt.colorbar(plot) plt.figure() plot = fe.plot(strain[1]) plt.colorbar(plot) plt.figure() plot = fe.plot(strain[2]) plt.colorbar(plot) plt.show() error = fe.errornorm( strain, fe.Expression(("1", "1", "0"), degree=0), degree_rise=3, mesh=test_part.mesh, ) assert error == approx(0, abs=1e-12) materials = { domains["soft"].tag: mat.Material(E_1, nu, "cp"), domains["stiff"].tag: mat.Material(E_2, nu, "cp"), } test_part = part.FenicsPart.part_from_file(mesh_file, materials, subdomains_import=True) V = fe.VectorFunctionSpace(test_part.mesh, elem_type, degree) W = fe.FunctionSpace( test_part.mesh, fe.VectorElement(elem_type, test_part.mesh.ufl_cell(), degree, dim=3), ) bcs = list() for tag, val in boundary_conditions.items(): bcs.append(fe.DirichletBC(V, val, test_part.facet_regions, tag)) v = fe.TestFunctions(V) u = fe.TrialFunctions(V) F = (fe.inner(mat.sigma(test_part.elasticity_tensor, mat.epsilon(u)), mat.epsilon(v)) * fe.dx) a, L = fe.lhs(F), fe.rhs(F) u_sol = fe.Function(V) fe.solve(a == L, u_sol, bcs) strain = mat.epsilon(u_sol) stress = mat.sigma(test_part.elasticity_tensor, strain) energy = 0.5 * fe.assemble( fe.inner(stress, strain) * fe.dx(test_part.mesh)) energy_abaqus = 12.8788939 assert energy == approx(energy_abaqus, rel=1e-3) geo.reset()
def test_mat_area(): """FenicsPart method global_aera, for 2D parts created from a gmsh mesh and from a FEniCS mesh""" L_x, L_y = 4.0, 5.0 H = 1.0 size = 0.5 rectangle = mshr.Rectangle(fe.Point(0.0, 0), fe.Point(L_x, L_y)) hole = mshr.Rectangle( fe.Point(L_x / 2 - H / 2, L_y / 2 - H / 2), fe.Point(L_x / 2 + H / 2, L_y / 2 + H / 2), ) domain = rectangle - hole domain.set_subdomain(1, rectangle) mesh = mshr.generate_mesh(domain, size) dimensions = np.array(((L_x, 0.0), (0.0, L_y))) material = {"0": mat.Material(1.0, 0.3, "cp")} rect_part = part.FenicsPart( mesh, materials=material, subdomains=None, global_dimensions=dimensions, facet_regions=None, ) assert rect_part.mat_area == (L_x * L_y - H**2) name = "test_mat_area" local_dir = Path(__file__).parent mesh_file = local_dir.joinpath(name + ".msh") gmsh.model.add(name) vertices = [(0.0, 0.0), (0.0, L_y), (L_x, L_y), (L_x, 0.0)] contour = geo.LineLoop([geo.Point(np.array(c)) for c in vertices], False) surface = geo.PlaneSurface(contour) cut_vertices = list() for local_coord in [(H, 0.0, 0.0), (0.0, H, 0.0), (-H, 0.0, 0.0), (0.0, -H, 0.0)]: vertex = geo.translation(contour.vertices[2], np.array(local_coord)) cut_vertices.append(vertex) cut_surface = geo.PlaneSurface(geo.LineLoop(cut_vertices, False)) for s in [surface, cut_surface]: s.add_gmsh() factory.synchronize() (surface, ) = geo.surface_bool_cut(surface, cut_surface) factory.synchronize() for dim_tag in model.getEntities(2): if not dim_tag[1] == surface.tag: model.removeEntities([dim_tag], True) charact_field = mesh_tools.MathEvalField("0.1") mesh_tools.set_background_mesh(charact_field) geo.set_gmsh_option("Mesh.SaveAll", 1) model.mesh.generate(2) gmsh.write(str(mesh_file)) cmd = f"dolfin-convert {mesh_file} {mesh_file.with_suffix('.xml')}" run(cmd, shell=True, check=True) mesh = fe.Mesh(str(mesh_file.with_suffix(".xml"))) dimensions = np.array(((L_x, 0.0), (0.0, L_y))) material = {"0": mat.Material(1.0, 0.3, "cp")} rect_part = part.FenicsPart( mesh, materials=material, subdomains=None, global_dimensions=dimensions, facet_regions=None, ) assert rect_part.mat_area == approx(L_x * L_y - H * H / 2) geo.reset()