-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #452 from cbegeman/port-merrygoround-from-legacy
Port merry-go-round test group from legacy
- Loading branch information
Showing
18 changed files
with
901 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from compass.testgroup import TestGroup | ||
from compass.ocean.tests.merry_go_round.default import Default | ||
from compass.ocean.tests.merry_go_round.convergence_test import ConvergenceTest | ||
|
||
|
||
class MerryGoRound(TestGroup): | ||
""" | ||
A test group for tracer advection test cases "merry-go-round" | ||
""" | ||
|
||
def __init__(self, mpas_core): | ||
""" | ||
mpas_core : compass.MpasCore | ||
the MPAS core that this test group belongs to | ||
""" | ||
super().__init__(mpas_core=mpas_core, name='merry_go_round') | ||
|
||
self.add_test_case(Default(test_group=self)) | ||
self.add_test_case(ConvergenceTest(test_group=self)) |
35 changes: 35 additions & 0 deletions
35
compass/ocean/tests/merry_go_round/convergence_test/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from compass.testcase import TestCase | ||
from compass.ocean.tests.merry_go_round.initial_state import InitialState | ||
from compass.ocean.tests.merry_go_round.forward import Forward | ||
from compass.ocean.tests.merry_go_round.viz import Viz | ||
from compass.ocean.tests.merry_go_round.convergence_test.analysis \ | ||
import Analysis | ||
from compass.ocean.tests import merry_go_round | ||
from compass.validate import compare_variables | ||
|
||
|
||
class ConvergenceTest(TestCase): | ||
""" | ||
The convergence test case for the merry-go-round test | ||
""" | ||
|
||
def __init__(self, test_group): | ||
""" | ||
Create the test case | ||
Parameters | ||
---------- | ||
test_group : compass.ocean.tests.merry_go_round.MerryGoRound | ||
The test group that this test case belongs to | ||
""" | ||
super().__init__(test_group=test_group, name='convergence_test') | ||
resolutions = ['1.25m', '2.5m', '5m'] | ||
for resolution in resolutions: | ||
self.add_step(InitialState(test_case=self, resolution=resolution, | ||
name=f'initial_state_{resolution}')) | ||
self.add_step(Forward(test_case=self, resolution=resolution, | ||
ntasks=4, openmp_threads=1, | ||
name=f'forward_{resolution}')) | ||
self.add_step(Viz(test_case=self, resolution=resolution, | ||
name=f'viz_{resolution}')) | ||
self.add_step(Analysis(test_case=self, resolutions=resolutions)) |
101 changes: 101 additions & 0 deletions
101
compass/ocean/tests/merry_go_round/convergence_test/analysis.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import math | ||
import numpy | ||
import xarray | ||
import matplotlib | ||
import matplotlib.pyplot as plt | ||
import cmocean | ||
|
||
from compass.step import Step | ||
|
||
|
||
class Analysis(Step): | ||
""" | ||
A step for plotting the convergence of the solution with resolution and | ||
time step in the merry-go-round test group | ||
Attributes | ||
---------- | ||
resolution : str | ||
The resolution of the test case | ||
""" | ||
def __init__(self, test_case, resolutions, name='analysis'): | ||
""" | ||
Create the step | ||
Parameters | ||
---------- | ||
test_case : compass.TestCase | ||
The test case this step belongs to | ||
resolutions : list of str | ||
The resolutions of the test case | ||
name: str | ||
The name of the step | ||
""" | ||
super().__init__(test_case=test_case, name=name) | ||
|
||
self.resolutions = resolutions | ||
|
||
self.add_output_file(filename='convergence_plot.png') | ||
|
||
def run(self): | ||
""" | ||
Run this step of the test case | ||
""" | ||
_plot(self.outputs[0], self.resolutions) | ||
|
||
|
||
def _plot(filename, resolutions): | ||
""" | ||
Plot section of the merry-go-round TODO | ||
Parameters | ||
---------- | ||
filename : str | ||
The output file name | ||
resolutions : list of str | ||
The resolutions of the test case | ||
""" | ||
plt.switch_backend('Agg') | ||
fig = plt.gcf() | ||
dt = [3, 6, 12] | ||
order2 = [0.01, 0.04, 0.16] | ||
fields = ['tracer1'] | ||
|
||
L2 = numpy.zeros((len(resolutions))) | ||
|
||
for k, field in enumerate(fields): | ||
for i, resolution in enumerate(resolutions): | ||
ds = xarray.open_dataset(f'../forward_{resolution}/output.nc') | ||
|
||
areaCell = ds.areaCell.values | ||
final_field = ds[field].isel(Time=1, nVertLevels=0).values | ||
initial_field = ds[field].isel(Time=0, nVertLevels=0).values | ||
|
||
diff = abs(final_field - initial_field) | ||
multDen = (initial_field**2)*areaCell | ||
multNum = (diff**2)*areaCell | ||
denL2 = numpy.sum(multDen)/numpy.sum(areaCell) | ||
numL2 = numpy.sum(multNum)/numpy.sum(areaCell) | ||
|
||
L2[i] = numpy.sqrt(numL2)/numpy.sqrt(denL2) | ||
|
||
print(f'Order of convergence from dt 6 min to 3 min: ', | ||
f'{math.log2(L2[0]/L2[1])}') | ||
print(f'Order of convergence from dt 12 min to 6 min: ', | ||
f'{math.log2(L2[1]/L2[2])}') | ||
|
||
plt.loglog(dt, L2[:], '-x', label=f'Simulated {field}') | ||
|
||
plt.loglog(dt, order2, 'k', label='Order 2 convergence') | ||
plt.title('Convergence to the exact solution') | ||
plt.ylabel('l_2 error norm') | ||
plt.legend() | ||
plt.grid() | ||
plt.xticks(dt, dt) | ||
plt.xlabel('time step (min)') | ||
|
||
plt.savefig(filename) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from compass.testcase import TestCase | ||
from compass.ocean.tests.merry_go_round.initial_state import InitialState | ||
from compass.ocean.tests.merry_go_round.forward import Forward | ||
from compass.ocean.tests.merry_go_round.viz import Viz | ||
from compass.ocean.tests import merry_go_round | ||
from compass.validate import compare_variables | ||
|
||
|
||
class Default(TestCase): | ||
""" | ||
The default test case for the merry-go-round test | ||
""" | ||
|
||
def __init__(self, test_group): | ||
""" | ||
Create the test case | ||
Parameters | ||
---------- | ||
test_group : compass.ocean.tests.merry_go_round.MerryGoRound | ||
The test group that this test case belongs to | ||
""" | ||
super().__init__(test_group=test_group, name='default') | ||
self.resolution = '5m' | ||
self.add_step(InitialState(test_case=self, resolution=self.resolution, | ||
name=f'initial_state_{self.resolution}')) | ||
self.add_step(Forward(test_case=self, resolution=self.resolution, | ||
ntasks=4, openmp_threads=1, | ||
name=f'forward_{self.resolution}')) | ||
self.add_step(Viz(test_case=self, resolution=self.resolution, | ||
name=f'viz_{self.resolution}')) | ||
|
||
def validate(self): | ||
""" | ||
Validate variables against a baseline | ||
""" | ||
compare_variables(test_case=self, | ||
variables=['normalVelocity', 'tracer1'], | ||
filename1=f'forward_{self.resolution}/output.nc') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
from compass.model import run_model | ||
from compass.step import Step | ||
|
||
|
||
class Forward(Step): | ||
""" | ||
A step for performing forward MPAS-Ocean runs as part of merry-go-round | ||
test cases. | ||
Attributes | ||
---------- | ||
resolution : str | ||
The resolution of the test case | ||
""" | ||
def __init__(self, test_case, resolution='5m', name='forward', subdir=None, | ||
ntasks=1, min_tasks=None, openmp_threads=1): | ||
""" | ||
Create a new test case | ||
Parameters | ||
---------- | ||
test_case : compass.TestCase | ||
The test case this step belongs to | ||
resolution : str | ||
The resolution of the test case | ||
name : str | ||
the name of the test case | ||
subdir : str, optional | ||
the subdirectory for the step. The default is ``name`` | ||
ntasks : int, optional | ||
the number of tasks the step would ideally use. If fewer tasks | ||
are available on the system, the step will run on all available | ||
tasks as long as this is not below ``min_tasks`` | ||
min_tasks : int, optional | ||
the number of tasks the step requires. If the system has fewer | ||
than this number of tasks, the step will fail | ||
openmp_threads : int, optional | ||
the number of OpenMP threads the step will use | ||
""" | ||
self.resolution = resolution | ||
if min_tasks is None: | ||
min_tasks = ntasks | ||
|
||
run_params = {'5m': {'config_dt': '00:12:00'}, | ||
'2.5m': {'config_dt': '00:06:00'}, | ||
'1.25m': {'config_dt': '00:03:00'}} | ||
|
||
super().__init__(test_case=test_case, name=name, subdir=subdir, | ||
ntasks=ntasks, min_tasks=min_tasks, | ||
openmp_threads=openmp_threads) | ||
self.add_namelist_file('compass.ocean.tests.merry_go_round', | ||
'namelist.forward') | ||
self.add_namelist_options(options=run_params[self.resolution]) | ||
|
||
self.add_streams_file('compass.ocean.tests.merry_go_round', | ||
'streams.forward') | ||
|
||
self.add_input_file(filename='init.nc', | ||
target=f'../initial_state_{resolution}/init.nc') | ||
self.add_input_file(filename='graph.info', | ||
target=f'../initial_state_{resolution}/' | ||
'culled_graph.info') | ||
|
||
self.add_model_as_input() | ||
|
||
self.add_output_file(filename='output.nc') | ||
|
||
# no setup() is needed | ||
|
||
def run(self): | ||
""" | ||
Run this step of the test case | ||
""" | ||
run_model(self) |
Oops, something went wrong.