예제 #1
0
    def setup(self, state):
        if not self._initialised:
            # check geometric dimension is 3D
            if state.mesh.geometric_dimension() != 3:
                raise ValueError(
                    'Spherical components only work when the geometric dimension is 3!'
                )
            space = FunctionSpace(state.mesh, "CG", 1)
            super().setup(state, space=space)

        V = VectorFunctionSpace(state.mesh, "CG", 1)
        self.x, self.y, self.z = SpatialCoordinate(state.mesh)
        self.x_hat = Function(V).interpolate(
            Constant(as_vector([1.0, 0.0, 0.0])))
        self.y_hat = Function(V).interpolate(
            Constant(as_vector([0.0, 1.0, 0.0])))
        self.z_hat = Function(V).interpolate(
            Constant(as_vector([0.0, 0.0, 1.0])))
        self.R = sqrt(self.x**2 + self.y**2)  # distance from z axis
        self.r = sqrt(self.x**2 + self.y**2 +
                      self.z**2)  # distance from origin
        self.f = state.fields(self.fname)
        if np.prod(self.f.ufl_shape) != 3:
            raise ValueError(
                'Components can only be found of a vector function space in 3D.'
            )
 def update_constants(self):
     """
     Update p and q constants from true peakon data.
     """
     self.p.assign(self.true_peakon_file['p'][self.outputting.t_idx] * 0.5 *
                   (1 + exp(-self.Ld / sqrt(self.alphasq))) /
                   (1 - exp(-self.Ld / sqrt(self.alphasq))))
     self.q.assign(self.true_peakon_file['q'][self.outputting.t_idx])
예제 #3
0
 def max_courant_number(self, u, dt):
     if not hasattr(self, "_area"):
         V = FunctionSpace(u.function_space().mesh(), "DG", 0)
         expr = TestFunction(V) * dx
         self._area = assemble(expr)
         self.Courant = Function(V)
     self.Courant.project(sqrt(inner(u, u)) / sqrt(self._area) * dt)
     return self.Courant.dat.data.max()
예제 #4
0
def get_true_sol_expr(spatial_coord, kappa):
    if mesh_dim == 3:
        x, y, z = spatial_coord
        norm = sqrt(x**2 + y**2 + z**2)
        return Constant(1j / (4 * pi)) / norm * exp(1j * kappa * norm)

    elif mesh_dim == 2:
        x, y = spatial_coord
        return Constant(1j / 4) * hankel_function(kappa * sqrt(x**2 + y**2),
                                                  n=hankel_cutoff)
    raise ValueError("Only meshes of dimension 2, 3 supported")
예제 #5
0
    def _K(self):
        """
        Create the function that defines the conductivity.

        Returns:
            Function: The Spitzer-Harm conductivity
        """
        tmp = 288 * pi * sqrt(2) * epsilon_0**2 / sqrt(e * m_e)
        tmp = tmp * pow(self.T, 5 / 2) / (self.coulomb_ln * self.ionisation)

        return tmp
예제 #6
0
def get_true_sol_expr(spatial_coord, wave_number):
    mesh_dim = len(spatial_coord)
    if mesh_dim == 3:
        x, y, z = spatial_coord
        norm = sqrt(x**2 + y**2 + z**2)
        return Constant(1j / (4 * pi)) / norm * exp(1j * wave_number * norm)

    elif mesh_dim == 2:
        x, y = spatial_coord
        return Constant(1j / 4) * hankel_function(
            wave_number * sqrt(x**2 + y**2), n=80)
    raise ValueError("Only meshes of dimension 2, 3 supported")
def run_advection_diffusion(tmpdir):

    # Mesh, state and equation
    L = 10
    mesh = PeriodicIntervalMesh(20, L)
    dt = 0.02
    tmax = 1.0

    diffusion_params = DiffusionParameters(kappa=0.75, mu=5)
    output = OutputParameters(dirname=str(tmpdir), dumpfreq=25)
    state = State(mesh, dt=dt, output=output)
    V = state.spaces("DG", "DG", 1)
    Vu = VectorFunctionSpace(mesh, "CG", 1)

    equation = AdvectionDiffusionEquation(
        state, V, "f", Vu=Vu, diffusion_parameters=diffusion_params)

    problem = [(equation, ((SSPRK3(state), transport), (BackwardEuler(state),
                                                        diffusion)))]

    # Initial conditions
    x = SpatialCoordinate(mesh)
    xc_init = 0.25 * L
    xc_end = 0.75 * L
    umax = 0.5 * L / tmax

    # Get minimum distance on periodic interval to xc
    x_init = conditional(
        sqrt((x[0] - xc_init)**2) < 0.5 * L, x[0] - xc_init,
        L + x[0] - xc_init)

    x_end = conditional(
        sqrt((x[0] - xc_end)**2) < 0.5 * L, x[0] - xc_end, L + x[0] - xc_end)

    f_init = 5.0
    f_end = f_init / 2.0
    f_width_init = L / 10.0
    f_width_end = f_width_init * 2.0
    f_init_expr = f_init * exp(-(x_init / f_width_init)**2)
    f_end_expr = f_end * exp(-(x_end / f_width_end)**2)

    state.fields('f').interpolate(f_init_expr)
    state.fields('u').interpolate(as_vector([Constant(umax)]))
    f_end = state.fields('f_end', V).interpolate(f_end_expr)

    # Time stepper
    timestepper = PrescribedTransport(state, problem)
    timestepper.run(0, tmax=tmax)

    error = norm(state.fields('f') - f_end) / norm(f_end)

    return error
def write_output(diag, t, counter, dfr, nc_h5_dfr, outf, outf_ll, fld_out,
                 fld_out_ll):
    """Function to write vtu, txt output"""

    # Update and output diagnostics
    energy = e_form(un, Dn)
    En.interpolate(energy)
    if 'Energy' in diag.keys():
        diag['Energy'] = assemble(energy * dx)
    if 'Mass' in diag.keys():
        diag['Mass'] = assemble(Dn * dx)
    if 'Enstrophy' in diag.keys():
        diag['Enstrophy'] = assemble(qn**2 * Dn * dx)
    if 'L2_error_D' in diag.keys():
        diag['L2_error_D'] = sqrt(assemble((Dn - D0) * (Dn - D0) * dx))
    if 'L2_error_u' in diag.keys():
        diag['L2_error_u'] = sqrt(assemble(inner(un - u0, un - u0) * dx))

    _c = 0
    for k in diag:
        nc_temp[counter % nc_h5_dfr][_c] = diag[k]
        _c += 1

    # Save I/O time by not writing at each timestep
    if (counter % nc_h5_dfr) == nc_h5_dfr - 1:

        if COMM_WORLD.Get_rank() == 0:
            print("Timestep nr", counter, ": Writing nc files at", ctime())
            write_to_nc_file(t, nc_temp)
            if nc_safe:
                write_to_nc_file(t, nc_temp, '_bckp')

        # Write to checkpoint
        chkpt.store(xn)
        chkpt.write_attribute("/", "time", t)
        if h5_safe:
            chkpt_bckp.store(xn)
            chkpt_bckp.write_attribute("/", "time", t)

    # Output vtu file
    if t in field_dumptimes:
        #q2Dn.project(qn**2*Dn)
        #eta_out.interpolate(Dn + b)
        #vortsolver.solve()
        u_err.assign(un - u0)
        D_err.assign(Dn - D0)
        q_err.assign(qn - q0)
        outf.write(*fld_out)
        if write_latlon:
            outf_ll.write(*fld_out_ll)
예제 #9
0
def norm(u, norm_type="L2"):
    r"""Compute the norm of a field

    Computes one of any number of norms of a scalar or vector field. The
    available options are:

    - ``L2``: :math:`\|u\|^2 = \int_\Omega|u|^2dx`

    - ``H01``: :math:`\|u\|^2 = \int_\Omega|\nabla u|^2dx`

    - ``H1``: :math:`\|u\|^2 = \int_\Omega\left(|u|^2 + L^2|\nabla u|^2\right)dx`

    - ``L1``: :math:`\|u\| = \int_\Omega|u|dx`

    - ``TV``: :math:`\|u\| = \int_\Omega|\nabla u|dx`

    - ``Linfty``: :math:`\|u\| = \max_{x\in\Omega}|u(x)|`

    The extra factor :math:`L` in the :math:`H^1` norm is the diameter of
    the domain in the infinity metric. This extra factor is included to
    make the norm scale appropriately with the size of the domain.
    """
    if norm_type == "L2":
        form, p = inner(u, u) * dx, 2

    if norm_type == "H01":
        form, p = inner(grad(u), grad(u)) * dx, 2

    if norm_type == "H1":
        L = utilities.diameter(u.ufl_domain())
        form, p = inner(u, u) * dx + L**2 * inner(grad(u), grad(u)) * dx, 2

    if norm_type == "L1":
        form, p = sqrt(inner(u, u)) * dx, 1

    if norm_type == "TV":
        form, p = sqrt(inner(grad(u), grad(u))) * dx, 1

    if norm_type == "Linfty":
        data = u.dat.data_ro
        if len(data.shape) == 1:
            local_max = np.max(np.abs(data))
        elif len(data.shape) == 2:
            local_max = np.max(np.sqrt(np.sum(data**2, 1)))

        return u.comm.allreduce(local_max, op=max)

    return assemble(form)**(1 / p)
예제 #10
0
파일: plot.py 프로젝트: zxdhpc/firedrake
def _plot_2d_field(method_name,
                   function,
                   *args,
                   complex_component="real",
                   **kwargs):
    axes = kwargs.pop("axes", None)
    if axes is None:
        figure = plt.figure()
        axes = figure.add_subplot(111)

    if len(function.ufl_shape) == 1:
        mesh = function.ufl_domain()
        element = function.ufl_element().sub_elements()[0]
        Q = FunctionSpace(mesh, element)
        function = interpolate(sqrt(inner(function, function)), Q)

    num_sample_points = kwargs.pop("num_sample_points", 10)
    coords, vals, triangles = _two_dimension_triangle_func_val(
        function, num_sample_points)

    coords = toreal(coords, "real")
    x, y = coords[:, 0], coords[:, 1]
    triangulation = matplotlib.tri.Triangulation(x, y, triangles=triangles)

    method = getattr(axes, method_name)
    return method(triangulation, toreal(vals, complex_component), *args,
                  **kwargs)
예제 #11
0
def _plot_2d_field(method_name,
                   function,
                   *args,
                   complex_component="real",
                   **kwargs):
    axes = kwargs.pop("axes", None)
    if axes is None:
        figure = plt.figure()
        axes = figure.add_subplot(111)

    Q = function.function_space()
    mesh = Q.mesh()
    if len(function.ufl_shape) == 1:
        element = function.ufl_element().sub_elements()[0]
        Q = FunctionSpace(mesh, element)
        function = interpolate(sqrt(inner(function, function)), Q)

    num_sample_points = kwargs.pop("num_sample_points", 10)
    function_plotter = FunctionPlotter(mesh, num_sample_points)
    triangulation = function_plotter.triangulation
    values = function_plotter(function)

    method = getattr(axes, method_name)
    return method(triangulation, toreal(values, complex_component), *args,
                  **kwargs)
예제 #12
0
def referencemesh(mesh, b, hinitial, Href):
    '''In-place modification of an extruded mesh to create the reference mesh.
    Changes the top surface to  lambda = b + sqrt(Href^2 + (Hinitial - b)^2).
    Assumes b,hinitial are Functions defined on the base mesh.  Assumes the
    input mesh is extruded 3D mesh with  0 <= z <= 1.'''

    if not _admissible(b, hinitial):
        assert ValueError('input hinitial not admissible')
    P1base = fd.FunctionSpace(mesh._base_mesh, 'P', 1)
    HH = fd.Function(P1base).interpolate(hinitial - b)
    # alternative:
    #lambase = fd.Function(P1base).interpolate(b + fd.max_value(Href, Hstart))
    lambase = fd.Function(P1base).interpolate(b + fd.sqrt(HH**2 + Href**2))

    lam = extend(mesh, lambase)
    Vcoord = mesh.coordinates.function_space()
    if mesh._base_mesh.cell_dimension() == 1:
        x, z = fd.SpatialCoordinate(mesh)
        XX = fd.Function(Vcoord).interpolate(fd.as_vector([x, lam * z]))
    elif mesh._base_mesh.cell_dimension() == 2:
        x, y, z = fd.SpatialCoordinate(mesh)
        XX = fd.Function(Vcoord).interpolate(fd.as_vector([x, y, lam * z]))
    else:
        raise ValueError('only 2D and 3D reference meshes are generated')
    mesh.coordinates.assign(XX)
    return 0
예제 #13
0
def Bueler_profile(mesh, R):
    x, y = firedrake.SpatialCoordinate(mesh)
    r = firedrake.sqrt(x**2 + y**2)
    h_divide = (2 * R * (alpha/A0)**(1/n) * (n-1)/n)**(n/(2*n+2))
    h_part2 = (n+1)*(r/R) - n*(r/R)**((n+1)/n) + n*(max_value(1-(r/R),0))**((n+1)/n) - 1
    h_expr = (h_divide/((n-1)**(n/(2*n+2)))) * (max_value(h_part2,0))**(n/(2*n+2))
    return h_expr
예제 #14
0
    def equation(z):
        Z = z.function_space()
        φ, v = firedrake.TestFunctions(Z)
        h, q = firedrake.split(z)
        F_h, F_q = _fluxes(h, q, g)

        mesh = Z.mesh()
        n = firedrake.FacetNormal(mesh)
        c = abs(inner(q / h, n)) + sqrt(g * h)

        sources = -inner(g * h * grad(b), v) * dx

        fluxes = (forms.cell_flux(F_h, φ) + forms.central_facet_flux(F_h, φ) +
                  forms.lax_friedrichs_facet_flux(h, c, φ) +
                  forms.cell_flux(F_q, v) + forms.central_facet_flux(F_q, v) +
                  forms.lax_friedrichs_facet_flux(q, c, v))

        boundary_ids = set(mesh.exterior_facets.unique_markers)
        wall_ids = tuple(boundary_ids - set(outflow_ids) - set(inflow_ids))
        q_wall = q - 2 * inner(q, n) * n
        boundary_fluxes = (
            _boundary_flux(z, h, q, g, outflow_ids) +
            _boundary_flux(z, h_in, q_in, g, inflow_ids) +
            _boundary_flux(z, h, q_wall, g, wall_ids) +
            forms.lax_friedrichs_boundary_flux(h, h, c, φ, outflow_ids) +
            forms.lax_friedrichs_boundary_flux(q, q, c, v, outflow_ids) +
            forms.lax_friedrichs_boundary_flux(h, h_in, c, φ, inflow_ids) +
            forms.lax_friedrichs_boundary_flux(q, q_in, c, v, inflow_ids) +
            forms.lax_friedrichs_boundary_flux(h, h, c, φ, wall_ids) +
            forms.lax_friedrichs_boundary_flux(q, q_wall, c, v, wall_ids))

        return sources - fluxes - boundary_fluxes
예제 #15
0
파일: plot.py 프로젝트: xywei/firedrake
def trisurf(function, *args, **kwargs):
    r"""Create a 3D surface plot of a 2D Firedrake :class:`~.Function`

    If the input function is a vector field, the magnitude will be plotted.

    :arg function: the Firedrake :class:`~.Function` to plot
    :arg args: same as for matplotlib :meth:`plot_trisurf <mpl_toolkits.mplot3d.axes3d.Axes3D.plot_trisurf>`
    :arg kwargs: same as for matplotlib
    :return: matplotlib :class:`Poly3DCollection <mpl_toolkits.mplot3d.art3d.Poly3DCollection>` object
    """
    axes = kwargs.pop("axes", None)
    if axes is None:
        figure = plt.figure()
        axes = figure.add_subplot(111, projection='3d')

    _kwargs = {"antialiased": False, "edgecolor": "none",
               "cmap": plt.rcParams["image.cmap"]}
    _kwargs.update(kwargs)

    mesh = function.ufl_domain()
    if mesh.geometric_dimension() == 3:
        return _trisurf_3d(axes, function, *args, **_kwargs)

    if len(function.ufl_shape) == 1:
        element = function.ufl_element().sub_elements()[0]
        Q = FunctionSpace(mesh, element)
        function = interpolate(sqrt(inner(function, function)), Q)

    num_sample_points = kwargs.pop("num_sample_points", 10)
    coords, vals, triangles = _two_dimension_triangle_func_val(function,
                                                               num_sample_points)
    x, y = coords[:, 0], coords[:, 1]
    triangulation = matplotlib.tri.Triangulation(x, y, triangles=triangles)
    _kwargs.update({"shade": False})
    return axes.plot_trisurf(triangulation, vals, *args, **_kwargs)
예제 #16
0
    def _K_min(self):
        r_ii = (3 / (4 * pi * self.ion_density))**(1 / 3)
        tau_min = r_ii / self.v_th
        tmp = 48 * self.ionisation * self.ion_density * e**2 * self.T * tau_min
        tmp = tmp / sqrt(pi) / m_e

        return tmp
예제 #17
0
def create_conductivity(mesh, V, T):
    """
    This is the conductivity term.
    Here we use the spitzer-harm conductivity.

    mesh: Mesh, The mesh to define the function for.
    V: FunctionSpace, The function space that the function should be in
    T: Function, The temperature of the plasma.
    """
    coulomb_ln = create_coulomb_ln(mesh, V)
    Z = create_Z(mesh, V)

    tmp = 288 * pi * sqrt(2) * epsilon_0**2 / sqrt(e * m_e)
    tmp = tmp * pow(T, 5 / 2) / (coulomb_ln * Z)

    return tmp
예제 #18
0
def latlon_coords(mesh):
    x0, y0, z0 = SpatialCoordinate(mesh)
    unsafe = z0 / sqrt(x0 * x0 + y0 * y0 + z0 * z0)
    safe = Min(Max(unsafe, -1.0), 1.0)  # avoid silly roundoff errors
    theta = asin(safe)  # latitude
    lamda = atan_2(y0, x0)  # longitude
    return theta, lamda
    def setup_solver(self, up_init=None):
        """ Setup the solvers
        """
        self.up0 = Function(self.W)
        if up_init is not None:
            chk_in = checkpointing.HDF5File(up_init, file_mode='r')
            chk_in.read(self.up0, "/up")
            chk_in.close()
        self.u0, self.p0 = split(self.up0)

        self.up = Function(self.W)
        if up_init is not None:
            chk_in = checkpointing.HDF5File(up_init, file_mode='r')
            chk_in.read(self.up, "/up")
            chk_in.close()
        self.u1, self.p1 = split(self.up)

        self.up.sub(0).rename("velocity")
        self.up.sub(1).rename("pressure")

        v, q = TestFunctions(self.W)

        h = CellVolume(self.mesh)
        u_norm = sqrt(dot(self.u0, self.u0))

        if self.has_nullspace:
            nullspace = MixedVectorSpaceBasis(
                self.W,
                [self.W.sub(0), VectorSpaceBasis(constant=True)])
        else:
            nullspace = None

        tau = ((2.0 / self.dt)**2 + (2.0 * u_norm / h)**2 +
               (4.0 * self.nu / h**2)**2)**(-0.5)

        # temporal discretization
        F = (1.0 / self.dt) * inner(self.u1 - self.u0, v) * dx

        # weak form
        F += (+inner(dot(self.u0, nabla_grad(self.u1)), v) * dx +
              self.nu * inner(grad(self.u1), grad(v)) * dx -
              (1.0 / self.rho) * self.p1 * div(v) * dx +
              div(self.u1) * q * dx - inner(self.forcing, v) * dx)

        # residual form
        R = (+(1.0 / self.dt) * (self.u1 - self.u0) +
             dot(self.u0, nabla_grad(self.u1)) - self.nu * div(grad(self.u1)) +
             (1.0 / self.rho) * grad(self.p1) - self.forcing)

        # GLS
        F += tau * inner(
            +dot(self.u0, nabla_grad(v)) - self.nu * div(grad(v)) +
            (1.0 / self.rho) * grad(q), R) * dx

        self.problem = NonlinearVariationalProblem(F, self.up, self.bcs)
        self.solver = NonlinearVariationalSolver(
            self.problem,
            nullspace=nullspace,
            solver_parameters=self.solver_parameters)
예제 #20
0
def eigenvalues(a):
    r"""Return a pair of symbolic expressions for the largest and smallest
    eigenvalues of a 2D rank-2 tensor"""
    tr_a = tr(a)
    det_a = det(a)
    # TODO: Fret about numerical stability
    Δ = sqrt(tr_a**2 - 4 * det_a)
    return ((tr_a + Δ) / 2, (tr_a - Δ) / 2)
예제 #21
0
def stresses(ε_x, ε_z, A):
    r"""Calculate the membrane and vertical shear stresses for the given
    horizontal and shear strain rates and fluidity"""
    I = Identity(2)
    tr = trace(ε_x)
    ε_e = sqrt((inner(ε_x, ε_x) + inner(ε_z, ε_z) + tr**2) / 2)
    μ = 0.5 * A**(-1 / n) * ε_e**(1 / n - 1)
    return 2 * μ * (ε_x + tr * I), 2 * μ * ε_z
예제 #22
0
    def __init__(self, state, V, direction=[], supg_params=None):
        super(SUPGAdvection, self).__init__(state)
        dt = state.timestepping.dt
        params = supg_params.copy() if supg_params else {}
        params.setdefault('a0', dt/sqrt(15.))
        params.setdefault('a1', dt/sqrt(15.))

        gamma = TestFunction(V)
        theta = TrialFunction(V)
        self.theta0 = Function(V)

        # make SUPG test function
        taus = [params["a0"], params["a1"]]
        for i in direction:
            taus[i] = 0.0
        tau = Constant(((taus[0], 0.), (0., taus[1])))

        dgamma = dot(dot(self.ubar, tau), grad(gamma))
        gammaSU = gamma + dgamma

        n = FacetNormal(state.mesh)
        un = 0.5*(dot(self.ubar, n) + abs(dot(self.ubar, n)))

        a_mass = gammaSU*theta*dx
        arhs = a_mass - dt*gammaSU*dot(self.ubar, grad(theta))*dx

        if 1 in direction:
            arhs -= (
                dt*dot(jump(gammaSU), (un('+')*theta('+')
                                       - un('-')*theta('-')))*dS_v
                - dt*(gammaSU('+')*dot(self.ubar('+'), n('+'))*theta('+')
                      + gammaSU('-')*dot(self.ubar('-'), n('-'))*theta('-'))*dS_v
            )
        if 2 in direction:
            arhs -= (
                dt*dot(jump(gammaSU), (un('+')*theta('+')
                                       - un('-')*theta('-')))*dS_h
                - dt*(gammaSU('+')*dot(self.ubar('+'), n('+'))*theta('+')
                      + gammaSU('-')*dot(self.ubar('-'), n('-'))*theta('-'))*dS_h
            )

        self.theta1 = Function(V)
        self.dtheta = Function(V)
        problem = LinearVariationalProblem(a_mass, action(arhs,self.theta1), self.dtheta)
        self.solver = LinearVariationalSolver(problem,
                                              options_prefix='SUPGAdvection')
예제 #23
0
def M(ε, A):
    r"""Calculate the membrane stress for a given strain rate and
    fluidity"""
    I = Identity(2)
    tr_ε = trace(ε)
    ε_e = sqrt((inner(ε, ε) + tr_ε**2) / 2)
    μ = 0.5 * A**(-1 / n) * ε_e**(1 / n - 1)
    return 2 * μ * (ε + tr_ε * I)
예제 #24
0
class CompressibleEadyParameters(CompressibleParameters, EadyParameters):
    """
    Physical parameters for Compressible Eady
    """
    g = 10.
    N = sqrt(EadyParameters.Nsq)
    theta_surf = 300.
    dthetady = theta_surf / g * EadyParameters.dbdy
    Pi0 = 0.0
예제 #25
0
def profilePlots(t, plotData, u, s, h, zb, zF, melt, Q, first=False):
    '''Plot profiles every nYears/20
    '''
    # Return if not ready for plot
    if t < plotData['nextProfPlotTime'] or plotData['axesP'] is None \
            and not first:
        return
    # Increment time for next plot: use max to kill initial -1
    plotData['nextProfPlotTime'] = max(plotData['nextProfPlotTime'], 0.)
    plotData['nextProfPlotTime'] += plotData['profileDT']
    myColor = plotData['cmap'][plotData['profNum']]
    myLabel = f'year={t:.1f}'
    # First is special case
    if first:
        myColor = 'k'
        zbProf = [zb((xy[0], xy[1])) for xy in plotData['profXY']]
        plotData['axesP'][1].plot(plotData['distance'], zbProf, color=myColor)
        myLabel = 'initial'
        zFProf = [zF((xy[0], xy[1])) for xy in plotData['profXY']]
        plotData['axesP'][1].plot(plotData['distance'], zFProf, color='b')
    # Now do plots
    speed = firedrake.interpolate(firedrake.sqrt(firedrake.inner(u, u)), Q)
    speedProf = [speed((xy[0], xy[1])) for xy in plotData['profXY']]
    plotData['axesP'][0].plot(plotData['distance'],
                              speedProf,
                              label=myLabel,
                              color=myColor)
    plotData['axesP'][0].legend(ncol=2)
    # Geometry
    sProf = [s((xy[0], xy[1])) for xy in plotData['profXY']]
    bProf = [
        s((xy[0], xy[1])) - h((xy[0], xy[1])) for xy in plotData['profXY']
    ]
    zbProf = [zb((xy[0], xy[1])) for xy in plotData['profXY']]
    plotData['axesP'][1].plot(plotData['distance'], sProf, color=myColor)
    plotData['axesP'][1].plot(plotData['distance'], bProf, color=myColor)
    plotData['axesP'][1].plot(plotData['distance'], zbProf, color='k')
    #
    if melt is not None:
        meltProf = [melt((xy[0], xy[1])) for xy in plotData['profXY']]
        plotData['axesP'][2].plot(plotData['distance'],
                                  meltProf,
                                  label=myLabel,
                                  color=myColor)
        hProf = np.array([h((xy[0], xy[1])) for xy in plotData['profXY']])
        dhdt = (hProf - plotData['lasth']) / plotData['profileDT']
        plotData['axesP'][3].plot(plotData['distance'],
                                  dhdt,
                                  label=myLabel,
                                  color=myColor)
        plotData['lasth'] = hProf
    plotData['profNum'] += 1
    # plt.draw()
    if plotData['plotResult']:
        plotData['figP'].canvas.draw()
예제 #26
0
 def violation(self):
     gradSv = self.gradS.vector()[:]
     av = self.upper_bound.vector()[:]
     violv = self.viol.vector()[:].copy()
     for i in range(len(gradSv)):
         W, Sigma, V = svd(gradSv[i], full_matrices=False)
         for j in range(self.dim):
             Sigma[j] = max(Sigma[j] - av[i], 0)**2
         violv[i] = self.c * 0.5 * np.sum(Sigma)
     self.viol.vector().set_local(violv.flatten())
     return fd.sqrt(fd.assemble(self.viol * fd.dx))
예제 #27
0
def betaInit(s, h, speed, V, Q, Q1, grounded, inversionParams):
    """Compute intitial beta using 0.5 taud.
    Parameters
    ----------
    s : firedrake function
        model surface elevation
    h : firedrake function
        model thickness
    speed : firedrake function
        modelled speed
    V : firedrake vector function space
        vector function space
    Q : firedrake function space
        scalar function space
    grounded : firedrake function
        Mask with 1s for grounded 0 for floating.
    """
    # Use a result from prior inversion
    checkFile = inversionParams['initFile']
    Quse = Q
    if inversionParams['initWithDeg1']:
        checkFile = f'{inversionParams["inversionResult"]}.deg1'
        Quse = Q1
    if checkFile is not None:
        betaTemp = mf.getCheckPointVars(checkFile, 'betaInv', Quse)['betaInv']
        beta1 = icepack.interpolate(betaTemp, Q)
        return beta1
    # No prior result, so use fraction of taud
    tauD = firedrake.project(-rhoI * g * h * grad(s), V)
    #
    stress = firedrake.sqrt(firedrake.inner(tauD, tauD))
    Print('stress', firedrake.assemble(stress * firedrake.dx))
    fraction = firedrake.Constant(0.95)
    U = max_value(speed, 1)
    C = fraction * stress / U**(1/m)
    if inversionParams['friction'] == 'schoof':
        mExp = 1/m + 1
        U0 = firedrake.Constant(inversionParams['uThresh'])
        C = C * (m/(m+1)) * (U0**mExp + U**mExp)**(1/(m+1))
    beta = firedrake.interpolate(firedrake.sqrt(C) * grounded, Q)
    return beta
예제 #28
0
def friction(**kwargs):
    keys = ('velocity', 'thickness', 'surface', 'friction')
    u, h, s, C = map(kwargs.get, keys)

    p_W = ρ_W * g * max_value(0, -(s - h))
    p_I = ρ_I * g * h
    N = p_I - p_W
    τ_c = N / 2

    u_c = (τ_c / C)**m
    u_b = sqrt(inner(u, u))

    return τ_c * ((u_c**(1 / m + 1) + u_b**(1 / m + 1))**(m / (m + 1)) - u_c)
예제 #29
0
def getModelVelocity(baseName, Q, V, minSigma=5, maxSigma=100):
    """Read in a tiff velocity data set and return
    firedrake interpolate functions.

    Parameters
    ----------
    baseName : str
        baseName should be of the form pattern.*.abc or pattern
        The wildcard (*) will be filled with the suffixes (vx, vy.)
        e.g.,pattern.vx.abc.tif, pattern.vy.abc.tif.
    Q : firedrake function space
        function space
    V : firedrake vector space
        vector space
    Returns
    -------
    uObs firedrake interp function on V
        velocity (m/yr)
    speed firedrake interp function on Q
        speed in (m)
    sigmaX firedrake interp function on Q
        vx error (m)
    sigmaY firedrake interp function on Q
        vy error (m)
    """
    # suffixes for products used
    suffixes = ['vx', 'vy', 'ex', 'ey']
    rasters = {}
    # prep baseName - baseName.*.xyz.tif or baseName.*
    if '*' not in baseName:
        baseName += '.*'
    if '.tif' not in baseName:
        baseName += '.tif'
    # read data
    for suffix in suffixes:
        myBand = baseName.replace('*', suffix)
        if not os.path.exists(myBand):
            u.myerror(f'Velocity/error file - {myBand} - does not exist')
        rasters[suffix] = rasterio.open(myBand, 'r')
    # Firedrake interpolators
    uObs = icepack.interpolate((rasters['vx'], rasters['vy']), V)
    # force error to be at least 1 to avoid 0 or negatives.
    sigmaX = icepack.interpolate(rasters['ex'], Q)
    sigmaX = icepack.interpolate(firedrake.max_value(sigmaX, minSigma), Q)
    sigmaX = icepack.interpolate(firedrake.min_value(sigmaX, maxSigma), Q)
    sigmaY = icepack.interpolate(rasters['ey'], Q)
    sigmaY = icepack.interpolate(firedrake.max_value(sigmaY, minSigma), Q)
    sigmaY = icepack.interpolate(firedrake.min_value(sigmaY, maxSigma), Q)
    speed = icepack.interpolate(firedrake.sqrt(inner(uObs, uObs)), Q)
    # return results
    return uObs, speed, sigmaX, sigmaY
예제 #30
0
def tracer_slice(tmpdir, degree):
    n = 30 if degree == 0 else 15
    m = PeriodicIntervalMesh(n, 1.)
    mesh = ExtrudedMesh(m, layers=n, layer_height=1. / n)

    # Parameters chosen so that dt != 1 and u != 1
    # Gaussian is translated by 1.5 times width of domain to demonstrate
    # that transport is working correctly

    dt = 0.01
    tmax = 0.75
    output = OutputParameters(dirname=str(tmpdir), dumpfreq=25)
    state = State(mesh, dt=dt, output=output)

    uexpr = as_vector([2.0, 0.0])

    x = SpatialCoordinate(mesh)
    width = 1. / 10.
    f0 = 0.5
    fmax = 2.0
    xc_init = 0.25
    xc_end = 0.75
    r_init = sqrt((x[0] - xc_init)**2 + (x[1] - 0.5)**2)
    r_end = sqrt((x[0] - xc_end)**2 + (x[1] - 0.5)**2)
    f_init = f0 + (fmax - f0) * exp(-(r_init / width)**2)
    f_end = f0 + (fmax - f0) * exp(-(r_end / width)**2)

    tol = 0.12

    return TracerSetup(state,
                       tmax,
                       f_init,
                       f_end,
                       "CG",
                       degree,
                       uexpr,
                       tol=tol)
예제 #31
0
 def min(f_in):
     fmin = op2.Global(1, [np.finfo(float).max], dtype=float)
     if len(f_in.ufl_shape) > 0:
         mesh = f_in.function_space().mesh()
         V = FunctionSpace(mesh, "DG", 1)
         f = Function(V).project(sqrt(inner(f_in, f_in)))
     else:
         f = f_in
     op2.par_loop(
         op2.Kernel(
             """void minify(double *a, double *b)
     {
     a[0] = a[0] > fabs(b[0]) ? fabs(b[0]) : a[0];
     }""", "minify"), f.dof_dset.set, fmin(op2.MIN), f.dat(op2.READ))
     return fmin.data[0]
예제 #32
0
 def compute(self, state):
     u = state.field_dict['u']
     dt = Constant(state.timestepping.dt)
     return self.field(state.mesh).project(sqrt(dot(u, u))/sqrt(self.area(state.mesh))*dt)
예제 #33
0
 def l2(f):
     return sqrt(assemble(dot(f, f)*dx))