Esempio n. 1
0
def _fluxes(h, q, g):
    r"""Calculate the flux of mass and momentum for the shallow water
    equations"""
    I = firedrake.Identity(2)
    F_h = q
    F_q = outer(q, q) / h + 0.5 * g * h**2 * I
    return F_h, F_q
Esempio n. 2
0
    def initialize_solvers(self):
        # Kinematics                # Right Cauchy-Green tensor
        if self.nonlin:
            d = self.X.geometric_dimension()
            I = fd.Identity(d)  # Identity tensor
            F = I + fd.grad(self.X)  # Deformation gradient
            C = F.T * F
            E = (C - I) / 2.  # Green-Lagrangian strain
#            E = 1./2.*( fd.grad(self.X).T + fd.grad(self.X) + fd.grad(self.X).T * fd.grad(self.X) ) # alternative equivalent definition
        else:
            E = 1. / 2. * (fd.grad(self.X).T + fd.grad(self.X)
                           )  # linear strain

        self.W = (self.lam / 2.) * (fd.tr(E))**2 + self.mu * fd.tr(E * E)
        #        f = fd.Constant((0, 0, -self.g)) # body force / rho
        #        T = self.surface_force()

        # Total potential energy
        Pi = self.W * fd.dx
        # Compute first variation of Pi (directional derivative about X in the direction of v)
        F_expr = fd.derivative(Pi, self.X, self.v)

        self.DBC = fd.DirichletBC(self.V, fd.as_vector([0., 0., 0.]),
                                  self.bottom_id)

        #        delX = fd.nabla_grad(self.X)
        #        delv_B = fd.nabla_grad(self.v)
        #        T_x_dv = self.lam * fd.div(self.X) * fd.div(self.v) \
        #                + self.mu * ( fd.inner( delX, delv_B + fd.transpose(delv_B) ) )

        self.a_U = fd.dot(self.trial, self.v) * fd.dx
        #        self.L_U = ( fd.dot( self.U, self.v ) - self.dt/2./self.rho * T_x_dv ) * fd.dx
        self.L_U = fd.dot(
            self.U, self.v) * fd.dx - self.dt / 2. / self.rho * F_expr  #\
        #                  + self.dt/2./self.rho*fd.dot(T,self.v)*fd.ds(1) # surface force at x==0 plane
        # + self.dt/2.*fd.dot(f,self.v)*fd.dx # body force
        self.a_X = fd.dot(self.trial, self.v) * fd.dx
        #        self.L_interface = fd.dot(self.phi_vect, self.v) * fd.ds(self.interface_id)
        self.L_X = fd.dot((self.X + self.dt * self.U), self.v) * fd.dx  #\
        #                    - self.dt/self.rho * self.L_interface

        self.LVP_U = fd.LinearVariationalProblem(self.a_U,
                                                 self.L_U,
                                                 self.U,
                                                 bcs=[self.DBC])
        self.LVS_U = fd.LinearVariationalSolver(self.LVP_U)
        self.LVP_X = fd.LinearVariationalProblem(self.a_X,
                                                 self.L_X,
                                                 self.X,
                                                 bcs=[self.DBC])
        self.LVS_X = fd.LinearVariationalSolver(self.LVP_X)
dt = np.sqrt(tol)
dtc = fd.Constant(dt)
n = fd.FacetNormal(mesh)
h = fd.sqrt(2) * fd.CellVolume(mesh) / fd.CellDiameter(mesh)

# advective velocity
velocity = fd.Function(vDG1)
velocity.interpolate(v_inlet)
vnorm = fd.sqrt(fd.dot(velocity, velocity))

# upwind term
vn = 0.5 * (fd.dot(velocity, n) + abs(fd.dot(velocity, n)))
cupw = fd.conditional(fd.dot(velocity, n) > 0, ch, lmbd_h)

# Diffusion tensor
Diff = fd.Identity(mesh.geometric_dimension()) * Dm
# Diff = fd.Identity(mesh.geometric_dimension())*(Dm + d_t*vnorm) + \
#     fd.Constant(d_l-d_t)*fd.outer(velocity, velocity)/vnorm

# stability
# tau = fd.Constant(1.0) / h + abs(fd.dot(velocity, n))
tau = fd.Constant(5) / h + vn

# numerical flux
chat = lmbd_h
qhat = qh + tau * (ch - chat) * n + velocity * chat
# qhat_n = fd.dot(qh, n) + tau*(ch - chat) + chat*vn

a_u = (
    fd.inner(fd.inv(Diff) * qh, vh) * fd.dx - ch * fd.div(vh) * fd.dx +
    # internal faces
L = p_out*fd.inner(v, n)*fd.ds(outlet) + \
    fd.inner(f, v)*fd.dx + idt*c_t*p0*q*fd.dx

# -------------------------------------------------------------------------
# transport
# coefficients
K = fd.Constant(K)
Dt = fd.Constant(dt)
c_mid = 0.5 * (c + c0)  # Crank-Nicolson timestepping

# advective velocity
vel = fd.Function(V, name='velocity')
vnorm = fd.sqrt(fd.dot(vel, vel))

# Diffusion tensor
Diff = fd.Identity(mesh.geometric_dimension())*(Dm + alphaT*vnorm) + \
    (alphaL-alphaT)*fd.outer(vel, vel)/vnorm

# source term
fc = fd.Constant(s)

# weak form (transport)
F1 = w * (c - c0) * fd.dx + Dt * (w * fd.dot(vel, fd.grad(c_mid)) + fd.dot(
    fd.grad(w), Diff * fd.grad(c_mid)) + w * K * c_mid -
                                  fc * w) * fd.dx  # - Dt*h_n*w*fd.ds(outlet)

# strong form
R = (c - c0) + Dt * (fd.dot(vel, fd.grad(c_mid)) -
                     fd.div(Diff * fd.grad(c_mid)) + K * c_mid - fc)

# *** Adding SUPG stabilizing and shock cap. terms ***
Esempio n. 5
0
# 3.4) Variational Form
# ----------------------
# coefficients
dt = np.sqrt(tol)
dtc = fd.Constant(dt)
n = fd.FacetNormal(mesh)
h = fd.sqrt(2) * fd.CellVolume(mesh) / fd.CellDiameter(mesh)

# advective velocity
velocity = fd.Function(vDG1)
velocity.interpolate(fd.Constant(v_inlet))
vnorm = fd.sqrt(fd.dot(velocity, velocity))

# Diffusion tensor
if d_t < 0:
    Diff = fd.Identity(mesh.geometric_dimension()) * Dm
else:
    Diff = fd.Identity(mesh.geometric_dimension())*(Dm + d_t*vnorm) + \
        fd.Constant(d_l-d_t)*fd.outer(velocity, velocity)/vnorm

# upwind ter
# vn = 0.5*(fd.dot(velocity, n) + abs(fd.dot(velocity, n)))
# cupw = fd.conditional(vn < 0, ch, lmbd_h)

# stability
tau_d = fd.Constant(max([Dm, tau_e])) / h
tau_a = abs(fd.dot(velocity, n))
# tau_a = vn

# numerical flux
chat = lmbd_h
Esempio n. 6
0
 def sigma(u):
     d = u.geometric_dimension()  # space dimension
     return self.lam * fd.nabla_div(u) * fd.Identity(
         d) + 2 * self.mu * epsilon(u)
# way #1: natural bdr condition
# src = None
# nat_bdr = fd.conditional(x**2 + y**2 < h_mesh**2,
#                          -0.1, 0.) # 10 m3/d

# way #2: source term
nat_bdr = None
src = fd.conditional(x**2 + y**2 < h_mesh**2, 0.1 * n, 0.)  # 10 m3/d/m3

# %%
# physical parameters
beta = 4.5e-8  # 1/Pa
rho = lambda x: 1000 * (1 + beta * (x - 1e5))
mu = 1e-3
phi = 0.1
k = 1e-14 * fd.Identity(dim)

g_ = -10  # None (without gravity)
g = fd.as_vector(
    tuple([0 for d in range(dim - 1)]) + (0 if g_ is None else -g_, ))

# %%
# set forms
# ---------

W = fd.FunctionSpace(mesh, "CG", 1)
q = fd.TestFunction(W)

p = fd.Function(W, name="p")
p0 = fd.Function(W, name="p0")
Esempio n. 8
0
def Identity(dim):
    r"""Return the unit tensor of a given dimension"""
    if dim == 1:
        return firedrake.Constant(1.0)
    return firedrake.Identity(dim)