def _copy(self, u=None, factor=1.0): """ Return a copy of this geometry and attach a moved mesh according to the provided displacement. If no displacement is provided this will just return a copy of the original geometry. """ new_mesh = Mesh(self.mesh) if u is not None: U = move(new_mesh, u, factor) else: U = u marker_functions_ = {} for dim, fun in ((0, "vfun"), (1, "efun"), (2, "ffun"), (3, "cfun")): f_old = getattr(self, fun) if f_old is None: continue f = dolfin.MeshFunction("size_t", new_mesh, dim, new_mesh.domains()) f.set_values(f_old.array()) marker_functions_[fun] = f marker_functions = MarkerFunctions(**marker_functions_) microstructure_ = {} for field in ("f0", "s0", "n0"): v0 = getattr(self, field) if v0 is None: continue v = map_vector_field(v0, new_mesh, U) microstructure_[field] = v microstructure = Microstructure(**microstructure_) crl_basis_ = {} for basis in ("c0", "r0", "l0"): v0 = getattr(self, basis) if v0 is None: continue v = map_vector_field(v0, new_mesh, U) crl_basis_[basis] = v crl_basis = CRLBasis(**crl_basis_) return dict( mesh=new_mesh, markers=self.markers, marker_functions=marker_functions, microstructure=microstructure, crl_basis=crl_basis, )
# Make Dirichlet boundary conditions def dirichlet_bc(W): V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0) return DirichletBC(V, Constant((0.0, 0.0, 0.0)), fixed) # Make Neumann boundary conditions neumann_bc = pulse.NeumannBC(traction=Constant(0.0), marker=free_marker) # Collect Boundary Conditions bcs = pulse.BoundaryConditions(dirichlet=(dirichlet_bc,), neumann=(neumann_bc,)) # Create problem problem = pulse.MechanicsProblem(geometry, material, bcs) # Solve problem pulse.iterate.iterate(problem, activation, 0.1) # Get displacement and hydrostatic pressure u, p = problem.state.split(deepcopy=True) V = dolfin.VectorFunctionSpace(mesh, "CG", 1) u_int = interpolate(u, V) new_mesh = Mesh(mesh) dolfin.ALE.move(new_mesh, u_int) fig = plot(mesh, show=False) fig.add_plot(plot(new_mesh, color="red", show=False)) fig.show()
def gmsh2dolfin(msh_file): msh = meshio.gmsh.read(msh_file) vertex_mesh = create_mesh(msh, "vertex") line_mesh = create_mesh(msh, "line") triangle_mesh = create_mesh(msh, "triangle") tetra_mesh = create_mesh(msh, "tetra") vertex_mesh_name = Path("vertex_mesh.xdmf") meshio.write(vertex_mesh_name, vertex_mesh) line_mesh_name = Path("line_mesh.xdmf") meshio.write(line_mesh_name, line_mesh) triangle_mesh_name = Path("triangle_mesh.xdmf") meshio.write(triangle_mesh_name, triangle_mesh) tetra_mesh_name = Path("mesh.xdmf") meshio.write( tetra_mesh_name, tetra_mesh, ) mesh = Mesh() with dolfin.XDMFFile(tetra_mesh_name.as_posix()) as infile: infile.read(mesh) cfun = dolfin.MeshFunction("size_t", mesh, 3) read_meshfunction(tetra_mesh_name, cfun) tetra_mesh_name.unlink() tetra_mesh_name.with_suffix(".h5").unlink() ffun_val = dolfin.MeshValueCollection("size_t", mesh, 2) read_meshfunction(triangle_mesh_name, ffun_val) ffun = dolfin.MeshFunction("size_t", mesh, ffun_val) for value in ffun_val.values(): mesh.domains().set_marker(value, 2) ffun.array()[ffun.array() == max(ffun.array())] = 0 triangle_mesh_name.unlink() triangle_mesh_name.with_suffix(".h5").unlink() efun_val = dolfin.MeshValueCollection("size_t", mesh, 1) read_meshfunction(line_mesh_name, efun_val) efun = dolfin.MeshFunction("size_t", mesh, efun_val) efun.array()[efun.array() == max(efun.array())] = 0 line_mesh_name.unlink() line_mesh_name.with_suffix(".h5").unlink() vfun_val = dolfin.MeshValueCollection("size_t", mesh, 0) read_meshfunction(vertex_mesh_name, vfun_val) vfun = dolfin.MeshFunction("size_t", mesh, vfun_val) vfun.array()[vfun.array() == max(vfun.array())] = 0 vertex_mesh_name.unlink() vertex_mesh_name.with_suffix(".h5").unlink() markers = msh.field_data marker_functions = MarkerFunctions(vfun=vfun, efun=efun, ffun=ffun, cfun=cfun) geo = HeartGeometry( mesh=mesh, markers=markers, marker_functions=marker_functions, ) return geo
# Example on how to load your data if it is currently in xml format import json import dolfin from fenics_plotly import plot import pulse try: from dolfin_adjoint import Constant, DirichletBC, Function, Mesh, interpolate except ImportError: from dolfin import Mesh, Function, Constant, DirichletBC, interpolate # Mesh mesh = Mesh(pulse.utils.mpi_comm_world(), "data/mesh.xml") # Marker functions facet_function = dolfin.MeshFunction("size_t", mesh, "data/facet_function.xml") marker_functions = pulse.MarkerFunctions(ffun=facet_function) # Markers with open("data/markers.json", "r") as f: markers = json.load(f) # Fiber fiber_element = dolfin.VectorElement( family="Quadrature", cell=mesh.ufl_cell(), degree=4, quad_scheme="default",
def load_geometry_from_h5( h5name, h5group="", include_sheets=True, comm=mpi_comm_world(), ): """Load geometry and other mesh data from a h5file to an object. If the file contains muliple fiber fields you can spefify the angles, and if the file contais sheets and cross-sheets this can also be included :param str h5name: Name of the h5file :param str h5group: The group within the file :param bool include_sheets: Include sheets and cross-sheets :returns: An object with geometry data :rtype: object """ h5name = Path(h5name) logger.info("\nLoad mesh from h5") # Set default groups ggroup = f"{h5group}/geometry" mgroup = f"{ggroup}/mesh" lgroup = f"{h5group}/local basis functions" fgroup = f"{h5group}/microstructure/" if not h5name.is_file(): raise IOError(f"File {h5name} does not exist") # Check that the given file contains # the geometry in the given h5group if not io_utils.check_h5group(h5name, mgroup, delete=False, comm=comm): msg = ("Warning!\nGroup: '{}' does not exist in file:" "\n{}").format( mgroup, h5name, ) with h5py.File(h5name) as h: keys = h.keys() msg += f"\nPossible values for the h5group are {keys}" raise IOError(msg) # Create a dummy object for easy parsing class Geometry(object): pass geo = Geometry() with dolfin.HDF5File(comm, h5name.as_posix(), "r") as h5file: # Load mesh mesh = Mesh(comm) io_utils.read_h5file(h5file, mesh, mgroup, True) geo.mesh = mesh # Get mesh functions for dim, attr in enumerate(["vfun", "efun", "ffun", "cfun"]): if dim > get_geometric_dimension(mesh): setattr(geo, attr, None) continue dgroup = f"{ggroup}/mesh/meshfunction_{dim}" mf = dolfin.MeshFunction("size_t", mesh, dim, mesh.domains()) if h5file.has_dataset(dgroup): io_utils.read_h5file(h5file, mf, dgroup) setattr(geo, attr, mf) load_local_basis(h5file, lgroup, mesh, geo) load_microstructure(h5file, fgroup, mesh, geo, include_sheets) # Load the boundary markers markers = load_markers(h5file, mesh, ggroup, dgroup) geo.markers = markers origmeshgroup = f"{h5group}/original_geometry" if h5file.has_dataset(origmeshgroup): original_mesh = Mesh(comm) io_utils.read_h5file(h5file, original_mesh, origmeshgroup, True) setattr(geo, "original_geometry", original_mesh) for attr in [ "f0", "s0", "n0", "r0", "c0", "l0", "cfun", "vfun", "efun", "ffun" ]: if not hasattr(geo, attr): setattr(geo, attr, None) return geo
bcs = pulse.BoundaryConditions(dirichlet=(dirichlet_bc, ), neumann=(neumann_bc, )) # Create problem problem = pulse.MechanicsProblem(geometry, material, bcs) # Solve problem problem.solve() # Get displacement and hydrostatic pressure u, p = problem.state.split(deepcopy=True) point = np.array([10.0, 0.5, 1.0]) disp = np.zeros(3) u.eval(disp, point) print(("Get z-position of point ({}): {:.4f} mm" "").format( ", ".join(["{:.1f}".format(p) for p in point]), point[2] + disp[2], ), ) V = dolfin.VectorFunctionSpace(geometry.mesh, "CG", 1) u_int = interpolate(u, V) mesh = Mesh(geometry.mesh) dolfin.ALE.move(mesh, u_int) fig = plot(geometry.mesh, show=False) fig.add_plot(plot(mesh, color="red", show=False)) fig.show()