Ejemplo n.º 1
0
def setup_balance(dirname):

    # set up grid and time stepping parameters
    dt = 1.
    tmax = 5.
    deltax = 400
    L = 2000.
    H = 10000.

    nlayers = int(H / deltax)
    ncolumns = int(L / deltax)

    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers)

    output = OutputParameters(dirname=dirname + '/dry_balance',
                              dumpfreq=10,
                              dumplist=['u'])
    parameters = CompressibleParameters()

    state = State(mesh, dt=dt, output=output, parameters=parameters)

    eqns = CompressibleEulerEquations(state, "CG", 1)

    # Initial conditions
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")

    # Isentropic background state
    Tsurf = Constant(300.)
    theta0.interpolate(Tsurf)

    # Calculate hydrostatic exner
    compressible_hydrostatic_balance(state, theta0, rho0, solve_for_rho=True)

    state.set_reference_profiles([('rho', rho0), ('theta', theta0)])

    # Set up transport schemes
    transported_fields = [
        ImplicitMidpoint(state, "u"),
        SSPRK3(state, "rho"),
        SSPRK3(state, "theta", options=EmbeddedDGOptions())
    ]

    # Set up linear solver
    linear_solver = CompressibleSolver(state, eqns)

    # build time stepper
    stepper = CrankNicolson(state,
                            eqns,
                            transported_fields,
                            linear_solver=linear_solver)

    return stepper, tmax
Ejemplo n.º 2
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
Ejemplo n.º 3
0
def mesh(geometry):

    Lx = 100.
    deltax = Lx / 5.
    ncolumnsx = int(Lx/deltax)

    if geometry == "periodic":
        m = PeriodicIntervalMesh(ncolumnsx, Lx)
    elif geometry == "non-periodic":
        m = IntervalMesh(ncolumnsx, Lx)

    return m
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
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
def setup_fallout(dirname):

    # declare grid shape, with length L and height H
    L = 10.
    H = 10.
    nlayers = 10
    ncolumns = 10

    # make mesh
    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=(H / nlayers))
    x = SpatialCoordinate(mesh)

    dt = 0.1
    output = OutputParameters(dirname=dirname + "/fallout",
                              dumpfreq=10,
                              dumplist=['rain_mixing_ratio'])
    parameters = CompressibleParameters()
    diagnostic_fields = [Precipitation()]
    state = State(mesh,
                  dt=dt,
                  output=output,
                  parameters=parameters,
                  diagnostic_fields=diagnostic_fields)

    Vrho = state.spaces("DG1_equispaced")
    problem = [(AdvectionEquation(state, Vrho, "rho", ufamily="CG",
                                  udegree=1), ForwardEuler(state))]
    state.fields("rho").assign(1.)

    physics_list = [Fallout(state)]
    rain0 = state.fields("rain_mixing_ratio")

    # set up rain
    xc = L / 2
    zc = H / 2
    rc = H / 4
    r = sqrt((x[0] - xc)**2 + (x[1] - zc)**2)
    rain_expr = conditional(r > rc, 0., 1e-3 * (cos(pi * r / (rc * 2)))**2)

    rain0.interpolate(rain_expr)

    # build time stepper
    stepper = PrescribedTransport(state, problem, physics_list=physics_list)

    return stepper, 10.0
Ejemplo n.º 7
0
def mesh(geometry):

    L = 100.
    H = 100.

    deltax = L / 5.
    deltaz = H / 5.
    nlayers = int(H / deltaz)
    ncolumns = int(L / deltax)

    if geometry == "periodic":
        m = PeriodicIntervalMesh(ncolumns, L)
    elif geometry == "non-periodic":
        m = IntervalMesh(ncolumns, L)

    extruded_mesh = ExtrudedMesh(m, layers=nlayers, layer_height=deltaz)

    return extruded_mesh
Ejemplo n.º 8
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
Ejemplo n.º 9
0
def setup_checkpointing(dirname):

    nlayers = 5  # horizontal layers
    columns = 15  # number of columns
    L = 3.e5
    m = PeriodicIntervalMesh(columns, L)
    dt = 2.0

    # build volume mesh
    H = 1.0e4  # Height position of the model top
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers)

    output = OutputParameters(dirname=dirname,
                              dumpfreq=1,
                              chkptfreq=2,
                              log_level='INFO')
    parameters = CompressibleParameters()

    state = State(mesh, dt=dt, output=output, parameters=parameters)

    eqns = CompressibleEulerEquations(state, "CG", 1)

    # Set up transport schemes
    transported_fields = []
    transported_fields.append(SSPRK3(state, "u"))
    transported_fields.append(SSPRK3(state, "rho"))
    transported_fields.append(SSPRK3(state, "theta"))

    # Set up linear solver
    linear_solver = CompressibleSolver(state, eqns)

    # build time stepper
    stepper = CrankNicolson(state,
                            eqns,
                            transported_fields,
                            linear_solver=linear_solver)

    return state, stepper, dt
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
def setup_tracer(dirname, hybridization):

    # declare grid shape, with length L and height H
    L = 1000.
    H = 1000.
    nlayers = int(H / 100.)
    ncolumns = int(L / 100.)

    # make mesh
    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=(H / nlayers))

    fieldlist = ['u', 'rho', 'theta']
    timestepping = TimesteppingParameters(dt=10.0, maxk=4, maxi=1)
    output = OutputParameters(dirname=dirname+"/tracer",
                              dumpfreq=1,
                              dumplist=['u'],
                              perturbation_fields=['theta', 'rho'])
    parameters = CompressibleParameters()

    state = State(mesh, vertical_degree=1, horizontal_degree=1,
                  family="CG",
                  timestepping=timestepping,
                  output=output,
                  parameters=parameters,
                  fieldlist=fieldlist,
                  diagnostic_fields=[Difference('theta', 'tracer')])

    # declare initial fields
    u0 = state.fields("u")
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")

    # spaces
    Vu = u0.function_space()
    Vt = theta0.function_space()
    Vr = rho0.function_space()

    # declare tracer field and a background field
    tracer0 = state.fields("tracer", Vt)

    # Isentropic background state
    Tsurf = Constant(300.)

    theta_b = Function(Vt).interpolate(Tsurf)
    rho_b = Function(Vr)

    # Calculate initial rho
    compressible_hydrostatic_balance(state, theta_b, rho_b,
                                     solve_for_rho=True)

    # set up perturbation to theta
    xc = 500.
    zc = 350.
    rc = 250.
    x = SpatialCoordinate(mesh)
    r = sqrt((x[0]-xc)**2 + (x[1]-zc)**2)
    theta_pert = conditional(r > rc, 0., 0.25*(1. + cos((pi/rc)*r)))

    theta0.interpolate(theta_b + theta_pert)
    rho0.interpolate(rho_b)
    tracer0.interpolate(theta0)

    state.initialise([('u', u0),
                      ('rho', rho0),
                      ('theta', theta0),
                      ('tracer', tracer0)])
    state.set_reference_profiles([('rho', rho_b),
                                  ('theta', theta_b)])

    # set up advection schemes
    ueqn = EulerPoincare(state, Vu)
    rhoeqn = AdvectionEquation(state, Vr, equation_form="continuity")
    thetaeqn = SUPGAdvection(state, Vt,
                             supg_params={"dg_direction": "horizontal"},
                             equation_form="advective")

    # build advection dictionary
    advected_fields = []
    advected_fields.append(("u", ThetaMethod(state, u0, ueqn)))
    advected_fields.append(("rho", SSPRK3(state, rho0, rhoeqn)))
    advected_fields.append(("theta", SSPRK3(state, theta0, thetaeqn)))
    advected_fields.append(("tracer", SSPRK3(state, tracer0, thetaeqn)))

    # Set up linear solver
    if hybridization:
        linear_solver = HybridizedCompressibleSolver(state)
    else:
        linear_solver = CompressibleSolver(state)

    compressible_forcing = CompressibleForcing(state)

    # build time stepper
    stepper = CrankNicolson(state, advected_fields, linear_solver,
                            compressible_forcing)

    return stepper, 100.0
Ejemplo n.º 12
0
def setup_saturated(dirname):

    # set up grid and time stepping parameters
    dt = 1.
    tmax = 3.
    deltax = 400.
    L = 2000.
    H = 10000.

    nlayers = int(H / deltax)
    ncolumns = int(L / deltax)

    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers)

    # option to easily change between recovered and not if necessary
    # default should be to use lowest order set of spaces
    recovered = True
    degree = 0 if recovered else 1

    fieldlist = ['u', 'rho', 'theta']
    timestepping = TimesteppingParameters(dt=dt, maxk=4, maxi=1)
    output = OutputParameters(dirname=dirname + '/saturated_balance',
                              dumpfreq=1,
                              dumplist=['u'],
                              perturbation_fields=['water_v'])
    parameters = CompressibleParameters()
    diagnostics = Diagnostics(*fieldlist)
    diagnostic_fields = [Theta_e()]

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

    # Initial conditions
    u0 = state.fields("u")
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")
    water_v0 = state.fields("water_v", theta0.function_space())
    water_c0 = state.fields("water_c", theta0.function_space())
    moisture = ['water_v', 'water_c']

    # spaces
    Vu = u0.function_space()
    Vt = theta0.function_space()
    Vr = rho0.function_space()

    # Isentropic background state
    Tsurf = Constant(300.)
    total_water = Constant(0.02)
    theta_e = Function(Vt).interpolate(Tsurf)
    water_t = Function(Vt).interpolate(total_water)

    # Calculate hydrostatic Pi
    saturated_hydrostatic_balance(state, theta_e, water_t)
    water_c0.assign(water_t - water_v0)

    state.initialise([('u', u0), ('rho', rho0), ('theta', theta0),
                      ('water_v', water_v0), ('water_c', water_c0)])
    state.set_reference_profiles([('rho', rho0), ('theta', theta0),
                                  ('water_v', water_v0)])

    # Set up advection schemes
    if recovered:
        VDG1 = FunctionSpace(mesh, "DG", 1)
        VCG1 = FunctionSpace(mesh, "CG", 1)
        Vt_brok = FunctionSpace(mesh, BrokenElement(Vt.ufl_element()))
        Vu_DG1 = VectorFunctionSpace(mesh, "DG", 1)
        Vu_CG1 = VectorFunctionSpace(mesh, "CG", 1)

        u_opts = RecoveredOptions(embedding_space=Vu_DG1,
                                  recovered_space=Vu_CG1,
                                  broken_space=Vu,
                                  boundary_method=Boundary_Method.dynamics)
        rho_opts = RecoveredOptions(embedding_space=VDG1,
                                    recovered_space=VCG1,
                                    broken_space=Vr,
                                    boundary_method=Boundary_Method.dynamics)
        theta_opts = RecoveredOptions(embedding_space=VDG1,
                                      recovered_space=VCG1,
                                      broken_space=Vt_brok)
        ueqn = EmbeddedDGAdvection(state,
                                   Vu,
                                   equation_form="advective",
                                   options=u_opts)
        rhoeqn = EmbeddedDGAdvection(state,
                                     Vr,
                                     equation_form="continuity",
                                     options=rho_opts)
        thetaeqn = EmbeddedDGAdvection(state,
                                       Vt,
                                       equation_form="advective",
                                       options=theta_opts)
    else:
        ueqn = EulerPoincare(state, Vu)
        rhoeqn = AdvectionEquation(state, Vr, equation_form="continuity")
        thetaeqn = EmbeddedDGAdvection(state,
                                       Vt,
                                       equation_form="advective",
                                       options=EmbeddedDGOptions())

    advected_fields = [('rho', SSPRK3(state, rho0, rhoeqn)),
                       ('theta', SSPRK3(state, theta0, thetaeqn)),
                       ('water_v', SSPRK3(state, water_v0, thetaeqn)),
                       ('water_c', SSPRK3(state, water_c0, thetaeqn))]
    if recovered:
        advected_fields.append(('u', SSPRK3(state, u0, ueqn)))
    else:
        advected_fields.append(('u', ThetaMethod(state, u0, ueqn)))

    linear_solver = CompressibleSolver(state, moisture=moisture)

    # Set up forcing
    if recovered:
        compressible_forcing = CompressibleForcing(state,
                                                   moisture=moisture,
                                                   euler_poincare=False)
    else:
        compressible_forcing = CompressibleForcing(state, moisture=moisture)

    # add physics
    physics_list = [Condensation(state)]

    # build time stepper
    stepper = CrankNicolson(state,
                            advected_fields,
                            linear_solver,
                            compressible_forcing,
                            physics_list=physics_list)

    return stepper, tmax
Ejemplo n.º 13
0
def run_cond_evap(dirname, process):
    # declare grid shape, with length L and height H
    L = 1000.
    H = 1000.
    nlayers = int(H / 10.)
    ncolumns = int(L / 10.)

    # make mesh
    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=(H / nlayers))
    x, z = SpatialCoordinate(mesh)

    dt = 2.0
    tmax = dt
    output = OutputParameters(dirname=dirname + "/cond_evap",
                              dumpfreq=1,
                              dumplist=['u'])
    parameters = CompressibleParameters()

    state = State(mesh,
                  dt=dt,
                  output=output,
                  parameters=parameters,
                  diagnostic_fields=[
                      Sum('vapour_mixing_ratio', 'cloud_liquid_mixing_ratio')
                  ])

    # spaces
    Vt = state.spaces("theta", degree=1)
    Vr = state.spaces("DG", "DG", degree=1)

    # Set up equation -- use compressible to set up these spaces
    # However the equation itself will be unused
    _ = CompressibleEulerEquations(state, "CG", 1)

    # Declare prognostic fields
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")
    water_v0 = state.fields("vapour_mixing_ratio", Vt)
    water_c0 = state.fields("cloud_liquid_mixing_ratio", Vt)

    # Set a background state with constant pressure and temperature
    pressure = Function(Vr).interpolate(Constant(100000.))
    temperature = Function(Vt).interpolate(Constant(300.))
    theta_d = td.theta(parameters, temperature, pressure)
    mv_sat = td.r_v(parameters, Constant(1.0), temperature, pressure)
    Lv_over_cpT = td.Lv(parameters,
                        temperature) / (parameters.cp * temperature)

    # Apply perturbation
    xc = L / 2.
    zc = H / 2.
    rc = L / 4.
    r = sqrt((x - xc)**2 + (z - zc)**2)
    pert = conditional(r < rc, 1.0, 0.0)

    if process == "evaporation":
        water_v0.interpolate(0.96 * mv_sat)
        water_c0.interpolate(0.005 * mv_sat * pert)
        # Approximate answers
        # Rate of change is roughly (m_sat - m_v) / 4 so should evaporate everything
        mc_true = Function(Vt).interpolate(Constant(0.0))
        theta_d_true = Function(Vt).interpolate(theta_d + 0.005 * mv_sat *
                                                pert * Lv_over_cpT)
        mv_true = Function(Vt).interpolate(mv_sat * (0.96 + 0.005 * pert))
    elif process == "condensation":
        water_v0.interpolate(mv_sat * (1.0 + 0.04 * pert))
        # Approximate answers -- rate of change is roughly (m_v - m_sat) / 4
        mc_true = Function(Vt).interpolate(0.01 * mv_sat * pert)
        theta_d_true = Function(Vt).interpolate(theta_d - 0.01 * mv_sat *
                                                pert * Lv_over_cpT)
        mv_true = Function(Vt).interpolate(mv_sat * (1.0 + 0.03 * pert))

    # Set prognostic variables
    theta0.project(theta_d * (1 + water_v0 * parameters.R_v / parameters.R_d))
    rho0.interpolate(pressure /
                     (temperature * parameters.R_d *
                      (1 + water_v0 * parameters.R_v / parameters.R_d)))
    mc_init = Function(Vt).assign(water_c0)

    # Have empty problem as only thing is condensation / evaporation
    problem = []
    physics_list = [Condensation(state)]

    # build time stepper
    stepper = PrescribedTransport(state, problem, physics_list=physics_list)

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

    return state, mv_true, mc_true, theta_d_true, mc_init
def setup_hori_limiters(dirname):

    # declare grid shape
    L = 400.
    H = L
    ncolumns = int(L / 10.)
    nlayers = ncolumns

    # make mesh
    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=(H / nlayers))
    x, z = SpatialCoordinate(mesh)

    fieldlist = ['u']
    timestepping = TimesteppingParameters(dt=1.0, maxk=4, maxi=1)
    output = OutputParameters(dirname=dirname + "/limiting_hori",
                              dumpfreq=5,
                              dumplist=['u'],
                              perturbation_fields=['theta0', 'theta1'])
    parameters = CompressibleParameters()

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

    # make elements
    # v is continuous in vertical, h is horizontal
    cell = mesh._base_mesh.ufl_cell().cellname()
    DG0_element = FiniteElement("DG", cell, 0)
    CG1_element = FiniteElement("CG", cell, 1)
    DG1_element = FiniteElement("DG", cell, 1)
    CG2_element = FiniteElement("CG", cell, 2)
    V0_element = TensorProductElement(DG0_element, CG1_element)
    V1_element = TensorProductElement(DG1_element, CG2_element)

    # spaces
    Vpsi = FunctionSpace(mesh, "CG", 2)
    VDG1 = FunctionSpace(mesh, "DG", 1)
    VCG1 = FunctionSpace(mesh, "CG", 1)
    V0 = FunctionSpace(mesh, V0_element)
    V1 = FunctionSpace(mesh, V1_element)

    V0_brok = FunctionSpace(mesh, BrokenElement(V0.ufl_element()))

    V0_spaces = (VDG1, VCG1, V0_brok)

    # declare initial fields
    u0 = state.fields("u")
    theta0 = state.fields("theta0", V0)
    theta1 = state.fields("theta1", V1)

    # make a gradperp
    gradperp = lambda u: as_vector([-u.dx(1), u.dx(0)])

    # Isentropic background state
    Tsurf = 300.
    thetab = Constant(Tsurf)
    theta_b1 = Function(V1).interpolate(thetab)
    theta_b0 = Function(V0).interpolate(thetab)

    # set up bubble
    xc = 200.
    zc = 200.
    rc = 100.
    theta_expr = conditional(
        sqrt((x - xc)**2.0) < rc,
        conditional(sqrt((z - zc)**2.0) < rc, Constant(2.0), Constant(0.0)),
        Constant(0.0))
    theta_pert1 = Function(V1).interpolate(theta_expr)
    theta_pert0 = Function(V0).interpolate(theta_expr)

    # set up velocity field
    u_max = Constant(10.0)

    psi_expr = -u_max * z

    psi0 = Function(Vpsi).interpolate(psi_expr)
    u0.project(gradperp(psi0))
    theta0.interpolate(theta_b0 + theta_pert0)
    theta1.interpolate(theta_b1 + theta_pert1)

    state.initialise([('u', u0), ('theta1', theta1), ('theta0', theta0)])
    state.set_reference_profiles([('theta1', theta_b1), ('theta0', theta_b0)])

    # set up advection schemes
    thetaeqn1 = EmbeddedDGAdvection(state, V1, equation_form="advective")
    thetaeqn0 = EmbeddedDGAdvection(state,
                                    V0,
                                    equation_form="advective",
                                    recovered_spaces=V0_spaces)

    # build advection dictionary
    advected_fields = []
    advected_fields.append(('u', NoAdvection(state, u0, None)))
    advected_fields.append(('theta1',
                            SSPRK3(state,
                                   theta1,
                                   thetaeqn1,
                                   limiter=ThetaLimiter(thetaeqn1))))
    advected_fields.append(('theta0',
                            SSPRK3(state,
                                   theta0,
                                   thetaeqn0,
                                   limiter=VertexBasedLimiter(VDG1))))

    # build time stepper
    stepper = AdvectionDiffusion(state, advected_fields)

    return stepper, 40.0
Ejemplo n.º 15
0
def setup_recovered_space(dirname):

    # declare grid shape, with length L and height H
    L = 400.
    H = 400.
    nlayers = int(H / 20.)
    ncolumns = int(L / 20.)

    # make mesh
    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=(H / nlayers))
    x, z = SpatialCoordinate(mesh)

    fieldlist = ['u', 'rho']
    timestepping = TimesteppingParameters(dt=1.0, maxk=4, maxi=1)
    output = OutputParameters(dirname=dirname + "/recovered_space_test",
                              dumpfreq=5,
                              dumplist=['u'])
    parameters = CompressibleParameters()

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

    # declare initial fields
    u0 = state.fields("u")

    # spaces
    Vpsi = FunctionSpace(mesh, "CG", 2)
    VDG0 = FunctionSpace(mesh, "DG", 0)
    VDG1 = FunctionSpace(mesh, "DG", 1)
    VCG1 = FunctionSpace(mesh, "CG", 1)

    # set up tracer field
    tracer0 = state.fields("tracer", VDG0)

    # make a gradperp
    gradperp = lambda u: as_vector([-u.dx(1), u.dx(0)])

    # set up bubble
    xc = 200.
    zc = 200.
    rc = 100.
    tracer0.interpolate(
        conditional(
            sqrt((x - xc)**2.0) < rc,
            conditional(
                sqrt((z - zc)**2.0) < rc, Constant(0.2), Constant(0.0)),
            Constant(0.0)))

    # set up velocity field
    u_max = Constant(10.0)
    psi_expr = -u_max * z
    psi0 = Function(Vpsi).interpolate(psi_expr)
    u0.project(gradperp(psi0))

    state.initialise([('u', u0), ('tracer', tracer0)])

    # set up advection schemes
    recovered_opts = RecoveredOptions(embedding_space=VDG1,
                                      recovered_space=VCG1,
                                      broken_space=VDG0,
                                      boundary_method=Boundary_Method.dynamics)
    tracereqn = EmbeddedDGAdvection(state,
                                    VDG0,
                                    equation_form="continuity",
                                    options=recovered_opts)

    # build advection dictionary
    advected_fields = []
    advected_fields.append(('tracer', SSPRK3(state, tracer0, tracereqn)))

    # build time stepper
    stepper = AdvectionDiffusion(state, advected_fields)

    return stepper, 100.0
def setup_balance(dirname):

    # set up grid and time stepping parameters
    dt = 1.
    tmax = 5.
    deltax = 400
    L = 2000.
    H = 10000.

    nlayers = int(H / deltax)
    ncolumns = int(L / deltax)

    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers)

    fieldlist = ['u', 'rho', 'theta']
    timestepping = TimesteppingParameters(dt=dt, maxk=4, maxi=1)
    output = OutputParameters(dirname=dirname + '/dry_balance',
                              dumpfreq=10,
                              dumplist=['u'])
    parameters = CompressibleParameters()
    diagnostics = Diagnostics(*fieldlist)
    diagnostic_fields = []

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

    # Initial conditions
    u0 = state.fields("u")
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")

    # spaces
    Vu = u0.function_space()
    Vt = theta0.function_space()
    Vr = rho0.function_space()

    # Isentropic background state
    Tsurf = Constant(300.)
    theta0.interpolate(Tsurf)

    # Calculate hydrostatic Pi
    compressible_hydrostatic_balance(state, theta0, rho0, solve_for_rho=True)

    state.initialise([('u', u0), ('rho', rho0), ('theta', theta0)])
    state.set_reference_profiles([('rho', rho0), ('theta', theta0)])

    # Set up advection schemes
    ueqn = VectorInvariant(state, Vu)
    rhoeqn = AdvectionEquation(state, Vr, equation_form="continuity")
    thetaeqn = EmbeddedDGAdvection(state,
                                   Vt,
                                   equation_form="advective",
                                   options=EmbeddedDGOptions())

    advected_fields = [("u", ThetaMethod(state, u0, ueqn)),
                       ("rho", SSPRK3(state, rho0, rhoeqn)),
                       ("theta", SSPRK3(state, theta0, thetaeqn))]

    # Set up linear solver
    linear_solver = CompressibleSolver(state)

    # Set up forcing
    compressible_forcing = CompressibleForcing(state)

    # build time stepper
    stepper = CrankNicolson(state, advected_fields, linear_solver,
                            compressible_forcing)

    return stepper, tmax
Ejemplo n.º 17
0
def do_simulation_loop(N,
                       variable_parameters,
                       simulation_parameters,
                       diagnostics=None,
                       fields_to_output=None,
                       expected_u=False):
    """
    A recursive strategy for setting up a variable number of for loops
    for the experiment.

    :arg N: the level of loop.
    :arg variable_parameters: an OrderedDict of the parameters to be varied.
    :arg simulation_parameters: a dict storing the parameters for that simulation.
    :arg diagnostics: a list of diagnostic values to be output.
    :arg fields_to_output: a list of fields to be output.
    """

    # we do the loop in reverse order to get the resolution loop on the outside
    M = len(variable_parameters)
    key = list(variable_parameters.items())[M - N][0]
    have_setup = False

    # we must turn the ordered dict into a list to iterate through it
    for index, value in enumerate(
            list(variable_parameters.items())[M - N][1][1]):
        simulation_parameters[key] = (index, value)

        # make mesh if loop is a resolution loop
        if key == 'resolution':
            mesh = PeriodicIntervalMesh(value, simulation_parameters['Ld'][-1])
            simulation_parameters['mesh'] = (mesh, )

        # do recursion if we aren't finished yet
        if N > 1:
            do_simulation_loop(N - 1,
                               variable_parameters,
                               simulation_parameters,
                               diagnostics=diagnostics,
                               fields_to_output=fields_to_output,
                               expected_u=expected_u)

        # finally do simulation
        elif N == 1:

            if expected_u:
                this_u = simulation(simulation_parameters,
                                    diagnostic_values=diagnostics,
                                    fields_to_output=fields_to_output,
                                    expected_u=True)
                if have_setup:
                    Eu.assign(counter * Eu + this_u)
                    counter.assign(counter + 1)
                    Eu.assign(Eu / counter)
                else:
                    scheme = simulation_parameters['scheme'][-1]
                    mesh = simulation_parameters['mesh'][-1]
                    prognostic_variables = PrognosticVariables(scheme, mesh)
                    Eu = Function(prognostic_variables.Vu,
                                  name='expected u').assign(this_u)
                    counter = Constant(1.0)
                    have_setup = True
            else:
                simulation(simulation_parameters,
                           diagnostic_values=diagnostics,
                           fields_to_output=fields_to_output)

    if expected_u:
        expected_u_file = File(simulation_parameters['dirname'][-1] +
                               '/expected_u.pvd')
        expected_u_file.write(Eu)
Ejemplo n.º 18
0
def setup_saturated(dirname, recovered):

    # set up grid and time stepping parameters
    dt = 1.
    tmax = 3.
    deltax = 400.
    L = 2000.
    H = 10000.

    nlayers = int(H / deltax)
    ncolumns = int(L / deltax)

    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers)

    # option to easily change between recovered and not if necessary
    # default should be to use lowest order set of spaces
    degree = 0 if recovered else 1

    output = OutputParameters(dirname=dirname + '/saturated_balance',
                              dumpfreq=1,
                              dumplist=['u'])
    parameters = CompressibleParameters()
    diagnostic_fields = [Theta_e()]

    state = State(mesh,
                  dt=dt,
                  output=output,
                  parameters=parameters,
                  diagnostic_fields=diagnostic_fields)

    tracers = [WaterVapour(), CloudWater()]

    if recovered:
        u_transport_option = "vector_advection_form"
    else:
        u_transport_option = "vector_invariant_form"
    eqns = CompressibleEulerEquations(state,
                                      "CG",
                                      degree,
                                      u_transport_option=u_transport_option,
                                      active_tracers=tracers)

    # Initial conditions
    u0 = state.fields("u")
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")
    water_v0 = state.fields("vapour_mixing_ratio")
    water_c0 = state.fields("cloud_liquid_mixing_ratio")
    moisture = ['vapour_mixing_ratio', 'cloud_liquid_mixing_ratio']

    # spaces
    Vu = u0.function_space()
    Vt = theta0.function_space()
    Vr = rho0.function_space()

    # Isentropic background state
    Tsurf = Constant(300.)
    total_water = Constant(0.02)
    theta_e = Function(Vt).interpolate(Tsurf)
    water_t = Function(Vt).interpolate(total_water)

    # Calculate hydrostatic exner
    saturated_hydrostatic_balance(state, theta_e, water_t)
    water_c0.assign(water_t - water_v0)

    state.set_reference_profiles([('rho', rho0), ('theta', theta0)])

    # Set up transport schemes
    if recovered:
        VDG1 = state.spaces("DG1_equispaced")
        VCG1 = FunctionSpace(mesh, "CG", 1)
        Vt_brok = FunctionSpace(mesh, BrokenElement(Vt.ufl_element()))
        Vu_DG1 = VectorFunctionSpace(mesh, VDG1.ufl_element())
        Vu_CG1 = VectorFunctionSpace(mesh, "CG", 1)

        u_opts = RecoveredOptions(embedding_space=Vu_DG1,
                                  recovered_space=Vu_CG1,
                                  broken_space=Vu,
                                  boundary_method=Boundary_Method.dynamics)
        rho_opts = RecoveredOptions(embedding_space=VDG1,
                                    recovered_space=VCG1,
                                    broken_space=Vr,
                                    boundary_method=Boundary_Method.dynamics)
        theta_opts = RecoveredOptions(embedding_space=VDG1,
                                      recovered_space=VCG1,
                                      broken_space=Vt_brok)
        wv_opts = RecoveredOptions(embedding_space=VDG1,
                                   recovered_space=VCG1,
                                   broken_space=Vt_brok)
        wc_opts = RecoveredOptions(embedding_space=VDG1,
                                   recovered_space=VCG1,
                                   broken_space=Vt_brok)
    else:

        rho_opts = None
        theta_opts = EmbeddedDGOptions()
        wv_opts = EmbeddedDGOptions()
        wc_opts = EmbeddedDGOptions()

    transported_fields = [
        SSPRK3(state, 'rho', options=rho_opts),
        SSPRK3(state, 'theta', options=theta_opts),
        SSPRK3(state, 'vapour_mixing_ratio', options=wv_opts),
        SSPRK3(state, 'cloud_liquid_mixing_ratio', options=wc_opts)
    ]

    if recovered:
        transported_fields.append(SSPRK3(state, 'u', options=u_opts))
    else:
        transported_fields.append(ImplicitMidpoint(state, 'u'))

    linear_solver = CompressibleSolver(state, eqns, moisture=moisture)

    # add physics
    physics_list = [Condensation(state)]

    # build time stepper
    stepper = CrankNicolson(state,
                            eqns,
                            transported_fields,
                            linear_solver=linear_solver,
                            physics_list=physics_list)

    return stepper, tmax
Ejemplo n.º 19
0
def setup_limiters(dirname, direction, grid_params, ic_params):

    # declare grid shape
    L, H, ncolumns, nlayers = grid_params

    # make mesh
    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=(H / nlayers))
    x, z = SpatialCoordinate(mesh)

    fieldlist = ['u']
    timestepping = TimesteppingParameters(dt=1.0)
    output = OutputParameters(dirname=dirname,
                              dumpfreq=5,
                              dumplist=['u'],
                              perturbation_fields=['theta0', 'theta1'])
    parameters = CompressibleParameters()

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

    # make elements
    # v is continuous in vertical, h is horizontal
    cell = mesh._base_mesh.ufl_cell().cellname()
    DG0_element = FiniteElement("DG", cell, 0)
    CG1_element = FiniteElement("CG", cell, 1)
    DG1_element = FiniteElement("DG", cell, 1)
    CG2_element = FiniteElement("CG", cell, 2)
    V0_element = TensorProductElement(DG0_element, CG1_element)
    V1_element = TensorProductElement(DG1_element, CG2_element)

    # spaces
    VDG1 = FunctionSpace(mesh, "DG", 1)
    VCG1 = FunctionSpace(mesh, "CG", 1)
    V0 = FunctionSpace(mesh, V0_element)
    V1 = FunctionSpace(mesh, V1_element)
    V0_brok = FunctionSpace(mesh, BrokenElement(V0.ufl_element()))

    # declare initial fields
    u0 = state.fields("u")
    theta0 = state.fields("theta0", V0)
    theta1 = state.fields("theta1", V1)
    Tsurf, xc, zc, rc, u_max = ic_params

    # Isentropic background state
    thetab = Constant(Tsurf)
    theta_b1 = Function(V1).interpolate(thetab)
    theta_b0 = Function(V0).interpolate(thetab)

    # set up bubble
    theta_expr = conditional(
        sqrt((x - xc)**2.0) < rc,
        conditional(sqrt((z - zc)**2.0) < rc, Constant(2.0), Constant(0.0)),
        Constant(0.0))
    theta_pert1 = Function(V1).interpolate(theta_expr)
    theta_pert0 = Function(V0).interpolate(theta_expr)

    if direction == "horizontal":
        Vpsi = FunctionSpace(mesh, "CG", 2)
        psi_expr = -u_max * z
        psi0 = Function(Vpsi).interpolate(psi_expr)
        gradperp = lambda u: as_vector([-u.dx(1), u.dx(0)])
        u0.project(gradperp(psi0))
    elif direction == "vertical":
        u0.project(as_vector([0, -u_max]))
    theta0.interpolate(theta_b0 + theta_pert0)
    theta1.interpolate(theta_b1 + theta_pert1)

    state.initialise([('u', u0), ('theta1', theta1), ('theta0', theta0)])
    state.set_reference_profiles([('theta1', theta_b1), ('theta0', theta_b0)])

    # set up advection schemes
    dg_opts = EmbeddedDGOptions()
    recovered_opts = RecoveredOptions(embedding_space=VDG1,
                                      recovered_space=VCG1,
                                      broken_space=V0_brok)
    thetaeqn1 = EmbeddedDGAdvection(state,
                                    V1,
                                    equation_form="advective",
                                    options=dg_opts)
    thetaeqn0 = EmbeddedDGAdvection(state,
                                    V0,
                                    equation_form="advective",
                                    options=recovered_opts)

    # build advection dictionary
    advected_fields = []
    advected_fields.append(
        ('theta1', SSPRK3(state, theta1, thetaeqn1, limiter=ThetaLimiter(V1))))
    advected_fields.append(('theta0',
                            SSPRK3(state,
                                   theta0,
                                   thetaeqn0,
                                   limiter=VertexBasedLimiter(VDG1))))

    # build time stepper
    stepper = AdvectionDiffusion(state, advected_fields)

    return stepper, 40.0
Ejemplo n.º 20
0
def run_incompressible(tmpdir):

    dt = 6.0
    tmax = 2*dt
    nlayers = 10  # horizontal layers
    ncols = 10  # number of columns
    Lx = 1000.0
    Lz = 1000.0
    m = PeriodicIntervalMesh(ncols, Lx)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=Lz/nlayers)

    output = OutputParameters(dirname=tmpdir+"/incompressible",
                              dumpfreq=2, chkptfreq=2)
    parameters = CompressibleParameters()

    state = State(mesh,
                  dt=dt,
                  output=output,
                  parameters=parameters)

    eqns = IncompressibleBoussinesqEquations(state, "CG", 1)

    # Initial conditions
    p0 = state.fields("p")
    b0 = state.fields("b")

    # z.grad(bref) = N**2
    x, z = SpatialCoordinate(mesh)
    N = parameters.N
    bref = z*(N**2)

    b_b = Function(b0.function_space()).interpolate(bref)
    incompressible_hydrostatic_balance(state, b_b, p0)
    state.initialise([('p', p0),
                      ('b', b_b)])

    # Add perturbation
    r = sqrt((x-Lx/2)**2 + (z-Lz/2)**2)
    b_pert = 0.1*exp(-(r/(Lx/5)**2))
    b0.interpolate(b_b + b_pert)

    # Set up transport schemes
    b_opts = SUPGOptions()
    transported_fields = [ImplicitMidpoint(state, "u"),
                          SSPRK3(state, "b", options=b_opts)]

    # Set up linear solver for the timestepping scheme
    linear_solver = IncompressibleSolver(state, eqns)

    # build time stepper
    stepper = CrankNicolson(state, eqns, transported_fields,
                            linear_solver=linear_solver)

    # Run
    stepper.run(t=0, tmax=tmax)

    # State for checking checkpoints
    checkpoint_name = 'incompressible_chkpt'
    new_path = join(abspath(dirname(__file__)), '..', f'data/{checkpoint_name}')
    check_output = OutputParameters(dirname=tmpdir+"/incompressible",
                                    checkpoint_pickup_filename=new_path)
    check_state = State(mesh, dt=dt, output=check_output)
    check_eqn = IncompressibleBoussinesqEquations(check_state, "CG", 1)
    check_stepper = CrankNicolson(check_state, check_eqn, [])
    check_stepper.run(t=0, tmax=0, pickup=True)

    return state, check_state
Ejemplo n.º 21
0
def setup_2d_recovery(dirname):

    L = 100.
    H = 100.

    deltax = L / 5.
    deltay = H / 5.
    nlayers = int(H / deltay)
    ncolumns = int(L / deltax)

    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers)
    x, y = SpatialCoordinate(mesh)

    # horizontal base spaces
    cell = mesh._base_mesh.ufl_cell().cellname()
    u_hori = FiniteElement("CG", cell, 1)
    w_hori = FiniteElement("DG", cell, 0)

    # vertical base spaces
    u_vert = FiniteElement("DG", interval, 0)
    w_vert = FiniteElement("CG", interval, 1)

    # build elements
    u_element = HDiv(TensorProductElement(u_hori, u_vert))
    w_element = HDiv(TensorProductElement(w_hori, w_vert))
    theta_element = TensorProductElement(w_hori, w_vert)
    v_element = u_element + w_element

    # spaces
    VDG0 = FunctionSpace(mesh, "DG", 0)
    VCG1 = FunctionSpace(mesh, "CG", 1)
    VDG1 = FunctionSpace(mesh, "DG", 1)
    Vt = FunctionSpace(mesh, theta_element)
    Vt_brok = FunctionSpace(mesh, BrokenElement(theta_element))
    Vu = FunctionSpace(mesh, v_element)
    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() * y

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

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

    # make the recoverers and do the recovery
    rho_recoverer = Recoverer(rho_DG0,
                              rho_CG1,
                              VDG=VDG1,
                              boundary_method=Boundary_Method.dynamics)
    theta_recoverer = Recoverer(theta_Vt,
                                theta_CG1,
                                VDG=VDG1,
                                boundary_method=Boundary_Method.dynamics)
    v_recoverer = Recoverer(v_Vu,
                            v_CG1,
                            VDG=VuDG1,
                            boundary_method=Boundary_Method.dynamics)
    rho_Vt_recoverer = Recoverer(rho_DG0,
                                 rho_Vt,
                                 VDG=Vt_brok,
                                 boundary_method=Boundary_Method.physics)

    rho_recoverer.project()
    theta_recoverer.project()
    v_recoverer.project()
    rho_Vt_recoverer.project()

    rho_diff = errornorm(rho_CG1, rho_CG1_true) / norm(rho_CG1_true)
    theta_diff = errornorm(theta_CG1, theta_CG1_true) / norm(theta_CG1_true)
    v_diff = errornorm(v_CG1, v_CG1_true) / norm(v_CG1_true)
    rho_Vt_diff = errornorm(rho_Vt, rho_Vt_true) / norm(rho_Vt_true)

    return (rho_diff, theta_diff, v_diff, rho_Vt_diff)
Ejemplo n.º 22
0
def run_dry_compressible(tmpdir):

    dt = 6.0
    tmax = 2 * dt
    nlayers = 10  # horizontal layers
    ncols = 10  # number of columns
    Lx = 1000.0
    Lz = 1000.0
    m = PeriodicIntervalMesh(ncols, Lx)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=Lz / nlayers)

    output = OutputParameters(dirname=tmpdir + "/dry_compressible",
                              dumpfreq=2,
                              chkptfreq=2)
    parameters = CompressibleParameters()
    R_d = parameters.R_d
    g = parameters.g

    state = State(mesh, dt=dt, output=output, parameters=parameters)

    eqn = CompressibleEulerEquations(state, "CG", 1)

    # Initial conditions
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")

    # Approximate hydrostatic balance
    x, z = SpatialCoordinate(mesh)
    T = Constant(300.0)
    zH = R_d * T / g
    p = Constant(100000.0) * exp(-z / zH)
    theta0.interpolate(tde.theta(parameters, T, p))
    rho0.interpolate(p / (R_d * T))

    state.set_reference_profiles([('rho', rho0), ('theta', theta0)])

    # Add perturbation
    r = sqrt((x - Lx / 2)**2 + (z - Lz / 2)**2)
    theta_pert = 1.0 * exp(-(r / (Lx / 5))**2)
    theta0.interpolate(theta0 + theta_pert)

    # Set up transport schemes
    transported_fields = [
        ImplicitMidpoint(state, "u"),
        SSPRK3(state, "rho"),
        SSPRK3(state, "theta")
    ]

    # Set up linear solver for the timestepping scheme
    linear_solver = CompressibleSolver(state, eqn)

    # build time stepper
    stepper = CrankNicolson(state,
                            eqn,
                            transported_fields,
                            linear_solver=linear_solver)

    # Run
    stepper.run(t=0, tmax=tmax)

    # State for checking checkpoints
    checkpoint_name = 'dry_compressible_chkpt'
    new_path = join(abspath(dirname(__file__)), '..',
                    f'data/{checkpoint_name}')
    check_output = OutputParameters(dirname=tmpdir + "/dry_compressible",
                                    checkpoint_pickup_filename=new_path)
    check_state = State(mesh,
                        dt=dt,
                        output=check_output,
                        parameters=parameters)
    check_eqn = CompressibleEulerEquations(check_state, "CG", 1)
    check_stepper = CrankNicolson(check_state, check_eqn, [])
    check_stepper.run(t=0, tmax=0, pickup=True)

    return state, check_state
Ejemplo n.º 23
0
def setup_limiters(dirname):

    dt = 0.01
    Ld = 1.
    tmax = 0.2
    rotations = 0.1
    m = PeriodicIntervalMesh(20, Ld)
    mesh = ExtrudedMesh(m, layers=20, layer_height=(Ld / 20))
    output = OutputParameters(
        dirname=dirname,
        dumpfreq=1,
        dumplist=['u', 'chemical', 'moisture_higher', 'moisture_lower'])
    parameters = CompressibleParameters()
    timestepping = TimesteppingParameters(dt=dt, maxk=4, maxi=1)
    fieldlist = [
        'u', 'rho', 'theta', 'chemical', 'moisture_higher', 'moisture_lower'
    ]
    diagnostic_fields = []
    state = State(mesh,
                  vertical_degree=1,
                  horizontal_degree=1,
                  family="CG",
                  timestepping=timestepping,
                  output=output,
                  parameters=parameters,
                  fieldlist=fieldlist,
                  diagnostic_fields=diagnostic_fields)

    x, z = SpatialCoordinate(mesh)

    Vr = state.spaces("DG")
    Vt = state.spaces("HDiv_v")
    Vpsi = FunctionSpace(mesh, "CG", 2)

    cell = mesh._base_mesh.ufl_cell().cellname()
    DG0_element = FiniteElement("DG", cell, 0)
    CG1_element = FiniteElement("CG", interval, 1)
    Vt0_element = TensorProductElement(DG0_element, CG1_element)
    Vt0 = FunctionSpace(mesh, Vt0_element)
    Vt0_brok = FunctionSpace(mesh, BrokenElement(Vt0_element))
    VCG1 = FunctionSpace(mesh, "CG", 1)

    u = state.fields("u", dump=True)
    chemical = state.fields("chemical", Vr, dump=True)
    moisture_higher = state.fields("moisture_higher", Vt, dump=True)
    moisture_lower = state.fields("moisture_lower", Vt0, dump=True)

    x_lower = 2 * Ld / 5
    x_upper = 3 * Ld / 5
    z_lower = 6 * Ld / 10
    z_upper = 8 * Ld / 10
    bubble_expr_1 = conditional(
        x > x_lower,
        conditional(
            x < x_upper,
            conditional(z > z_lower, conditional(z < z_upper, 1.0, 0.0), 0.0),
            0.0), 0.0)

    bubble_expr_2 = conditional(
        x > z_lower,
        conditional(
            x < z_upper,
            conditional(z > x_lower, conditional(z < x_upper, 1.0, 0.0), 0.0),
            0.0), 0.0)

    chemical.assign(1.0)
    moisture_higher.assign(280.)
    chem_pert_1 = Function(Vr).interpolate(bubble_expr_1)
    chem_pert_2 = Function(Vr).interpolate(bubble_expr_2)
    moist_h_pert_1 = Function(Vt).interpolate(bubble_expr_1)
    moist_h_pert_2 = Function(Vt).interpolate(bubble_expr_2)
    moist_l_pert_1 = Function(Vt0).interpolate(bubble_expr_1)
    moist_l_pert_2 = Function(Vt0).interpolate(bubble_expr_2)

    chemical.assign(chemical + chem_pert_1 + chem_pert_2)
    moisture_higher.assign(moisture_higher + moist_h_pert_1 + moist_h_pert_2)
    moisture_lower.assign(moisture_lower + moist_l_pert_1 + moist_l_pert_2)

    # set up solid body rotation for advection
    # we do this slightly complicated stream function to make the velocity 0 at edges
    # thus we avoid odd effects at boundaries
    xc = Ld / 2
    zc = Ld / 2
    r = sqrt((x - xc)**2 + (z - zc)**2)
    omega = rotations * 2 * pi / tmax
    r_out = 9 * Ld / 20
    r_in = 2 * Ld / 5
    A = omega * r_in / (2 * (r_in - r_out))
    B = -omega * r_in * r_out / (r_in - r_out)
    C = omega * r_in**2 * r_out / (r_in - r_out) / 2
    psi_expr = conditional(
        r < r_in, omega * r**2 / 2,
        conditional(r < r_out, A * r**2 + B * r + C,
                    A * r_out**2 + B * r_out + C))
    psi = Function(Vpsi).interpolate(psi_expr)

    gradperp = lambda v: as_vector([-v.dx(1), v.dx(0)])
    u.project(gradperp(psi))

    state.initialise([('u', u), ('chemical', chemical),
                      ('moisture_higher', moisture_higher),
                      ('moisture_lower', moisture_lower)])

    # set up advection schemes
    dg_opts = EmbeddedDGOptions()
    recovered_opts = RecoveredOptions(embedding_space=Vr,
                                      recovered_space=VCG1,
                                      broken_space=Vt0_brok,
                                      boundary_method=Boundary_Method.dynamics)

    chemeqn = AdvectionEquation(state, Vr, equation_form="advective")
    moisteqn_higher = EmbeddedDGAdvection(state,
                                          Vt,
                                          equation_form="advective",
                                          options=dg_opts)
    moisteqn_lower = EmbeddedDGAdvection(state,
                                         Vt0,
                                         equation_form="advective",
                                         options=recovered_opts)

    # build advection dictionary
    advected_fields = []
    advected_fields.append(('chemical',
                            SSPRK3(state,
                                   chemical,
                                   chemeqn,
                                   limiter=VertexBasedLimiter(Vr))))
    advected_fields.append(('moisture_higher',
                            SSPRK3(state,
                                   moisture_higher,
                                   moisteqn_higher,
                                   limiter=ThetaLimiter(Vt))))
    advected_fields.append(('moisture_lower',
                            SSPRK3(state,
                                   moisture_lower,
                                   moisteqn_lower,
                                   limiter=VertexBasedLimiter(Vr))))

    # build time stepper
    stepper = AdvectionDiffusion(state, advected_fields)

    return stepper, tmax
Ejemplo n.º 24
0
def setup_condens(dirname):

    # declare grid shape, with length L and height H
    L = 1000.
    H = 1000.
    nlayers = int(H / 100.)
    ncolumns = int(L / 100.)

    # make mesh
    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=(H / nlayers))
    x = SpatialCoordinate(mesh)

    fieldlist = ['u', 'rho', 'theta']
    timestepping = TimesteppingParameters(dt=1.0, maxk=4, maxi=1)
    output = OutputParameters(dirname=dirname + "/condens",
                              dumpfreq=1,
                              dumplist=['u'],
                              perturbation_fields=['theta', 'rho'])
    parameters = CompressibleParameters()

    state = State(mesh,
                  vertical_degree=1,
                  horizontal_degree=1,
                  family="CG",
                  timestepping=timestepping,
                  output=output,
                  parameters=parameters,
                  fieldlist=fieldlist,
                  diagnostic_fields=[Sum('water_v', 'water_c')])

    # declare initial fields
    u0 = state.fields("u")
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")

    # spaces
    Vpsi = FunctionSpace(mesh, "CG", 2)
    Vt = theta0.function_space()
    Vr = rho0.function_space()

    # make a gradperp
    gradperp = lambda u: as_vector([-u.dx(1), u.dx(0)])

    # declare tracer field and a background field
    water_v0 = state.fields("water_v", Vt)
    water_c0 = state.fields("water_c", Vt)

    # Isentropic background state
    Tsurf = Constant(300.)

    theta_b = Function(Vt).interpolate(Tsurf)
    rho_b = Function(Vr)

    # Calculate initial rho
    compressible_hydrostatic_balance(state, theta_b, rho_b, solve_for_rho=True)

    # set up water_v
    xc = 500.
    zc = 350.
    rc = 250.
    r = sqrt((x[0] - xc)**2 + (x[1] - zc)**2)
    w_expr = conditional(r > rc, 0., 0.25 * (1. + cos((pi / rc) * r)))

    # set up velocity field
    u_max = 10.0

    psi_expr = ((-u_max * L / pi) * sin(2 * pi * x[0] / L) *
                sin(pi * x[1] / L))

    psi0 = Function(Vpsi).interpolate(psi_expr)
    u0.project(gradperp(psi0))
    theta0.interpolate(theta_b)
    rho0.interpolate(rho_b)
    water_v0.interpolate(w_expr)

    state.initialise([('u', u0), ('rho', rho0), ('theta', theta0),
                      ('water_v', water_v0), ('water_c', water_c0)])
    state.set_reference_profiles([('rho', rho_b), ('theta', theta_b)])

    # set up advection schemes
    rhoeqn = AdvectionEquation(state, Vr, equation_form="continuity")
    thetaeqn = SUPGAdvection(state,
                             Vt,
                             supg_params={"dg_direction": "horizontal"},
                             equation_form="advective")

    # build advection dictionary
    advected_fields = []
    advected_fields.append(("u", NoAdvection(state, u0, None)))
    advected_fields.append(("rho", SSPRK3(state, rho0, rhoeqn)))
    advected_fields.append(("theta", SSPRK3(state, theta0, thetaeqn)))
    advected_fields.append(("water_v", SSPRK3(state, water_v0, thetaeqn)))
    advected_fields.append(("water_c", SSPRK3(state, water_c0, thetaeqn)))

    physics_list = [Condensation(state)]

    # build time stepper
    stepper = AdvectionDiffusion(state,
                                 advected_fields,
                                 physics_list=physics_list)

    return stepper, 5.0
Ejemplo n.º 25
0
def setup_sk(dirname):
    nlayers = 10  # horizontal layers
    columns = 30  # number of columns
    L = 1.e5
    m = PeriodicIntervalMesh(columns, L)
    dt = 6.0

    # build volume mesh
    H = 1.0e4  # Height position of the model top
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers)

    # Set up points for output at the centre of the domain, edges and corners.
    # The point at x=L*(13.0/30) is in the halo region for a two-way MPI decomposition
    points_x = [0.0, L * (13.0 / 30), L / 2.0, L]
    points_z = [0.0, H / 2.0, H]
    points = np.array([p for p in itertools.product(points_x, points_z)])

    fieldlist = ['u', 'rho', 'theta']
    timestepping = TimesteppingParameters(dt=dt)
    output = OutputParameters(dirname=dirname + "/sk_nonlinear",
                              dumplist=['u'],
                              dumpfreq=5,
                              log_level=INFO,
                              point_data=[('rho', points), ('u', points)])
    parameters = CompressibleParameters()
    diagnostic_fields = [CourantNumber()]

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

    # Initial conditions
    u0 = state.fields("u")
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")

    # spaces
    Vu = u0.function_space()
    Vt = theta0.function_space()
    Vr = rho0.function_space()

    # Thermodynamic constants required for setting initial conditions
    # and reference profiles
    g = parameters.g
    N = parameters.N

    # N^2 = (g/theta)dtheta/dz => dtheta/dz = theta N^2g => theta=theta_0exp(N^2gz)
    x, z = SpatialCoordinate(mesh)
    Tsurf = 300.
    thetab = Tsurf * exp(N**2 * z / g)

    theta_b = Function(Vt).interpolate(thetab)
    rho_b = Function(Vr)

    # Calculate hydrostatic Pi
    compressible_hydrostatic_balance(state, theta_b, rho_b)

    a = 5.0e3
    deltaTheta = 1.0e-2
    theta_pert = deltaTheta * sin(np.pi * z / H) / (1 + (x - L / 2)**2 / a**2)
    theta0.interpolate(theta_b + theta_pert)
    rho0.assign(rho_b)
    u0.project(as_vector([20.0, 0.0]))

    state.initialise([('u', u0), ('rho', rho0), ('theta', theta0)])
    state.set_reference_profiles([('rho', rho_b), ('theta', theta_b)])

    # Set up advection schemes
    ueqn = EulerPoincare(state, Vu)
    rhoeqn = AdvectionEquation(state, Vr, equation_form="continuity")
    thetaeqn = SUPGAdvection(state, Vt)
    advected_fields = []
    advected_fields.append(("u", ThetaMethod(state, u0, ueqn)))
    advected_fields.append(("rho", SSPRK3(state, rho0, rhoeqn)))
    advected_fields.append(("theta", SSPRK3(state, theta0, thetaeqn)))

    # Set up linear solver
    linear_solver = CompressibleSolver(state)

    # Set up forcing
    compressible_forcing = CompressibleForcing(state)

    # build time stepper
    stepper = CrankNicolson(state, advected_fields, linear_solver,
                            compressible_forcing)

    return stepper, 2 * dt
Ejemplo n.º 26
0
def experiment(code,
               Ld,
               tmax,
               resolutions=[],
               dts=[],
               sigmas=[],
               seeds=[],
               schemes=[],
               timesteppings=[],
               alphasq=[],
               c0=[],
               gamma=[],
               ics=[],
               num_Xis=[],
               Xi_family=[],
               diagnostics=None,
               fields_to_output=None,
               ndump=-1,
               field_ndump=-1,
               nXi_updates=1,
               allow_fail=False,
               t_kick=[],
               sigma_kick=0.0,
               smooth_t=None,
               peakon_equations=False,
               only_peakons=False,
               true_peakon_data=None,
               true_mean_peakon_data=None,
               peakon_speed=None,
               expected_u=False,
               periodic=False,
               peak_width=1.0,
               peakon_method='ito_euler',
               fixed_dW=None):

    # set up dumping
    dirname = 'results/' + code
    if path.exists(dirname):
        raise IOError("results directory '%s' already exists" % dirname)
    else:
        makedirs(dirname)

    expmt_dict = {
        'dt': (float, dts),
        'resolution': (float, resolutions),
        'seed': (int, seeds),
        'sigma': (float, sigmas),
        'scheme': ('S1', schemes),
        'timestepping': ('S1', timesteppings),
        'alphasq': (float, alphasq),
        'c0': (float, c0),
        'gamma': (float, gamma),
        'ic': ('S1', ics),
        'num_Xis': (int, num_Xis),
        'Xi_family': ('S1', Xi_family),
    }

    # turns expmt_dict values into lists so they can be iterated over
    for key, value in expmt_dict.items():
        # need to not accidentally accept strings
        if not isinstance(value, str):
            try:
                iter(value[1])
            except TypeError:
                expmt_dict[key] = (value[0], [value[1]])
        else:
            expmt_dict[key] = (value[0], [value[1]])

    # we need a dictionary of parameters to form the loops over
    # also a dictionary of fixed parameters for all simulations
    # finally a dictionary of all parameters for individual simulations
    # the first should be an ordered dict
    variable_parameters = OrderedDict()
    fixed_parameters = {}
    simulation_parameters = {}

    # need resolutions to be first in variable parameters dict (to loop over first)
    if len(expmt_dict['resolution'][1]) > 1:
        variable_parameters['resolution'] = None

    # here we separate parameters into variable or fixed
    # this is done by asking if they are iterable, and being careful to ignore strings
    for key, value in expmt_dict.items():
        if not isinstance(value[1], str) and len(value[1]) > 1:
            variable_parameters[key] = value
            simulation_parameters[key] = None
        elif isinstance(value[1], str):
            fixed_parameters[key] = value
            simulation_parameters[key] = (value[1], )
        elif len(value[1]) == 1:
            fixed_parameters[key] = value
            simulation_parameters[key] = (value[1][0], )

    # Stuff where there can be only one value that is fixed for all experiments
    for key, value in zip([
            'dirname', 'Ld', 'tmax', 'ndump', 'field_ndump', 'nXi_updates',
            'allow_fail', 'smooth_t', 'peakon_equations', 'only_peakons',
            'true_peakon_data', 'true_mean_peakon_data', 'peakon_speed',
            'periodic', 'fixed_dW', 'peak_width', 'peakon_method'
    ], [
            dirname, Ld, tmax, ndump, field_ndump, nXi_updates, allow_fail,
            smooth_t, peakon_equations, only_peakons, true_peakon_data,
            true_mean_peakon_data, peakon_speed, periodic, fixed_dW,
            peak_width, peakon_method
    ]):
        simulation_parameters[key] = (value, )

    output_arguments = ('time', ) + tuple(variable_parameters.keys())
    list_of_peakon_diagnostics = [
        'peakon_loc', 'peakon_min_du', 'peakon_max_du', 'peakon_min_du_loc',
        'peakon_max_du_loc', 'peakon_max_u', 'peakon_mu', 'peakon_nu'
    ]

    for i, dt in enumerate(expmt_dict['dt'][1]):
        # make data file
        if len(expmt_dict['dt'][1]) > 1:
            file_name = dirname + '/data_dt' + str(i) + '.nc'
        else:
            file_name = dirname + '/data.nc'

        simulation_parameters['file_name'] = (file_name, )

        data_file = Dataset(file_name, 'w')

        # create dimensions and variables
        data_file.createDimension('time', None)
        data_file.createVariable('time', float, ('time', ))

        if 'resolution' in variable_parameters.keys():
            data_file.createDimension(
                'resolution', len(variable_parameters['resolution'][1]))
            data_file.createVariable('deltax', float, ('resolution', ))
            for j, res in enumerate(variable_parameters['resolution'][1]):
                data_file['deltax'][
                    j:j + 1] = Ld / variable_parameters['resolution'][1][j]

            # create a fixed x dimension for a and b fields
            data_file.createDimension('x', 100)
            data_file.createVariable('x', float, ('x', ))
            data_file['x'][:] = np.linspace(0, Ld, num=100, endpoint=False)
            simulation_parameters['store_coordinates'] = [False]

        else:
            # if the resolution is not varying, we can use the real resolution
            num_points = simulation_parameters['resolution'][-1]
            data_file.createDimension('x', num_points)
            data_file.createVariable('x', float, ('x', ))
            simulation_parameters['store_coordinates'] = [True]

        for key, values in variable_parameters.items():
            if key != 'resolution':
                data_file.createDimension(key, len(values[1]))
                data_file.createVariable(key, values[0], (key, ))
                for j, value in enumerate(values[1]):
                    data_file[key][j:j + 1] = value

        # create diagnostic variables, with dimensions dependent upon parameters
        if diagnostics is not None:
            for output in diagnostics:
                if output == 'mu':
                    for i in range(4):
                        data_file.createVariable(output + '_' + str(i), float,
                                                 output_arguments)
                        data_file.createVariable(
                            'alt_' + output + '_' + str(i), float,
                            output_arguments)
                elif output in ('a', 'b', 'u_field'):
                    data_file.createVariable(output, float,
                                             output_arguments + ('x', ))
                elif output == 'peakon_suite':
                    for peakon_diag in list_of_peakon_diagnostics:
                        data_file.createVariable(peakon_diag, float,
                                                 output_arguments)
                else:
                    data_file.createVariable(output, float, output_arguments)

        if peakon_equations:
            data_file.createVariable('p', float, output_arguments)
            data_file.createVariable('q', float, output_arguments)

        # create diagnostics for wallclock time and failure time
        data_file.createDimension('wallclock_times', 2)
        data_file.createVariable('wallclock_time', float,
                                 ('wallclock_times', ) +
                                 tuple(variable_parameters.keys()))
        data_file.createVariable('failed_time', float,
                                 tuple(variable_parameters.keys()))

        data_file.close()

        # we want to do a variable number of for loops so use recursive strategy

        N = len(variable_parameters)
        if N > 0:
            # measure length of loops
            # raise error if it's too long
            num_sims = np.prod(
                [len(value[1]) for value in variable_parameters.values()])
            if num_sims > 1000:
                raise ValueError(
                    'You are asking to do %d simulations! Please reduce your loops.'
                    % num_sims)

            # do the simulation loop
            if len(expmt_dict['resolution'][1]) == 1:
                resolution = simulation_parameters['resolution'][-1]
                mesh = PeriodicIntervalMesh(resolution, Ld)
                simulation_parameters['mesh'] = (mesh, )
            do_simulation_loop(N,
                               variable_parameters,
                               simulation_parameters,
                               diagnostics=diagnostics,
                               fields_to_output=fields_to_output,
                               expected_u=expected_u)
        else:
            resolution = simulation_parameters['resolution'][-1]
            mesh = PeriodicIntervalMesh(resolution, Ld)
            simulation_parameters['mesh'] = (mesh, )

            simulation(simulation_parameters,
                       diagnostic_values=diagnostics,
                       fields_to_output=fields_to_output)
Ejemplo n.º 27
0
def setup_fallout(dirname):

    # declare grid shape, with length L and height H
    L = 10.
    H = 10.
    nlayers = 10
    ncolumns = 10

    # make mesh
    m = PeriodicIntervalMesh(ncolumns, L)
    mesh = ExtrudedMesh(m, layers=nlayers, layer_height=(H / nlayers))
    x = SpatialCoordinate(mesh)

    fieldlist = ['u', 'rho', 'theta', 'rain']
    timestepping = TimesteppingParameters(dt=0.1, maxk=4, maxi=1)
    output = OutputParameters(dirname=dirname + "/fallout",
                              dumpfreq=10,
                              dumplist=['rain'])
    parameters = CompressibleParameters()
    diagnostic_fields = [Precipitation()]
    state = State(mesh,
                  vertical_degree=1,
                  horizontal_degree=1,
                  family="CG",
                  timestepping=timestepping,
                  output=output,
                  parameters=parameters,
                  fieldlist=fieldlist,
                  diagnostic_fields=diagnostic_fields)

    # declare initial fields
    u0 = state.fields("u")
    rho0 = state.fields("rho")
    theta0 = state.fields("theta")

    # spaces
    Vt = theta0.function_space()

    # declare tracer field and a background field
    rain0 = state.fields("rain", Vt)

    # set up rain
    xc = L / 2
    zc = H / 2
    rc = H / 4
    r = sqrt((x[0] - xc)**2 + (x[1] - zc)**2)
    rain_expr = conditional(r > rc, 0., 1e-3 * (cos(pi * r / (rc * 2)))**2)

    rain0.interpolate(rain_expr)

    rho0.assign(1.0)

    state.initialise([('u', u0), ('rho', rho0), ('rain', rain0)])

    # build advection dictionary
    advected_fields = []
    advected_fields.append(("u", NoAdvection(state, u0, None)))
    advected_fields.append(("rho", NoAdvection(state, rho0, None)))
    advected_fields.append(("rain", NoAdvection(state, rain0, None)))

    physics_list = [Fallout(state)]

    # build time stepper
    stepper = AdvectionDiffusion(state,
                                 advected_fields,
                                 physics_list=physics_list)

    return stepper, 10.0
Ejemplo n.º 28
0
dt = 10.
if '--running-tests' in sys.argv:
    tmax = dt
else:
    tmax = 3600.

if '--hybridization' in sys.argv:
    hybridization = True
else:
    hybridization = False

nlayers = 50  # horizontal layers
columns = 50  # number of columns
L = 3.0e5
m = PeriodicIntervalMesh(columns, L)

# build volume mesh
H = 1.0e4  # Height position of the model top
mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers)

fieldlist = ['u', 'rho', 'theta']
timestepping = TimesteppingParameters(dt=dt)

dirname = 'sk_linear'
if hybridization:
    dirname += '_hybridization'

output = OutputParameters(dirname=dirname,
                          dumplist=['u'],
                          perturbation_fields=['theta', 'rho'])
Ejemplo n.º 29
0
# ---------------
# 1D mesh support ncells, Length (left coords), right coords (opt.)
#  m= IntervalMesh(nx,-L,L)
m = IntervalMesh(nx, L)
xIM = m.coordinates.dat.data


# -> UnitIntervalMesh
# -------------------
m = UnitIntervalMesh(nx)
xUIM = m.coordinates.dat.data


# -> PeriodicInternalMesh
# -----------------------
m = PeriodicIntervalMesh(nx, L)
xPIM = m.coordinates.dat.data

y = np.ones([nx+1, ])
plt.plot(xIM, 0*y, color="black", marker="o", label="IntervalMesh")
plt.plot(xUIM, 1*y, color="red", marker="o", label="UnitIntervalMesh")
plt.plot(xPIM, 2*np.ones(np.shape(xPIM)), color="blue",
         marker="o", label="PeriodicInternalMesh")
plt.legend()
plt.savefig("plots/oneDimensionMesh.png")


# TwoDimensional Meshes
# -> RectangleMesh
# ----------------
# support quadrilateral input (True or False)