Пример #1
0
    def __init__(self, V, u, v, b,
                 kappa, rho, cp,
                 source,
                 dirichlet_bcs=[],
                 neumann_bcs={},
                 robin_bcs={},
                 dx=dx,
                 ds=ds
                 ):
        super(HeatCylindrical, self).__init__()
        self.dirichlet_bcs = dirichlet_bcs
        r = Expression('x[0]', degree=1, domain=V.mesh())
        self.V = V
        self.dx_multiplier = 2*pi*r

        self.F0 = kappa * r * dot(grad(u), grad(v / (rho * cp))) \
            * 2*pi * dx
        #F -= dot(b, grad(u)) * v * 2*pi*r * dx_workpiece(0)
        if b:
            self.F0 += (b[0] * u.dx(0) + b[1] * u.dx(1)) * v * 2*pi*r * dx
        # Joule heat
        self.F0 -= 1.0 / (rho * cp) * source * v * 2*pi*r * dx
        # Neumann boundary conditions
        for k, nGradT in neumann_bcs.iteritems():
            self.F0 -= r * kappa * nGradT * v / (rho * cp) \
                * 2 * pi * ds(k)
        # Robin boundary conditions
        for k, value in robin_bcs.iteritems():
            alpha, u0 = value
            self.F0 -= r * kappa * alpha * (u - u0) * v / (rho * cp) \
                * 2 * pi * ds(k)
        return
    def setup_forms(self, old_solver):
        prob = self.prob

        if old_solver is not None:
            self.old_vel = dfn.interpolate(old_solver.old_vel,
                                                     prob.v_fnc_space)
            self.cur_vel = dfn.interpolate(old_solver.cur_vel,
                                                     prob.v_fnc_space)
        else:
            self.old_vel = dfn.Function(prob.v_fnc_space)
            self.cur_vel = dfn.Function(prob.v_fnc_space)

        # Assemble matrices from variational forms. Ax = Ls
        self.a = dfn.inner(dfn.grad(prob.v), dfn.grad(prob.vt)) * dfn.dx
        self.A = dfn.assemble(self.a)

        if params['bcs'] is 'test':
            self.bcs = get_test_bcs(prob.v_fnc_space, test_bc)
        else:
            self.bcs = get_normal_bcs(prob.v_fnc_space, test_bc)

        # For the gradient term in the stress update
        self.l_elastic = self.dt * self.mu * \
            dfn.inner(dfn.grad(prob.v), prob.St) * dfn.dx
        self.L_elastic = dfn.assemble(self.l_elastic)
Пример #3
0
def les_update(nut_, nut_form, A_mass, At, u_, dt, bc_ksgs, bt, ksgs_sol,
        KineticEnergySGS, CG1, ksgs, delta, **NS_namespace):

    p, q = TrialFunction(CG1), TestFunction(CG1)

    Ck = KineticEnergySGS["Ck"]
    Ce = KineticEnergySGS["Ce"]

    Sij = sym(grad(u_))
    assemble(dt*inner(dot(u_, 0.5*grad(p)), q)*dx
             + inner((dt*Ce*sqrt(ksgs)/delta)*0.5*p, q)*dx
             + inner(dt*Ck*sqrt(ksgs)*delta*grad(0.5*p), grad(q))*dx, tensor=At)
    
    assemble(dt*2*Ck*delta*sqrt(ksgs)*inner(Sij,grad(u_))*q*dx, tensor=bt)
    bt.axpy(1.0, A_mass*ksgs.vector())
    bt.axpy(-1.0, At*ksgs.vector())
    At.axpy(1.0, A_mass, True)

    # Solve for ksgs
    bc_ksgs.apply(At, bt)
    ksgs_sol.solve(At, ksgs.vector(), bt)
    ksgs.vector().set_local(ksgs.vector().array().clip(min=1e-7))
    ksgs.vector().apply("insert")

    # Update nut_
    nut_()
def get_distance_function(config, domains):
    V = dolfin.FunctionSpace(config.domain.mesh, "CG", 1)
    v = dolfin.TestFunction(V)
    d = dolfin.TrialFunction(V)
    sol = dolfin.Function(V)
    s = dolfin.interpolate(Constant(1.0), V)
    domains_func = dolfin.Function(dolfin.FunctionSpace(config.domain.mesh, "DG", 0))
    domains_func.vector().set_local(domains.array().astype(numpy.float))

    def boundary(x):
        eps_x = config.params["turbine_x"]
        eps_y = config.params["turbine_y"]

        min_val = 1
        for e_x, e_y in [(-eps_x, 0), (eps_x, 0), (0, -eps_y), (0, eps_y)]:
            try:
                min_val = min(min_val, domains_func((x[0] + e_x, x[1] + e_y)))
            except RuntimeError:
                pass

        return min_val == 1.0

    bc = dolfin.DirichletBC(V, 0.0, boundary)

    # Solve the diffusion problem with a constant source term
    log(INFO, "Solving diffusion problem to identify feasible area ...")
    a = dolfin.inner(dolfin.grad(d), dolfin.grad(v)) * dolfin.dx
    L = dolfin.inner(s, v) * dolfin.dx
    dolfin.solve(a == L, sol, bc)

    return sol
Пример #5
0
    def solve(self, mesh, num=5):
        """ Solve for num eigenvalues based on the mesh. """
        # conforming elements
        V = FunctionSpace(mesh, "CG", self.degree)
        u = TrialFunction(V)
        v = TestFunction(V)

        # weak formulation
        a = inner(grad(u), grad(v)) * dx
        b = u * v * ds
        A = PETScMatrix()
        B = PETScMatrix()
        A = assemble(a, tensor=A)
        B = assemble(b, tensor=B)

        # find eigenvalues
        eigensolver = SLEPcEigenSolver(A, B)
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["spectrum"] = "smallest real"
        eigensolver.parameters["spectral_shift"] = 1.0E-10
        eigensolver.solve(num + 1)

        # extract solutions
        lst = [
            eigensolver.get_eigenpair(i) for i in range(
                1,
                eigensolver.get_number_converged())]
        for k in range(len(lst)):
            u = Function(V)
            u.vector()[:] = lst[k][2]
            lst[k] = (lst[k][0], u)  # pair (eigenvalue,eigenfunction)
        return np.array(lst)
Пример #6
0
def neumann_poisson_data():
    '''
    Return:
        a  bilinear form in the neumann poisson problem
        L  linear form in therein
        V  function space, where a, L are defined
        bc homog. dirichlet conditions for case where we want pos. def problem
        z  list of orthonormal vectors in the nullspace of A that form basis
           of ker(A)

    '''
    mesh = UnitSquareMesh(40, 40)

    V = FunctionSpace(mesh, 'CG', 1)
    u = TrialFunction(V)
    v = TestFunction(V)

    f = Expression('x[0]+x[1]')
    a = inner(grad(u), grad(v))*dx
    L = inner(f, v)*dx

    bc = DirichletBC(V, Constant(0), DomainBoundary())

    z0 = interpolate(Constant(1), V).vector()
    normalize(z0, 'l2')

    print '%16E' % z0.norm('l2')
    assert abs(z0.norm('l2')-1) < 1E-13

    return a, L, V, bc, [z0]
Пример #7
0
 def weak_F(t, u_t, u, v):
     # All time-dependent components be set to t.
     u0.t = t
     f.t = f
     F = - 1.0 / (rho * cp) * kappa * dot(grad(u), grad(v)) * dx \
         + 1.0 / (rho * cp) * kappa * (u*u*u*u - u0*u0*u0*u0) * v * ds \
         + 1.0 / (rho * cp) * f * v * dx
     return F
Пример #8
0
    def compute(self, get):
        u = get("Velocity")
        p = get("Pressure")
        mu = get("DynamicViscosity")
        if isinstance(mu, (float, int)):
            mu = Constant(mu)

        expr = mu*(grad(u) + grad(u).T) - p*Identity(len(u))

        return self.expr2function(expr, self._function)
Пример #9
0
 def get_system(self, t):
     kappa.t = t
     f.t = t
     n = FacetNormal(self.V.mesh())
     u = TrialFunction(self.V)
     v = TestFunction(self.V)
     F = inner(kappa * grad(u), grad(v / self.rho_cp)) * dx \
         - inner(kappa * grad(u), n) * v / self.rho_cp * ds \
         - f * v / self.rho_cp * dx
     return assemble(lhs(F)), assemble(rhs(F))
Пример #10
0
 def weak_F(t, u_t, u, v):
     # Define the differential equation.
     mesh = v.function_space().mesh()
     n = FacetNormal(mesh)
     # All time-dependent components be set to t.
     f.t = t
     F = - inner(kappa * grad(u), grad(v / (rho * cp))) * dx \
         + inner(kappa * grad(u), n) * v / (rho * cp) * ds \
         + f * v / (rho * cp) * dx
     return F
Пример #11
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)
Пример #12
0
def compute_lorentz(Phi, omega, sigma):
    '''
    In a time-harmonic discretization with

    .. math::
        A &= \Re(a \exp(i \omega t)),\\\\
        B &= \Re(b \exp(i \omega t)),

    the time-average of :math:`A\\times B` over one period is

    .. math::
        \overline{A\\times B} = \\frac{1}{2} \Re(a \\times b^*),

    see <http://www.ece.rutgers.edu/~orfanidi/ewa/ch01.pdf>.
    Since the Lorentz force generated by the current :math:`J` in the magnetic
    field :math:`B` is

    .. math::
        F_L = J \\times B,

    its time average is

    .. math::
       \overline{F_L} = \\frac{1}{2} \Re(j \\times b^*).

    With

    .. math::
       J &= \exp(i \omega t) j e_{\\theta},\\\\
       B &= \exp(i \omega t) \left(-\\frac{d\phi}{dz} e_r + \\frac{1}{r}
            \\frac{d(r\phi)}{dr} e_z\\right),

    we have

    .. math::
       \overline{F_L} &= \\frac{1}{2} \Re\left(j \\frac{d\phi}{dz} e_z + \\frac{j}{r}
       \\frac{d(r\phi)}{dr} e_r\\right)\\\\
                      &= \\frac{1}{2} \Re\\left(\\frac{j}{r} \\nabla(r\phi^*)\\right)\\\\
                      &= \\frac{1}{2} \\left(\\frac{\Re(j)}{r} \\nabla(r \Re(\phi))
                             +\\frac{\Im(j)}{r} \\nabla(r \Im(\phi))\\right)

    Only create the Lorentz force for the workpiece. This avoids
    complications with j(r,z) for which we here can assume

    .. math::
        j = -i \sigma \omega \phi

    (in particular not containing a voltage term).
    '''
    r = Expression('x[0]', degree=1, domain=Phi[0].function_space().mesh())
    j_r = + sigma * omega * Phi[1]
    j_i = - sigma * omega * Phi[0]
    return 0.5 * (j_r / r * grad(r * Phi[0])
                 +j_i / r * grad(r * Phi[1]))
    def Jt(self, state, turbine_field):
        """ Computes the cost of the farm.

        :param state: Current solution state
        :type state: dolfin.Function
        :param turbine_field: Turbine friction field
        :type turbine_field: dolfin.Function

        """
        # Note, this will not work properly for DG elements (need to add dS measures)
        mesh = turbine_field.function_space().mesh()
        return inner(grad(turbine_field), grad(turbine_field))*self.farm.site_dx(domain=mesh)
def get_convmats(u0_dolfun=None, u0_vec=None, V=None, invinds=None,
                 dbcvals=None, dbcinds=None, diribcs=None):
    """returns the matrices related to the linearized convection

    where u_0 is the linearization point

    Returns
    -------
    N1 : (N,N) sparse matrix
        representing :math:`(u_0 \\cdot \\nabla )u`
    N2 : (N,N) sparse matrix
        representing :math:`(u \\cdot \\nabla )u_0`
    fv : (N,1) array
        representing :math:`(u_0 \\cdot \\nabla )u_0`

    See Also
    --------
    stokes_navier_utils.get_v_conv_conts : the convection contributions \
            reduced to the inner nodes

    """

    if u0_vec is not None:
        u0, p = expand_vp_dolfunc(vc=u0_vec, V=V, diribcs=diribcs,
                                  dbcvals=dbcvals, dbcinds=dbcinds,
                                  invinds=invinds)
    else:
        u0 = u0_dolfun

    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)

    # Assemble system
    n1 = inner(grad(u) * u0, v) * dx
    n2 = inner(grad(u0) * u, v) * dx
    f3 = inner(grad(u0) * u0, v) * dx

    n1 = dolfin.assemble(n1)
    n2 = dolfin.assemble(n2)
    f3 = dolfin.assemble(f3)

    # Convert DOLFIN representation to scipy arrays
    N1 = mat_dolfin2sparse(n1)
    N1.eliminate_zeros()

    N2 = mat_dolfin2sparse(n2)
    N2.eliminate_zeros()

    fv = f3.get_local()
    fv = fv.reshape(len(fv), 1)

    return N1, N2, fv
Пример #15
0
    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
Пример #16
0
 def weak_F(t, u_t, u, v):
     # Define the differential equation.
     mesh = v.function_space().mesh()
     n = FacetNormal(mesh)
     r = Expression('x[0]', degree=1, cell=triangle)
     # All time-dependent components be set to t.
     f.t = t
     b.t = t
     kappa.t = t
     F = - inner(b, grad(u)) * v * dx \
         - 1.0 / (rho * cp) * dot(r * kappa * grad(u), grad(v / r)) * dx \
         + 1.0 / (rho * cp) * dot(r * kappa * grad(u), n) * v / r * ds \
         + 1.0 / (rho * cp) * f * v * dx
     return F
Пример #17
0
 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 get_convvec(u0_dolfun=None, V=None, u0_vec=None, femp=None,
                dbcvals=None, dbcinds=None,
                diribcs=None, invinds=None):
    """return the convection vector e.g. for explicit schemes

    given a dolfin function or the coefficient vector
    """

    if u0_vec is not None:
        if femp is not None:
            diribcs = femp['diribcs']
            invinds = femp['invinds']
        u0, p = expand_vp_dolfunc(vc=u0_vec, V=V, diribcs=diribcs,
                                  dbcvals=dbcvals, dbcinds=dbcinds,
                                  invinds=invinds)
    else:
        u0 = u0_dolfun

    v = dolfin.TestFunction(V)
    ConvForm = inner(grad(u0) * u0, v) * dx

    ConvForm = dolfin.assemble(ConvForm)
    if invinds is not None:
        ConvVec = ConvForm.get_local()[invinds]
    else:
        ConvVec = ConvForm.get_local()
    ConvVec = ConvVec.reshape(len(ConvVec), 1)

    return ConvVec
Пример #19
0
    def __init__(self, N, dt):
        """Set up PDE problem for NxN mesh and time step dt."""
        from dolfin import UnitSquareMesh, FunctionSpace, TrialFunction, TestFunction, Function, dx, dot, grad

        mesh = UnitSquareMesh(N, N)
        self.V = V = FunctionSpace(mesh, "Lagrange", 1)

        u = TrialFunction(V)
        v = TestFunction(V)

        a = u * v * dx + dt * dot(grad(u), grad(v)) * dx

        self.a = a
        self.dt = dt
        self.mesh = mesh
        self.U = Function(V)
Пример #20
0
def system0(n):
    import dolfin as df
    mesh = df.UnitIntervalMesh(n)
    V = df.FunctionSpace(mesh, 'CG', 1)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)
    bc = df.DirichletBC(V, df.Constant(0), 'on_boundary')

    a = df.inner(df.grad(u), df.grad(v))*df.dx
    m = df.inner(u, v)*df.dx
    L = df.inner(df.Constant(0), v)*df.dx

    A, _ = df.assemble_system(a, L, bc)
    M, _ = df.assemble_system(m, L, bc)

    return A, M
Пример #21
0
 def __init__(self, nut, u, Space, bcs=[], name=""):
     
     Function.__init__(self, Space, name=name)
     
     dim = Space.mesh().geometry().dim()    
     test = TestFunction(Space)
     self.bf = [inner(inner(grad(nut), u.dx(i)), test)*dx for i in range(dim)]
Пример #22
0
    def __init__(self, mesh, num, denom, method="CR"):
        """ Assemble matrices and cache matrices. """
        self.V = FunctionSpace(mesh, method, 1)
        # save coordinates of DOFs
        self.dofs = np.reshape(self.V.dofmap().tabulate_all_coordinates(mesh),
                               (-1, 2))
        u = TrialFunction(self.V)
        v = TestFunction(self.V)
        self.boundary = MeshFunction("size_t", mesh, 1)
        # assemble matrices
        a = inner(grad(u), grad(v)) * dx
        b = u * v * dx
        self.A = uBLASSparseMatrix()
        self.A = assemble(a, tensor=self.A)
        self.A.compress()
        self.B = uBLASSparseMatrix()
        self.B = assemble(b, tensor=self.B)
        self.B.compress()
        size = mesh.size(2)
        # cell diameter calculation
        self.H2 = (num ** 2 + denom ** 2) * 1.0 / size
        # print "Theoretical cell diameter: ", sqrt(self.H2)
        # print "FEniCS calculated: ", mesh.hmax()

        # Matrices have rational entries. We can rescale to get integers
        # and save as scipy matrices
        scaleB = 6.0*size/num/denom
        self.scaleB = scaleB
        self.B *= scaleB
        r, c, val = self.B.data()
        val = np.round(val)
        self.B = sps.csr_matrix((val, c, r))
        # check if B is diagonal
        assert len(self.B.diagonal()) == self.B.nnz
        # find B inverse
        self.Binv = sps.csr_matrix((1.0/val, c, r))
        scaleA = 1.0*num*denom/2
        self.scaleA = scaleA
        self.A *= scaleA
        r, c, val = self.A.data()
        self.A = sps.csr_matrix((np.round(val), c, r))

        self.scale = scaleA/scaleB
        print 'scaling A by: ', scaleA
        print 'scaling B by: ', scaleB
        print 'eigenvalues scale by:', self.scale
Пример #23
0
    def test_conv_asquad(self):
        import dolfin_navier_scipy as dns
        from dolfin import dx, grad, inner
        import scipy.sparse as sps

        femp, stokesmatsc, rhsd_vfrc, rhsd_stbc, \
            data_prfx, ddir, proutdir = \
            dns.problem_setups.get_sysmats(problem='drivencavity',
                                           N=15, nu=1e-2)

        invinds = femp['invinds']
        V = femp['V']

        hmat = dns.dolfin_to_sparrays.\
            ass_convmat_asmatquad(W=femp['V'], invindsw=invinds)

        xexp = '(1-x[0])*x[0]*(1-x[1])*x[1]*x[0]+2'
        yexp = '(1-x[0])*x[0]*(1-x[1])*x[1]*x[1]+1'
        # yexp = 'x[0]*x[0]*x[1]*x[1]'

        f = dolfin.Expression((xexp, yexp))

        u = dolfin.interpolate(f, V)
        uvec = np.atleast_2d(u.vector().array()).T

        uvec_gamma = uvec.copy()
        uvec_gamma[invinds] = 0
        u_gamma = dolfin.Function(V)
        u_gamma.vector().set_local(uvec_gamma)

        uvec_i = 0 * uvec
        uvec_i[invinds, :] = uvec[invinds]
        u_i = dolfin.Function(V)
        u_i.vector().set_local(uvec_i)

        # Assemble the 'actual' form
        w = dolfin.TrialFunction(V)
        wt = dolfin.TestFunction(V)
        nform = dolfin.assemble(inner(grad(w) * u, wt) * dx)
        rows, cols, values = nform.data()
        nmat = sps.csr_matrix((values, cols, rows))
        # consider only the 'inner' equations
        nmatrc = nmat[invinds, :][:, :]

        # the boundary terms
        N1, N2, fv = dns.dolfin_to_sparrays.\
            get_convmats(u0_dolfun=u_gamma, V=V)

        # print np.linalg.norm(nmatrc * uvec_i + nmatrc * uvec_gamma)
        classicalconv = nmatrc * uvec
        quadconv = (hmat * np.kron(uvec[invinds], uvec[invinds])
                    + ((N1 + N2) * uvec_i)[invinds, :] + fv[invinds, :])
        self.assertTrue(np.allclose(classicalconv, quadconv))
        # print 'consistency tests'
        self.assertTrue((np.linalg.norm(uvec[invinds])
                         - np.linalg.norm(uvec_i)) < 1e-14)
        self.assertTrue(np.linalg.norm(uvec - uvec_gamma - uvec_i) < 1e-14)
Пример #24
0
    def before_first_compute(self, get):
        u = get("Velocity")
        assert len(u) == 2, "Can only compute stream function for 2D problems"
        V = u.function_space()
        spaces = SpacePool(V.mesh())
        degree = V.ufl_element().degree()
        V = spaces.get_space(degree, 0)

        psi = TrialFunction(V)
        self.q = TestFunction(V)
        a = dot(grad(psi), grad(self.q))*dx()

        self.bc = DirichletBC(V, Constant(0), DomainBoundary())
        self.A = assemble(a)
        self.L = Vector()
        self.bc.apply(self.A)
        self.solver = KrylovSolver(self.A, "cg")
        self.psi = Function(V)
Пример #25
0
def _momentum_equation(u, v, p, f, rho, mu, my_dx):
    """Weak form of the momentum equation.
    """
    # rho and my are Constant() functions
    assert rho.values()[0] > 0.0
    assert mu.values()[0] > 0.0

    # Skew-symmetric formulation.
    # Don't include the boundary term
    #
    #   - mu *inner(r*grad(u2)*n  , v2) * 2*pi*ds.
    #
    # This effectively means that at all boundaries where no sufficient
    # Dirichlet-conditions are posed, we assume grad(u)*n to vanish.
    #
    # The original term
    #    u2[0]/(r*r) * v2[0]
    # doesn't explode iff u2[0]~r and v2[0]~r at r=0. Hence, we need to enforce
    # homogeneous Dirichlet-conditions for n.u at r=0. This corresponds to no
    # flow in normal direction through the symmetry axis -- makes sense.
    # When using the 2*pi*r weighting, we can even be a bit lax on the
    # enforcement on u2[0].
    #
    # For this to be well defined, u[0]/r and u[2]/r must be bounded for r=0,
    # so u[0]~u[2]~r must hold. This either needs to be enforced in the
    # boundary conditions (homogeneous Dirichlet for u[0], u[2] at r=0) or must
    # follow from the dynamics of the system.
    #
    # TODO some more explanation for the following lines of code
    mesh = v.function_space().mesh()
    r = SpatialCoordinate(mesh)[0]
    F = (
        rho * 0.5 * (dot(grad(u) * u, v) - dot(grad(v) * u, u)) * 2 * pi * r * my_dx
        + mu * inner(r * grad(u), grad(v)) * 2 * pi * my_dx
        + mu * u[0] / r * v[0] * 2 * pi * my_dx
        - dot(f, v) * 2 * pi * r * my_dx
    )
    if p:
        F += (p.dx(0) * v[0] + p.dx(1) * v[1]) * 2 * pi * r * my_dx
    if len(u) == 3:
        F += rho * (-u[2] * u[2] * v[0] + u[0] * u[2] * v[2]) * 2 * pi * my_dx
        F += mu * u[2] / r * v[2] * 2 * pi * my_dx

    return F
Пример #26
0
def neumann_elasticity_data():
    '''
    Return:
        a  bilinear form in the neumann elasticity problem
        L  linear form in therein
        V  function space, where a, L are defined
        bc homog. dirichlet conditions for case where we want pos. def problem
        z  list of orthonormal vectors in the nullspace of A that form basis
           of ker(A)
    '''
    mesh = UnitSquareMesh(40, 40)

    V = VectorFunctionSpace(mesh, 'CG', 1)
    u = TrialFunction(V)
    v = TestFunction(V)

    f = Expression(('sin(pi*x[0])', 'cos(pi*x[1])'))

    epsilon = lambda u: sym(grad(u))

    # Material properties
    E, nu = 10.0, 0.3
    mu, lmbda = Constant(E/(2*(1 + nu))), Constant(E*nu/((1 + nu)*(1 - 2*nu)))

    sigma = lambda u: 2*mu*epsilon(u) + lmbda*tr(epsilon(u))*Identity(2)

    a = inner(sigma(u), epsilon(v))*dx
    L = inner(f, v)*dx  # Zero stress

    bc = DirichletBC(V, Constant((0, 0)), DomainBoundary())

    z0 = interpolate(Constant((1, 0)), V).vector()
    normalize(z0, 'l2')

    z1 = interpolate(Constant((0, 1)), V).vector()
    normalize(z1, 'l2')

    X = mesh.coordinates().reshape((-1, 2))
    c0, c1 = np.sum(X, axis=0)/len(X)
    z2 = interpolate(Expression(('x[1]-c1',
                                 '-(x[0]-c0)'), c0=c0, c1=c1), V).vector()
    normalize(z2, 'l2')

    z = [z0, z1, z2]

    # Check that this is orthonormal basis
    I = np.zeros((3, 3))
    for i, zi in enumerate(z):
        for j, zj in enumerate(z):
            I[i, j] = zi.inner(zj)

    print I
    print la.norm(I-np.eye(3))
    assert la.norm(I-np.eye(3)) < 1E-13

    return a, L, V, bc, z
def Matrix_creation(mesh,mu_r,k,k0,ref,extinction = None,vector_order = 3,nodal_order = 3):
    combined_space = function_space(vector_order,nodal_order,mesh)
    # Define the test and trial functions from the combined space here N_i and N_j are Nedelec 
    # basis functions and L_i and L_j are Lagrange basis functions
    (N_i,L_i) = df.TestFunctions(combined_space)
    (N_j,L_j) = df.TrialFunctions(combined_space)
    e_r_real = epsilon_real(ref)

    s_tt_ij = 1.0/mu_r*df.inner(df.curl(N_i),df.curl(N_j))
    t_tt_ij = e_r_real*df.inner(N_i,N_j)
    s_zz_ij = (1.0/mu_r) * df.inner(df.grad(L_i),df.grad(L_j))
    t_zz_ij = e_r_real*df.inner(L_i,L_j)


    A_tt_ij = s_tt_ij - k0**2*t_tt_ij
    B_zz_ij = s_zz_ij - k0**2*t_zz_ij

    B_tt_ij = 1/mu_r*df.inner(N_i, N_j)
    B_tz_ij = 1/mu_r*df.inner(N_i, df.grad(L_j))

    B_zt_ij = 1/mu_r*df.inner(df.grad(L_i),N_j)
    #post-multiplication by dx will result in integration over the domain of the mesh at assembly time
    A_ij = A_tt_ij*df.dx
    B_ij = (B_tt_ij+B_tz_ij+B_zt_ij+B_zz_ij)*df.dx
    #assemble the system Matrices. If there is loss in the system then
    #we create a new set of matrixes and assemble them


    ####This is to try and introduce the complex part
    if k !=0:
        A = df.assemble(A_ij)
        B = df.assemble(B_ij)
        e_r_imag = epsilon_imag(extinction)
        A_ii_complex = e_r_imag*k0**2*df.inner(N_i,N_j)*df.dx
        B_ii_complex = e_r_imag*k0**2*df.inner(L_i,L_j)*df.dx
        A_complex = df.assemble(A_ii_complex)
        B_complex = df.assemble(B_ii_complex)
    else:
        A_complex, B_complex = None, None
        A,B = df.PETScMatrix(),df.PETScMatrix()
        df.assemble(A_ij, tensor=A)
        df.assemble(B_ij, tensor=B)
    return combined_space, A,B, A_complex,B_complex
def amr(mesh, m, DirichletBoundary, g, mesh2d, s0=1, alpha=1):
    """Function for computing the Anisotropic MagnetoResistance (AMR),
    using given magnetisation configuration."""
    # Scalar and vector function spaces.
    V = df.FunctionSpace(mesh, "CG", 1)
    VV = df.VectorFunctionSpace(mesh, 'CG', 1, 3)

    # Define boundary conditions.
    bcs = df.DirichletBC(V, g, DirichletBoundary())

    # Nonlinear conductivity.
    def sigma(u):
        E = -df.grad(u)
        costheta = df.dot(m, E)/(df.sqrt(df.dot(E, E))*df.sqrt(df.dot(m, m)))
        return s0/(1 + alpha*costheta**2)

    # Define variational problem for Picard iteration.
    u = df.TrialFunction(V)  # electric potential
    v = df.TestFunction(V)
    u_k = df.interpolate(df.Expression('x[0]'), V)  # previous (known) u
    a = df.inner(sigma(u_k)*df.grad(u), df.grad(v))*df.dx
    
    # RHS to mimic linear problem.
    f = df.Constant(0.0)  # set to 0 -> nonlinear Poisson equation.
    L = f*v*df.dx

    u = df.Function(V)  # new unknown function
    eps = 1.0           # error measure ||u-u_k||
    tol = 1.0e-20       # tolerance
    iter = 0            # iteration counter
    maxiter = 50        # maximum number of iterations allowed
    while eps > tol and iter < maxiter:
        iter += 1
        df.solve(a == L, u, bcs)
        diff = u.vector().array() - u_k.vector().array()
        eps = np.linalg.norm(diff, ord=np.Inf)
        print 'iter=%d: norm=%g' % (iter, eps)
        u_k.assign(u)   # update for next iteration

    j = df.project(-sigma(u)*df.grad(u), VV)
    return u, j, compute_flux(j, mesh2d)
Пример #29
0
    def compute(self, get):
        u = get("Velocity")
        mu = get("DynamicViscosity")
        if isinstance(mu, (float, int)):
            mu = Constant(mu)

        n = self._n
        T = -mu*dot((grad(u) + grad(u).T), n)
        Tn = dot(T, n)
        Tt = T - Tn*n

        tau_form = dot(self.v, Tt)*ds()
        assemble(tau_form, tensor=self.tau.vector())

        #self.b[self._keys] = self.tau.vector()[self._values] # FIXME: This is not safe!!!
        get_set_vector(self.b, self._keys, self.tau.vector(), self._values, self._temp_array)

        # Ensure proper scaling
        self.solver.solve(self.tau_boundary.vector(), self.b)

        return self.tau_boundary
Пример #30
0
def F(u, p, v, q, f, r, mu, my_dx):
    mu = Constant(mu)
    # Momentum equation (without the nonlinear Navier term).
    F0 = (
        mu * inner(r * grad(u), grad(v)) * 2 * pi * my_dx
        + mu * u[0] / r * v[0] * 2 * pi * my_dx
        - dot(f, v) * 2 * pi * r * my_dx
    )
    if len(u) == 3:
        F0 += mu * u[2] / r * v[2] * 2 * pi * my_dx
    F0 += (p.dx(0) * v[0] + p.dx(1) * v[1]) * 2 * pi * r * my_dx

    # Incompressibility condition.
    # div_u = 1/r * div(r*u)
    F0 += ((r * u[0]).dx(0) + r * u[1].dx(1)) * q * 2 * pi * my_dx

    # a = mu * inner(r * grad(u), grad(v)) * 2*pi * my_dx \
    #     - ((r * v[0]).dx(0) + (r * v[1]).dx(1)) * p * 2*pi * my_dx \
    #     + ((r * u[0]).dx(0) + (r * u[1]).dx(1)) * q * 2*pi * my_dx
    # #   - div(r*v)*p* 2*pi*my_dx \
    # #   + q*div(r*u)* 2*pi*my_dx
    return F0
#       values[1] = 2.4142
#       values[2] = -22.252E-3
#         print("counter value",values)
#     else:
#       values[0] = 1.0
#       values[1] = 1.0
#       values[2] = 0.0
#         print("counter value 2 ",values)
# def value_shape(self):
#   return (3,)
# u.interpolate(InitialConditions(degree=1))

an, ca, psi = split(u)
van, vca, vpsi = TestFunctions(ME)

Fan = D_an*(-inner(grad(an), grad(van))*dx - Farad / R / Temp * z_an*an*inner(grad(psi), grad(van))*dx)
Fca = D_ca*(-inner(grad(ca), grad(vca))*dx - Farad / R / Temp * z_ca*ca*inner(grad(psi), grad(vca))*dx)
Fpsi = inner(grad(psi), grad(vpsi))*dx - (Farad/(eps0*epsR))*(z_an*an + z_ca*ca + z_fc*fc_function)*vpsi*dx

F = Fpsi + Fan + Fca

J = derivative(F, u)
problem = NonlinearVariationalProblem(F, u, bcs = bcs, J = J)
solver = NonlinearVariationalSolver(problem)
#solver = AdaptiveNonlinearVariationalSolver(problem, M)

#print(solver.default_parameters().items())
solver.parameters["newton_solver"]["linear_solver"] = "mumps"
solver.solve()

#########################  Post - Processing  #################################
Пример #32
0
    def constructGalerkinWeakFormulation(self):
        #-----------------------------------------------------------------------------------
        tDim = self.tDim
        wr, wi = self.wr, self.wi
        ur, ui = self.ur, self.ui
        MS, MT = self.MS, self.MT
        mOpt = self.materialOpt
        pmlOpt = self.pmlOpt
        s = sigmaFun

        MTR = MT[tDim](mOpt,
                       s,
                       pmlOpt,
                       returnReal=True,
                       degree=self.meshOpt['polynomialOrder'])
        MTI = MT[tDim](mOpt,
                       s,
                       pmlOpt,
                       returnReal=False,
                       degree=self.meshOpt['polynomialOrder'])
        MSR = MS[tDim](mOpt,
                       s,
                       pmlOpt,
                       returnReal=True,
                       degree=self.meshOpt['polynomialOrder'])
        MSI = MS[tDim](mOpt,
                       s,
                       pmlOpt,
                       returnReal=False,
                       degree=self.meshOpt['polynomialOrder'])

        bFormR = df.inner(df.grad(wr), MTR*df.grad(ur) - MTI*df.grad(ui))*df.dx \
         -df.inner(df.grad(wi), MTI*df.grad(ur) + MTR*df.grad(ui))*df.dx \
                - ( df.inner(wr, MSR*ur - MSI*ui)*df.dx \
            -df.inner(wi, MSI*ur + MSR*ui)*df.dx )

        bFormI = df.inner(df.grad(wr), MTI*df.grad(ur) + MTR*df.grad(ui))*df.dx \
         +df.inner(df.grad(wi), MTR*df.grad(ur) - MTI*df.grad(ui))*df.dx \
                - ( df.inner(wr, MSI*ur + MSR*ui)*df.dx \
            +df.inner(wi, MSR*ur - MSI*ui)*df.dx )

        self.bForm = bFormR + bFormI

        return
Пример #33
0
 def __init__(self, Th):
     mesh = UnitSquareMesh(Th, Th)
     self.V = FunctionSpace(mesh, "Lagrange", 1)
     u = TrialFunction(self.V)
     v = TestFunction(self.V)
     self.a = lambda k: k * inner(grad(u), grad(v)) * dx
Пример #34
0
bc1_t = d.DirichletBC(V, T_0, facets, 4)
bc2_t = d.DirichletBC(V, T_0, facets, 5)  # circle

bc_e = [bc0_e, bc1_e]
bc_t = [bc0_t, bc1_t, bc2_t]

# Define initial value, which will later be the solution from the previous (n-th) time step
T_n = d.Function(V)
T_n = d.interpolate(T_ref, V)

# Define variational problem for temperature and potential
psi = d.TrialFunction(V)  # trial for potential
T_n1 = d.TrialFunction(V)  # trial for temperature
v = d.TestFunction(V)
# potential
a = d.inner(sigma_T(T_n) * d.grad(psi), d.grad(v)) * dx
L = f * v * dx  # keep in mind: f=0

psi = d.Function(V)  # solution for potential
# temperature
a_1 = (rho * C_p * T_n1 * v * dx +
       k_iso * dt * d.dot(d.grad(T_n1), d.grad(v)) * dx)
L_1 = (rho * C_p * T_n +
       dt * sigma_T(T_n) * d.dot(d.grad(psi), d.grad(psi))) * v * dx
T_n1 = d.Function(V)  # solution for T

# Time-stepping
t = 0
# write initial temperature
datafile.write("%f\t%f\n" % (t, T_n(d.Point(0., 0.25))))
datafileHDF5.write(T_n, "/T_0")
Пример #35
0
def eps(d, u):
    return 1. / 2 * (grad(u) * inv(F_(d)) + inv(F_(d)).T * grad(u).T)
Пример #36
0
def F_(U):
    return Identity(len(U)) + grad(U)
Пример #37
0
def test_krylov_reuse_pc():
    "Test preconditioner re-use with PETScKrylovSolver"

    # Define problem
    mesh = UnitSquareMesh(MPI.comm_world, 8, 8)
    V = FunctionSpace(mesh, 'Lagrange', 1)
    bc = DirichletBC(V, Constant(0.0), lambda x, on_boundary: on_boundary)
    u = TrialFunction(V)
    v = TestFunction(V)

    # Forms
    a, L = inner(grad(u), grad(v)) * dx, dot(Constant(1.0), v) * dx

    A, P = PETScMatrix(), PETScMatrix()
    b = PETScVector()

    # Assemble linear algebra objects
    assemble(a, tensor=A)  # noqa
    assemble(a, tensor=P)  # noqa
    assemble(L, tensor=b)  # noqa

    # Apply boundary conditions
    bc.apply(A)
    bc.apply(P)
    bc.apply(b)

    # Create Krysolv solver and set operators
    solver = PETScKrylovSolver("gmres", "bjacobi")
    solver.set_operators(A, P)

    # Solve
    x = PETScVector()
    num_iter_ref = solver.solve(x, b)

    # Change preconditioner matrix (bad matrix) and solve (PC will be
    # updated)
    a_p = u * v * dx
    assemble(a_p, tensor=P)  # noqa
    bc.apply(P)
    x = PETScVector()
    num_iter_mod = solver.solve(x, b)
    assert num_iter_mod > num_iter_ref

    # Change preconditioner matrix (good matrix) and solve (PC will be
    # updated)
    a_p = a
    assemble(a_p, tensor=P)  # noqa
    bc.apply(P)
    x = PETScVector()
    num_iter = solver.solve(x, b)
    assert num_iter == num_iter_ref

    # Change preconditioner matrix (bad matrix) and solve (PC will not
    # be updated)
    solver.set_reuse_preconditioner(True)
    a_p = u * v * dx
    assemble(a_p, tensor=P)  # noqa
    bc.apply(P)
    x = PETScVector()
    num_iter = solver.solve(x, b)
    assert num_iter == num_iter_ref

    # Update preconditioner (bad PC, will increase iteration count)
    solver.set_reuse_preconditioner(False)
    x = PETScVector()
    num_iter = solver.solve(x, b)
    assert num_iter == num_iter_mod
Пример #38
0
 def sigma(v):
     return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym(
         grad(v))) * Identity(2)
Пример #39
0
def dn_mat(s, n):
    return dot(outer(grad(s) * n, n).T, n) - dot(grad(s).T, n)
Пример #40
0
def tan_div(s, n):
    return div(s) - dot(dot(grad(s), n), n)
Пример #41
0
# Assign a function to each mesh, such that T and lmb are discontinuous at the
# interface Gamma
T = MultiMeshFunction(V)
T.assign_part(0, project(sin(x0[1]), FunctionSpace(meshes[0], "CG", degree)))
T.assign_part(
    1, project(cos(x1[0]) * x1[1], FunctionSpace(meshes[1], "CG", degree)))
lmb = MultiMeshFunction(V)
lmb.assign_part(
    0, project(cos(x0[1]) * x0[0], FunctionSpace(meshes[0], "CG", degree)))
lmb.assign_part(
    1, project(x1[0] * sin(x1[1]), FunctionSpace(meshes[1], "CG", degree)))

# Create bilinear form and corresponding gradients

#----------------------------------------------------------------------------
a1 = inner(grad(T), grad(lmb)) * dX
# Classic shape derivative term top mesh
da1_top = div(s_top) * inner(grad(T), grad(lmb)) * dX
# Term stemming from grad(T)
da1_top -= inner(dot(grad(s_top), grad(T)), grad(lmb)) * dX
# Term stemming from grad(lmb)
da1_top -= inner(grad(T), dot(grad(s_top), grad(lmb))) * dX
# Classic shape derivative term bottom mesh
da1_bottom = div(s_bottom) * inner(grad(T), grad(lmb)) * dX
# Term stemming from grad(T)
da1_bottom += inner(grad(dot(s_bottom, grad(T))), grad(lmb)) * dX
# Term stemming from grad(lmb)
da1_bottom += inner(grad(T), grad(dot(s_bottom, grad(lmb)))) * dX
# Material derivative of background T
da1_bottom -= inner(dot(nabla_grad(s_bottom), grad(T)), grad(lmb)) * dX
# Material derivative of background lmb
Пример #42
0
def _test_linear_solver_sparse(callback_type):
    from dolfin import Function
    from rbnics.backends.dolfin import LinearSolver

    # Create mesh and define function space
    mesh = IntervalMesh(132, 0, 2 * pi)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define Dirichlet boundary (x = 0 or x = 2 * pi)
    def boundary(x):
        return x[0] < 0 + DOLFIN_EPS or x[0] > 2 * pi - 10 * DOLFIN_EPS

    # Define exact solution
    exact_solution_expression = Expression("x[0] + sin(2 * x[0])",
                                           element=V.ufl_element())
    exact_solution = project(exact_solution_expression, V)

    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    g = Expression("4 * sin(2 * x[0])", element=V.ufl_element())
    a = inner(grad(u), grad(v)) * dx
    f = g * v * dx
    x = inner(u, v) * dx

    # Assemble inner product matrix
    X = assemble(x)

    # Define boundary condition
    bc = [DirichletBC(V, exact_solution_expression, boundary)]

    # Define callback function depending on callback type
    assert callback_type in ("form callbacks", "tensor callbacks")
    if callback_type == "form callbacks":

        def callback(arg):
            return arg
    elif callback_type == "tensor callbacks":

        def callback(arg):
            return assemble(arg)

    # Define problem wrapper
    class ProblemWrapper(LinearProblemWrapper):
        # Vector function
        def vector_eval(self):
            return callback(f)

        # Matrix function
        def matrix_eval(self):
            return callback(a)

        # Define boundary condition
        def bc_eval(self):
            return bc

        # Define custom monitor to plot the solution
        def monitor(self, solution):
            if matplotlib.get_backend() != "agg":
                plot(solution, title="u")
                plt.show(block=False)
                plt.pause(1)
            else:
                print("||u|| = " + str(solution.vector().norm("l2")))

    # Solve the linear problem
    problem_wrapper = ProblemWrapper()
    solution = Function(V)
    solver = LinearSolver(problem_wrapper, solution)
    solver.solve()

    # Compute the error
    error = Function(V)
    error.vector().add_local(+solution.vector().get_local())
    error.vector().add_local(-exact_solution.vector().get_local())
    error.vector().apply("")
    error_norm = error.vector().inner(X * error.vector())
    print("Sparse error (" + callback_type + "):", error_norm)
    assert isclose(error_norm, 0., atol=1.e-5)
    return (error_norm, V, a, f, X, exact_solution)
Пример #43
0
def sigma_f_u(u, d, mu_f):
    """
    Deviatoric component of the Cauchy stress tensor (fluid problem)
    """
    return mu_f * (grad(u) * inv(F_(d)) + inv(F_(d)).T * grad(u).T)
Пример #44
0
 def form(self, x):
     #return dl.avg(dl.exp(x[PARAMETER])*dl.dot( dl.grad(x[STATE]), self.n) )*self.dsGamma
     return dl.exp(x[PARAMETER]) * dl.dot(dl.grad(x[STATE]),
                                          self.n) * self.dsGamma
Пример #45
0
    def define_advection_equation(self):
        """
        Setup the advection equation for the colour function

        This implementation assembles the full LHS and RHS each time they are needed
        """
        sim = self.simulation
        mesh = sim.data['mesh']
        n = dolfin.FacetNormal(mesh)
        dS, dx = dolfin.dS(mesh), dolfin.dx(mesh)

        # Trial and test functions
        Vc = self.Vc
        c = dolfin.TrialFunction(Vc)
        d = dolfin.TestFunction(Vc)

        c1, c2, c3 = self.time_coeffs
        dt = self.dt
        u_conv = self.u_conv

        if not self.colour_is_discontinuous:
            # Continous Galerkin implementation of the advection equation
            # FIXME: add stabilization
            eq = (c1 * c + c2 * self.cp + c3 * self.cpp) / dt * d * dx + div(
                c * u_conv) * d * dx

        elif self.velocity_is_trace:
            # Upstream and downstream normal velocities
            w_nU = (dot(u_conv, n) + abs(dot(u_conv, n))) / 2
            w_nD = (dot(u_conv, n) - abs(dot(u_conv, n))) / 2

            if self.beta is not None:
                # Define the blended flux
                # The blending factor beta is not DG, so beta('+') == beta('-')
                b = self.beta('+')
                flux = (1 - b) * jump(c * w_nU) + b * jump(c * w_nD)
            else:
                flux = jump(c * w_nU)

            # Discontinuous Galerkin implementation of the advection equation
            eq = (c1 * c + c2 * self.cp +
                  c3 * self.cpp) / dt * d * dx + flux * jump(d) * dS

            # On each facet either w_nD or w_nU will be 0, the other is multiplied
            # with the appropriate flux, either the value c going out of the domain
            # or the Dirichlet value coming into the domain
            for dbc in self.dirichlet_bcs:
                eq += w_nD * dbc.func() * d * dbc.ds()
                eq += w_nU * c * d * dbc.ds()

        elif self.beta is not None:
            # Upstream and downstream normal velocities
            w_nU = (dot(u_conv, n) + abs(dot(u_conv, n))) / 2
            w_nD = (dot(u_conv, n) - abs(dot(u_conv, n))) / 2

            if self.beta is not None:
                # Define the blended flux
                # The blending factor beta is not DG, so beta('+') == beta('-')
                b = self.beta('+')
                flux = (1 - b) * jump(c * w_nU) + b * jump(c * w_nD)
            else:
                flux = jump(c * w_nU)

            # Discontinuous Galerkin implementation of the advection equation
            eq = ((c1 * c + c2 * self.cp + c3 * self.cpp) / dt * d * dx -
                  dot(c * u_conv, grad(d)) * dx + flux * jump(d) * dS)

            # Enforce Dirichlet BCs weakly
            for dbc in self.dirichlet_bcs:
                eq += w_nD * dbc.func() * d * dbc.ds()
                eq += w_nU * c * d * dbc.ds()

        else:
            # Downstream normal velocities
            w_nD = (dot(u_conv, n) - abs(dot(u_conv, n))) / 2

            # Discontinuous Galerkin implementation of the advection equation
            eq = (c1 * c + c2 * self.cp + c3 * self.cpp) / dt * d * dx

            # Convection integrated by parts two times to bring back the original
            # div form (this means we must subtract and add all fluxes)
            eq += div(c * u_conv) * d * dx

            # Replace downwind flux with upwind flux on downwind internal facets
            eq -= jump(w_nD * d) * jump(c) * dS

            # Replace downwind flux with upwind BC flux on downwind external facets
            for dbc in self.dirichlet_bcs:
                # Subtract the "normal" downwind flux
                eq -= w_nD * c * d * dbc.ds()
                # Add the boundary value upwind flux
                eq += w_nD * dbc.func() * d * dbc.ds()

        # Penalty forcing zones
        for fz in self.forcing_zones:
            eq += fz.penalty * fz.beta * (c - fz.target) * d * dx

        a, L = dolfin.system(eq)
        self.form_lhs = dolfin.Form(a)
        self.form_rhs = dolfin.Form(L)
        self.tensor_lhs = None
        self.tensor_rhs = None
Пример #46
0
def eps(d):
    """
    Infinitesimal strain tensor
    """
    return 0.5 * (grad(d) * inv(F_(d)) + inv(F_(d)).T * grad(d).T)
Пример #47
0
def D_U(d, v):
    return 1. / 2 * grad(v) * inv(F_(d))
Пример #48
0
def F_(d):
    """
    Deformation gradient tensor
    """
    return Identity(len(d)) + grad(d)
Пример #49
0
def A_E(d, v, lamda_s, mu_s, rho_s, delta, psi, phi, dx_s):
    return inner(Piola1(d, lamda_s, mu_s), grad(psi))*dx_s \
        - delta*rho_s*inner(v, phi)*dx_s
Пример #50
0
# Incident plane wave
theta = np.pi / 8
ui = Expression('exp(j*k0*(cos(theta)*x[0] + sin(theta)*x[1]))',
                k0=k0,
                theta=theta,
                degree=deg + 3,
                domain=mesh.ufl_domain())

# Test and trial function space
V = FunctionSpace(mesh, "Lagrange", deg)

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
g = dot(grad(ui), n) + 1j * k0 * ui
a = inner(grad(u), grad(v)) * dx - k0**2 * inner(u, v) * dx + \
    1j * k0 * inner(u, v) * ds
L = inner(g, v) * ds

# Compute solution
u = Function(V)
solve(a == L, u, [])

# Save solution in XDMF format (to be viewed in Paraview, for example)
with XDMFFile(MPI.comm_world,
              "plane_wave.xdmf",
              encoding=XDMFFile.Encoding.HDF5) as file:
    file.write(u)
''' Calculate L2 and H1 errors of FEM solution and best approximation.
This demonstrates the error bounds given in Ihlenburg.
Пример #51
0
def get_poisson_steps_dolfin(pts, cells, tol):
    from dolfin import (
        Constant,
        DirichletBC,
        Function,
        FunctionSpace,
        KrylovSolver,
        Mesh,
        TestFunction,
        TrialFunction,
        XDMFFile,
        assemble,
        dx,
        grad,
        inner,
    )

    # Still can't initialize a mesh from points, cells
    filename = "mesh.xdmf"
    if cells.shape[1] == 3:
        meshio.write_points_cells(filename, pts, {"triangle": cells})
    else:
        assert cells.shape[1] == 4
        meshio.write_points_cells(filename, pts, {"tetra": cells})

    mesh = Mesh()
    with XDMFFile(filename) as f:
        f.read(mesh)
    os.remove(filename)
    os.remove("mesh.h5")

    # build Laplace matrix with Dirichlet boundary using dolfin
    V = FunctionSpace(mesh, "Lagrange", 1)

    u = TrialFunction(V)
    v = TestFunction(V)
    a = inner(grad(u), grad(v)) * dx
    u0 = Constant(0.0)
    bc = DirichletBC(V, u0, "on_boundary")
    f = Constant(1.0)
    L = f * v * dx

    A = assemble(a)
    b = assemble(L)
    bc.apply(A, b)

    # solve(A, x, b, "cg")
    solver = KrylovSolver("cg", "none")
    solver.parameters["absolute_tolerance"] = 0.0
    solver.parameters["relative_tolerance"] = tol

    x = Function(V)
    x_vec = x.vector()
    num_steps = solver.solve(A, x_vec, b)

    # # convert to scipy matrix
    # A = as_backend_type(A).mat()
    # ai, aj, av = A.getValuesCSR()
    # A = scipy.sparse.csr_matrix(
    #     (av, aj, ai), shape=(A.getLocalSize()[0], A.getSize()[1])
    # )

    # # ev = eigvals(A.todense())
    # ev_max = scipy.sparse.linalg.eigs(A, k=1, which="LM")[0][0]
    # assert numpy.abs(ev_max.imag) < 1.0e-15
    # ev_max = ev_max.real
    # ev_min = scipy.sparse.linalg.eigs(A, k=1, which="SM")[0][0]
    # assert numpy.abs(ev_min.imag) < 1.0e-15
    # ev_min = ev_min.real
    # cond = ev_max / ev_min

    # solve poisson system, count num steps
    # b = numpy.ones(A.shape[0])
    # out = pykry.gmres(A, b)
    # num_steps = len(out.resnorms)
    return num_steps
#defiene external force
f = df.Expression(("f_0 + f_1*cos(2*M_PI*t/tau)", "0."),
                  f_0=f0,
                  f_1=f1,
                  t=0.,
                  tau=tau,
                  degree=2)

#define Crank-Nikolsen and Adams-Basforth for the time-dependent terms and derivative terms
u_CN = 0.5 * (u + u_1)
u_CN_ = 0.5 * (u_ + u_1)
u_AB_ = 1.5 * u_1 - 0.5 * u_2

#variational form of NSE
F = (df.dot(u - u_1, v) / dt * df.dx +
     nu * df.inner(df.grad(u_CN), df.grad(v)) * df.dx - df.div(v) * p * df.dx -
     df.div(u) * q * df.dx - df.dot(f, v) * df.dx)

#additional term if including u*grad*u
if enable_inertia:
    F += df.inner(df.grad(u_CN) * u_AB_, v) * df.dx

#for parallelization
x0, y0 = x[0, 0], x[0, 1]
x0 = comm.bcast(x0, root=0)
y0 = comm.bcast(y0, root=0)

#pressure boundary conditions
bcp = df.DirichletBC(W.sub(1), df.Constant(0.),
                     ("abs(x[0]-({x0})) < DOLFIN_EPS && "
                      "abs(x[1]-({y0})) < DOLFIN_EPS").format(x0=x0, y0=y0),
Пример #53
0
# g0 and g1
n = FacetNormal(mesh)
xy = Expression(('x[0]', 'x[1]'))
g1 = assemble(inner(xy, xy) / inner(xy, n) * ds) * 2 * pi / L**2
g0 = assemble(1. / inner(xy, n) * ds) / 2 / pi
g = np.sqrt(g0 * g1)
print "g0, g1, g: ", g0, g1, g

# final solutions
print "Final solving ..."
sol = solver.solve(mesh, numeig)
print "Eigenvalues: "
eigs = np.zeros(len(sol[:, 0]))
for i in range(len(eigs)):
    # Rayleigh quotients
    eigs[i] = assemble(inner(grad(sol[i, 1]), grad(sol[i, 1])) *
                       dx) / assemble(sol[i, 1] * sol[i, 1] * ds)
    print sol[i, 0], eigs[i]

disk = np.cumsum(sorted(range(1, len(eigs)) * 2))
print "sum*L/(2pi)/disk (optimal g): "
sums = np.cumsum(eigs)
for i in range(len(eigs)):
    print sums[i] * L / 2 / pi / disk[i]

# make pdf from solutions
from export import export
export(name, mesh, eigs, sums, disk, sol, f, degree, n, k, l, size, L, g0, g1,
       g, density)
Пример #54
0
def xtest_mg_solver_stokes():

    mesh0 = UnitCubeMesh(2, 2, 2)
    mesh1 = UnitCubeMesh(4, 4, 4)
    mesh2 = UnitCubeMesh(8, 8, 8)

    Ve = VectorElement("CG", mesh0.ufl_cell(), 2)
    Qe = FiniteElement("CG", mesh0.ufl_cell(), 1)
    Ze = MixedElement([Ve, Qe])

    Z0 = FunctionSpace(mesh0, Ze)
    Z1 = FunctionSpace(mesh1, Ze)
    Z2 = FunctionSpace(mesh2, Ze)
    W = Z2

    # Boundaries
    def right(x, on_boundary):
        return x[0] > (1.0 - DOLFIN_EPS)

    def left(x, on_boundary):
        return x[0] < DOLFIN_EPS

    def top_bottom(x, on_boundary):
        return x[1] > 1.0 - DOLFIN_EPS or x[1] < DOLFIN_EPS

    # No-slip boundary condition for velocity
    noslip = Constant((0.0, 0.0, 0.0))
    bc0 = DirichletBC(W.sub(0), noslip, top_bottom)

    # Inflow boundary condition for velocity
    inflow = Expression(("-sin(x[1]*pi)", "0.0", "0.0"), degree=2)
    bc1 = DirichletBC(W.sub(0), inflow, right)

    # Collect boundary conditions
    bcs = [bc0, bc1]

    # Define variational problem
    (u, p) = TrialFunctions(W)
    (v, q) = TestFunctions(W)
    f = Constant((0.0, 0.0, 0.0))
    a = inner(grad(u), grad(v)) * dx + div(v) * p * dx + q * div(u) * dx
    L = inner(f, v) * dx

    # Form for use in constructing preconditioner matrix
    b = inner(grad(u), grad(v)) * dx + p * q * dx

    # Assemble system
    A, bb = assemble_system(a, L, bcs)

    # Assemble preconditioner system
    P, btmp = assemble_system(b, L, bcs)

    spaces = [Z0, Z1, Z2]
    dm_collection = PETScDMCollection(spaces)

    solver = PETScKrylovSolver()
    solver.set_operators(A, P)

    PETScOptions.set("ksp_type", "gcr")
    PETScOptions.set("pc_type", "mg")
    PETScOptions.set("pc_mg_levels", 3)
    PETScOptions.set("pc_mg_galerkin")
    PETScOptions.set("ksp_monitor_true_residual")

    PETScOptions.set("ksp_atol", 1.0e-10)
    PETScOptions.set("ksp_rtol", 1.0e-10)
    solver.set_from_options()

    from petsc4py import PETSc

    ksp = solver.ksp()

    ksp.setDM(dm_collection.dm())
    ksp.setDMActive(False)

    x = PETScVector()
    solver.solve(x, bb)

    # Check multigrid solution against LU solver
    solver = LUSolver(A)  # noqa
    x_lu = PETScVector()
    solver.solve(x_lu, bb)
    assert round((x - x_lu).norm("l2"), 10) == 0

    # Clear all PETSc options
    opts = PETSc.Options()
    for key in opts.getAll():
        opts.delValue(key)
Пример #55
0
def _test_time_stepping_2_sparse(callback_type, integrator_type):
    from dolfin import Function
    from rbnics.backends.dolfin import TimeStepping

    # Create mesh and define function space
    mesh = IntervalMesh(132, 0, 2 * pi)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define Dirichlet boundary (x = 0 or x = 2*pi)
    def boundary(x):
        return x[0] < 0 + DOLFIN_EPS or x[0] > 2 * pi - 10 * DOLFIN_EPS

    # Define time step
    dt = 0.01
    monitor_dt = 0.02
    T = 1.

    # Define exact solution
    exact_solution_expression = Expression("sin(x[0]+t)", t=0, element=V.ufl_element())
    # ... and interpolate it at the final time
    exact_solution_expression.t = T
    exact_solution = project(exact_solution_expression, V)

    # Define exact solution dot
    exact_solution_dot_expression = Expression("cos(x[0]+t)", t=0, element=V.ufl_element())
    # ... and interpolate it at the final time
    exact_solution_dot_expression.t = T
    exact_solution_dot = project(exact_solution_dot_expression, V)

    # Define variational problem
    du = TrialFunction(V)
    du_dot = TrialFunction(V)
    v = TestFunction(V)
    u = Function(V)
    u_dot = Function(V)
    g = Expression("5. / 4. * sin(t + x[0]) - 3. / 4. * sin(3 * (t + x[0])) + cos(t + x[0])", t=0.,
                   element=V.ufl_element())
    r_u = inner((1 + u**2) * grad(u), grad(v)) * dx
    j_u = derivative(r_u, u, du)
    r_u_dot = inner(u_dot, v) * dx
    j_u_dot = derivative(r_u_dot, u_dot, du_dot)
    r = r_u_dot + r_u - g * v * dx
    x = inner(du, v) * dx

    def bc(t):
        exact_solution_expression.t = t
        return [DirichletBC(V, exact_solution_expression, boundary)]

    # Assemble inner product matrix
    X = assemble(x)

    # Define callback function depending on callback type
    assert callback_type in ("form callbacks", "tensor callbacks")
    if callback_type == "form callbacks":
        def callback(arg):
            return arg
    elif callback_type == "tensor callbacks":
        def callback(arg):
            return assemble(arg)

    # Define problem wrapper
    class ProblemWrapper(TimeDependentProblemWrapper):
        # Residual and jacobian functions
        def residual_eval(self, t, solution, solution_dot):
            g.t = t
            return callback(r)

        def jacobian_eval(self, t, solution, solution_dot, solution_dot_coefficient):
            return callback(Constant(solution_dot_coefficient) * j_u_dot + j_u)

        # Define boundary condition
        def bc_eval(self, t):
            return bc(t)

        # Define initial condition
        def ic_eval(self):
            exact_solution_expression.t = 0.
            return project(exact_solution_expression, V)

        # Define custom monitor to plot the solution
        def monitor(self, t, solution, solution_dot):
            assert isclose(round(t / monitor_dt), t / monitor_dt)
            if matplotlib.get_backend() != "agg":
                plt.subplot(1, 2, 1).clear()
                plot(solution, title="u at t = " + str(t))
                plt.subplot(1, 2, 2).clear()
                plot(solution_dot, title="u_dot at t = " + str(t))
                plt.show(block=False)
                plt.pause(DOLFIN_EPS)
            else:
                print("||u|| at t = " + str(t) + ": " + str(solution.vector().norm("l2")))
                print("||u_dot|| at t = " + str(t) + ": " + str(solution_dot.vector().norm("l2")))

    # Solve the time dependent problem
    problem_wrapper = ProblemWrapper()
    (solution, solution_dot) = (u, u_dot)
    solver = TimeStepping(problem_wrapper, solution, solution_dot)
    solver.set_parameters({
        "initial_time": 0.0,
        "time_step_size": dt,
        "monitor": {
            "time_step_size": monitor_dt,
        },
        "final_time": T,
        "exact_final_time": "stepover",
        "integrator_type": integrator_type,
        "problem_type": "nonlinear",
        "snes_solver": {
            "linear_solver": "mumps",
            "maximum_iterations": 20,
            "report": True
        },
        "report": True
    })
    solver.solve()

    # Compute the error at the final time
    error = Function(V)
    error.vector().add_local(+ solution.vector().get_local())
    error.vector().add_local(- exact_solution.vector().get_local())
    error.vector().apply("")
    error_norm = error.vector().inner(X * error.vector())
    error_dot = Function(V)
    error_dot.vector().add_local(+ solution_dot.vector().get_local())
    error_dot.vector().add_local(- exact_solution_dot.vector().get_local())
    error_dot.vector().apply("")
    error_dot_norm = error_dot.vector().inner(X * error_dot.vector())
    print("Sparse error (" + callback_type + ", " + integrator_type + "):", error_norm, error_dot_norm)
    assert isclose(error_norm, 0., atol=1.e-4)
    assert isclose(error_dot_norm, 0., atol=1.e-4)
    return ((error_norm, error_dot_norm), V, dt, monitor_dt, T, u, u_dot, g, r, j_u, j_u_dot, X,
            exact_solution_expression, exact_solution, exact_solution_dot)
Пример #56
0
 def Fbarevol(v, i):
     dx = geo.dx("molecule")
     return dolfin.Constant(Moleculeqv) * (-r * lscale *
                                           dolfin.grad(v)[i]) * dx
Пример #57
0
def scalar_laplacians(mesh):
    """
    Calculate the laplacians needed by fiberrule algorithms
    
    Arguments
    ---------
    mesh : dolfin.Mesh
       A dolfin mesh with marked boundaries:
       base = 10, rv = 20, lv = 30, epi = 40
       The base is assumed placed at x=0
    
    """
    
    if not isinstance(mesh, d.Mesh):
        raise TypeError("Expected a dolfin.Mesh as the mesh argument.")

    # Init connectivities
    mesh.init(2)
    facet_markers = d.MeshFunction("size_t", mesh, 2, mesh.domains())

    # Boundary markers, solutions and cases
    markers = dict(base=10, rv=20, lv=30, epi=40, apex=50)

    # Solver parameters
    solver_param=dict(solver_parameters=dict(
        preconditioner="ml_amg" if d.has_krylov_solver_preconditioner("ml_amg") \
        else "default", linear_solver="gmres"))
    
    cases = ["rv", "lv", "epi"]
    boundaries = cases + ["base"]

    # Check that all boundary faces are marked
    num_boundary_facets = d.BoundaryMesh(mesh, "exterior").num_cells()

    if num_boundary_facets != sum(np.sum(\
        facet_markers.array()==markers[boundary])\
                                  for boundary in boundaries):
        d.error("Not all boundary faces are marked correctly. Make sure all "\
                "boundary facets are marked as: base = 10, rv = 20, lv = 30, "\
                "epi = 40.")
    
    # Coords and cells
    coords = mesh.coordinates()
    cells_info = mesh.cells()
    
    # Find apex by solving a laplacian with base solution = 0
    # Create Base variational problem
    V = d.FunctionSpace(mesh, "CG", 1)
    
    u = d.TrialFunction(V)
    v = d.TestFunction(V)
    
    a = d.dot(d.grad(u), d.grad(v))*d.dx
    L = v*d.Constant(1)*d.dx
    
    DBC_10 = d.DirichletBC(V, 1, facet_markers, markers["base"], "topological")

    # Create solutions
    solutions = dict((what, d.Function(V)) for what in markers if what != "base")

    d.solve(a==L, solutions["apex"], DBC_10,
            solver_parameters={"linear_solver": "gmres"})

    apex_values = solutions["apex"].vector().array()
    apex_values[d.dof_to_vertex_map(V)] = solutions["apex"].vector().array()
    ind_apex_max = apex_values.argmax()
    apex_coord = coords[ind_apex_max,:]

    # Update rhs
    L = v*d.Constant(0)*d.dx
    
    d.info("  Apex coord: ({0}, {1}, {2})".format(*apex_coord))
    d.info("  Num coords: {0}".format(len(coords)))
    d.info("  Num cells: {0}".format(len(cells_info)))
    
    # Calculate volume
    volume = 0.0
    for cell in d.cells(mesh):
        volume += cell.volume()
    
    d.info("  Volume: {0}".format(volume))
    d.info("")
    
    # Cases
    # =====
    #
    # 1) base: 1, apex: 0
    # 2) lv: 1, rv, epi: 0
    # 3) rv: 1, lv, epi: 0
    # 4) epi: 1, rv, lv: 0
    
    class ApexDomain(d.SubDomain):
        def inside(self, x, on_boundary):
            return d.near(x[0], apex_coord[0]) and d.near(x[1], apex_coord[1]) and \
                   d.near(x[2], apex_coord[2])
    
    apex_domain = ApexDomain()
    
    # Case 1:
    Poisson = 1
    DBC_11 = d.DirichletBC(V, 0, apex_domain, "pointwise")

    # Using Poisson
    if Poisson:
        d.solve(a==L, solutions["apex"], [DBC_10, DBC_11],
                solver_parameters={"linear_solver": "gmres"})

    # Using Eikonal equation
    else:
        Le = v*d.Constant(1)*d.dx
        d.solve(a==Le, solutions["apex"], DBC_11,
                solver_parameters={"linear_solver": "gmres"})

        # Create Eikonal problem
        eps = d.Constant(mesh.hmax()/25)
        y = solutions["apex"]
        F = d.sqrt(d.inner(d.grad(y), d.grad(y)))*v*d.dx - \
            d.Constant(1)*v*d.dx + eps*d.inner(d.grad(y), d.grad(v))*d.dx
        d.solve(F==0, y, DBC_11, solver_parameters={
            "linear_solver": "lu",
            "newton_solver": {"relative_tolerance":1e-5}})
    
    # Check that solution of the three last cases all sum to 1.
    sol = solutions["apex"].vector().copy()
    sol[:] = 0.0
    
    # Iterate over the three different cases
    for case in cases:

        # Solve linear system
        bcs = [d.DirichletBC(V, 1 if what == case else 0, \
                             facet_markers, markers[what], "topological") \
               for what in cases]
def acoustic_main(theta, plot=False, level=0):
    """
    
    
    theta is the parameter vector. here we have 
    
    
    theta 0 = x1
    theta 1 = x2
    theta 2 = alpha
    theta 3 = beta
    
    
    """

    x1 = theta[0]
    x2 = theta[1]
    alpha = theta[2]**2.0
    beta = theta[3]**2.0

    ML = 2**level
    #c=500
    Nx = 40 * ML
    Ny = 40 * ML
    p0 = dl.Point(0., 0.)
    p1 = dl.Point(3, 2)

    rx = [1., 1.5, 2.]
    ry = [1.99, 1.99, 1.99]

    Nrx = len(rx)
    Nry = len(ry)
    Nr = Nry
    t0 = time.time()

    #beta/alpha=c^2=500**2
    #beta=5000**2
    #alpha=10**2

    #defines the source model
    def source(t, x1, x2):
        delta = dl.Expression(
            'M*exp(-(x[0]-x1)*(x[0]-x1)/(a*a)-(x[1]-x2)*(x[1]-x2)/(a*a))/a*(1-2*pi2*f02*t*t)*exp(-pi2*f02*t*t)',
            pi2=np.pi**2,
            a=1E-1,
            f02=f02,
            M=1E10,
            x1=x1,
            x2=x2,
            t=t,
            degree=1)
        return delta

    B = dl.Constant(beta)
    A = dl.Constant(alpha)

    mesh = dl.RectangleMesh(p0, p1, Nx, Ny)
    V = dl.FunctionSpace(mesh, "Lagrange", 1)
    c2 = beta / alpha
    hmin = mesh.hmin()

    dt = 0.15 * hmin / (c2**0.5)

    # Time variables

    t = 0
    T = 0.003
    Nt = int(np.ceil(T / dt))
    if plot:
        print('value of Nt is ' + str(Nt))
        print('dt is ' + str(dt))

    time_ = np.zeros(Nt)

    U_wave = np.zeros((Nt, Nr))
    # Previous and current solution
    u1 = dl.interpolate(dl.Constant(0.0), V)
    u0 = dl.interpolate(dl.Constant(0.0), V)

    # Variational problem at each time
    u = dl.TrialFunction(V)
    v = dl.TestFunction(V)
    M, K = dl.PETScMatrix(), dl.PETScMatrix()  # Assembles matrices
    M = dl.assemble(A * u * v * dl.dx, tensor=M)
    f02 = 1000**2.0
    K = dl.assemble(dl.inner(B * dl.grad(u), dl.grad(v)) * dl.dx, tensor=K)

    # M=dl.assemble(u*v*dl.dx)
    # K=dl.assemble(dl.inner(dl.grad(u),dl.grad(v))*dl.dx)
    delta = source(t, x1, x2)

    f = dl.interpolate(delta, V)

    # ABC
    class ABCdom(dl.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and (x[1] < 2.0)

    abc_boundaryparts = dl.MeshFunction("size_t", mesh,
                                        mesh.topology().dim() - 1)
    ABCdom().mark(abc_boundaryparts, 1)
    #self.ds = Measure("ds")[abc_boundaryparts]
    ds = dl.Measure('ds', domain=mesh, subdomain_data=abc_boundaryparts)
    weak_d = dl.inner((A * B)**0.5 * u, v) * ds(1)
    class_bc_abc = ABCdom()  # to make copies
    # builds the ABS matrix
    D = dl.assemble(weak_d)

    #saves
    if plot:

        ofile = dl.File('output/ud_.pvd')

    u = dl.Function(V)
    ti = 0
    while t <= T:
        fv = dl.assemble(f * v * dl.dx)
        Kun = K * u1.vector()
        Dun = D * (u1.vector() - u0.vector()) / dt
        b = fv - Kun - Dun
        dl.solve(M, u.vector(), b)
        # dl.plot(u);plt.show()
        # import pdb
        # pdb.set_trace()
        u.vector(
        )[:] = dt**2.0 * u.vector()[:] + 2.0 * u1.vector()[:] - u0.vector()[:]
        #u=dt**2*u+2.0*u1-u0
        u0.assign(u1)
        u1.assign(u)

        for rec in range(Nr):
            U_wave[ti, rec] = u([rx[rec], ry[rec]])
        time_[ti] = t
        t += dt
        ti += 1

        delta = source(t, x1, x2)

        f = dl.interpolate(delta, V)
        # Reduce the range of the solution so that we can see the waves
        if plot:
            ofile << (u, t)

    #print('Total time '+str(round(time.time()-t0,3)))

    return U_wave, time_
Пример #59
0
    def transpmult(self, b):
        '''Action on vector from V0'''
        raise NotImplementedError


# --------------------------------------------------------------------

if __name__ == '__main__':
    import numpy as np

    mesh = df.UnitSquareMesh(32, 32)
    V = df.FunctionSpace(mesh, 'CG', 1)
    u, v = df.TrialFunction(V), df.TestFunction(V)

    a = df.inner(u, df.grad(v)[0]) * df.dx
    A = df.assemble(a)

    class Foo(FESpaceOperator):
        def __init__(self, V=V, A=A):
            self.A = A

            FESpaceOperator.__init__(self, V1=V)

        def matvec(self, b):
            return self.A * b

    foo = Foo()

    x = df.interpolate(df.Constant(0), V).vector()
    x.set_local(np.r_[1, np.zeros(V.dim() - 1)])
Пример #60
0
def run_with_params(Tb, mu_value, k_s, path):
    run_time_init = clock()

    temperature_vals = [27.0 + 273, Tb + 273, 1300.0 + 273, 1305.0 + 273]
    temp_prof = TemperatureProfile(temperature_vals)

    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

    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)

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

    time_step = 3.0E11 / tau / 10.0

    dt = Constant(time_step)
    tEnd = 3.0E15 / tau / 5.0  # Non-dimensionalising times

    mesh = RectangleMesh(Point(0.0, 0.0), Point(mesh_width, mesh_height), nx,
                         ny)

    pbc = PeriodicBoundary()
    W = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc)
    S = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc)
    WSSS = MixedFunctionSpace([W, S, S, S])  # WSSS -> W

    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)

    FluidTemp = Expression('max(T0, 1.031)', T0=T0)

    muExp = Expression(
        'exp(-Ep * (T_val * dTemp - 1573.0) + cc * x[1] / mesh_height)',
        Ep=Ep,
        dTemp=temp_prof.delta,
        cc=cc,
        mesh_height=mesh_height,
        T_val=T0)

    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

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

    r_p = p_t * div(v) * dx

    heat_transfer = k_s * (Tf_theta - T_theta) * dt

    r_T = (T_t * ((T - T0) + dt * inner(v_theta, grad(T_theta))) +
           (dt / Ra) * inner(grad(T_t), grad(T_theta)) -
           T_t * heat_transfer) * dx

    # yvec = Constant((0.0, 1.0))
    # rhosolid = rho_0 * (1.0 - alpha * (T_theta * temp_prof.delta - 1573.0))
    # deltarho = rhosolid - rhomelt
    # v_f = v_theta - darcy * (grad(p) * p0 / h - deltarho * yvec * g) / w0

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

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

    r = r_v + r_p + r_T + r_Tf

    bcv0 = DirichletBC(WSSS.sub(0), noslip, top)
    bcv1 = DirichletBC(WSSS.sub(0), vslip, bottom)
    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, bcp0, bct0, bct1, bctf1]

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

    while t < tEnd:
        mu.interpolate(muExp)
        rhosolid = rho_0 * (1.0 - alpha * (T0 * temp_prof.delta - 1573.0))
        deltarho = rhosolid - rhomelt
        assign(
            v_melt,
            project(v0 - darcy * (grad(p) * p0 / h - deltarho * yvec * g) / w0,
                    W))
        # use nP after to avoid projection?
        # pdb.set_trace()

        solve(r == 0, u, bcs)
        nV, nP, nT, nTf = u.split()

        if count % output_every == 0:
            time_left(count, tEnd / time_step, run_time_init)

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

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

        t += time_step
        count += 1

    log('Case mu=%g, Tb=%g complete. Run time = %g s' %
        (mu_a, Tb, clock() - run_time_init))