def calculate_darcy_flow(self):
        # equation 5a
        du = self.mech_velocity
        p = self.pressure
        rho = Constant(self.parameters['rho'])
        phi = [Constant(phi) for phi in self.parameters['phi']]
        F = df.variable(kinematics.DeformationGradient(self.displacement))
        J = kinematics.Jacobian(F)
        dx = self.geometry.dx
        N = self.parameters['N']

        # Calculate endo to epi permeability gradient
        w = [TrialFunction(self.vector_space) for i in range(N)]
        v = [TestFunction(self.vector_space) for i in range(N)]
        a = [(1 / phi[i]) * df.inner(F * J * df.inv(F) * w[i], v[i]) * dx
             for i in range(N)]
        # a = [phi[i]*df.inner((w[i]-du), v[i])*dx for i in range(N)]
        # porous dynamics
        if self.parameters['mechanics']:
            A = [-J * self.K[i] * df.inv(F.T) for i in range(N)]
        else:
            A = [self.K[i] for i in range(N)]
        L = [-df.dot(A[i] * df.grad(p[i]), v[i]) * dx for i in range(N)]

        [
            df.solve(a[i] == L[i],
                     self.darcy_flow[i], [],
                     solver_parameters={
                         "linear_solver": "cg",
                         "preconditioner": "sor"
                     }) for i in range(N)
        ]
示例#2
0
def Coupled_setup(d_, v_, p_, psi_v, psi_p, psi_d, dS2, n, mu_f, body_force,
                  dx_s, dx_f, mu_s, rho_s, lamda_s, k, mesh_file, rho_f,
                  **semimp_namespace):

    F_coupled_linear = rho_s / k**2 * inner(
        d_["n"] - 2 * d_["n-1"] + d_["n-2"], psi_d) * dx_s
    F_coupled_linear -= rho_s * inner(body_force, psi_d) * dx_s

    F_coupled_linear = rho_f / k * J_(d_["tilde"]) * inner(
        v_["n"] - v_["tilde"], psi_v) * dx_f
    F_coupled_linear += J_(d_["tilde"]) * inner(
        inv(F_(d_["tilde"])).T * grad(p_["n"]), psi_v) * dx_f
    F_coupled_linear += inner(
        div(J_(d_["tilde"]) * inv(F_(d_["tilde"])) * v_["n"]), psi_p) * dx_f

    # Non-linear part
    F_coupled_nonlinear = Constant(0.5) * inner(Piola1(d_["n"], lamda_s, mu_s), grad(psi_d))*dx_s \
                        + Constant(0.5) * inner(Piola1(d_["n-2"], lamda_s, mu_s), grad(psi_d))*dx_s

    # Impose BC weakly
    F_coupled_nonlinear -= inner(J_(d_["tilde"]("+"))*sigma_f(p_["n"]("+"), v_["tilde"]("+"),
                                                            d_["tilde"]("+"), mu_f) \
                         * inv(F_(d_["tilde"]("+"))).T*n("+"), psi_d("+"))*dS2(5)
    # TODO: This might be better strongly...
    F_coupled_linear += J_(d_["tilde"]("+")) * inner(
        dot(v_["n"]("+") - -(d_["n"]("-") - d_["n-1"]("-")) / k, n("+")),
        psi_p("+")) * dS2(5)

    return dict(F_coupled_linear=F_coupled_linear,
                F_coupled_nonlinear=F_coupled_nonlinear)
示例#3
0
def fluid_setup(v_, p_, d_, n, psi, gamma, dx_f, ds, dS, mu_f, rho_f, k, v_deg,
                **semimp_namespace):

    F_fluid_linear = (rho_f / k) * inner(
        J_(d_["n"]) * (v_["n"] - v_["n-1"]), psi) * dx_f
    F_fluid_linear -= inner(div(J_(d_["n"]) * inv(F_(d_["n"])) * v_["n"]),
                            gamma) * dx_f
    F_fluid_linear += inner(
        J_(d_["n"]) * sigma_f_new(v_["n"], p_["n"], d_["n"], mu_f) *
        inv(F_(d_["n"])).T, grad(psi)) * dx_f

    F_fluid_linear -= inner(dot(J_(d_["n"]("-"))*\
        sigma_f_new(v_["n"]("-"), p_["n"]("-"), d_["n"]("-"), mu_f)*inv(F_(d_["n"]("-"))).T, n("+")) , psi("-") )*dS(5)

    F_fluid_nonlinear = rho_f * inner(
        J_(d_["n"]) * grad(v_["n"]) * inv(F_(d_["n"])) *
        (v_["n"] - ((d_["n"] - d_["n-1"]) / k)), psi) * dx_f
    if v_deg == 1:
        F_fluid -= beta * h * h * inner(
            J_(d_["n"]) * inv(F_(d_["n"]).T) * grad(p), grad(gamma)) * dx_f

        print "v_deg", v_deg

    return dict(F_fluid_linear=F_fluid_linear,
                F_fluid_nonlinear=F_fluid_nonlinear)
示例#4
0
def fluid_setup(v_, p_, d_, n, psi, gamma, dx_f, ds, mu_f, rho_f, k, dt, v_deg,
                theta, **semimp_namespace):

    J_theta = theta * J_(d_["n"]) + (1 - theta) * J_(d_["n-1"])
    d_cn = Constant(theta) * d_["n"] + Constant(1 - theta) * d_["n-1"]
    v_cn = Constant(theta) * v_["n"] + Constant(1 - theta) * v_["n-1"]
    p_cn = Constant(theta) * p_["n"] + Constant(1 - theta) * p_["n-1"]

    F_fluid_linear = rho_f / k * inner(J_theta *
                                       (v_["n"] - v_["n-1"]), psi) * dx_f
    F_fluid_nonlinear =  rho_f*inner(J_(d_cn)*grad(v_cn)*inv(F_(d_cn))* \
                         (0.5*(3*v_["n-1"] - v_["n-2"]) - \
                         0.5/k*((3*d_["n-1"] - d_["n-2"]) - (3*d_["n-2"] - d_["n-3"]))), psi)*dx_f
    #(d_["n"]-d_["n-1"])/k), psi)*dx_f

    F_fluid_nonlinear += inner(
        J_(d_cn) * sigma_f_p(p_cn, d_cn) * inv(F_(d_cn)).T, grad(psi)) * dx_f
    F_fluid_nonlinear += inner(
        J_(d_cn) * sigma_f_u(v_cn, d_cn, mu_f) * inv(F_(d_cn)).T,
        grad(psi)) * dx_f
    #OrgF_fluid_nonlinear +=inner(div(J_(d_["n"])*inv(F_(d_["n"]))*v_["n"]), gamma)*dx_f
    F_fluid_nonlinear += inner(div(J_(d_cn) * inv(F_(d_cn)) * v_cn),
                               gamma) * dx_f

    return dict(F_fluid_linear=F_fluid_linear,
                F_fluid_nonlinear=F_fluid_nonlinear)
    def SecondPiolaStress(self, F, p=None, deviatoric=False):
        import dolfin
        from pulse import kinematics
        material = self.material
        I = kinematics.SecondOrderIdentity(F)

        f0 = material.f0
        f0f0 = dolfin.outer(f0, f0)

        I1 = dolfin.variable(material.active.I1(F))
        I4f = dolfin.variable(material.active.I4(F))

        Fe = material.active.Fe(F)
        Fa = material.active.Fa
        Ce = Fe.T * Fe

        # fe = Fe*f0
        # fefe = dolfin.outer(fe, fe)

        # Elastic volume ratio
        J = dolfin.variable(dolfin.det(Fe))
        # Active volume ration
        Ja = dolfin.det(Fa)

        dim = self.geometry.dim()
        Ce_bar = pow(J, -2.0 / float(dim)) * Ce

        w1 = material.W_1(I1, diff=1, dim=dim)
        w4f = material.W_4(I4f, diff=1)

        # Total Stress
        S_bar = Ja * (2 * w1 * I + 2 * w4f * f0f0) * dolfin.inv(Fa).T

        if material.is_isochoric:

            # Deviatoric
            Dev_S_bar = S_bar - (1.0 / 3.0) * dolfin.inner(
                S_bar, Ce_bar) * dolfin.inv(Ce_bar)

            S_mat = J**(-2.0 / 3.0) * Dev_S_bar
        else:
            S_mat = S_bar

        # Volumetric
        if p is None or deviatoric:
            S_vol = dolfin.zero((dim, dim))
        else:
            psi_vol = material.compressibility(p, J)
            S_vol = J * dolfin.diff(psi_vol, J) * dolfin.inv(Ce)

        # Active stress
        wactive = material.active.Wactive(F, diff=1)
        eta = material.active.eta

        S_active = wactive * (f0f0 + eta * (I - f0f0))

        S = S_mat + S_vol + S_active

        return S
示例#6
0
def Fluid_correction_variation(v, p, v_, d_, vp_, dw_, psi, eta, dx_f, \
    mu_f, rho_f, k, dt, n, dS, **semimp_namespace):

	# Pressure update
	F_correction = rho_f/k*J_(d_["tilde"])*inner(v - v_["tilde"], psi)*dx_f
	F_correction += J_(d_["tilde"])*inner(inv(F_(d_["tilde"])).T*grad(p), psi)*dx_f
	#F_correction -= p*J_(d_["tilde"])*inner(inv(F_(d_["tilde"])).T, grad(psi))*dx_f
	F_correction += inner(div(J_(d_["n"])*inv(F_(d_["n"]))*v), eta)*dx_f


	return dict(F_correction=F_correction)
示例#7
0
    def SecondPiolaStress(self, F, p=None, deviatoric=False, *args, **kwargs):

        # First Piola Kirchoff
        if deviatoric:
            p = None

        P = self.FirstPiolaStress(F, p)

        S = dolfin.inv(F) * P * dolfin.inv(F).T

        return S
    def permeability_tensor(self, K):
        FS = self.geometry.f0.function_space()
        TS = TensorFunctionSpace(self.geometry.mesh, 'P', 1)
        d = self.geometry.dim()
        fibers = Function(FS)
        fibers.vector()[:] = self.geometry.f0.vector().get_local()
        fibers.vector()[:] /= df.norm(self.geometry.f0)
        if self.geometry.s0 is not None:
            # normalize vectors
            sheet = Function(FS)
            sheet.vector()[:] = self.geometry.s0.vector().get_local()
            sheet.vector()[:] /= df.norm(self.geometry.s0)
            if d == 3:
                csheet = Function(FS)
                csheet.vector()[:] = self.geometry.n0.vector().get_local()
                csheet.vector()[:] /= df.norm(self.geometry.n0)
        else:
            return Constant(1)

        from ufl import diag
        factor = 10
        if d == 3:
            ftensor = df.as_matrix(((fibers[0], sheet[0], csheet[0]),
                                    (fibers[1], sheet[1], csheet[1]),
                                    (fibers[2], sheet[2], csheet[2])))
            ktensor = diag(df.as_vector([K, K / factor, K / factor]))
        else:
            ftensor = df.as_matrix(
                ((fibers[0], sheet[0]), (fibers[1], sheet[1])))
            ktensor = diag(df.as_vector([K, K / factor]))

        permeability = df.project(
            df.dot(df.dot(ftensor, ktensor), df.inv(ftensor)), TS)
        return permeability
def Fluid_correction_variation(v, p, v_, d_, vp_, dw_, psi, eta, dx_f, \
    mu_f, rho_f, k, dt, n, dS2, **semimp_namespace):

    # Pressure update
    F_correction = rho_f/k*J_(d_["tilde"])*inner(v - v_["tilde"], psi)*dx_f

    # This gives no pressure gradient thorugh the pipe
    #F_correction -= J_(d_["tilde"])*inner(p*inv(F_(d_["tilde"])).T, grad(psi))*dx_f
    F_correction += J_(d_["tilde"])*inner(inv(F_(d_["tilde"])).T*grad(p), psi)*dx_f

    F_correction += inner(div(J_(d_["tilde"])*inv(F_(d_["tilde"]))*v), eta)*dx_f

    #F_correction += J_(d_["tilde"]("+"))*inner(dot(v("+") - \
    #                (d_["n"]("-") - d_["n-1"]("-"))/k, n("+")), eta("+"))*dS2(5)

    return dict(F_correction=F_correction)
示例#10
0
    def Fe(self, F):
        if self.model == ActiveModels.active_stress:
            return F
        Fa = self.Fa
        Fe = F * dolfin.inv(Fa)

        return Fe
示例#11
0
    def __call__(self, u=None):

        if u is None:
            u = dolfin.Function(
                self._displacement_space,
                name="Zero displacement from strain observation",
            )

        u_int = map_displacement(
            u, self._displacement_space, self._interpolation_space, self._approx
        )
        # We need to correct for th reference deformation
        F = pulse.kinematics.DeformationGradient(u_int) * dolfin.inv(self._F_ref)

        # Compute the strains
        if self._tensor == "gradu":
            tensor = pulse.kinematics.EngineeringStrain(F, isochoric=self._isochoric)

        elif self._tensor == "E":
            tensor = pulse.kinematics.GreenLagrangeStrain(F, isochoric=self._isochoric)

        elif self._tensor == "almansi":
            tensor = pulse.kinematics.EulerAlmansiStrain(F, isochoric=self._isochoric)

        form = dolfin.inner(tensor * self.field, self.field)
        strain = dolfin_adjoint.Function(self._V, name="Simulated Strain")
        dolfin_adjoint.solve(
            dolfin.inner(self._trial, self._test) / self._vol * self._dmu
            == dolfin.inner(self._test, form) * self._dmu,
            strain,
            solver_parameters={"linear_solver": "gmres"},
        )

        return strain
示例#12
0
    def __call__(self, u=None):
        """

        Arguments
        ---------
        u : :py:class:`dolfin.Function`
            The displacement
        """

        if u is None:

            volume_form = (-1.0 / 3.0) * dolfin.dot(self._X, self._N)

        else:
            u_int = map_displacement(
                u, self._displacement_space, self._interpolation_space, self._approx
            )

            # Compute volume
            F = pulse.kinematics.DeformationGradient(u_int)
            J = pulse.kinematics.Jacobian(F)
            volume_form = (-1.0 / 3.0) * dolfin.dot(
                self._X + u_int, J * dolfin.inv(F).T * self._N
            )

        volume = dolfin_adjoint.Function(self._V, name="Simulated volume")
        # Make a project for dolfin-adjoint recording
        dolfin_adjoint.solve(
            dolfin.inner(self._trial, self._test) / self._endoarea * self._dmu
            == dolfin.inner(volume_form, self._test) * self._dmu,
            volume,
        )

        return volume
示例#13
0
def Structure_setup(d_, w_, v_, p_, phi, gamma, dS, n, mu_f, \
            vp_, dx_s, mu_s, rho_s, lamda_s, k, mesh_file, theta, **semimp_namespace):

    delta = 1E10
    theta = 1.0


    F_solid_linear = rho_s/k*inner(w_["n"] - w_["n-1"], phi)*dx_s \
                   + delta*(1./k)*inner(d_["n"] - d_["n-1"], gamma)*dx_s \
             - delta*inner(Constant(theta)*w_["n"] \
          + Constant(1 - theta)*w_["n-1"], gamma)*dx_s

    F_solid_nonlinear = inner(Piola1(Constant(theta)*d_["n"] \
                      + Constant(1 - theta)*d_["n-1"], lamda_s, mu_s), grad(phi))*dx_s

    #F_solid_nonlinear -= inner(J_(d_["n"]("+")) * \
    #3sigma_f(p_["n"]("+"),v_["tilde"]("+"), d_["n"]("+"), mu_f) \
    #*inv(F_(d_["n"]("+"))).T*n("+"), phi("+"))*dS(5)

    #org
    F_solid_nonlinear -= inner(J_(d_["tilde"]("+")) * \
    sigma_f(p_["n"]("+"),v_["tilde"]("+"), d_["tilde"]("+"), mu_f) \
    *inv(F_(d_["tilde"]("+"))).T*n("+"), phi("-"))*dS(5)

    return dict(F_solid_linear=F_solid_linear,
                F_solid_nonlinear=F_solid_nonlinear)
示例#14
0
def Structure_setup(d_, w_, v_, p_, phi, gamma, dS2, n, mu_f, body_force, \
            vp_, dx_s, mu_s, rho_s, lamda_s, k, mesh_file, theta, **semimp_namespace):

    delta = 1E10
    #theta = 1.0
    theta = 0.5

    F_solid_linear = rho_s/k*inner(w_["n"] - w_["n-1"], phi)*dx_s \
                   + delta*(1./k)*inner(d_["n"] - d_["n-1"], gamma)*dx_s \
                   - delta*inner(Constant(theta)*w_["n"] \
                   + Constant(1 - theta)*w_["n-1"], gamma)*dx_s

    F_solid_linear -= rho_s * inner(body_force, phi) * dx_s

    # Non-linear part
    F_solid_nonlinear = Constant(theta)*inner(Piola1(d_["n"], lamda_s, mu_s), grad(phi))*dx_s \
                      + Constant(1 - theta)*inner(Piola1(d_["n-1"], lamda_s, mu_s), grad(phi))*dx_s

    u = vp_["tilde"].sub(0)
    p = vp_["n"].sub(1)
    F_solid_nonlinear -= inner(J_(d_["tilde"]("+"))*sigma_f(p("+"), u("+"), d_["tilde"]("+"), mu_f) \
                         *inv(F_(d_["tilde"]("+"))).T*n("+"), phi("+"))*dS2(5)

    return dict(F_solid_linear=F_solid_linear,
                F_solid_nonlinear=F_solid_nonlinear)
示例#15
0
def get_volume(geometry, u=None, chamber="lv"):

    if "ENDO" in geometry.markers:
        lv_endo_marker = geometry.markers["ENDO"]
        rv_endo_marker = None
    else:
        lv_endo_marker = geometry.markers["ENDO_LV"]
        rv_endo_marker = geometry.markers["ENDO_RV"]

    marker = lv_endo_marker if chamber == "lv" else rv_endo_marker

    if marker is None:
        return None

    if hasattr(marker, "__len__"):
        marker = marker[0]

    ds = df.Measure(
        "exterior_facet", subdomain_data=geometry.ffun, domain=geometry.mesh
    )(marker)

    X = df.SpatialCoordinate(geometry.mesh)
    N = df.FacetNormal(geometry.mesh)

    if u is None:
        vol = df.assemble((-1.0 / 3.0) * df.dot(X, N) * ds)
    else:
        F = df.grad(u) + df.Identity(3)
        J = df.det(F)
        vol = df.assemble((-1.0 / 3.0) * df.dot(X + u, J * df.inv(F).T * N) * ds)

    return vol
示例#16
0
def fluid_setup(v_, p_, d_, n, psi, gamma, dx_f, ds, mu_f, rho_f, k, dt, v_deg,
                theta, **semimp_namespace):

    #J_theta = theta*J_(d_["n"]) + (1 - theta)*J_(d_["n-1"])
    #F_fluid_linear = rho_f/k*inner(J_theta*(v_["n"] - v_["n-1"]), psi)*dx_f
    #F_fluid_nonlinear = rho_f/k*inner(J_theta*(v_["n"] - v_["n-1"]), psi)*dx_f

    J_theta = theta * J_(d_["n"]) + (1 - theta) * J_(d_["n-1"])
    F_fluid_nonlinear = rho_f / k * inner(
        J_theta * (v_["n"]) - theta * J_(d_["n"]) * v_["n-1"], psi) * dx_f
    F_fluid_linear = rho_f / k * inner(
        Constant(1 - theta) * J_(d_["n-1"]) * -(v_["n-1"]), psi) * dx_f

    F_fluid_nonlinear = Constant(theta) * rho_f * inner(
        J_(d_["n"]) * grad(v_["n"]) * inv(F_(d_["n"])) * v_["n"], psi) * dx_f
    F_fluid_nonlinear += inner(
        J_(d_["n"]) * sigma_f_p(p_["n"], d_["n"]) * inv(F_(d_["n"])).T,
        grad(psi)) * dx_f
    F_fluid_nonlinear += Constant(theta) * inner(
        J_(d_["n"]) * sigma_f_u(v_["n"], d_["n"], mu_f) * inv(F_(d_["n"])).T,
        grad(psi)) * dx_f
    F_fluid_linear += Constant(1 - theta) * inner(
        J_(d_["n-1"]) * sigma_f_u(v_["n-1"], d_["n-1"], mu_f) *
        inv(F_(d_["n-1"])).T, grad(psi)) * dx_f
    F_fluid_nonlinear += inner(div(J_(d_["n"]) * inv(F_(d_["n"])) * v_["n"]),
                               gamma) * dx_f
    F_fluid_linear += Constant(1 - theta) * rho_f * inner(
        J_(d_["n-1"]) * grad(v_["n-1"]) * inv(F_(d_["n-1"])) * v_["n-1"],
        psi) * dx_f
    F_fluid_nonlinear -= rho_f * inner(
        J_(d_["n"]) * grad(v_["n"]) * inv(F_(d_["n"])) *
        ((d_["n"] - d_["n-1"]) / k), psi) * dx_f

    return dict(F_fluid_linear=F_fluid_linear,
                F_fluid_nonlinear=F_fluid_nonlinear)
示例#17
0
def Fluid_correction_variation(v_f, p_f, v_, p_, d_, dvp_, psi, gamma, dx_f, \
    mu_f, rho_f, k, dt, n, dS, **semimp_namespace):

	F_correction = rho_f/k*J_(d_["tilde"])*inner(v_f - v_["tilde"], psi)*dx_f
	F_correction -= p_f*J_(d_["tilde"])*inner(inv(F_(d_["tilde"])).T, grad(psi))*dx_f
	F_correction += J_(d_["tilde"])*inner(grad(v_f), inv(F_(d_["tilde"])).T)*gamma*dx_f

	#Use newly computed "n" from step 3.2m first time "tilde"

	F_correction += J_(d_["tilde"]("-"))*dot(v_f("-") - \
	(d_["n"]("-")-d_["n-1"]("-"))/k, n("-"))*gamma("-")*dS(5)

	#F_correction += J_(d_["tilde"]("+"))*dot(v_f("+") - \
	#(d_["n"]("-")-d_["n-1"]("-"))/k, n("+"))*gamma("+")*dS(5)

	#F_correction += dot(v_f("+") - \
	#(d_["n"]("-")-d_["n-1"]("-"))/k, n("+"))*gamma("+")*dS(5)
	return dict(F_correction=F_correction)
示例#18
0
def Fluid_tentative_variation(v_tent, v_, d_, beta, dx_f, mu_f, rho_f, k, dS2,
                              **semimp_namespace):

    F_tentative = rho_f / k * J_(d_["tilde"]) * inner(v_tent - v_["n-1"],
                                                      beta) * dx_f

    F_tentative += rho_f*inner(J_(d_["tilde"])*grad(v_tent)*inv(F_(d_["tilde"])) \
                    * (v_["tilde-1"] - (d_["tilde"] - d_["n-1"]) / k), beta)*dx_f
    F_tentative += 2*mu_f*J_(d_["tilde"])*inner(eps(d_["tilde"], v_tent), \
                                                eps(d_["tilde"], beta))*dx_f

    F_tentative -= inner(Constant((0, 0)), beta) * dx_f

    return dict(F_tentative=F_tentative)
示例#19
0
def fluid_setup(v_, p_, d_, psi, gamma, dx_f, mu_f, rho_f, k, theta,
                **namespace):
    """
    ALE formulation (theta-scheme) of the incompressible Navier-Stokes flow problem:

        du/dt + u * grad(u - w) = grad(p) + nu * div(grad(u))
        div(u) = 0
    """

    theta0 = Constant(theta)
    theta1 = Constant(1 - theta)

    # Note that we here split the equation into a linear and nonlinear part for faster
    # computation of the Jacobian matrix.

    # Temporal derivative
    F_fluid_nonlinear = rho_f / k * inner(
        J_(d_["n"]) * theta0 * (v_["n"] - v_["n-1"]), psi) * dx_f
    F_fluid_linear = rho_f / k * inner(
        J_(d_["n-1"]) * theta1 * (v_["n"] - v_["n-1"]), psi) * dx_f

    # Convection
    F_fluid_nonlinear += theta0 * rho_f * inner(
        grad(v_["n"]) * inv(F_(d_["n"])) * J_(d_["n"]) * v_["n"], psi) * dx_f
    F_fluid_linear += theta1 * rho_f * inner(
        grad(v_["n-1"]) * inv(F_(d_["n-1"])) * J_(d_["n-1"]) * v_["n-1"],
        psi) * dx_f

    # Stress from pressure
    F_fluid_nonlinear += inner(
        J_(d_["n"]) * sigma_f_p(p_["n"], d_["n"]) * inv(F_(d_["n"])).T,
        grad(psi)) * dx_f

    # Stress from velocity
    F_fluid_nonlinear += theta0 * inner(
        J_(d_["n"]) * sigma_f_u(v_["n"], d_["n"], mu_f) * inv(F_(d_["n"])).T,
        grad(psi)) * dx_f
    F_fluid_linear += theta1 * inner(
        J_(d_["n-1"]) * sigma_f_u(v_["n-1"], d_["n-1"], mu_f) *
        inv(F_(d_["n-1"])).T, grad(psi)) * dx_f

    # Divergence free term
    F_fluid_nonlinear += inner(div(J_(d_["n"]) * inv(F_(d_["n"])) * v_["n"]),
                               gamma) * dx_f

    # ALE term
    F_fluid_nonlinear -= rho_f / k * inner(
        J_(d_["n"]) * grad(v_["n"]) * inv(F_(d_["n"])) *
        (d_["n"] - d_["n-1"]), psi) * dx_f

    return dict(F_fluid_linear=F_fluid_linear,
                F_fluid_nonlinear=F_fluid_nonlinear)
示例#20
0
def fluid_setup(d, v, p, v_, p_, d_, n, psi, gamma, dx_f, ds, mu_f, rho_f, k,
                dt, v_deg, theta, **semimp_namespace):

    #First Order
    """
	dvdt = 1./k*(d - v_["n-1"])
	dudt = 1./(2*k)*(d_["n-1"] - d_["n-3"])
	J_tilde = J_(d_["n-1"])
	F_tilde = F_(d_["n-1"])
	d_tilde = d_["n-1"]
	"""

    #Second Order
    dvdt = 1. / (2 * k) * (3. * v - 4. * v_["n-1"] + v_["n-2"])
    dudt = 1. / (2 * k) * (3. * d_["n-1"] - 4. * d_["n-2"] + d_["n-3"])
    J_tilde = 2. * J_(d_["n-1"]) - J_(d_["n-2"])
    F_tilde = 2. * F_(d_["n-1"]) - F_(d_["n-2"])
    d_tilde = 2. * d_["n-1"] - d_["n-2"]

    F_fluid = rho_f * inner(J_tilde * dvdt, psi) * dx_f
    F_fluid += rho_f * inner(
        J_tilde * grad(v) * inv(F_tilde) * (v_["n-1"] - dudt), psi) * dx_f
    F_fluid += J_tilde * inner(2 * mu_f * D_U(d_tilde, v), D_U(d_tilde,
                                                               psi)) * dx_f
    F_fluid -= inner(J_tilde * p * inv(F_tilde).T, grad(psi)) * dx_f

    #F_fluid += inner(div(J_tilde*inv(F_tilde)*v), gamma)*dx_f #Check 2.13 paper
    F_fluid += inner(J_tilde * grad(v),
                     inv(F_tilde).T * gamma) * dx_f  #Check 2.13 paper

    #Not a must
    #djdt = 1./(2*k)*(3.*J_(d_["n-1"]) - 4.*J_(d_["n-2"]) + J_(d_["n-3"]) )
    #F_fluid += rho_f/2.*inner(djdt*v, psi)*dx_f
    #F_fluid += rho_f/2.*inner(div(J_(d_["n-1"])*inv(F_tilde)\
    #		*(v_["n-1"] - dudt))*v, psi)*dx_f

    return dict(F_fluid=F_fluid)
def get_cavity_volume_form(mesh, u=None, xshift=0.0):

    from . import kinematics

    shift = Constant((xshift, 0.0, 0.0))
    X = dolfin.SpatialCoordinate(mesh) - shift
    N = dolfin.FacetNormal(mesh)

    if u is None:
        vol_form = (-1.0 / 3.0) * dolfin.dot(X, N)
    else:
        F = kinematics.DeformationGradient(u)
        J = kinematics.Jacobian(F)
        vol_form = (-1.0 / 3.0) * dolfin.dot(X + u, J * dolfin.inv(F).T * N)

    return vol_form
def Fluid_tentative_variation(v_tent, v_, p_, d_, dw_, vp_, v, \
    beta, dx_f, mu_f, rho_f, k, dt, dS2, **semimp_namespace):

    #Reuse of TrialFunction w, TestFunction psi
    #used in extrapolation assuming same degree

    F_tentative = rho_f/k*J_(d_["tilde"])*inner(v_tent - v_["n-1"], beta)*dx_f

    F_tentative += rho_f*inner(J_(d_["tilde"])*grad(v_tent)*inv(F_(d_["tilde"])) \
                    * (v_["tilde-1"] - 1./k*(d_["tilde"] - d_["n-1"])), beta)*dx_f

    F_tentative += J_(d_["tilde"])*inner(2*mu_f*eps(d_["tilde"], v_tent), eps(d_["tilde"], beta))*dx_f

    F_tentative -= inner(Constant((0, 0)), beta)*dx_f

    return dict(F_tentative=F_tentative)
示例#23
0
    def FirstPiolaStress(self, F, p=None, *args, **kwargs):

        F = dolfin.variable(F)

        # First Piola Kirchoff
        psi_iso = self.strain_energy(F)
        P = dolfin.diff(psi_iso, F)

        if p is not None:
            J = dolfin.variable(kinematics.Jacobian(F))
            psi_vol = self.compressibility(p, J)
            # PiolaTransform
            P_vol = J * dolfin.diff(psi_vol, J) * dolfin.inv(F).T

            P += P_vol

        return P
示例#24
0
def extrapolate_setup(F_fluid_linear, extype, mesh_file, d_, phi, gamma, dx_f,
                      **semimp_namespace):
    def F_(U):
        return Identity(len(U)) + grad(U)

    def J_(U):
        return det(F_(U))

    def eps(U):
        return 0.5 * (grad(U) * inv(F_(U)) + inv(F_(U)).T * grad(U).T)

    def STVK(U, alfa_mu, alfa_lam):
        return alfa_lam * tr(eps(U)) * Identity(
            len(U)) + 2.0 * alfa_mu * eps(U)
        #return F_(U)*(alfa_lam*tr(eps(U))*Identity(len(U)) + 2.0*alfa_mu*eps(U))

    alfa = 1.0  # holder value if linear is chosen
    if extype == "det":
        #alfa = inv(J_(d_["n"]))
        alfa = 1. / (J_(d_["n"]))
    if extype == "smallconst":
        alfa = 0.01 * (mesh_file.hmin())**2
    if extype == "const":
        alfa = 1.0

    F_extrapolate = alfa * inner(grad(d_["n"]), grad(phi)) * dx_f

    if extype == "linear":
        hmin = mesh_file.hmin()
        #E_y =  1./(J_(d_["n"]))
        #nu = -0.2 #(-1, 0.5)
        E_y = 1. / CellVolume(mesh_file)
        nu = 0.25
        alfa_lam = nu * E_y / ((1. + nu) * (1. - 2. * nu))
        alfa_mu = E_y / (2. * (1. + nu))
        #alfa_lam = hmin*hmin ; alfa_mu = hmin*hmin
        F_extrapolate = inner(
            J_(d_["n"]) * STVK(d_["n"], alfa_mu, alfa_lam) *
            inv(F_(d_["n"])).T, grad(phi)) * dx_f
        #F_extrapolate = inner(STVK(d_["n"],alfa_mu,alfa_lam) , grad(phi))*dx_f

    F_fluid_linear += F_extrapolate

    return dict(F_fluid_linear=F_fluid_linear)
示例#25
0
def extrapolate_setup(F_fluid_linear, mesh, d_, phi, gamma, dx_f, **namespace):
    """
    Elastic lifting operator solving the equation of linear elasticity.

    div(sigma(d)) = 0   in the fluid domain
    d = 0               on the fluid boundaries other than FSI interface
    d = solid_d         on the FSI interface
    """
    E_y = 1.0 / CellVolume(mesh)
    nu = 0.25
    alpha_lam = nu * E_y / ((1.0 + nu) * (1.0 - 2.0 * nu))
    alpha_mu = E_y / (2.0 * (1.0 + nu))
    F_extrapolate = inner(
        J_(d_["n"]) * S_linear(d_["n"], alpha_mu, alpha_lam) *
        inv(F_(d_["n"])).T, grad(phi)) * dx_f

    F_fluid_linear += F_extrapolate

    return dict(F_fluid_linear=F_fluid_linear)
示例#26
0
    def initialize_with_field(self, u):
        super().initialize_with_field(u)

        d = self.deformation_measures.d
        F = self.deformation_measures.F
        J = self.deformation_measures.J
        I1 = self.deformation_measures.I1
        # I2 = self.deformation_measures.I2
        # I3 = self.deformation_measures.I3

        for m in self.material_parameters:

            E = m.get('E', None)
            nu = m.get('nu', None)

            mu = m.get('mu', None)
            lm = m.get('lm', None)

            if mu is None:
                if E is None or nu is None:
                    raise RuntimeError(
                        'Material model requires parameter "mu"; '
                        'otherwise, require parameters "E" and "nu".')

                mu = E / (2 * (1 + nu))

            if lm is None:
                if E is None or nu is None:
                    raise RuntimeError(
                        'Material model requires parameter "lm"; '
                        'otherwise, require parameters "E" and "nu".')

                lm = E * nu / ((1 + nu) * (1 - 2 * nu))

            psi = (mu / 2) * (I1 - d - 2 * ln(J)) + (lm / 2) * ln(J)**2

            pk1 = diff(psi, F)
            pk2 = dot(inv(F), pk1)

            self.psi.append(psi)
            self.pk1.append(pk1)
            self.pk2.append(pk2)
示例#27
0
def Fluid_tentative_variation(v_, p_, d_, dvp_, w, w_f, v_tilde_n1, \
psi, beta, gamma, dx_f, mu_f, rho_f, k, dt, **semimp_namespace):

	d_tent = dvp_["tilde"].sub(0, deepcopy=True)
	d_n = dvp_["tilde"].sub(0, deepcopy=True)
	d_n1 = dvp_["n-1"].sub(0, deepcopy=True)

	v_n1   = dvp_["n-1"].sub(1, deepcopy=True)


	#Reuse of TrialFunction w, TestFunction beta
	#used in extrapolation assuming same degree

	F_tentative = rho_f/k*J_(d_tent)*inner(w - v_n1, beta)*dx_f
	F_tentative += rho_f*inner(J_(d_tent)*grad(w)*inv(F_(d_tent)) \
             	* (v_tilde_n1 - 1./k*(d_n - d_n1)), beta)*dx_f

	F_tentative += J_(d_tent)*inner(mu_f*D_U(d_tent, w), D_U(d_tent, beta))*dx_f

	F_tentative -= inner(Constant((0, 0)), beta)*dx_f

	return dict(F_tentative=F_tentative)
示例#28
0
 def eps(U):
     return 0.5 * (grad(U) * inv(F_(U)) + inv(F_(U)).T * grad(U).T)
示例#29
0
def sigma_f(p, u, d, mu_f):
    return  -p*Identity(len(u)) +\
            mu_f*(grad(u)*inv(F_(d)) + inv(F_(d)).T*grad(u).T)
示例#30
0
def main(dt,
         tEnd,
         length=10.0,
         height=5.0,
         numElementsFilm=2.0,
         reGen=True,
         ratLame=5.0,
         ratFilmSub=100.0):
    #fileDir = ("results-dt-%.2f-tEnd-%.0f-L-%.1f-H-%.1f-ratioLame-%.0f-ratioFilm-%.0f" %
    #           (dt, tEnd, length, height, ratLame, ratFilmSub))
    fileDir = "results-1"
    # create geometry
    rectDomain = Geometry(length=length, height=height, filmHeight=0.05)
    rectDomain.read_mesh(numElementsFilm, reGen)
    # define periodic boundary conditions
    periodicBC = PeriodicBoundary(rectDomain)
    # specify physical parameters
    physParams = Physical_Params(lmbdaSub=ratLame, muSub=1.0, ratFilmSub=100.0)
    physParams.create_Lame(rectDomain)
    # create discrete function space
    element = create_vector_element(rectDomain, order=1)
    W = dl.FunctionSpace(rectDomain.mesh,
                         element,
                         constrained_domain=periodicBC)

    # define boundaries
    def left(x, on_boundary):
        return dl.near(x[0], 0.) and on_boundary

    def right(x, on_boundary):
        return dl.near(x[0], rectDomain.length) and on_boundary

    def bottom(x, on_boundary):
        return dl.near(x[1], 0.0) and on_boundary

    def top(x, on_boundary):
        return dl.near(x[1], rectDomain.height) and on_boundary

    def corner(x, on_boundary):
        return dl.near(x[0], 0.0) and dl.near(x[1], 0.0)

    # define fixed boundary
    bcs = [
        dl.DirichletBC(W.sub(0), dl.Constant(0), left),
        dl.DirichletBC(W.sub(0), dl.Constant(0), right),
        dl.DirichletBC(W.sub(1), dl.Constant(0), bottom),
        dl.DirichletBC(W.sub(0), dl.Constant(0), corner, method="pointwise")
    ]
    bcs = bcs[-2:]
    # the variable to solve for
    w = dl.Function(W, name="Variables at current step")
    # test and trial function
    dw = dl.TrialFunction(W)
    w_ = dl.TestFunction(W)
    # dealing with physics of growth
    growthFactor = create_growthFactor(rectDomain, filmGrowth=1, subGrowth=0)
    Fg = create_Fg(growthFactor, "uniaxial")
    # kinematics
    I = dl.Identity(2)
    F = I + dl.grad(w)
    Fe = F * dl.inv(Fg)
    # write the variational form from potential energy
    psi = cal_neoHookean(Fe, physParams)
    Energy = psi * dl.dx
    Residual = dl.derivative(Energy, w, w_)
    Jacobian = dl.derivative(Residual, w, dw)
    problem = BucklingProblem(w, Energy, Residual, Jacobian)
    wLowerBound, wUpperBound = create_bounds(wMin=[-0.5, -0.5],
                                             wMax=[0.5, 0.5],
                                             functionSpace=W,
                                             boundaryCondtions=bcs)
    # Create the PETScTAOSolver
    solver = dl.PETScTAOSolver()
    TAOSolverParameters = {
        "method": "tron",
        "maximum_iterations": 1000,
        "monitor_convergence": True
    }
    solver.parameters.update(TAOSolverParameters)
    #solver.parameters["report"] = False
    #solver.parameters["linear_solver"] = "umfpack"
    #solver.parameters["line_search"] = "gpcg"
    #solver.parameters["preconditioner"] = "ml_amg"

    growthRate = 0.1
    growthEnd = growthRate * tEnd
    gF = 0.0
    outDisp = dl.File(fileDir + "/displacement.pvd")
    outDisp << (w, 0.0)
    iCounter = 0
    wArray = w.compute_vertex_values()

    while gF <= growthEnd - tol:
        gF += growthRate * dt
        iCounter += 1
        growthFactor.gF = gF
        w.vector()[:] += 2e-04 * np.random.uniform(-1, 1,
                                                   w.vector().local_size())
        nIters, converged = solver.solve(problem, w.vector(),
                                         wLowerBound.vector(),
                                         wUpperBound.vector())
        wArray[:] = w.compute_vertex_values()
        np.save(fileDir + "/w-{}.npy".format(iCounter), wArray)
        print("--- growth = %.4f, niters = %d, dt = %.5f -----" %
              (1 + gF, nIters, dt))
        outDisp << (w, gF)