예제 #1
0
    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)
예제 #2
0
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
예제 #3
0
 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"})
예제 #4
0
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
예제 #5
0
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)
예제 #6
0
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():
예제 #8
0
    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)]
예제 #10
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
예제 #11
0
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
예제 #12
0
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
예제 #15
0
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