def unitcube_geometry(): N = 3 mesh = UnitCubeMesh(mpi_comm_world(), N, N, N) ffun = dolfin.MeshFunction("size_t", mesh, 2) ffun.set_all(0) fixed.mark(ffun, fixed_marker) free.mark(ffun, free_marker) marker_functions = MarkerFunctions(ffun=ffun) # Fibers V_f = dolfin.VectorFunctionSpace(mesh, "CG", 1) f0 = interpolate(Expression(("1.0", "0.0", "0.0"), degree=1), V_f) s0 = interpolate(Expression(("0.0", "1.0", "0.0"), degree=1), V_f) n0 = interpolate(Expression(("0.0", "0.0", "1.0"), degree=1), V_f) microstructure = Microstructure(f0=f0, s0=s0, n0=n0) geometry = Geometry( mesh=mesh, marker_functions=marker_functions, microstructure=microstructure, ) return geometry
def backward_displacement(self): """ Return the current backward displacement as a function on the original geometry. """ W = dolfin.VectorFunctionSpace(self.U.function_space().mesh(), "CG", 1) u_int = interpolate(self.U, W) u = Function(W) u.vector()[:] = -1 * u_int.vector() return u
def target_solution_rc(args, pde): pde.source = da.Expression( "k*100*exp( (-(x[0]-x0)*(x[0]-x0) -(x[1]-x1)*(x[1]-x1)) / (2*0.01*l) )", k=1, l=1, x0=0.1, x1=0.1, degree=3) source_vec = da.interpolate(pde.source, pde.V) save_solution(args, source_vec, 'opt_fem_f') u = pde.solve_problem_variational_form() dof_data = torch.tensor(u.vector()[:], dtype=torch.float).unsqueeze(0) return dof_data, u, source_vec.vector()[:]
def test_strain(isochoric=True): mesh = dolfin_adjoint.UnitCubeMesh(3, 3, 3) x_dir = dolfin_adjoint.Constant([1.0, 0.0, 0.0]) y_dir = dolfin_adjoint.Constant([0.0, 1.0, 0.0]) V = dolfin.VectorFunctionSpace(mesh, "CG", 2) # u = dolfin_adjoint.Function(V) # Make an incompressible deformation (with J = 1) x_strain = -0.1 y_strain = 1 / (1 + x_strain) - 1 u = dolfin_adjoint.interpolate( dolfin.Expression( ("x_strain * x[0]", "y_strain * x[1]", "0.0"), x_strain=x_strain, y_strain=y_strain, degree=2, ), V, ) x_strain_obs = StrainObservation(mesh=mesh, field=x_dir, isochoric=isochoric, strain_tensor="gradu") assert abs(x_strain_obs(u).vector().get_local()[0] - x_strain) < 1e-12 x_strain_obs = StrainObservation(mesh=mesh, field=x_dir, isochoric=isochoric, strain_tensor="E") assert (abs( x_strain_obs(u).vector().get_local()[0] - 0.5 * ((1 + x_strain)**2 - 1)) < 1e-12) y_strain_obs = StrainObservation(mesh=mesh, field=y_dir, isochoric=isochoric, strain_tensor="gradu") assert abs(y_strain_obs(u).vector().get_local()[0] - y_strain) < 1e-12 y_strain_obs = StrainObservation(mesh=mesh, field=y_dir, isochoric=isochoric, strain_tensor="E") assert (abs( y_strain_obs(u).vector().get_local()[0] - 0.5 * ((1 + y_strain)**2 - 1)) < 1e-12)
def _build_function_space(self): class Exterior(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and (fa.near(x[1], 1) or fa.near(x[0], 1) or fa.near(x[0], 0) or fa.near(x[1], 0)) class Left(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[0], 0) class Right(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[0], 1) class Bottom(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[1], 0) class Top(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[1], 1) class Interior(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and (x[0] > 0.1 and x[0] < 0.9 and x[1] > 0.1 and x[1] < 0.9) self.exteriors_dic = { 'left': Left(), 'right': Right(), 'bottom': Bottom(), 'top': Top() } self.exterior = Exterior() self.interior = Interior() self.V = fa.FunctionSpace(self.mesh, 'P', 1) self.source = da.Expression(("100*sin(2*pi*x[0])"), degree=3) # self.source = da.Expression("k*100*exp( (-(x[0]-x0)*(x[0]-x0) -(x[1]-x1)*(x[1]-x1)) / (2*0.01*l) )", # k=1, l=1, x0=0.9, x1=0.1, degree=3) # self.source = da.Constant(10) self.source = da.interpolate(self.source, self.V) boundary_fn_ext = da.Constant(1.) boundary_fn_int = da.Constant(1.) boundary_bc_ext = da.DirichletBC(self.V, boundary_fn_ext, self.exterior) boundary_bc_int = da.DirichletBC(self.V, boundary_fn_int, self.interior) self.bcs = [boundary_bc_ext, boundary_bc_int]
def map_displacement(u, old_space, new_space, approx, name="mapped displacement"): if approx == "interpolate": # Do we need dolfin-adjoint here or is dolfin enough? u_int = interpolate(project(u, old_space), new_space) # , name=name) elif approx == "project": # Do we need dolfin-adjoint here or is dolfin enough? u_int = project(u, new_space) # , name=name) else: u_int = u return u_int
def move(mesh, u, factor=1.0): """ Move mesh according to some displacement times some factor """ W = dolfin.VectorFunctionSpace(u.function_space().mesh(), "CG", 1) # Use interpolation for now. It is the only thing that makes sense u_int = interpolate(u, W) u0 = Function(W) # arr = factor * numpy_mpi.gather_vector(u_int.vector()) # numpy_mpi.assign_to_vector(u0.vector(), arr) u0.vector()[:] = factor * u_int.vector() V = dolfin.VectorFunctionSpace(mesh, "CG", 1) U = Function(V) U.vector()[:] = u0.vector() # numpy_mpi.assign_to_vector(U.vector(), arr) dolfin.ALE.move(mesh, U) return u0
def test_strain(strains): mesh = dolfin_adjoint.UnitCubeMesh(3, 3, 3) x_dir = dolfin_adjoint.Constant([1.0, 0.0, 0.0]) V = dolfin.VectorFunctionSpace(mesh, "CG", 2) # Make an incompressible deformation (with J = 1) x_strain = -0.1 y_strain = 1 / (1 + x_strain) - 1 u = dolfin_adjoint.interpolate( dolfin.Expression( ("x_strain * x[0]", "y_strain * x[1]", "0.0"), x_strain=x_strain, y_strain=y_strain, degree=2, ), V, ) strain_obs = StrainObservation(mesh=mesh, field=x_dir) model_strain = strain_obs(u).vector().get_local()[0] weight = 0.1 target = OptimizationTarget(strains, strain_obs, weight=weight, collect=False) if np.isscalar(strains): strains = (strains, ) for t, s in zip(target, strains): fun = dolfin.project(t.assign(u), t._V) f = fun.vector().get_local()[0] g = (model_strain - s)**2 assert abs(f - weight * g) < 1e-12 # Nothing is collected for k, v in target.collector.items(): assert len(v) == 0
def unitcube_geometry(): N = 2 mesh = UnitCubeMesh(N, N, N) V_f = dolfin.VectorFunctionSpace(mesh, "CG", 1) l0 = interpolate(dolfin.Expression(("1.0", "0.0", "0.0"), degree=1), V_f) r0 = interpolate(dolfin.Expression(("0.0", "1.0", "0.0"), degree=1), V_f) c0 = interpolate(dolfin.Expression(("0.0", "0.0", "1.0"), degree=1), V_f) crl_basis = CRLBasis(l0=l0, r0=r0, c0=c0) cfun = strain_markers_3d(mesh, 2) ffun = dolfin.MeshFunction("size_t", mesh, 2) ffun.set_all(0) fixed.mark(ffun, fixed_marker) free.mark(ffun, free_marker) marker_functions = MarkerFunctions(ffun=ffun, cfun=cfun) # Fibers f0 = interpolate(dolfin.Expression(("1.0", "0.0", "0.0"), degree=1), V_f) s0 = interpolate(dolfin.Expression(("0.0", "1.0", "0.0"), degree=1), V_f) n0 = interpolate(dolfin.Expression(("0.0", "0.0", "1.0"), degree=1), V_f) microstructure = Microstructure(f0=f0, s0=s0, n0=n0) geometry = Geometry( mesh=mesh, marker_functions=marker_functions, microstructure=microstructure, crl_basis=crl_basis, ) return geometry
# case_flag = 0 runs the default case by # http://www.dolfin-adjoint.org/en/latest/documentation/poisson-mother/poisson-mother.html # change to any other value runs the other case case_flag = 1 x = fa.SpatialCoordinate(mesh) w = da.Expression("sin(pi*x[0])*sin(pi*x[1])", degree=3) V = fa.FunctionSpace(mesh, "CG", 1) W = fa.FunctionSpace(mesh, "DG", 0) # g is the ground truth for source term # f is the control variable if case_flag == 0: g = da.interpolate( da.Expression("1/(1+alpha*4*pow(pi, 4))*w", w=w, alpha=alpha, degree=3), W) f = da.interpolate( da.Expression("1/(1+alpha*4*pow(pi, 4))*w", w=w, alpha=alpha, degree=3), W) else: g = da.interpolate(da.Expression(("sin(2*pi*x[0])"), degree=3), W) f = da.interpolate(da.Expression(("sin(2*pi*x[0])"), degree=3), W) u = da.Function(V, name='State') v = fa.TestFunction(V) F = (fa.inner(fa.grad(u), fa.grad(v)) - f * v) * fa.dx bc = da.DirichletBC(V, 0.0, "on_boundary") da.solve(F == 0, u, bc)
free_marker = 2 free.mark(ffun, free_marker) # Create a cell function (but we are not using it) cfun = dolfin.MeshFunction("size_t", mesh, 3) cfun.set_all(0) # Collect the functions containing the markers marker_functions = pulse.MarkerFunctions(ffun=ffun, cfun=cfun) # Create mictrotructure V_f = dolfin.VectorFunctionSpace(mesh, "CG", 1) # Fibers f0 = interpolate(Expression(("1.0", "0.0", "0.0"), degree=1), V_f) # Sheets s0 = interpolate(Expression(("0.0", "1.0", "0.0"), degree=1), V_f) # Fiber-sheet normal n0 = interpolate(Expression(("0.0", "0.0", "1.0"), degree=1), V_f) # Collect the mictrotructure microstructure = pulse.Microstructure(f0=f0, s0=s0, n0=n0) # Create the geometry geometry = pulse.Geometry( mesh=mesh, marker_functions=marker_functions, microstructure=microstructure, )
def from_parameters(cls, params=None): params = params or {} parameters = cls.default_parameters() parameters.update(params) msh_name = Path("test.msh") create_benchmark_ellipsoid_mesh_gmsh( msh_name, r_short_endo=parameters["r_short_endo"], r_short_epi=parameters["r_short_epi"], r_long_endo=parameters["r_long_endo"], r_long_epi=parameters["r_long_epi"], quota_base=parameters["quota_base"], psize=parameters["mesh_generation"]["psize"], ndiv=parameters["mesh_generation"]["ndiv"], ) geo: HeartGeometry = gmsh2dolfin(msh_name) msh_name.unlink() obj = cls( mesh=geo.mesh, marker_functions=geo.marker_functions, markers=geo.markers, ) obj._parameters = parameters # microstructure mspace = obj._parameters["microstructure"]["function_space"] dolfin.info("Creating microstructure") # coordinate mapping cart2coords_code = obj._compile_cart2coords_code() cart2coords = dolfin.compile_cpp_code(cart2coords_code) cart2coords_expr = dolfin.CompiledExpression( cart2coords.SimpleEllipsoidCart2Coords(), degree=1, ) # local coordinate base localbase_code = obj._compile_localbase_code() localbase = dolfin.compile_cpp_code(localbase_code) localbase_expr = dolfin.CompiledExpression( localbase.SimpleEllipsoidLocalCoords( cart2coords_expr.cpp_object()), degree=1, ) # function space family, degree = mspace.split("_") degree = int(degree) V = dolfin.TensorFunctionSpace(obj.mesh, family, degree, shape=(3, 3)) # microstructure expression alpha_endo = obj._parameters["microstructure"]["alpha_endo"] alpha_epi = obj._parameters["microstructure"]["alpha_epi"] microstructure_code = obj._compile_microstructure_code() microstructure = dolfin.compile_cpp_code(microstructure_code) microstructure_expr = dolfin.CompiledExpression( microstructure.EllipsoidMicrostructure( cart2coords_expr.cpp_object(), localbase_expr.cpp_object(), alpha_epi, alpha_endo, ), degree=1, ) # interpolation W = dolfin.VectorFunctionSpace(obj.mesh, family, degree) microinterp = interpolate(microstructure_expr, V) s0 = project(microinterp[0, :], W) n0 = project(microinterp[1, :], W) f0 = project(microinterp[2, :], W) obj.microstructure = Microstructure(f0=f0, s0=s0, n0=n0) obj.update_xshift() return obj
# Collect boundary conditions bcs = pulse.BoundaryConditions( dirichlet=dirichlet_bc, neumann=neumann_bc, robin=robin_bc, ) # Create the problem problem = pulse.MechanicsProblem(geometry, material, bcs) problem.solve() # Solve the problem pulse.iterate.iterate(problem, (lvp, activation), (1.0, 0.2)) # Get the solution u, p = problem.state.split(deepcopy=True) volume = geometry.cavity_volume(u=u) print(f"Cavity volume = {volume}") # Move mesh accoring to displacement u_int = interpolate(u, dolfin.VectorFunctionSpace(geometry.mesh, "CG", 1)) mesh = Mesh(geometry.mesh) dolfin.ALE.move(mesh, u_int) fig = plot(geometry.mesh, color="red", show=False) fig.add_plot(plot(mesh, show=False)) fig.show()
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()