Beispiel #1
0
    def __init__(self, fileName, timeEnd, timeStep, average=False):



        fc.set_log_active(False)

        self.times = []
        self.BB = []
        self.HH = []
        self.TD = []
        self.TB = []
        self.TX = []
        self.TY = []
        self.TZ = []
        self.us = []
        self.ub = []

        ##########################################################
        ################           MESH          #################
        ##########################################################
        # TODO: Probably do not have to save then open mesh
        self.mesh = df.Mesh()
        self.inFile = fc.HDF5File(self.mesh.mpi_comm(), fileName, "r")
        self.inFile.read(self.mesh, "/mesh", False)

        #########################################################
        #################  FUNCTION SPACES  #####################
        #########################################################
        self.E_Q = df.FiniteElement("CG", self.mesh.ufl_cell(), 1)
        self.Q = df.FunctionSpace(self.mesh, self.E_Q)
        self.E_V = df.MixedElement(self.E_Q, self.E_Q, self.E_Q)
        self.V = df.FunctionSpace(self.mesh, self.E_V)

        self.assigner_inv = fc.FunctionAssigner([self.Q, self.Q, self.Q], self.V)
        self.assigner = fc.FunctionAssigner(self.V, [self.Q, self.Q, self.Q])

        self.U = df.Function(self.V)
        self.dU = df.TrialFunction(self.V)
        self.Phi = df.TestFunction(self.V)
        self.u, self.u2, self.H = df.split(self.U)
        self.phi, self.phi1, self.xsi = df.split(self.Phi)

        self.un = df.Function(self.Q)
        self.u2n = df.Function(self.Q)

        self.zero_sol = df.Function(self.Q)

        self.Bhat = df.Function(self.Q)
        self.H0 = df.Function(self.Q)
        self.A = df.Function(self.Q)

        if average:
            self.inFile.read(self.Bhat.vector(), "/bedAvg", True)
            self.inFile.read(self.A.vector(), "/smbAvg", True)
            self.inFile.read(self.H0.vector(), "/thicknessAvg", True)
        else:
            self.inFile.read(self.Bhat.vector(), "/bed", True)
            self.inFile.read(self.A.vector(), "/smb", True)
            self.inFile.read(self.H0.vector(), "/thickness", True)

        self.Hmid = theta * self.H + (1 - theta) * self.H0

        self.B = softplus(self.Bhat, -rho / rho_w * self.Hmid, alpha=0.2)  # Is not the bed, it is the lower surface

        self.S = self.B + self.Hmid

        self.width = df.interpolate(Width(degree=2), self.Q)

        self.strs = Stresses(self.U, self.Hmid, self.H0, self.H, self.width, self.B, self.S, self.Phi)

        self.R = -(self.strs.tau_xx + self.strs.tau_xz + self.strs.tau_b + self.strs.tau_d + self.strs.tau_xy) * df.dx

        #############################################################################
        ########################  MASS CONSERVATION  ################################
        #############################################################################
        self.h = df.CellSize(self.mesh)
        self.D = self.h * abs(self.U[0]) / 2.
        self.area = self.Hmid * self.width

        self.mesh_min = self.mesh.coordinates().min()
        self.mesh_max = self.mesh.coordinates().max()

        # Define boundaries
        self.ocean = df.FacetFunctionSizet(self.mesh, 0)
        self.ds = fc.ds(subdomain_data=self.ocean)  # THIS DS IS FROM FENICS! border integral

        for f in df.facets(self.mesh):
            if df.near(f.midpoint().x(), self.mesh_max):
                self.ocean[f] = 1
            if df.near(f.midpoint().x(), self.mesh_min):
                self.ocean[f] = 2

        self.R += ((self.H - self.H0) / dt * self.xsi \
                   - self.xsi.dx(0) * self.U[0] * self.Hmid \
                   + self.D * self.xsi.dx(0) * self.Hmid.dx(0) \
                   - (self.A - self.U[0] * self.H / self.width * self.width.dx(0)) \
                   * self.xsi) * df.dx + self.U[0] * self.area * self.xsi * self.ds(1) \
                  - self.U[0] * self.area * self.xsi * self.ds(0)

        #####################################################################
        #########################  SOLVER SETUP   ###########################
        #####################################################################

        # Bounds
        self.l_thick_bound = df.project(Constant(thklim), self.Q)
        self.u_thick_bound = df.project(Constant(1e4), self.Q)

        self.l_v_bound = df.project(-10000.0, self.Q)
        self.u_v_bound = df.project(10000.0, self.Q)

        self.l_bound = df.Function(self.V)
        self.u_bound = df.Function(self.V)

        self.assigner.assign(self.l_bound, [self.l_v_bound] * 2 + [self.l_thick_bound])
        self.assigner.assign(self.u_bound, [self.u_v_bound] * 2 + [self.u_thick_bound])

        # This should set the velocity at the divide (left) to zero
        self.dbc0 = df.DirichletBC(self.V.sub(0), 0, lambda x, o: df.near(x[0], self.mesh_min) and o)
        # Set the velocity on the right terminus to zero
        self.dbc1 = df.DirichletBC(self.V.sub(0), 0, lambda x, o: df.near(x[0], self.mesh_max) and o)
        # overkill?
        self.dbc2 = df.DirichletBC(self.V.sub(1), 0, lambda x, o: df.near(x[0], self.mesh_max) and o)
        # set the thickness on the right edge to thklim
        self.dbc3 = df.DirichletBC(self.V.sub(2), thklim, lambda x, o: df.near(x[0], self.mesh_max) and o)

        # Define variational solver for the mass-momentum coupled problem
        self.J = df.derivative(self.R, self.U, self.dU)

        self.coupled_problem = df.NonlinearVariationalProblem(self.R, self.U, bcs=[self.dbc0, self.dbc1, self.dbc3], \
                                                              J=self.J)

        self.coupled_problem.set_bounds(self.l_bound, self.u_bound)

        self.coupled_solver = df.NonlinearVariationalSolver(self.coupled_problem)

        # Acquire the optimizations in fenics_optimizations
        set_solver_options(self.coupled_solver)

        self.t = 0
        self.timeEnd = float(timeEnd)
        self.dtFloat = float(timeStep)

        self.inFile.close()
Beispiel #2
0
##########################################################

# Define a unit interval mesh with equal cell size
N_cells = 300
mesh = df.IntervalMesh(N_cells, 0, 1)

# Shift vertices such that they are concentrated towards the
# terminus following a polynomial curve.
mesh_exp = 1.5
mesh.coordinates()[:] = (1 - mesh.coordinates()**mesh_exp)[::-1]

# Mesh Functions
h = df.CellSize(mesh)  # Cell size
x_spatial = df.SpatialCoordinate(mesh)  # spatial coordinate
nhat = df.FacetNormal(mesh)  # facet normal vector
ocean = df.FacetFunctionSizet(mesh, 0)  # boundary subdomain function
# ocean=1 -> terminus
# ocean=2 -> ice divide
df.ds = df.ds(subdomain_data=ocean)

for f in df.facets(mesh):
    if df.near(f.midpoint().x(), 1):
        ocean[f] = 1
    if df.near(f.midpoint().x(), 0):
        ocean[f] = 2

#########################################################
#################  FUNCTION SPACES  #####################
#########################################################

# Define finite element function spaces.  Here we use CG1 for