def __init__(self, V, **kwargs):
     # Call parent
     ParametrizedProblem.__init__(
         self,
         os.path.join("test_eim_approximation_14_tempdir",
                      expression_type, basis_generation,
                      "mock_problem"))
     # Minimal subset of a ParametrizedDifferentialProblem
     self.V = V
     self._solution = Function(V)
     self.components = ["u", "s", "p"]
     # Parametrized function to be interpolated
     x = SpatialCoordinate(V.mesh())
     mu = SymbolicParameters(self, V, (1., ))
     self.f00 = (1 - x[0]) * cos(3 * pi * mu[0] *
                                 (1 + x[0])) * exp(-mu[0] * (1 + x[0]))
     self.f01 = (1 - x[0]) * sin(3 * pi * mu[0] *
                                 (1 + x[0])) * exp(-mu[0] * (1 + x[0]))
     # Inner product
     f = TrialFunction(self.V)
     g = TestFunction(self.V)
     self.inner_product = assemble(inner(f, g) * dx)
     # Collapsed vector and space
     self.V0 = V.sub(0).collapse()
     self.V00 = V.sub(0).sub(0).collapse()
     self.V1 = V.sub(1).collapse()
Exemple #2
0
    def setChargeDensity(self):
        print("Setting charge density...")
        if self.eqn == "laplace":
            return dolfin.Constant("0.0") * self.v * self.dx
        elif self.eqn == "poisson":
            #use equilibrium charge density
            self.dp.dopingCalc()
            temp = -self.dp.getAsFunction(self.dp.rho, self.mesh, "x[2]")
            # dolfin.plot(temp)
            # plt.savefig(os.path.join(self.exporter.abs_in_dir,"temp.pdf"))
            return -self.dp.getAsFunction(self.dp.rho, self.mesh,
                                          "x[2]") * self.v * self.dx
        else:
            #use the poisson boltzmann definition for charge density.
            ni = 1E-14  #in ang^-3
            ni_exp = dolfin.Expression('x[2] < depth + DOLFIN_EPS ? p1 : p2', \
                depth=self.bounds["dielectric"], p1=dolfin.Constant(ni), \
                p2=dolfin.Constant(0), degree=1, domain=self.mesh)
            q = self.q
            k = 1.38064852E-23  # Boltzmann constant - metre^2 kilogram / second^2 Kelvin
            T = self.temp
            self.dp.dopingCalc()
            nd = dolfin.Expression('x[2] < depth + DOLFIN_EPS ? p1 : p2', \
               depth=self.dp.depth, p1=dolfin.Constant(self.dp.d_conc), p2=dolfin.Constant(0), degree=1, domain=self.mesh)

            if self.eqn == "linpoisboltz":
                return -2*q*q*ni_exp/k/T*self.u*self.v*self.dx \
                       -q*nd*self.v*self.dx

            elif self.eqn == "poisboltz":
                return q*ni_exp*dolfin.exp(q/k/T*(self.u))*self.v*self.dx \
                         - q*ni_exp*dolfin.exp(-q/k/T*self.u)*self.v*self.dx \
                         - q*nd*self.v*self.dx
    def updateCoefficients(self):

        # Init coefficient matrix
        x, y = SpatialCoordinate(self.mesh)

        self.a = 0.5 * as_matrix(
            [[cos(self.gamma[0]), sin(self.gamma[0])],
             [- sin(self.gamma[0]), cos(self.gamma[0])]]) \
            * as_matrix([[20, 1], [1, 0.1]]) \
            * as_matrix(
            [[cos(self.gamma[0]), - sin(self.gamma[0])],
             [sin(self.gamma[0]), cos(self.gamma[0])]])

        self.b = as_vector([Constant(0.0), Constant(1.0)])

        self.c = Constant(-10.0)

        self.u_ = (2*x-1.) \
            * (exp(1 - abs(2*x-1.)) - 1) \
            * (y + (1 - exp(y/self.delta))/(exp(1/self.delta)-1))

        # Init right-hand side
        self.f = inner(self.a, grad(grad(self.u_))) \
            + inner(self.b, grad(self.u_)) \
            + self.c * self.u_

        # Set boundary conditions
        self.g = Constant(0.0)
Exemple #4
0
    def W_1(self, I_1, diff=0, *args, **kwargs):
        r"""
        Isotropic contribution.

        If `diff = 0`, return

        .. math::

           \frac{a}{2 b} \left( e^{ b (I_1 - 3)}  -1 \right)

        If `diff = 1`, return

        .. math::

           \frac{a}{b} e^{ b (I_1 - 3)}

        If `diff = 2`, return

        .. math::

           \frac{a b}{2}  e^{ b (I_1 - 3)}

        """

        a = self.a
        b = self.b

        if diff == 0:
            return a / (2.0 * b) * (dolfin.exp(b * (I_1 - 3)) - 1)
        elif diff == 1:
            return a / 2.0 * dolfin.exp(b * (I_1 - 3))
        elif diff == 2:
            return a * b / 2.0 * dolfin.exp(b * (I_1 - 3))
    def initControl(self):
        self.controlSpace = [FunctionSpace(self.mesh, "DG", 0)]

        x, y = SpatialCoordinate(self.mesh)
        u_ = (2*x-1.) \
            * (exp(1 - abs(2*x-1.)) - 1) \
            * (y + (1 - exp(y/self.delta))/(exp(1/self.delta)-1))
        cs = self.controlSpace[0]
        du = self.u - u_

        du_xx = Dx(Dx(du, 0), 0)
        du_xy = Dx(Dx(du, 0), 1)
        du_yx = Dx(Dx(du, 1), 0)
        du_yy = Dx(Dx(du, 1), 1)

        du_xx_proj = project(du_xx, cs)
        du_xy_proj = project(du_xy, cs)
        du_yx_proj = project(du_yx, cs)
        du_yy_proj = project(du_yy, cs)

        # Use the UserExpression
        gamma_star = Gallistl_Sueli_1_optControl(du_xx_proj, du_xy_proj,
                                                 du_yx_proj, du_yy_proj,
                                                 self.alphamin, self.alphamax)
        # Interpolate evaluates expression in centers of mass
        # Project evaluates expression in vertices
        self.gamma = [gamma_star]
Exemple #6
0
    def W_4(self, I4, direction, diff=0, use_heaviside=False, *args, **kwargs):
        r"""
        Anisotropic contribution.

        If `diff = 0`, return

        .. math::

           \frac{a_f}{2 b_f} \left( e^{ b_f (I_{4f_0} - 1)_+^2} -1 \right)

        If `diff = 1`, return

        .. math::

           a_f (I_{4f_0} - 1)_+ e^{ b_f (I_{4f_0} - 1)^2}

        If `diff = 2`, return

        .. math::

           a_f h(I_{4f_0} - 1) (1 + 2b(I_{4f_0} - 1))
           e^{ b_f (I_{4f_0} - 1)_+^2}

        where

        .. math::

           h(x) = \frac{\mathrm{d}}{\mathrm{d}x} \max\{x,0\}

        is the Heaviside function.

        """
        assert direction in ["f", "s", "n"]
        a = getattr(self, f"a_{direction}")
        b = getattr(self, f"b_{direction}")

        if I4 == 0:
            return 0

        if diff == 0:
            try:
                if float(a) > dolfin.DOLFIN_EPS:
                    if float(b) > dolfin.DOLFIN_EPS:
                        return (a / (2.0 * b) *
                                (dolfin.exp(b * subplus(I4 - 1)**2) - 1.0))
                    else:
                        return a / 2.0 * subplus(I4 - 1)**2
                else:
                    return 0.0
            except Exception:
                # Probably failed to convert a and b to float
                return a / (2.0 * b) * (dolfin.exp(b * subplus(I4 - 1)**2) -
                                        1.0)

        elif diff == 1:
            return a * subplus(I4 - 1) * dolfin.exp(b * pow(I4 - 1, 2))
        elif diff == 2:
            return (a * heaviside(I4 - 1) * (1 + 2.0 * b * pow(I4 - 1, 2)) *
                    dolfin.exp(b * pow(I4 - 1, 2)))
def QoI_FEM(x0,y0,lam1,lam2,gridx,gridy,p):
    mesh = fn.UnitSquareMesh(gridx, gridy)
    V = fn.FunctionSpace(mesh, "Lagrange", p)

    # Define diffusion tensor (here, just a scalar function) and parameters
    A = fn.Expression((('exp(lam1)','a'),
                ('a','exp(lam2)')), a = fn.Constant(0.0), lam1 = lam1, lam2 = lam2, degree=3) 

    u_exact = fn.Expression("sin(lam1*pi*x[0])*cos(lam2*pi*x[1])", lam1 = lam1, lam2 = lam2, degree=2+p)

    # Define the mix of Neumann and Dirichlet BCs
    class LeftBoundary(fn.SubDomain):
        def inside(self, x, on_boundary):
            return (x[0] < fn.DOLFIN_EPS)
    class RightBoundary(fn.SubDomain):
        def inside(self, x, on_boundary):
            return (x[0] > 1.0 - fn.DOLFIN_EPS)
    class TopBoundary(fn.SubDomain):
        def inside(self, x, on_boundary):
            return (x[1] > 1.0 - fn.DOLFIN_EPS)
    class BottomBoundary(fn.SubDomain):
        def inside(self, x, on_boundary):
            return (x[1] < fn.DOLFIN_EPS)

    # Create a mesh function (mf) assigning an unsigned integer ('uint')
    # to each edge (which is a "Facet" in 2D)
    mf = fn.MeshFunction('size_t', mesh, 1)
    mf.set_all(0) # initialize the function to be zero
    # Setup the boundary classes that use Neumann boundary conditions
    NTB = TopBoundary() # instatiate
    NTB.mark(mf, 1) # set all values of the mf to be 1 on this boundary
    NBB = BottomBoundary()
    NBB.mark(mf, 2) # set all values of the mf to be 2 on this boundary
    NRB = RightBoundary()
    NRB.mark(mf, 3)

    # Define Dirichlet boundary conditions
    Gamma_0 = fn.DirichletBC(V, u_exact, LeftBoundary())
    bcs = [Gamma_0]

    # Define data necessary to approximate exact solution
    f = ( fn.exp(lam1)*(lam1*fn.pi)**2 + fn.exp(lam2)*(lam2*fn.pi)**2 ) * u_exact
    g1 = fn.Expression("-exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)    #pointing outward unit normal vector, pointing upaward (0,1)
    g2 = fn.Expression("exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)     #pointing downward (0,1)
    g3 = fn.Expression("exp(lam1)*lam1*pi*cos(lam1*pi*x[0])*cos(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)

    fn.ds = fn.ds(subdomain_data=mf)
    # Define variational problem
    u = fn.TrialFunction(V)
    v = fn.TestFunction(V)
    a = fn.inner(A*fn.grad(u), fn.grad(v))*fn.dx
    L = f*v*fn.dx + g1*v*fn.ds(1) + g2*v*fn.ds(2) + g3*v*fn.ds(3)  #note the 1, 2 and 3 correspond to the mf

    # Compute solution
    u = fn.Function(V)
    fn.solve(a == L, u, bcs)

    return u(x0,y0)
    def updateCoefficients(self):
        # Init coefficient matrix
        x, y = SpatialCoordinate(self.mesh)

        off_diag = conditional(x * y > 0, 1.0, -1.0)
        self.a = as_matrix([[2.0, off_diag], [off_diag, 2.0]])

        self.u_ = x * y * (1 - exp(1 - abs(x))) * (1 - exp(1 - abs(y)))

        # Init right-hand side
        self.f = inner(self.a, grad(grad(self.u_)))

        # Set boundary conditions to exact solution
        self.g = self.u_
Exemple #9
0
 def df_dlmbda(self, u, lmbda):
     v = TestFunction(self.V)
     ufun = Function(self.V)
     ufun.vector()[:] = u
     out = -assemble(exp(ufun) * v * dx)
     self.bc.apply(out)
     return out
    def assembleA(self, x, assemble_adjoint=False, assemble_rhs=False):
        """
        Assemble the matrices and rhs for the forward/adjoint problems
        """
        trial = dl.TrialFunction(self.Vh[STATE])
        test = dl.TestFunction(self.Vh[STATE])
        c = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
        Avarf = dl.inner(
            dl.exp(c) * dl.nabla_grad(trial), dl.nabla_grad(test)) * dl.dx
        if not assemble_adjoint:
            bform = dl.inner(self.f, test) * dl.dx
            Matrix, rhs = dl.assemble_system(Avarf, bform, self.bc)
        else:
            # Assemble the adjoint of A (i.e. the transpose of A)
            s = vector2Function(x[STATE], self.Vh[STATE])
            bform = dl.inner(dl.Constant(0.), test) * dl.dx
            Matrix, _ = dl.assemble_system(dl.adjoint(Avarf), bform, self.bc0)
            Bu = -(self.B * x[STATE])
            Bu += self.u_o
            rhs = dl.Vector()
            self.B.init_vector(rhs, 1)
            self.B.transpmult(Bu, rhs)
            rhs *= 1.0 / self.noise_variance

        if assemble_rhs:
            return Matrix, rhs
        else:
            return Matrix
 def f(self, u, lmbda):
     v = TestFunction(self.V)
     ufun = Function(self.V)
     ufun.vector()[:] = u
     out = (self.a * u - 10 * assemble(ufun * v * dx) +
            10 * lmbda * assemble(exp(ufun) * v * dx))
     return out
def perm_update_rutqvist_newton(mesh, p, p0, phi0, phi, coeff):
    DG0 = TensorFunctionSpace(mesh, 'DG', 0)
    mult_min = 1e-10
    expr = exp(coeff * (phi / phi0 - 1.0))
    mult = conditional(ge(expr, 0.0), expr, mult_min)
    p = p0 * mult
    return project(p, DG0)
Exemple #13
0
    def updateCoefficients(self):

        # Init coefficient matrix
        x, y = SpatialCoordinate(self.mesh)

        self.a = 0.5 * as_matrix(
            [[cos(self.gamma[0]), sin(self.gamma[0])],
             [- sin(self.gamma[0]), cos(self.gamma[0])]]) \
            * as_matrix([[1, sin(self.gamma[1])], [0, cos(self.gamma[1])]]) \
            * as_matrix([[1, 0], [sin(self.gamma[1]), cos(self.gamma[1])]]) \
            * as_matrix(
            [[cos(self.gamma[0]), - sin(self.gamma[0])],
             [sin(self.gamma[0]), cos(self.gamma[0])]])
        self.b = as_vector([Constant(0.0), Constant(0.0)])
        self.c = -pi**2

        self.u_ = exp(x * y) * sin(pi * x) * sin(pi * y)

        # Init right-hand side
        self.f = - sqrt(3) * (sin(self.gamma[1])/pi)**2 \
            + 111111
        # TODO work here

        # Set boundary conditions
        self.g = Constant(0.0)
def softplus(y1, y2, alpha=1):
    # The softplus function is a differentiable approximation
    # to the ramp function.  Its derivative is the logistic function.
    # Larger alpha makes a sharper transition.
    return Max(y1,
               y2) + (1. / alpha) * ln(1 + exp(alpha *
                                               (Min(y1, y2) - Max(y1, y2))))
Exemple #15
0
 def f(self, u, lmbda):
     v = TestFunction(self.V)
     ufun = Function(self.V)
     ufun.vector()[:] = u
     out = self.a * u - lmbda * assemble(exp(ufun) * v * dx)
     DirichletBC(self.V, ufun, "on_boundary").apply(out)
     return out
 def __init__(self, mock_problem, expression_type, basis_generation):
     self.V = mock_problem.V
     # Parametrized function to be interpolated
     mu = SymbolicParameters(mock_problem, self.V, (1., ))
     x = SpatialCoordinate(self.V.mesh())
     f = (1 - x[0]) * cos(3 * pi * mu[0] * (1 + x[0])) * exp(-mu[0] *
                                                             (1 + x[0]))
     #
     folder_prefix = os.path.join("test_eim_approximation_09_tempdir",
                                  expression_type, basis_generation)
     assert expression_type in ("Function", "Vector", "Matrix")
     if expression_type == "Function":
         # Call Parent constructor
         EIMApproximation.__init__(self, mock_problem,
                                   ParametrizedExpressionFactory(f),
                                   folder_prefix, basis_generation)
     elif expression_type == "Vector":
         v = TestFunction(self.V)
         form = f * v * dx
         # Call Parent constructor
         EIMApproximation.__init__(self, mock_problem,
                                   ParametrizedTensorFactory(form),
                                   folder_prefix, basis_generation)
     elif expression_type == "Matrix":
         u = TrialFunction(self.V)
         v = TestFunction(self.V)
         form = f * u * v * dx
         # Call Parent constructor
         EIMApproximation.__init__(self, mock_problem,
                                   ParametrizedTensorFactory(form),
                                   folder_prefix, basis_generation)
     else:  # impossible to arrive here anyway thanks to the assert
         raise AssertionError("Invalid expression_type")
Exemple #17
0
def compute_velocity(mesh, Vh, a, u):
    #export the velocity field v = - exp( a ) \grad u: then we solve ( exp(-a) v, w) = ( u, div w)
    Vv = dl.FunctionSpace(mesh, 'RT', 1)
    v = dl.Function(Vv, name="velocity")
    vtrial = dl.TrialFunction(Vv)
    vtest = dl.TestFunction(Vv)
    afun = dl.Function(Vh[PARAMETER], a)
    ufun = dl.Function(Vh[STATE], u)
    Mv = dl.exp(-afun) * dl.inner(vtrial, vtest) * dl.dx
    n = dl.FacetNormal(mesh)

    class TopBoundary(dl.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] > 1 - dl.DOLFIN_EPS

    Gamma_M = TopBoundary()
    boundaries = dl.FacetFunction("size_t", mesh)
    boundaries.set_all(0)
    Gamma_M.mark(boundaries, 1)
    dss = dl.Measure("ds")[boundaries]
    rhs = ufun * dl.div(vtest) * dl.dx - dl.dot(vtest, n) * dss(1)
    bcv = dl.DirichletBC(Vv, dl.Expression(("0.0", "0.0")), v_boundary)
    dl.solve(Mv == rhs, v, bcv)

    return v
    def updateCoefficients(self):

        # Init coefficient matrix
        x = SpatialCoordinate(self.mesh)[0]

        self.a = as_matrix([[.5 * (x * self.gamma[0] * self.sigmax)**2]])
        self.b = as_vector([x * (self.gamma[0] * (self.mu - self.r) + self.r)])
        self.c = Constant(0.0)

        # Init right-hand side
        self.f = Constant(0.0)
        self.u_ = exp(
            ((self.mu - self.r)**2 / (2 * self.sigmax**2) * self.alpha /
             (1 - self.alpha) + self.r * self.alpha) *
            (self.T[1] - self.t)) * (x**self.alpha) / self.alpha
        self.u_T = (x**self.alpha) / self.alpha

        # Set boundary conditions
        # self.g_t = lambda t : [(Constant(0.0), "near(x[0],0)")]
        self.g = Constant(0.0)
        # self.g_t = lambda t : self.u_t(t)

        self.gamma_star = [
            Constant((self.mu - self.r) / (self.sigmax**2 * (1 - self.alpha)))
        ]

        self.loc = conditional(x > 0.5, conditional(x < 1.5, 1, 0), 0)
Exemple #19
0
    def W_4(self, I_4, diff=0, *args, **kwargs):
        r"""
        Anisotropic contribution.

        If `diff = 0`, return

        .. math::

           \frac{a_f}{2 b_f} \left( e^{ b_f (I_{4f_0} - 1)_+^2} -1 \right)

        If `diff = 1`, return

        .. math::

           a_f (I_{4f_0} - 1)_+ e^{ b_f (I_{4f_0} - 1)^2}

        If `diff = 2`, return

        .. math::

           a_f h(I_{4f_0} - 1) (1 + 2b(I_{4f_0} - 1))
           e^{ b_f (I_{4f_0} - 1)_+^2}

        where

        .. math::

           h(x) = \frac{\mathrm{d}}{\mathrm{d}x} \max\{x,0\}

        is the Heaviside function.

        """
        a = self.a_f
        b = self.b_f

        if I_4 == 0:
            return 0

        if diff == 0:
            return (a / (2.0 * b) * heaviside(I_4 - 1) *
                    (dolfin.exp(b * pow(I_4 - 1, 2)) - 1))

        elif diff == 1:
            return a * subplus(I_4 - 1) * dolfin.exp(b * pow(I_4 - 1, 2))
        elif diff == 2:
            return (a * heaviside(I_4 - 1) * (1 + 2.0 * b * pow(I_4 - 1, 2)) *
                    dolfin.exp(b * pow(I_4 - 1, 2)))
Exemple #20
0
def main():
    fsr = FunctionSubspaceRegistry()

    deg = 2
    mesh = dolfin.UnitSquareMesh(100, 3)
    muc = mesh.ufl_cell()
    el_w = dolfin.FiniteElement('DG', muc, deg - 1)
    el_j = dolfin.FiniteElement('BDM', muc, deg)
    el_DG0 = dolfin.FiniteElement('DG', muc, 0)
    el = dolfin.MixedElement([el_w, el_j])
    space = dolfin.FunctionSpace(mesh, el)
    DG0 = dolfin.FunctionSpace(mesh, el_DG0)
    fsr.register(space)
    facet_normal = dolfin.FacetNormal(mesh)
    xyz = dolfin.SpatialCoordinate(mesh)

    trial = dolfin.Function(space)
    test = dolfin.TestFunction(space)

    w, c = dolfin.split(trial)
    v, phi = dolfin.split(test)

    sympy_exprs = derive_exprs()
    exprs = {
        k: sympy_dolfin_printer.to_ufl(sympy_exprs['R'], mesh, v)
        for k, v in sympy_exprs['quantities'].items()
    }

    f = exprs['f']
    w0 = dolfin.project(dolfin.conditional(dolfin.gt(xyz[0], 0.5), 1.0, 0.3),
                        DG0)
    w_BC = exprs['w']

    dx = dolfin.dx()
    form = (+v * dolfin.div(c) * dx - v * f * dx +
            dolfin.exp(w + w0) * dolfin.dot(phi, c) * dx +
            dolfin.div(phi) * w * dx -
            (w_BC - w0) * dolfin.dot(phi, facet_normal) * dolfin.ds() -
            (w0('-') - w0('+')) * dolfin.dot(phi('+'), facet_normal('+')) *
            dolfin.dS())

    solver = NewtonSolver(form,
                          trial, [],
                          parameters=dict(relaxation_parameter=1.0,
                                          maximum_iterations=15,
                                          extra_iterations=10,
                                          relative_tolerance=1e-6,
                                          absolute_tolerance=1e-7))

    solver.solve()

    with closing(XdmfPlot("out/qflop_test.xdmf", fsr)) as X:
        CG1 = dolfin.FunctionSpace(mesh, dolfin.FiniteElement('CG', muc, 1))
        X.add('w0', 1, w0, CG1)
        X.add('w_c', 1, w + w0, CG1)
        X.add('w_e', 1, exprs['w'], CG1)
        X.add('f', 1, f, CG1)
        X.add('cx_c', 1, c[0], CG1)
        X.add('cx_e', 1, exprs['c'][0], CG1)
Exemple #21
0
    def W_8(self, I8, *args, **kwargs):
        """
        Cross fiber-sheet contribution.
        """
        a = self.a_fs
        b = self.b_fs

        try:
            if float(a) > dolfin.DOLFIN_EPS:
                if float(b) > dolfin.DOLFIN_EPS:
                    return a / (2.0 * b) * (dolfin.exp(b * I8**2) - 1.0)
                else:
                    return a / 2.0 * I8**2
            else:
                return 0.0
        except Exception:
            return a / (2.0 * b) * (dolfin.exp(b * I8**2) - 1.0)
Exemple #22
0
    def updateCoefficients(self):
        # Init coefficient matrix
        x, y = SpatialCoordinate(self.mesh)

        self.a = as_matrix([[1.0, 0.0], [0.0, 1.0]])
        self.b = 100 * as_vector([1.0, -1.0])
        self.c = -0.1

        self.u_ = x * y * (1 - exp(1 - abs(x))) * (1 - exp(1 - abs(y)))

        # Init right-hand side
        self.f = inner(self.a, grad(grad(self.u_))) \
            + inner(self.b, grad(self.u_)) \
            + self.c * self.u_

        # Set boundary conditions to exact solution
        self.g = self.u_
    def strain_energy(self, F_):
        """
        UFL form of the strain energy.
        """

        params = self.parameters

        # Elastic part of deformation gradient
        F = self.Fe(F_)

        E = kinematics.GreenLagrangeStrain(F, isochoric=self.isochoric)

        CC = Constant(params["C"], name="C")

        e1 = self.f0
        e2 = self.s0
        e3 = self.n0

        if any(e is None for e in (e1, e2, e3)):
            msg = ("Need to provide the full orthotropic basis "
                   "for the Guccione model got \ne1 = {e1}\n"
                   "e2 = {e2}\ne3 = {e3}").format(e1=e1, e2=e2, e3=e3)
            raise ValueError(msg)

        if self.is_isotropic():
            # isotropic case
            Q = dolfin.inner(E, E)

        else:
            # fully anisotropic
            bt = Constant(params["bt"], name="bt")
            bf = Constant(params["bf"], name="bf")
            bfs = Constant(params["bfs"], name="bfs")

            E11, E12, E13 = (
                dolfin.inner(E * e1, e1),
                dolfin.inner(E * e1, e2),
                dolfin.inner(E * e1, e3),
            )
            _, E22, E23 = (
                dolfin.inner(E * e2, e1),
                dolfin.inner(E * e2, e2),
                dolfin.inner(E * e2, e3),
            )
            _, _, E33 = (
                dolfin.inner(E * e3, e1),
                dolfin.inner(E * e3, e2),
                dolfin.inner(E * e3, e3),
            )

            Q = (bf * E11**2 + bt * (E22**2 + E33**2 + 2 * E23**2) + bfs *
                 (2 * E12**2 + 2 * E13**2))

        # passive strain energy
        Wpassive = CC / 2.0 * (dolfin.exp(Q) - 1)
        Wactive = self.Wactive(F, diff=0)

        return Wpassive + Wactive
Exemple #24
0
 def plot_prior_sample(self, exp=False):
     samp = self.sample(exp)
     s = dl.Function(self.V)
     s.vector()[:] = samp[:]
     if exp == False:
         p = dl.plot(s)
         plt.colorbar(p)
     else:
         p = dl.plot(dl.exp(s))
         plt.colorbar(p)
Exemple #25
0
 def plot_prior(self, samp, exp=False, cmap='Spectral'):
     s = dl.Function(self.V)
     s.vector()[:] = samp[:]
     if exp == False:
         p = dl.plot(s, cmap=cmap)
         plt.colorbar(p)
     else:
         p = dl.plot(dl.exp(s))
         plt.colorbar(p)
     return p
 def jacobian_solver(self, u, lmbda, rhs):
     t = TrialFunction(self.V)
     v = TestFunction(self.V)
     ufun = Function(self.V)
     ufun.vector()[:] = u
     a = (self.a - 10 * assemble(t * v * dx) +
          10 * lmbda * assemble(exp(ufun) * t * v * dx))
     x = Function(self.V)
     solve(a, x.vector(), rhs)
     return x.vector()
Exemple #27
0
    def W_1(self, I1, diff=0, *args, **kwargs):
        r"""
        Isotropic contribution.

        If `diff = 0`, return

        .. math::

           \frac{a}{2 b} \left( e^{ b (I_1 - 3)}  -1 \right)

        If `diff = 1`, return

        .. math::

           \frac{a}{b} e^{ b (I_1 - 3)}

        If `diff = 2`, return

        .. math::

           \frac{a b}{2}  e^{ b (I_1 - 3)}

        """

        a = self.a
        b = self.b

        if diff == 0:
            try:
                if float(a) > dolfin.DOLFIN_EPS:
                    if float(b) > dolfin.DOLFIN_EPS:
                        return a / (2.0 * b) * (dolfin.exp(b * (I1 - 3)) - 1.0)
                    else:
                        return a / 2.0 * (I1 - 3)
                else:
                    return 0.0
            except Exception:
                return a / (2.0 * b) * (dolfin.exp(b * (I1 - 3)) - 1)
        elif diff == 1:
            return a / 2.0 * dolfin.exp(b * (I1 - 3))
        elif diff == 2:
            return a * b / 2.0 * dolfin.exp(b * (I1 - 3))
  def eval(self,values,x):
    '''

    :param values: value 1d array of length 1 with value ~0.69 in one case
    :param x:
    :return:
    '''
    # L = mesh_max-mesh_min
    # values[0] = 2.0 - (x[0]-mesh_min) / L * 6.0

    values[0] = 8.7/(1 + 200*exp(0.05e-3*(x[0]-300.e3))) - 8.0
 def assembleWmm(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the parameter (Newton method)
     """
     trial = dl.TrialFunction(self.Vh[PARAMETER])
     test  = dl.TestFunction(self.Vh[PARAMETER])
     u = vector2Function(x[STATE], self.Vh[STATE])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     p = vector2Function(x[ADJOINT], self.Vh[ADJOINT])
     varf = dl.inner(dl.grad(p),dl.exp(m)*dl.grad(u))*trial*test*dl.dx
     return dl.assemble(varf)
 def assembleWmm(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the parameter (Newton method)
     """
     trial = dl.TrialFunction(self.Vh[PARAMETER])
     test  = dl.TestFunction(self.Vh[PARAMETER])
     u = vector2Function(x[STATE], self.Vh[STATE])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     p = vector2Function(x[ADJOINT], self.Vh[ADJOINT])
     varf = dl.inner(dl.grad(p),dl.exp(m)*dl.grad(u))*trial*test*dl.dx
     return dl.assemble(varf)
 def assembleRaa(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the parameter (Newton method)
     """
     trial = dl.TrialFunction(self.Vh[PARAMETER])
     test = dl.TestFunction(self.Vh[PARAMETER])
     s = vector2Function(x[STATE], Vh[STATE])
     c = vector2Function(x[PARAMETER], Vh[PARAMETER])
     a = vector2Function(x[ADJOINT], Vh[ADJOINT])
     varf = dl.inner(dl.nabla_grad(a),
                     dl.exp(c) * dl.nabla_grad(s)) * trial * test * dl.dx
     return dl.assemble(varf)
    def assembleC(self, x):
        """
        Assemble the derivative of the forward problem with respect to the parameter
        """
        trial = dl.TrialFunction(self.Vh[PARAMETER])
        test = dl.TestFunction(self.Vh[STATE])
        u = vector2Function(x[STATE], Vh[STATE])
        m = vector2Function(x[PARAMETER], Vh[PARAMETER])
        Cvarf = dl.inner(dl.exp(m) * trial * dl.grad(u), dl.grad(test)) * dl.dx
        C = dl.assemble(Cvarf)
#        print ( "||m||", x[PARAMETER].norm("l2"), "||u||", x[STATE].norm("l2"), "||C||", C.norm("linf") )
        self.bc0.zero(C)
        return C
 def assembleWmu(self, x):
     """
     Assemble the derivative of the parameter equation with respect to the state
     """
     trial = dl.TrialFunction(self.Vh[STATE])
     test  = dl.TestFunction(self.Vh[PARAMETER])
     p = vector2Function(x[ADJOINT], self.Vh[ADJOINT])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     varf = dl.inner(dl.exp(m)*dl.grad(trial),dl.grad(p))*test*dl.dx
     Wmu = dl.assemble(varf)
     Wmu_t = Transpose(Wmu)
     self.bc0.zero(Wmu_t)
     Wmu = Transpose(Wmu_t)
     return Wmu
 def assembleA(self,x, assemble_adjoint = False, assemble_rhs = False):
     """
     Assemble the matrices and rhs for the forward/adjoint problems
     """
     trial = dl.TrialFunction(self.Vh[STATE])
     test = dl.TestFunction(self.Vh[STATE])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     Avarf = dl.inner(dl.exp(m)*dl.grad(trial), dl.grad(test))*dl.dx
     if not assemble_adjoint:
         bform = dl.inner(self.f, test)*dl.dx
         Matrix, rhs = dl.assemble_system(Avarf, bform, self.bc)
     else:
         # Assemble the adjoint of A (i.e. the transpose of A)
         u = vector2Function(x[STATE], self.Vh[STATE])
         obs = vector2Function(self.u_o, self.Vh[STATE])
         bform = dl.inner(obs - u, test)*dl.dx
         Matrix, rhs = dl.assemble_system(dl.adjoint(Avarf), bform, self.bc0)
         
     if assemble_rhs:
         return Matrix, rhs
     else:
         return Matrix
def RunJob(Tb, mu_value, path):
    runtimeInit = clock()

    tfile = File(path + '/t6t.pvd')
    mufile = File(path + "/mu.pvd")
    ufile = File(path + '/velocity.pvd')
    gradpfile = File(path + '/gradp.pvd')
    pfile = File(path + '/pstar.pvd')
    parameters = open(path + '/parameters', 'w', 0)
    vmeltfile = File(path + '/vmelt.pvd')
    rhofile = File(path + '/rhosolid.pvd')

    for name in dir():
        ev = str(eval(name))
        if name[0] != '_' and ev[0] != '<':
            parameters.write(name + ' = ' + ev + '\n')

    temp_values = [27. + 273, Tb + 273, 1300. + 273, 1305. + 273]
    dTemp = temp_values[3] - temp_values[0]
    temp_values = [x / dTemp for x in temp_values]  # non dimensionalising temp

    mu_a = mu_value  # this was taken from the blankenbach paper, can change..
    
    Ep = b / dTemp

    mu_bot = exp(-Ep * (temp_values[3] * dTemp - 1573) + cc) * mu_a

    Ra = rho_0 * alpha * g * dTemp * h**3 / (kappa_0 * mu_a)
    w0 = rho_0 * alpha * g * dTemp * h**2 / mu_a
    tau = h / w0
    p0 = mu_a * w0 / h

    print(mu_a, mu_bot, Ra, w0, p0)

    vslipx = 1.6e-09 / w0
    vslip = Constant((vslipx, 0.0))  # nondimensional
    noslip = Constant((0.0, 0.0))

    dt = 3.E11 / tau
    tEnd = 3.E13 / tau  # non-dimensionalising times

    class PeriodicBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return left(x, on_boundary)

        def map(self, x, y):
            y[0] = x[0] - MeshWidth
            y[1] = x[1]

    pbc = PeriodicBoundary()

    class TempExp(Expression):
        def eval(self, value, x):
            if x[1] >= LAB(x):
                value[0] = temp_values[0] + (temp_values[1] - temp_values[0]) * (MeshHeight - x[1]) / (MeshHeight - LAB(x))
            else:
                value[0] = temp_values[3] - (temp_values[3] - temp_values[2]) * (x[1]) / (LAB(x))

    class FluidTemp(Expression):
        def eval(self, value, x):
            if value[0] < 1295:
                value[0] = 1295

    mesh = RectangleMesh(Point(0.0, 0.0), Point(MeshWidth, MeshHeight), nx, ny)

    Svel = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc)
    Spre = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Stemp = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Smu = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    Sgradp = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc)
    Srho = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    S0 = MixedFunctionSpace([Svel, Spre, Stemp])

    u = Function(S0)
    v, p, T = split(u)
    v_t, p_t, T_t = TestFunctions(S0)

    T0 = interpolate(TempExp(), Stemp)

    muExp = Expression('exp(-Ep * (T_val * dTemp - 1573) + cc * x[2] / meshHeight)', Smu.ufl_element(),
                        Ep=Ep, dTemp=dTemp, cc=cc, meshHeight=MeshHeight, T_val=T0)

    mu = interpolate(muExp, Smu)

    rhosolid = Function(Srho)
    deltarho = Function(Srho)

    v0 = Function(Svel)
    vmelt = Function(Svel)

    v_theta = (1. - theta)*v0 + theta*v

    T_theta = (1. - theta)*T + theta*T0

    r_v = (inner(sym(grad(v_t)), 2.*mu*sym(grad(v))) \
        - div(v_t)*p \
        - T*v_t[1] )*dx

    r_p = p_t*div(v)*dx

    r_T = (T_t*((T - T0) \
        + dt*inner(v_theta, grad(T_theta))) \
        + (dt/Ra)*inner(grad(T_t), grad(T_theta)) )*dx
#           + k_s*(Tf-T_theta)*dt

    Tf = T0.interpolate(FluidTemp())
    # Tf = T0.interpolate(Expression('value[0] >= 1295.0 ? value[0] : 1295.0'))

    # Tf.interpolate(Expression('value[0] >= 1295 ? value[0] : 1295'))
    # project(Expression('value[0] >= 1295 ? value[0] : 1295'), Tf)
# Alex, a question for you:
# can you see if there is a way to set Tf = T in regions where T >=1295 celsius
#
# 1295 celsius is my arbitrary choice for the LAB isotherm.  In regions
# where T < 1295 C, set Tf to be some constant for now, such as 1295 C.
# Once we do this, then we can add in a term like that last line above where
# it will only be non-zero when the solid temperature, T, is cooler than 1295
# can you do this? After this is done, we will then worry about a calculation
# where we solve for Tf as a function of time in the regions cooler than 1295 C
# Makes sense?  If not, we can skype soon -- email me with questions
# 3/19/16
    r = r_v + r_p + r_T

    bcv0 = DirichletBC(S0.sub(0), noslip, top)
    bcv1 = DirichletBC(S0.sub(0), vslip, bottom)
    bcp0 = DirichletBC(S0.sub(1), Constant(0.0), bottom)
    bct0 = DirichletBC(S0.sub(2), Constant(temp_values[0]), top)
    bct1 = DirichletBC(S0.sub(2), Constant(temp_values[3]), bottom)

    bcs = [bcv0, bcv1, bcp0, bct0, bct1]

    t = 0
    count = 0
    while (t < tEnd):
        solve(r == 0, u, bcs)
        t += dt
        nV, nP, nT = u.split()
        gp = grad(nP)
        rhosolid = rho_0 * (1 - alpha * (nT * dTemp - 1573))
        deltarho = rhosolid - rhomelt
        yvec = Constant((0.0, 1.0))
        vmelt = nV * w0 - darcy * (gp * p0 / h - deltarho * yvec * g)
        if (count % 100 == 0):
            pfile << nP
            ufile << nV
            tfile << nT
            mufile << mu
            gradpfile << project(grad(nP), Sgradp)
            mufile << project(mu * mu_a, Smu)
            rhofile << project(rhosolid, Srho)
            vmeltfile << project(vmelt, Svel)
        count += 1
        assign(T0, nT)
        assign(v0, nV)
        mu.interpolate(muExp)

    print('Case mu=%g, Tb=%g complete.' % (mu_a, Tb), ' Run time =', clock() - runtimeInit, 's')
        else:
            print ("\nNot Converged")

        print ("Termination reason: ", solver.termination_reasons[solver.reason])
        print ("Final gradient norm: ", solver.final_grad_norm)
        print ("Final cost: ", solver.final_cost)
    
    model.setPointForHessianEvaluations(x, gauss_newton_approx=False)
    Hmisfit = ReducedHessian(model, solver.parameters["inner_rel_tolerance"], misfit_only=True)
    p = 20
    k = 50
    Omega = MultiVector(x[PARAMETER], k+p)
    parRandom.normal(1., Omega)

    d, U = doublePassG(Hmisfit, Prior.R, Prior.Rsolver, Omega, k, s=1, check=False)

    if rank == 0:
        plt.figure()
        plt.plot(range(0,k), d, 'b*',range(0,k), np.ones(k), '-r')
        plt.yscale('log')
        plt.show()
    
    if nproc == 1:
        xx = [vector2Function(x[i], Vh[i]) for i in range(len(Vh))]
        dl.plot(xx[STATE], title = "State")
        dl.plot(dl.exp(xx[PARAMETER]), title = "exp(Parameter)")
        dl.plot(xx[ADJOINT], title = "Adjoint")
        dl.plot(vector2Function(model.u_o, Vh[STATE]), title = "Observation")
        dl.interactive()
    
 def eval(self, values, x):
   y_0       = -H + a0 * (exp(-((x[0]-L/2.)**2 + (x[1]-L/2.)**2) / sigma**2))
   values[0] = sin(theta)/cos(theta) * (x[0] + sin(theta)*y_0) \
               + cos(theta)*y_0
Exemple #38
0
m4 = 4.49
m5 = 4.49
m6 = 12.02 
m = (m0,m1,m2,m3,m4,m5,m6)
parameters = dl.interpolate(dl.Constant(m),parameterV)

#Model
d    = len(u)
I    = dl.Identity(d)            # Identity tensor
F    = I + dl.grad(u)            # Deformation gradient
C    = F.T*F                     # Right Cauchy-Green tensor
J    = dl.det(F)                 # Jacobian of deformation gradient
Cbar = C*(J**(-2.0/3.0))           # Deviatoric Right Cauchy-Green tensor
E    = dl.Constant(0.5)*(Cbar-I) # Deviatoric Green strain

c0,c1,c2,c3,c4,c5,c6 = dl.split(parameters)

Q = c1*(E[0,0]**2)+c2*(E[1,1]**2)+c3*(E[2,2]**2) + c4*(dl.Constant(4.0)*(E[1,2]**2)) #+c5*(dl.Constant(4.0)*(E[0,1]**2))#)#+c6*(dl.Constant(4.0)*(E[0,2]**2))
Energy = dl.Constant(0.5)*c0*(dl.exp(Q)-dl.Constant(1.0))
IncompressibilityConstraint = (J-dl.Constant(1.0))
Lagrangian = p*IncompressibilityConstraint*dl.dx  + Energy*dl.dx
yhat = dl.interpolate(dl.Constant((1,1,1,1)),TaylorHoodV)
residual_form = dl.derivative(Lagrangian,y,yhat) 
residual_form_a = dl.derivative(residual_form, a,atest)
residual_form_y = dl.derivative(residual_form, y,ytest)

residual_form_ya = dl.assemble(dl.derivative(residual_form_y, a,atrial))
residual_form_ay = dl.assemble(dl.derivative(residual_form_a, y,ytrial))
residual_form_aa = dl.assemble(dl.derivative(residual_form_a, a,atrial))
residual_form_yy = dl.assemble(dl.derivative(residual_form_y, y,ytrial))
Exemple #39
0
def run_with_params(Tb, mu_value, k_s, path):
    run_time_init = clock()

    mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(mesh_width, mesh_width, mesh_height), nx, ny, nz)

    pbc = PeriodicBoundary()

    WE = VectorElement('CG', mesh.ufl_cell(), 2)
    SE = FiniteElement('CG', mesh.ufl_cell(), 1)
    WSSS = FunctionSpace(mesh, MixedElement(WE, SE, SE, SE), constrained_domain=pbc)
    # W = FunctionSpace(mesh, WE, constrained_domain=pbc)
    # S = FunctionSpace(mesh, SE, constrained_domain=pbc)
    W = WSSS.sub(0).collapse()
    S = WSSS.sub(1).collapse()

    temperature_vals = [27.0 + 273, Tb + 273, 1300.0 + 273, 1305.0 + 273]
    temp_prof = TemperatureProfile(temperature_vals, element=S.ufl_element())

    mu_a = mu_value  # this was taken from the Blankenbach paper, can change

    Ep = b / temp_prof.delta

    mu_bot = exp(-Ep * (temp_prof.bottom * temp_prof.delta - 1573.0) + cc) * mu_a

    # TODO: verify exponentiation
    Ra = rho_0 * alpha * g * temp_prof.delta * h ** 3 / (kappa_0 * mu_a)
    w0 = rho_0 * alpha * g * temp_prof.delta * h ** 2 / mu_a
    tau = h / w0
    p0 = mu_a * w0 / h

    log(mu_a, mu_bot, Ra, w0, p0)

    slip_vx = 1.6E-09 / w0  # Non-dimensional
    slip_velocity = Constant((slip_vx, 0.0, 0.0))
    zero_slip = Constant((0.0, 0.0, 0.0))

    time_step = 3.0E11 / tau * 2

    dt = Constant(time_step)
    t_end = 3.0E15 / tau / 5.0  # Non-dimensional times

    u = Function(WSSS)

    # Instead of TrialFunctions, we use split(u) for our non-linear problem
    v, p, T, Tf = split(u)
    v_t, p_t, T_t, Tf_t = TestFunctions(WSSS)

    T0 = interpolate(temp_prof, S)

    mu_exp = Expression('exp(-Ep * (T_val * dTemp - 1573.0) + cc * x[2] / mesh_height)',
                       Ep=Ep, dTemp=temp_prof.delta, cc=cc, mesh_height=mesh_height, T_val=T0,
                       element=S.ufl_element())

    Tf0 = interpolate(temp_prof, S)

    mu = Function(S)
    v0 = Function(W)

    v_theta = (1.0 - theta) * v0 + theta * v

    T_theta = (1.0 - theta) * T0 + theta * T

    Tf_theta = (1.0 - theta) * Tf0 + theta * Tf

    # TODO: Verify forms

    r_v = (inner(sym(grad(v_t)), 2.0 * mu * sym(grad(v)))
           - div(v_t) * p
           - T * v_t[2]) * dx

    r_p = p_t * div(v) * dx

    heat_transfer = Constant(k_s) * (Tf_theta - T_theta) * dt

    r_T = (T_t * ((T - T0) + dt * inner(v_theta, grad(T_theta)))  # TODO: Inner vs dot
           + (dt / Ra) * inner(grad(T_t), grad(T_theta))
           - T_t * heat_transfer) * dx

    v_melt = Function(W)
    z_hat = Constant((0.0, 0.0, 1.0))

    # TODO: inner -> dot, take out Tf_t
    r_Tf = (Tf_t * ((Tf - Tf0) + dt * inner(v_melt, grad(Tf_theta)))
            + Tf_t * heat_transfer) * dx

    r = r_v + r_p + r_T + r_Tf

    bcv0 = DirichletBC(WSSS.sub(0), zero_slip, top)
    bcv1 = DirichletBC(WSSS.sub(0), slip_velocity, bottom)
    bcv2 = DirichletBC(WSSS.sub(0).sub(1), Constant(0.0), back)
    bcv3 = DirichletBC(WSSS.sub(0).sub(1), Constant(0.0), front)

    bcp0 = DirichletBC(WSSS.sub(1), Constant(0.0), bottom)
    bct0 = DirichletBC(WSSS.sub(2), Constant(temp_prof.surface), top)
    bct1 = DirichletBC(WSSS.sub(2), Constant(temp_prof.bottom), bottom)
    bctf1 = DirichletBC(WSSS.sub(3), Constant(temp_prof.bottom), bottom)

    bcs = [bcv0, bcv1, bcv2, bcv3, bcp0, bct0, bct1, bctf1]

    t = 0
    count = 0
    files = DefaultDictByKey(partial(create_xdmf, path))

    while t < t_end:
        mu.interpolate(mu_exp)
        rhosolid = rho_0 * (1.0 - alpha * (T0 * temp_prof.delta - 1573.0))
        deltarho = rhosolid - rho_melt
        # TODO: project (accuracy) vs interpolate
        assign(v_melt, project(v0 - darcy * (grad(p) * p0 / h - deltarho * z_hat * g) / w0, W))
        # TODO: Written out one step later?
        # v_melt.assign(v0 - darcy * (grad(p) * p0 / h - deltarho * yvec * g) / w0)
        # TODO: use nP after to avoid projection?

        solve(r == 0, u, bcs)
        nV, nP, nT, nTf = u.split()  # TODO: write with Tf, ... etc

        if count % output_every == 0:
            time_left(count, t_end / time_step, run_time_init)  # TODO: timestep vs dt

            # TODO: Make sure all writes are to the same function for each time step
            files['T_fluid'].write(nTf, t)
            files['p'].write(nP, t)
            files['v_solid'].write(nV, t)
            files['T_solid'].write(nT, t)
            files['mu'].write(mu, t)
            files['v_melt'].write(v_melt, t)
            files['gradp'].write(project(grad(nP), W), t)
            files['rho'].write(project(rhosolid, S), t)
            files['Tf_grad'].write(project(grad(Tf), W), t)
            files['advect'].write(project(dt * dot(v_melt, grad(nTf))), t)
            files['ht'].write(project(heat_transfer, S), t)

        assign(T0, nT)
        assign(v0, nV)
        assign(Tf0, nTf)

        t += time_step
        count += 1

    log('Case mu={}, Tb={}, k={} complete. Run time = {:.2f} minutes'.format(mu_a, Tb, k_s, (clock() - run_time_init) / 60.0))