def generate_function_spaces(self, order=1, use_periodic=False): r""" Generates the finite-element function spaces used with topological dimension :math:`d` set by variable ``self.top_dim``. :param order: order :math:`k` of the shape function, currently only supported are Lagrange :math:`P_1` elements. :param use_periodic: use periodic boundaries along lateral boundary (currently not supported). :type use_periodic: bool The element shape-functions available from this method are : * ``self.Q`` -- :math:`\mathcal{H}^k(\Omega)` * ``self.Q3`` -- :math:`[\mathcal{H}^k(\Omega)]^3` * ``self.V`` -- :math:`[\mathcal{H}^k(\Omega)]^d` formed using :func:`~dolfin.functions.functionspace.VectorFunctionSpace` * ``self.T`` -- :math:`[\mathcal{H}^k(\Omega)]^{d \times d}` formed using :func:`~dolfin.functions.functionspace.TensorFunctionSpace` """ s = "::: generating fundamental function spaces of order %i :::" % order print_text(s, cls=self.this) if use_periodic: self.generate_pbc() else: self.pBC = None order = 1 space = 'CG' Qe = dl.FiniteElement("CG", self.mesh.ufl_cell(), order) self.Q3 = dl.FunctionSpace(self.mesh, dl.MixedElement([Qe] * 3)) self.Q = dl.FunctionSpace(self.mesh, space, order) self.V = dl.VectorFunctionSpace(self.mesh, space, order) self.T = dl.TensorFunctionSpace(self.mesh, space, order) s = " - fundamental function spaces created - " print_text(s, cls=self.this)
def get_spaces(mesh): """ Return an object of dolfin FunctionSpace, to be used in the optimization pipeline :param mesh: The mesh :type mesh: :py:class:`dolfin.Mesh` :returns: An object of functionspaces :rtype: object """ # Make a dummy object spaces = utils.Object() # A real space with scalars used for dolfin adjoint spaces.r_space = dolfin.FunctionSpace(mesh, "R", 0) # A space for the strain fields spaces.strainfieldspace = dolfin.VectorFunctionSpace(mesh, "CG", 1, dim=3) # A space used for scalar strains spaces.strainspace = dolfin.VectorFunctionSpace(mesh, "R", 0, dim=3) # Spaces for the strain weights spaces.strain_weight_space = dolfin.TensorFunctionSpace(mesh, "R", 0) return spaces
def get_CauchyFiberStressTensor(self): if self.heartModel == 'lcleeHeart': cauchy1 = self.heartModelObj.uflforms.Cauchy1( ) + self.heartModelObj.activeforms.cauchy() return fenics.project( cauchy1, fenics.TensorFunctionSpace(self.get_Mesh(), "DG", 1), form_compiler_parameters={"representation": "uflacs"})
def create_cg1_function_space(mesh, sh): r = len(sh) if r == 0: V = dolfin.FunctionSpace(mesh, "CG", 1) elif r == 1: V = dolfin.VectorFunctionSpace(mesh, "CG", 1, dim=sh[0]) else: V = dolfin.TensorFunctionSpace(mesh, "CG", 1, shape=sh) return V
def point_trace_space(V, mesh): '''Space from point trace values live - these are just R^n''' shape = V.ufl_element().value_shape() # Scalars if shape == (): return df.FunctionSpace(mesh, 'R', 0) # Elsewhere only allow vectors if len(shape) == 1: assert isinstance(V.ufl_element(), ufl.VectorElement) return df.VectorFunctionSpace(mesh, 'R', 0, shape[0]) # Or tensors if len(shape) == 2: assert isinstance(V.ufl_element(), ufl.TensorElement) return df.TensorFunctionSpace(mesh, 'R', 0, shape)
def function_space_scalar2tensor(V, val_shape): if len(val_shape) == 0: VV = V elif len(val_shape) == 1: VV = dl.VectorFunctionSpace(V.mesh(), V.ufl_element().family(), V.ufl_element().degree(), dim=val_shape[0]) else: VV = dl.TensorFunctionSpace(V.mesh(), V.ufl_element().family(), V.ufl_element().degree(), shape=val_shape) return VV
W = psi * dolfin.dx F = dolfin.derivative(W, u) equilibrium_solve = utility.equilibrium_solver( F, u, bcs, bcs_set_values, bcs_values) if model_name == "LinearElastic": equilibrium_solve(incremental=False) else: equilibrium_solve(incremental=True) ### Post-process V_S = dolfin.TensorFunctionSpace(mesh, 'DG', 0) stress_field = dolfin.project(pk2, V_S) stress_field.rename("stress (PK2)", '') maximal_compressive_stress_field = \ utility.compute_maximal_compressive_stress_field(stress_field) fraction_compressive_stress_field = \ utility.compute_fraction_compressive_stress_field(stress_field) maximal_compressive_stress_field.rename('maximal_compression', '') fraction_compressive_stress_field.rename('fraction_compression', '') def save_functions():
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
def otherSpaces(self): return [df.TensorFunctionSpace(self.mesh, "Real", 0)]
def set_D_with_protein(setup): meshp = setup.geo.mesh # mesh WITH protein x0 = np.array(setup.geop.x0) dim = setup.phys.dim x0 = x0 if dim == 3 else x0[::2] r0 = setup.geop.rMolecule rion = 0.11 # load diffusivity on mesh without protein functions, mesh = fields.get_functions(**setup.solverp.diffusivity_data) dist = functions["dist"] D0 = functions["D"] # evaluate dist, D on meshp nodes Vp = dolfin.FunctionSpace(meshp, "CG", 1) VVp = dolfin.VectorFunctionSpace(meshp, "CG", 1) distp_ = dolfin.interpolate(dist, Vp) D0p_ = dolfin.interpolate(D0, VVp) distp = distp_.vector()[dolfin.vertex_to_dof_map(Vp)] D0p = D0p_.vector()[dolfin.vertex_to_dof_map(VVp)] D0p = np.column_stack([D0p[i::dim] for i in range(dim)]) x = meshp.coordinates() # probes = Probes(x.flatten(), V) # probes(dist) # distp = probes.array(0) # # probes_ = Probes(x.flatten(), VV) # probes_(D0) # D0p = probes_.array(0) # first create (N,3,3) array from D0 (N,3) N = len(D0p) Da = np.zeros((N, dim, dim)) i3 = np.array(range(dim)) Da[:, i3, i3] = D0p # modify (N,3,3) array to include protein interaction R = x - x0 r = np.sqrt(np.sum(R**2, 1)) overlap = r < rion + r0 near = ~overlap & (r - r0 < distp) h = np.maximum(r[near] - r0, rion) eps = 1e-2 D00 = setup.phys.D Dt = np.zeros_like(r) Dn = np.zeros_like(r) Dt[overlap] = eps Dn[overlap] = eps Dt[near] = diff.Dt_plane(h, rion) Dn[near] = diff.Dn_plane(h, rion, N=20) # D(R) = Dn(h) RR^T + Dt(h) (I - RR^T) where R is normalized R0 = R / (r[:, None] + 1e-100) RR = (R0[:, :, None] * R0[:, None, :]) I = np.zeros((N, dim, dim)) I[:, i3, i3] = 1. Dpp = Dn[:, None, None] * RR + Dt[:, None, None] * (I - RR) Da[overlap | near] = D00 * Dpp[overlap | near] # assign final result to dolfin P1 TensorFunction VVV = dolfin.TensorFunctionSpace(meshp, "CG", 1, shape=(dim, dim)) D = dolfin.Function(VVV) v2d = dolfin.vertex_to_dof_map(VVV) Dv = D.vector() for k, (i, j) in enumerate(product(i3, i3)): Dv[np.ascontiguousarray(v2d[k::dim**2])] = np.ascontiguousarray(Da[:, i, j]) setup.phys.update(Dp=D, Dm=D) #embed() return D
def calculate_fiber_strain(fib, e_circ, e_rad, e_long, strain_markers, mesh, strains): import dolfin from dolfin import ( Measure, Function, TensorFunctionSpace, VectorFunctionSpace, TrialFunction, TestFunction, inner, assemble_system, solve, ) dX = dolfin.Measure("dx", subdomain_data=strain_markers, domain=mesh) fiber_space = fib.function_space() strain_space = dolfin.VectorFunctionSpace(mesh, "R", 0, dim=3) full_strain_space = dolfin.TensorFunctionSpace(mesh, "R", 0) fib1 = dolfin.Function(strain_space) e_c1 = dolfin.Function(strain_space) e_r1 = dolfin.Function(strain_space) e_l1 = dolfin.Function(strain_space) mean_coords, coords = get_regional_midpoints(strain_markers, mesh) # ax = plt.subplot(111, projection='3d') region = 1 fiber_strain = [] for region in range(1, 18): # For each region # Find the average unit normal in the fiber direction u = dolfin.TrialFunction(strain_space) v = TestFunction(strain_space) a = inner(u, v) * dX(region) L_fib = inner(fib, v) * dX(region) A, b = assemble_system(a, L_fib) solve(A, fib1.vector(), b) fib1_norm = np.linalg.norm(fib1.vector().array()) # Unit normal fib1_arr = fib1.vector().array() / fib1_norm # Find the average unit normal in Circumferential direction u = TrialFunction(strain_space) v = TestFunction(strain_space) a = inner(u, v) * dX(region) L_c = inner(e_circ, v) * dX(region) A, b = assemble_system(a, L_c) solve(A, e_c1.vector(), b) e_c1_norm = np.linalg.norm(e_c1.vector().array()) # Unit normal e_c1_arr = e_c1.vector().array() / e_c1_norm # Find the averag unit normal in Radial direction u = TrialFunction(strain_space) v = TestFunction(strain_space) a = inner(u, v) * dX(region) L_r = inner(e_rad, v) * dX(region) A, b = assemble_system(a, L_r) solve(A, e_r1.vector(), b) e_r1_norm = np.linalg.norm(e_r1.vector().array()) # Unit normal e_r1_arr = e_r1.vector().array() / e_r1_norm # Find the average unit normal in Longitudinal direction u = TrialFunction(strain_space) v = TestFunction(strain_space) a = inner(u, v) * dX(region) L_l = inner(e_long, v) * dX(region) A, b = assemble_system(a, L_l) solve(A, e_l1.vector(), b) e_l1_norm = np.linalg.norm(e_l1.vector().array()) # Unit normal e_l1_arr = e_l1.vector().array() / e_l1_norm # ax.plot([mean_coords[region][0], mean_coords[region][0]+e_c1_arr[0]],[mean_coords[region][1], mean_coords[region][1]+e_c1_arr[1]], [mean_coords[region][2],mean_coords[region][2]+e_c1_arr[2]], 'b', label = "circ") # ax.plot([mean_coords[region][0],mean_coords[region][0]+e_r1_arr[0]],[mean_coords[region][1], mean_coords[region][1]+e_r1_arr[1]], [mean_coords[region][2],mean_coords[region][2]+e_r1_arr[2]] , 'r',label = "rad") # ax.plot([mean_coords[region][0],mean_coords[region][0]+e_l1_arr[0]],[mean_coords[region][1], mean_coords[region][1]+e_l1_arr[1]], [mean_coords[region][2],mean_coords[region][2]+e_l1_arr[2]] , 'g',label = "long") # ax.plot([mean_coords[region][0],mean_coords[region][0]+fib1_arr[0]],[mean_coords[region][1], mean_coords[region][1]+fib1_arr[1]], [mean_coords[region][2],mean_coords[region][2]+fib1_arr[2]] , 'y', label = "fib") fiber_strain_region = [] for strain in strains[region]: mat = np.array([ strain[0] * e_c1_arr, strain[1] * e_r1_arr, strain[2] * e_l1_arr ]).T fiber_strain_region.append(np.linalg.norm(np.dot(mat, fib1_arr))) fiber_strain.append(fiber_strain_region) # for i in range(18): # ax.scatter3D(coords[i][0], coords[i][1], coords[i][2], s = 0.1) # plt.show() return fiber_strain
import pytest import dolfin as df mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(1, 1, 1), 10, 10, 10) V1 = df.VectorFunctionSpace(mesh, "CG", 1) VT = df.TensorFunctionSpace(mesh, "CG", 1) Vs = df.FunctionSpace(mesh, "CG", 1) tf = df.TestFunction(Vs) #from finmag.energies.dmi import dmi_term3d, dmi_term2d, dmi_term3d_dolfin @pytest.mark.skip(reason='Not sure if we even use dmi_term3d anymore') def compare_dmi_term3d_with_dolfin(Mexp): """Expects string to feed into df.Expression for M""" print "Working on Mexp=", Mexp Mexp = df.Expression(Mexp, degree=1) M = df.interpolate(Mexp, V1) E = dmi_term3d(M, tf, 1)[0] * df.dx E1 = df.assemble(E) E_dolfin = dmi_term3d_dolfin(M, tf, 1)[0] * df.dx dolfin_curl = df.project(df.curl(M), V1) curlx, curly, curlz = dolfin_curl.split() print "dolfin-curlx=", df.assemble(curlx * df.dx) print "dolfin-curly=", df.assemble(curly * df.dx) print "dolfin-curlz=", df.assemble(curlz * df.dx) E2 = df.assemble(E_dolfin) print E1, E2 print "Diff is %.18e" % (E1 - E2) return abs(E1 - E2)
def F_3D_CG1(): mesh = df.UnitCubeMesh(2, 2, 2) V = df.TensorFunctionSpace(mesh, "CG", 1) F = df.Function(V) F.assign(df.Constant([[A, 0, 0], [0.0, B, 0], [0, 0, C]])) return F
def F_2D_CG1(): mesh = df.UnitSquareMesh(2, 2) V = df.TensorFunctionSpace(mesh, "CG", 1) F = df.Function(V) F.assign(df.Constant([[A, 0], [0.0, B]])) return F
def mesh_metric(mesh): """ Compute the square inverse of a mesh metric """ # this function calculates a mesh metric (or perhaps a square inverse of that, see mesh_metric2...) cell2dof = _c_cell_dofs(mesh, dl.TensorFunctionSpace(mesh, "DG", 0)) cells = mesh.cells() coords = mesh.coordinates() p1 = coords[cells[:, 0], :] p2 = coords[cells[:, 1], :] p3 = coords[cells[:, 2], :] r1 = p1 - p2 r2 = p1 - p3 r3 = p2 - p3 Nedg = 3 if mesh.geometry().dim() == 3: Nedg = 6 p4 = coords[cells[:, 3], :] r4 = p1 - p4 r5 = p2 - p4 r6 = p3 - p4 rall = np.zeros([p1.shape[0], p1.shape[1], Nedg]) rall[:, :, 0] = r1 rall[:, :, 1] = r2 rall[:, :, 2] = r3 if mesh.geometry().dim() == 3: rall[:, :, 3] = r4 rall[:, :, 4] = r5 rall[:, :, 5] = r6 All = np.zeros([p1.shape[0], Nedg**2]) inds = np.arange(Nedg**2).reshape([Nedg, Nedg]) for i in range(Nedg): All[:, inds[i, 0]] = rall[:, 0, i]**2 All[:, inds[i, 1]] = 2. * rall[:, 0, i] * rall[:, 1, i] All[:, inds[i, 2]] = rall[:, 1, i]**2 if mesh.geometry().dim() == 3: All[:, inds[i, 3]] = 2. * rall[:, 0, i] * rall[:, 2, i] All[:, inds[i, 4]] = 2. * rall[:, 1, i] * rall[:, 2, i] All[:, inds[i, 5]] = rall[:, 2, i]**2 Ain = np.zeros([Nedg * 2 - 1, Nedg * p1.shape[0]]) ndia = np.zeros(Nedg * 2 - 1) for i in range(Nedg): for j in range(i, Nedg): iks1 = np.arange(j, Ain.shape[1], Nedg) if i == 0: Ain[i, iks1] = All[:, inds[j, j]] else: iks2 = np.arange(j - i, Ain.shape[1], Nedg) Ain[2 * i - 1, iks1] = All[:, inds[j - i, j]] Ain[2 * i, iks2] = All[:, inds[j, j - i]] ndia[2 * i - 1] = i ndia[2 * i] = -i A = scipy.sparse.spdiags(Ain, ndia, Ain.shape[1], Ain.shape[1]).tocsr() b = np.ones(Ain.shape[1]) X = spsolve(A, b) #set solution XX = _sym2asym(X.reshape([mesh.num_cells(), Nedg]).transpose()) M = dl.Function(dl.TensorFunctionSpace(mesh, "DG", 0)) M.vector().set_local(XX.transpose().flatten()[cell2dof]) return M