From 021d9d7f017830159c05015f55a4fc9d64afc59e Mon Sep 17 00:00:00 2001 From: Tim Andrews Date: Wed, 15 Nov 2023 01:00:46 +0000 Subject: [PATCH] changed mixed_fs_limiter test to DG and DG1_equispaced --- gusto/limiters.py | 37 +++++--------- integration-tests/transport/test_limiters.py | 51 ++++++++------------ 2 files changed, 32 insertions(+), 56 deletions(-) diff --git a/gusto/limiters.py b/gusto/limiters.py index b8d97382f..2011bc680 100644 --- a/gusto/limiters.py +++ b/gusto/limiters.py @@ -6,7 +6,7 @@ """ from firedrake import (BrokenElement, Function, FunctionSpace, interval, - FiniteElement, TensorProductElement, split) + FiniteElement, TensorProductElement) from firedrake.slope_limiter.vertex_based_limiter import VertexBasedLimiter from gusto.kernels import LimitMidpoints @@ -184,44 +184,29 @@ class MixedFSLimiter(object): """An object to hold a dictionary that defines limiters for transported prognostic variables. Different limiters may be applied to different fields and not every transported variable needs a defined limiter. """ - + def __init__(self, equation, sublimiters): """ Args: equation (:class: 'PrognosticEquationSet'): the prognostic equation(s) - sublimiters (dict): A dictionary holding limiters defined for individual prognostic variables + sublimiters (dict): A dictionary holding limiters defined for individual prognostic variables Raises: ValueError: If a limiter is defined for a field that is not in the prognostic variable set """ self.sublimiters = sublimiters - - for tracer, sublimiter in sublimiters.items(): - # Check that the tracer is being solved in the equation: - if tracer not in equation.field_names: - raise ValueError(f"The limiter for {tracer} is for a field that does not exist in the equation set") + + for field, sublimiter in sublimiters.items(): + # Check that the field is in the prognostic variable set: + if field not in equation.field_names: + raise ValueError(f"The limiter defined for {field} is for a field that does not exist in the equation set") else: - self.sublimiters[tracer].idx = equation.field_names.index(tracer) - - #for tracer in tracers: - # if tracer.name in sublimiters: - # sublimiter = sublimiters.get(tracer.name) - # print(sublimiter) - # self.sublimiters[tracer.name].idx = equation.field_names.index(tracer.name - + self.sublimiters[field].idx = equation.field_names.index(field) + def apply(self, fields): """ Apply the individual limiters to specific prognostic variables """ - - #for tracer in self.tracers: - # if tracer.name in self.sublimiters: - # sublimiter = self.sublimiters[tracer.name] - # field = fields.subfunctions[sublimiter.idx] - # sublimiter.apply(field) - # print(f'Applying sublimiter on {tracer.name} field') - + for _, sublimiter in self.sublimiters.items(): field = fields.subfunctions[sublimiter.idx] sublimiter.apply(field) - #print(f'Applying sublimiter on {tracer} field') - \ No newline at end of file diff --git a/integration-tests/transport/test_limiters.py b/integration-tests/transport/test_limiters.py index 0e507dcba..d992dfded 100644 --- a/integration-tests/transport/test_limiters.py +++ b/integration-tests/transport/test_limiters.py @@ -53,8 +53,7 @@ def setup_limiters(dirname, space): elif space == 'mixed_FS': V = domain.spaces('HDiv') VA = domain.spaces('DG') - #VB = domain.spaces('theta') - VB = domain.spaces('DG') + VB = domain.spaces('DG1_equispaced') else: raise NotImplementedError @@ -65,10 +64,7 @@ def setup_limiters(dirname, space): tracerA = ActiveTracer(name='tracerA', space='DG', variable_type=TracerVariableType.mixing_ratio, transport_eqn=TransportEquationType.advective) - #tracerB = ActiveTracer(name='tracerB', space='theta', - # variable_type=TracerVariableType.mixing_ratio, - # transport_eqn=TransportEquationType.advective) - tracerB = ActiveTracer(name='tracerB', space='DG', + tracerB = ActiveTracer(name='tracerB', space='DG1_equispaced', variable_type=TracerVariableType.mixing_ratio, transport_eqn=TransportEquationType.advective) tracers = [tracerA, tracerB] @@ -106,14 +102,9 @@ def setup_limiters(dirname, space): elif space == 'mixed_FS': sublimiters = {'tracerA': DG1Limiter(domain.spaces('DG')), - 'tracerB': DG1Limiter(domain.spaces('DG'))} - #'tracerB': ThetaLimiter(domain.spaces('theta'))} - # Need Embedded DG if wanting to test theta limiter. + 'tracerB': VertexBasedLimiter(domain.spaces('DG1_equispaced'))} MixedLimiter = MixedFSLimiter(eqn, sublimiters) transport_schemes = SSPRK3(domain, limiter=MixedLimiter) - - #theta_opts = EmbeddedDGOptions() - else: raise NotImplementedError @@ -234,8 +225,8 @@ def setup_limiters(dirname, space): return stepper, tmax, true_field #move mixed_FS to the end once finished debugging -@pytest.mark.parametrize('space', ['Vtheta_degree_0', 'mixed_FS'])#, 'Vtheta_degree_1', - #'DG0', 'DG1', 'DG1_equispaced']) +@pytest.mark.parametrize('space', ['Vtheta_degree_0', 'Vtheta_degree_1', 'DG0', + 'DG1', 'DG1_equispaced', 'mixed_FS']) def test_limiters(tmpdir, space): # Setup and run @@ -245,50 +236,50 @@ def test_limiters(tmpdir, space): stepper, tmax, true_fieldA, true_fieldB = setup_limiters(dirname, space) else: stepper, tmax, true_field = setup_limiters(dirname, space) - + stepper.run(t=0, tmax=tmax) - + tol = 1e-9 - + if space == 'mixed_FS': final_fieldA = stepper.fields('tracerA') final_fieldB = stepper.fields('tracerB') - + # Check tracer is roughly in the correct place assert norm(true_fieldA - final_fieldA) / norm(true_fieldA) < 0.05, \ 'Something is wrong with the DG space tracer using a mixed limiter' - + # Check tracer is roughly in the correct place assert norm(true_fieldB - final_fieldB) / norm(true_fieldB) < 0.05, \ - 'Something is wrong with the theta space tracer using a mixed limiter' - + 'Something is wrong with the DG1 equispaced tracer using a mixed limiter' + # Check for no new overshoots in A assert np.max(final_fieldA.dat.data) <= np.max(true_fieldA.dat.data) + tol, \ 'Application of the DG space limiter in the mixed limiter has not prevented overshoots' - + # Check for no new undershoots in A assert np.min(final_fieldA.dat.data) >= np.min(true_fieldA.dat.data) - tol, \ 'Application of the DG space limiter in the mixed limiter has not prevented undershoots' - + # Check for no new overshoots in B assert np.max(final_fieldB.dat.data) <= np.max(true_fieldB.dat.data) + tol, \ - 'Application of the theta space limiter in the mixed limiter has not prevented overshoots' - + 'Application of the DG1 equispaced limiter in the mixed limiter has not prevented overshoots' + # Check for no new undershoots in B assert np.min(final_fieldB.dat.data) >= np.min(true_fieldB.dat.data) - tol, \ - 'Application of the theta space limiter in the mixed limiter has not prevented undershoots' - + 'Application of the DG1 equispaced limiter in the mixed limiter has not prevented undershoots' + else: final_field = stepper.fields('tracer') - + # Check tracer is roughly in the correct place assert norm(true_field - final_field) / norm(true_field) < 0.05, \ 'Something appears to have gone wrong with transport of tracer using a limiter' - + # Check for no new overshoots assert np.max(final_field.dat.data) <= np.max(true_field.dat.data) + tol, \ 'Application of limiter has not prevented overshoots' - + # Check for no new undershoots assert np.min(final_field.dat.data) >= np.min(true_field.dat.data) - tol, \ 'Application of limiter has not prevented undershoots'