コード例 #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.'
            )
コード例 #2
0
 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")
コード例 #7
0
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
コード例 #8
0
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
ファイル: meshes.py プロジェクト: bueler/stokes-implicit
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
ファイル: shallow_ice_test.py プロジェクト: benhills/icepack
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
ファイル: shallow_water.py プロジェクト: icepack/plumes
    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
ファイル: parameters.py プロジェクト: AndrewLister-STFC/TTiP
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
コード例 #19
0
    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
ファイル: advection.py プロジェクト: firedrakeproject/gusto
    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
ファイル: viscosity.py プロジェクト: jonatanrg/icepack
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
ファイル: configuration.py プロジェクト: jtessier10/gusto
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
ファイル: mismip+3d.py プロジェクト: icepack/icepack-paper
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
ファイル: diagnostics.py プロジェクト: firedrakeproject/gusto
 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
ファイル: diagnostics.py プロジェクト: firedrakeproject/gusto
 def l2(f):
     return sqrt(assemble(dot(f, f)*dx))