Exemple #1
0
def Expression(f, V, degree_raise=None):
    if degree_raise != None:
        V = FunctionSpaceDegreeRaise(V, degree_raise)

    mesh_dim = V.mesh().cell_dimension()
    f_len = len(f)

    if mesh_dim == 1:
        x = SpatialCoordinate(V.mesh())
    elif mesh_dim == 2:
        (x, y) = SpatialCoordinate(V.mesh())
    elif mesh_dim == 3:
        (x, y, z) = SpatialCoordinate(V.mesh())

    f_eval = [None] * f_len
    for i in range(f_len):
        if 'x' not in f[i] and 'y' not in f[i] and 'z' not in f[i]:
            f_eval[i] = Constant(eval(f[i]))
        else:
            f_eval[i] = eval(f[i])

    if isinstance(f, list):
        if f_len == 1:
            out = interpolate(f_eval[0], V)
        elif f_len == 2:
            out = interpolate(as_vector([f_eval[0], f_eval[1]]), V)
        elif f_len == 3:
            out = interpolate(as_vector([f_eval[0], f_eval[1], f_eval[2]]), V)
        else:
            raise RuntimeError('Input list for function value is of '
                               'dimension {}, need to be at most a 3D '
                               'vector'.format(len(f)))
        return out
    else:
        raise RuntimeError('Input function f needs to be list')
Exemple #2
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
Exemple #3
0
def _bezier_plot(function, axes, **kwargs):
    """Plot a 1D function on a function space with order no more than 4 using
    Bezier curves within each cell

    :arg function: 1D :class:`~.Function` to plot
    :arg axes: :class:`Axes <matplotlib.axes.Axes>` for plotting
    :arg kwargs: additional key work arguments to plot
    :return: matplotlib :class:`PathPatch <matplotlib.patches.PathPatch>`
    """
    deg = function.function_space().ufl_element().degree()
    mesh = function.function_space().mesh()
    if deg == 0:
        V = FunctionSpace(mesh, "DG", 1)
        func = Function(V).interpolate(function)
        return _bezier_plot(func, axes, **kwargs)
    y_vals = _bezier_calculate_points(function)
    x = SpatialCoordinate(mesh)
    coords = Function(FunctionSpace(mesh, 'DG', deg))
    coords.interpolate(x[0])
    x_vals = _bezier_calculate_points(coords)
    vals = np.dstack((x_vals, y_vals))

    codes = {1: [Path.MOVETO, Path.LINETO],
             2: [Path.MOVETO, Path.CURVE3, Path.CURVE3],
             3: [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]}
    vertices = vals.reshape(-1, 2)
    path = Path(vertices, np.tile(codes[deg],
                function.function_space().cell_node_list.shape[0]))

    kwargs["facecolor"] = kwargs.pop("facecolor", "none")
    kwargs["linewidth"] = kwargs.pop("linewidth", 2.)
    patch = matplotlib.patches.PathPatch(path, **kwargs)
    axes.add_patch(patch)
    return patch
Exemple #4
0
    def initialize(self, obj):
        if complex_mode:
            raise NotImplementedError("HypreAMS preconditioner not yet implemented in complex mode")

        Citations().register("Kolev2009")
        A, P = obj.getOperators()
        prefix = obj.getOptionsPrefix()
        V = get_function_space(obj.getDM())
        mesh = V.mesh()

        family = str(V.ufl_element().family())
        degree = V.ufl_element().degree()
        if family != 'Nedelec 1st kind H(curl)' or degree != 1:
            raise ValueError("Hypre AMS requires lowest order Nedelec elements! (not %s of degree %d)" % (family, degree))

        P1 = FunctionSpace(mesh, "Lagrange", 1)
        G = Interpolator(grad(TestFunction(P1)), V).callable().handle

        pc = PETSc.PC().create(comm=obj.comm)
        pc.incrementTabLevel(1, parent=obj)
        pc.setOptionsPrefix(prefix + "hypre_ams_")
        pc.setOperators(A, P)

        pc.setType('hypre')
        pc.setHYPREType('ams')
        pc.setHYPREDiscreteGradient(G)
        zero_beta = PETSc.Options(prefix).getBool("pc_hypre_ams_zero_beta_poisson", default=False)
        if zero_beta:
            pc.setHYPRESetBetaPoissonMatrix(None)

        VectorP1 = VectorFunctionSpace(mesh, "Lagrange", 1)
        pc.setCoordinates(interpolate(SpatialCoordinate(mesh), VectorP1).dat.data_ro.copy())
        pc.setUp()

        self.pc = pc
Exemple #5
0
 def compute(self, state):
     x, y, z = SpatialCoordinate(state.mesh)
     b = state.fields("b")
     bbar = state.fields("bbar")
     H = state.parameters.H
     potential = -(z - H / 2) * (b - bbar)
     return self.field.interpolate(potential)
Exemple #6
0
def fdrake_mesh(request):
    mesh_name = request.param
    if mesh_name == "FiredrakeUnitIntervalMesh":
        return UnitIntervalMesh(100)
    elif mesh_name == "FiredrakeUnitSquareMesh":
        return UnitSquareMesh(10, 10)
    elif mesh_name == "FiredrakeUnitSquareMesh-order2":
        m = UnitSquareMesh(10, 10)
        fspace = VectorFunctionSpace(m, "CG", 2)
        coords = Function(fspace).interpolate(SpatialCoordinate(m))
        from firedrake.mesh import Mesh
        return Mesh(coords)
    elif mesh_name == "FiredrakeUnitCubeMesh":
        return UnitCubeMesh(5, 5, 5)
    elif mesh_name not in ("annulus.msh", "blob2d-order1-h4e-2.msh",
                           "blob2d-order1-h6e-2.msh",
                           "blob2d-order1-h8e-2.msh"):
        raise ValueError("Unexpected value for request.param")

    # Firedrake can't read in higher order meshes from gmsh,
    # so we can only use the order1 blobs
    from firedrake import Mesh
    fd_mesh = Mesh(mesh_name)
    fd_mesh.init()
    return fd_mesh
Exemple #7
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.'
            )
Exemple #8
0
    def test_upper_and_lower_bound_vector(self):
        """
        Test that setting lower and upper bounds work as expected for vector
        functions.
        """
        x = SpatialCoordinate(self.mesh)
        self.prob.to_bound = as_tensor([
            Function(self.V).interpolate(x[0]),
            Function(self.V).interpolate(1 - x[0])
        ])
        self.prob.test_func = self.prob.to_bound + as_tensor([1, 1])

        self.assertAlmostEqual(self.prob.test_func[0]([0.1, 0.1, 0.1]), 1.1)
        self.assertAlmostEqual(self.prob.test_func[1]([0.1, 0.1, 0.1]), 1.9)

        self.assertAlmostEqual(self.prob.test_func[0]([0.6, 0.1, 0.1]), 1.6)
        self.assertAlmostEqual(self.prob.test_func[1]([0.6, 0.1, 0.1]), 1.4)

        self.prob.bound('to_bound', lower=0.45, upper=0.55)

        self.assertAlmostEqual(self.prob.test_func[0]([0.1, 0.1, 0.1]), 1.45)
        self.assertAlmostEqual(self.prob.test_func[1]([0.1, 0.1, 0.1]), 1.55)

        self.assertAlmostEqual(self.prob.test_func[0]([0.6, 0.1, 0.1]), 1.55)
        self.assertAlmostEqual(self.prob.test_func[1]([0.6, 0.1, 0.1]), 1.45)
def setup_values(geometry, DG0_field, weights):

    x = SpatialCoordinate(weights.function_space().mesh())
    coords_CG1 = Function(weights.function_space()).interpolate(x)
    coords_DG0 = Function(DG0_field.function_space()).interpolate(x)

    if geometry == "1D":
        # Let us focus on the point at x = 1.0
        # The test is if at CG_field[CG_index] we get the average of the corresponding DG_field values
        CG_index = set_val_at_point(coords_CG1, 1.0)
        set_val_at_point(coords_DG0, 0.5, DG0_field, 6.0)
        set_val_at_point(coords_DG0, 1.5, DG0_field, -10.0)
        set_val_at_point(coords_CG1, 1.0, weights, 2.0)

        true_values = 0.5 * (6.0 - 10.0)

    elif geometry == "2D":
        # Let us focus on the point at (1,1)
        # The test is if at CG_field[CG_index] we get the average of the corresponding DG_field values
        # We do it for both components of the vector field

        CG_index = set_val_at_point(coords_CG1, [1.0, 1.0])
        set_val_at_point(coords_CG1, [1.0, 1.0], weights, [4.0, 4.0])
        set_val_at_point(coords_DG0, [0.5, 0.5], DG0_field, [6.0, -3.0])
        set_val_at_point(coords_DG0, [1.5, 0.5], DG0_field, [-7.0, -6.0])
        set_val_at_point(coords_DG0, [0.5, 1.5], DG0_field, [0.0, 3.0])
        set_val_at_point(coords_DG0, [1.5, 1.5], DG0_field, [-9.0, -1.0])

        true_values = [
            0.25 * (6.0 - 7.0 + 0.0 - 9.0), 0.25 * (-3.0 - 6.0 + 3.0 - 1.0)
        ]

    return DG0_field, weights, true_values, CG_index
    def build(self):
        """
        Build the gaussian function.

        Raises:
            AttributeError: If required properties are not defined.

        Returns:
            Function: firedrake Constant set to the given value.
        """
        for k in self.properties:
            if self._props[k] is None:
                raise AttributeError('"{}" has not been defined.'.format(k))

        mean = self._props['mean']
        sd = self._props['sd']
        scale = self._props['scale']

        xs = SpatialCoordinate(self.mesh)
        if not isinstance(mean, list):
            mean = [mean] * len(xs)
        if not isinstance(sd, list):
            sd = [sd] * len(xs)

        gaussian = Function(self.V)
        components = [exp(-(x - m)**2 / 2 / s**2)
                      for x, m, s in zip(xs, mean, sd)]
        product = components[0]
        for c in components[1:]:
            product *= c

        gaussian.interpolate(scale * product)

        return gaussian
def setup_values(geometry, true_field):

    # The true values can be determined by the number of elements
    # that the DoF is shared between.

    x = SpatialCoordinate(true_field.function_space().mesh())
    coords_CG1 = Function(true_field.function_space()).interpolate(x)

    if geometry == "1D":
        # List coords of DoFs
        edge_coords = [0.0, 3.0]
        internal_coords = [1.0, 2.0]

        for coord in edge_coords:
            set_val_at_point(coords_CG1, coord, true_field, 1.0)
        for coord in internal_coords:
            set_val_at_point(coords_CG1, coord, true_field, 2.0)

    elif geometry == "2D":

        # List coords of DoFs
        corner_coords = [[0.0, 0.0], [0.0, 3.0], [3.0, 0.0], [3.0, 3.0]]
        edge_coords = [[0.0, 1.0], [0.0, 2.0], [3.0, 1.0], [3.0, 2.0],
                       [1.0, 0.0], [2.0, 0.0], [1.0, 3.0], [2.0, 3.0]]
        internal_coords = [[1.0, 1.0], [1.0, 2.0], [2.0, 1.0], [2.0, 2.0]]

        for coord in corner_coords:
            set_val_at_point(coords_CG1, coord, true_field, 1.0)
        for coord in edge_coords:
            set_val_at_point(coords_CG1, coord, true_field, 2.0)
        for coord in internal_coords:
            set_val_at_point(coords_CG1, coord, true_field, 4.0)

    return true_field
Exemple #12
0
def eady_initial_v(state, p0, v):
    f = state.parameters.f
    x, y, z = SpatialCoordinate(state.mesh)

    # get pressure gradient
    Vu = state.spaces("HDiv")
    g = TrialFunction(Vu)
    wg = TestFunction(Vu)

    n = FacetNormal(state.mesh)

    a = inner(wg, g)*dx
    L = -div(wg)*p0*dx + inner(wg, n)*p0*ds_tb
    pgrad = Function(Vu)
    solve(a == L, pgrad)

    # get initial v
    Vp = p0.function_space()
    phi = TestFunction(Vp)
    m = TrialFunction(Vp)

    a = f*phi*m*dx
    L = phi*pgrad[0]*dx
    solve(a == L, v)

    return v
Exemple #13
0
    def __init__(self, mesh, conditions, timestepping, params, output, solver_params):

        self.timestepping = timestepping
        self.timestep = timestepping.timestep
        self.timescale = timestepping.timescale
        self.params = params
        if output is None:
            raise RuntimeError("You must provide a directory name for dumping results")
        else:
            self.output = output
        self.outfile = File(output.dirname)
        self.dump_count = 0
        self.dump_freq = output.dumpfreq
        self.solver_params = solver_params
        self.mesh = mesh
        self.conditions = conditions

        if conditions.steady_state == True:
            self.ind = 1
        else:
            self.ind = 1
        
        family = conditions.family
        self.x, self.y = SpatialCoordinate(mesh)
        self.n = FacetNormal(mesh)
        self.V = VectorFunctionSpace(mesh, family, conditions.order + 1)
        self.U = FunctionSpace(mesh, family, conditions.order + 1)
        self.U1 = FunctionSpace(mesh, 'DG', conditions.order)
        self.S = TensorFunctionSpace(mesh, 'DG', conditions.order)
        self.D = FunctionSpace(mesh, 'DG', 0)
        self.W1 = MixedFunctionSpace([self.V, self.S])
        self.W2 = MixedFunctionSpace([self.V, self.U1, self.U1])
        self.W3 = MixedFunctionSpace([self.V, self.S, self.U1, self.U1])
Exemple #14
0
def tracer_sphere(tmpdir, degree):
    radius = 1
    mesh = IcosahedralSphereMesh(radius=radius, refinement_level=3, degree=1)
    x = SpatialCoordinate(mesh)
    mesh.init_cell_orientations(x)

    # Parameters chosen so that dt != 1
    # Gaussian is translated from (lon=pi/2, lat=0) to (lon=0, lat=0)
    # to demonstrate that transport is working correctly

    dt = pi / 3. * 0.02
    output = OutputParameters(dirname=str(tmpdir), dumpfreq=15)
    state = State(mesh, dt=dt, output=output)

    umax = 1.0
    uexpr = as_vector([-umax * x[1] / radius, umax * x[0] / radius, 0.0])

    tmax = pi / 2
    f_init = exp(-x[2]**2 - x[0]**2)
    f_end = exp(-x[2]**2 - x[1]**2)

    tol = 0.05

    return TracerSetup(state, tmax, f_init, f_end, "BDM", degree, uexpr, umax,
                       radius, tol)
Exemple #15
0
def b(mesh, fs):
    v = TestFunction(fs)
    f = Function(fs)
    x = SpatialCoordinate(mesh)
    f.interpolate((4.*pi*pi)*sin(x[0]*pi*2))
    L = f * v * dx
    b = assemble(L)

    return b
Exemple #16
0
def run_tracer(setup):

    # Get initial conditions from shared config
    state = setup.state
    mesh = state.mesh
    dt = state.dt
    output = state.output

    x = SpatialCoordinate(state.mesh)
    H = 0.1
    parameters = ShallowWaterParameters(H=H)
    Omega = parameters.Omega
    g = parameters.g
    umax = setup.umax
    R = setup.radius
    fexpr = 2 * Omega * x[2] / R

    # Need to create a new state containing parameters
    state = State(mesh, dt=dt, output=output, parameters=parameters)

    # Equations
    eqns = LinearShallowWaterEquations(state,
                                       setup.family,
                                       setup.degree,
                                       fexpr=fexpr)
    tracer_eqn = AdvectionEquation(state, state.spaces("DG"), "tracer")

    # Specify initial prognostic fields
    u0 = state.fields("u")
    D0 = state.fields("D")
    tracer0 = state.fields("tracer", D0.function_space())
    tracer_end = Function(D0.function_space())

    # Expressions for initial fields corresponding to Williamson 2 test case
    Dexpr = H - ((R * Omega * umax) * (x[2] * x[2] / (R * R))) / g
    u0.project(setup.uexpr)
    D0.interpolate(Dexpr)
    tracer0.interpolate(setup.f_init)
    tracer_end.interpolate(setup.f_end)

    # set up transport schemes
    transport_schemes = [ForwardEuler(state, "D")]

    # Set up tracer transport
    tracer_transport = [(tracer_eqn, SSPRK3(state))]

    # build time stepper
    stepper = CrankNicolson(state,
                            eqns,
                            transport_schemes,
                            auxiliary_equations_and_schemes=tracer_transport)

    stepper.run(t=0, tmax=setup.tmax)

    error = norm(state.fields("tracer") - tracer_end) / norm(tracer_end)

    return error
Exemple #17
0
def setup_2d_recovery(dirname):

    L = 100.
    W = 100.

    deltax = L / 5.
    deltay = W / 5.
    ncolumnsx = int(L / deltax)
    ncolumnsy = int(W / deltay)

    mesh = PeriodicRectangleMesh(ncolumnsx,
                                 ncolumnsy,
                                 L,
                                 W,
                                 direction='y',
                                 quadrilateral=True)
    x, y = SpatialCoordinate(mesh)

    # spaces
    VDG0 = FunctionSpace(mesh, "DG", 0)
    VCG1 = FunctionSpace(mesh, "CG", 1)
    VDG1 = FunctionSpace(mesh, "DG", 1)
    Vu = FunctionSpace(mesh, "RTCF", 1)
    VuCG1 = VectorFunctionSpace(mesh, "CG", 1)
    VuDG1 = VectorFunctionSpace(mesh, "DG", 1)

    # set up initial conditions
    np.random.seed(0)
    expr = np.random.randn() + np.random.randn() * x

    # our actual theta and rho and v
    rho_CG1_true = Function(VCG1).interpolate(expr)
    v_CG1_true = Function(VuCG1).interpolate(as_vector([expr, expr]))

    # make the initial fields by projecting expressions into the lowest order spaces
    rho_DG0 = Function(VDG0).interpolate(expr)
    rho_CG1 = Function(VCG1)
    v_Vu = Function(Vu).project(as_vector([expr, expr]))
    v_CG1 = Function(VuCG1)

    # make the recoverers and do the recovery
    rho_recoverer = Recoverer(rho_DG0,
                              rho_CG1,
                              VDG=VDG1,
                              boundary_method=Boundary_Method.dynamics)
    v_recoverer = Recoverer(v_Vu,
                            v_CG1,
                            VDG=VuDG1,
                            boundary_method=Boundary_Method.dynamics)

    rho_recoverer.project()
    v_recoverer.project()

    rho_diff = errornorm(rho_CG1, rho_CG1_true) / norm(rho_CG1_true)
    v_diff = errornorm(v_CG1, v_CG1_true) / norm(v_CG1_true)

    return (rho_diff, v_diff)
Exemple #18
0
def f_end(geometry, state):
    """
    returns an expression for the expected final state
    """
    x = SpatialCoordinate(state.mesh)
    if geometry == "sphere":
        fexpr = exp(-x[2]**2 - x[0]**2)
    if geometry == "slice":
        fexpr = sin(2 * pi * (x[0] - 0.5)) * sin(2 * pi * x[1])
    return fexpr
Exemple #19
0
def f_init(geometry, state):
    """
    returns an expression for the initial condition
    """
    x = SpatialCoordinate(state.mesh)
    if geometry == "sphere":
        fexpr = exp(-x[2]**2 - x[1]**2)
    if geometry == "slice":
        fexpr = sin(2 * pi * x[0]) * sin(2 * pi * x[1])
    return fexpr
Exemple #20
0
def expr(geometry, mesh):

    x, = SpatialCoordinate(mesh)

    if geometry == "periodic":
        # N.B. this is a very trivial test -- no boundary recovery should happen
        analytic_expr = np.random.randn() + 0.0 * x
    elif geometry == "non-periodic":
        analytic_expr = np.random.randn() + np.random.randn() * x

    return analytic_expr
Exemple #21
0
def expr(geometry, mesh):

    x, z = SpatialCoordinate(mesh)

    if geometry == "periodic":
        analytic_expr = np.random.randn() + np.random.randn() * z
    elif geometry == "non-periodic":
        analytic_expr = np.random.randn(
        ) + np.random.randn() * x + np.random.randn() * z

    return analytic_expr
Exemple #22
0
def setup_IPdiffusion(dirname, vector, DG):

    dt = 0.01
    L = 10.
    m = PeriodicIntervalMesh(50, L)
    mesh = ExtrudedMesh(m, layers=50, layer_height=0.2)

    fieldlist = ['u', 'D']
    timestepping = TimesteppingParameters(dt=dt)
    parameters = CompressibleParameters()
    output = OutputParameters(dirname=dirname)

    state = State(mesh,
                  vertical_degree=1,
                  horizontal_degree=1,
                  family="CG",
                  timestepping=timestepping,
                  parameters=parameters,
                  output=output,
                  fieldlist=fieldlist)

    x = SpatialCoordinate(mesh)
    if vector:
        kappa = Constant([[0.05, 0.], [0., 0.05]])
        if DG:
            Space = VectorFunctionSpace(mesh, "DG", 1)
        else:
            Space = state.spaces("HDiv")
        fexpr = as_vector([exp(-(L / 2. - x[0])**2 - (L / 2. - x[1])**2), 0.])
    else:
        kappa = 0.05
        if DG:
            Space = state.spaces("DG")
        else:
            Space = state.spaces("HDiv_v")
        fexpr = exp(-(L / 2. - x[0])**2 - (L / 2. - x[1])**2)

    f = state.fields("f", Space)
    try:
        f.interpolate(fexpr)
    except NotImplementedError:
        # finat elements raise NotImplementedError if they don't
        # advertise a dual for interpolation.
        f.project(fexpr)

    mu = 5.
    f_diffusion = InteriorPenalty(state,
                                  f.function_space(),
                                  kappa=kappa,
                                  mu=mu)
    diffused_fields = [("f", f_diffusion)]
    stepper = AdvectionDiffusion(state, diffused_fields=diffused_fields)
    return stepper
Exemple #23
0
    def test_upper_bound_scalar(self):
        """
        Test that setting upper bounds work as expected for normal functions.
        """
        x = SpatialCoordinate(self.mesh)
        self.prob.to_bound.interpolate(x[0])

        self.assertAlmostEqual(self.prob.test_func([0.1, 0.1, 0.1]), 1.1)
        self.assertAlmostEqual(self.prob.test_func([0.6, 0.1, 0.1]), 1.6)
        self.prob.bound('to_bound', upper=0.2)
        self.assertAlmostEqual(self.prob.test_func([0.1, 0.1, 0.1]), 1.1)
        self.assertAlmostEqual(self.prob.test_func([0.6, 0.1, 0.1]), 1.2)
Exemple #24
0
    def forcing_term(self):

        L = Forcing.forcing_term(self)
        dbdy = self.state.parameters.dbdy
        H = self.state.parameters.H
        Vp = self.state.spaces("DG")
        _, _, z = SpatialCoordinate(self.state.mesh)
        eady_exp = Function(Vp).interpolate(z - H / 2.)

        L -= self.scaling * dbdy * eady_exp * inner(
            self.test, as_vector([0., 1., 0.])) * dx
        return L
Exemple #25
0
def state(tmpdir, geometry):
    """
    returns an instance of the State class, having set up either spherical
    geometry or 2D vertical slice geometry
    """

    output = OutputParameters(dirname=str(tmpdir), dumplist=["f"], dumpfreq=15)

    if geometry == "sphere":
        mesh = IcosahedralSphereMesh(radius=1, refinement_level=3, degree=1)
        x = SpatialCoordinate(mesh)
        mesh.init_cell_orientations(x)
        family = "BDM"
        vertical_degree = None
        fieldlist = ["u", "D"]
        dt = pi / 3. * 0.01
        uexpr = as_vector([-x[1], x[0], 0.0])

    if geometry == "slice":
        m = PeriodicIntervalMesh(15, 1.)
        mesh = ExtrudedMesh(m, layers=15, layer_height=1. / 15.)
        family = "CG"
        vertical_degree = 1
        fieldlist = ["u", "rho", "theta"]
        dt = 0.01
        x = SpatialCoordinate(mesh)
        uexpr = as_vector([1.0, 0.0])

    timestepping = TimesteppingParameters(dt=dt)
    state = State(mesh,
                  vertical_degree=vertical_degree,
                  horizontal_degree=1,
                  family=family,
                  timestepping=timestepping,
                  output=output,
                  fieldlist=fieldlist)

    u0 = state.fields("u")
    u0.project(uexpr)
    return state
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
Exemple #27
0
    def compute(self, state):
        x, y, z = SpatialCoordinate(state.mesh)
        g = state.parameters.g
        cp = state.parameters.cp
        cv = state.parameters.cv
        Pi0 = state.parameters.Pi0

        rho = state.fields("rho")
        theta = state.fields("theta")
        Pi = thermodynamics.pi(state.parameters, rho, theta)

        potential = rho * (g * z + cv * Pi * theta - cp * Pi0 * theta)
        return self.field.interpolate(potential)
Exemple #28
0
def set_initial_value(mesh, T, extent):
    """
    Setup T to hold the initial value for the problem.

    mesh: Mesh, The mesh to define the function for
    T: Function, The function to define the initial value on
    extent: list<float>, The length of each side of the mesh (assumes rect)
    """
    x = SpatialCoordinate(mesh)
    val = 1
    for pos, length in zip(x, extent):
        val *= sin(2*pos/length*pi)
    T.interpolate(100 + 1000**val)
Exemple #29
0
def create_S(mesh, V, extent):
    """
    This is the source term.

    mesh: Mesh, The mesh to define the function for.
    V: FunctionSpace, The function space that the function should be in
    extent: list<float>, The length of each side of the mesh (assumes rect)
    """
    x = SpatialCoordinate(mesh)
    val = 1
    for pos, length in zip(x, extent):
        val *= sin(pos / length * pi)**2
    return Function(V).interpolate(1e9 * val)
Exemple #30
0
def tracer_blob_slice(tmpdir, degree):
    dt = 0.01
    L = 10.
    m = PeriodicIntervalMesh(10, L)
    mesh = ExtrudedMesh(m, layers=10, layer_height=1.)

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

    tmax = 1.
    x = SpatialCoordinate(mesh)
    f_init = exp(-((x[0] - 0.5 * L)**2 + (x[1] - 0.5 * L)**2))

    return TracerSetup(state, tmax, f_init, family="CG", degree=degree)