diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6572ca9..49648f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: fail-fast: false matrix: #python-version: [3.7, 3.8, 3.9] - python-version: [3.9] + python-version: [3.10] steps: - name: Cancel previous runs @@ -46,10 +46,6 @@ jobs: run: | conda env list conda list - - name: Download test data - run: | - curl -o xwmt_test_data.nc ftp://ftp.gfdl.noaa.gov/perm/John.Krasting/xwmt/xwmt_test_data.20220810.nc - curl -o xwmt_test_3d_data_baltic_3d.nc ftp://ftp.gfdl.noaa.gov/perm/John.Krasting/xwmt/xwmt_test_data_baltic_3d.20221012.nc - name: Test with pytest run: | pytest diff --git a/xwmt/tests/conftest.py b/xwmt/tests/conftest.py new file mode 100644 index 0000000..b9fd78a --- /dev/null +++ b/xwmt/tests/conftest.py @@ -0,0 +1,187 @@ +import pytest +import os +import numpy as np +import xarray as xr +import xgcm +import xwmt +import urllib.request + +fname = 'xwmb_test_data_Baltic_3d.20230830.nc' +ftp_path = 'ftp://ftp.gfdl.noaa.gov/perm/John.Krasting/xwmt/' +if not os.path.isfile(fname): + print(f'Downloading test dataset from {ftp_path}{fname}') + urllib.request.urlretrieve(f'{ftp_path}{fname}', fname) + +class Helpers: + + def __init__(self): + pass + + def idealized_transformations(self, extensive_tendency, lam_profile, Nz=1e3, Nlam=8): + bins = np.linspace(0., 1., int(Nlam)+1) + + ds = xr.Dataset() + ds = ds.assign_coords({ + 'z_i': xr.DataArray(np.linspace(0., 1., int(Nz)+1), dims=("z_i",)), + 'z_l': xr.DataArray(np.linspace(1. /Nz, 1. - 1. /Nz, int(Nz)), dims=("z_l",)), + }) + ds = ds.assign_coords({'dz': xr.DataArray(np.diff(ds.z_i.values), dims=("z_l",))}) + extensive_tendency_method = getattr(self, extensive_tendency) + ds['tendency_name'] = xr.DataArray(extensive_tendency_method(ds.z_i.values), coords=(ds.z_l,))*ds.dz + lam_profile_method = getattr(self, lam_profile) + ds['temperature'] = xr.DataArray(lam_profile_method(ds.z_l.values), coords=(ds.z_l,)) + + # expand to horizontal dimension and add grid metrics + ds = ds.expand_dims(dim=('x', 'y')).assign_coords({'x':xr.DataArray([1.], dims=('x',)), 'y':xr.DataArray([1.], dims=('y',))}) + ds = ds.assign_coords({'rA': xr.DataArray([[1.]], dims=('x','y',))}) + + metrics = { + ('X', 'Y'): ['rA'] # Areas + } + coords = { + 'X': {'center': 'x',}, + 'Y': {'center': 'y',}, + 'Z': {'center': 'z_l', 'outer': 'z_i'}, + } + grid = xgcm.Grid(ds, coords=coords, metrics=metrics, periodic=False, autoparse_metadata=False) + + budget_dict = { + 'mass': { + 'lambda': None, + 'rhs': {}, + 'lhs': {} + }, + 'heat': { + 'lambda': 'temperature', + 'lhs': {'tendency':'tendency_name'}, + 'rhs': {} + }, + 'salt': { + 'lambda': None, + 'rhs': {}, + 'lhs': {} + } + } + + wmt = xwmt.WaterMassTransformations(grid, budget_dict, cp=1., rho_ref=1., method="xgcm") + T = wmt.integrate_transformations("heat", bins=bins, sum_components=False) + T = T.assign_coords({'temperature_i': xr.DataArray(bins, dims=("temperature_i",))}) + return T + + def mean_absolute_relative_errors(self, wmt_xwmt, wmt_local_exact, wmt_layer_exact): + def absolute_relative_errors(wmt, wmt_ref): + return np.abs((wmt - wmt_ref)/wmt_ref).where(np.abs(wmt_ref)>1.e-5).mean(skipna=True).values + wmt_local_exact_method = getattr(self, wmt_local_exact) + wmt_layer_exact_method = getattr(self, wmt_layer_exact) + return ( + absolute_relative_errors( + wmt_xwmt['tendency'], + wmt_layer_exact_method(wmt_xwmt.temperature_i.values) + ), + absolute_relative_errors( + wmt_xwmt['tendency'], + wmt_local_exact_method(wmt_xwmt.temperature.values) + ) + ) + + # Extensive (layer-integrated) analytical tendency profiles + def diffusive_extensive_tendency(self, z_i): + def f(z): + return -np.cos(2*np.pi*z)/(2*np.pi) + return np.diff(f(z_i))/np.diff(z_i) + + def constant_extensive_tendency(self, z_i): + return np.diff(z_i)/np.diff(z_i) + + def constant_plus_diffusion_tendency(self, z_i): + return self.diffusive_extensive_tendency(z_i) + self.constant_extensive_tendency(z_i) + + def differential_heating_layer(self, z_i): + sign = 2*np.float64(z_i>0.5)-1 + out = np.diff(sign*z_i)/np.diff(z_i) + out[(z_i[:-1]<=0.5)&(0.5<=z_i[1:])] = 0. + return out + + # Stratification profiles + def lam_const_dlamdz(self, z): + return z + + def lam_linear_dlamdz(self, z): + return z**2 + + def lam_overturning_dlamdz(self, z): + return 1 - (2*z - 1)**2 + + def lam_vanishing_dlamdz(self, z): + sign = 2*np.float64(z>0.5)-1 + return (1 + sign*(2*z - 1)**2)/2. + + # Analytical point-wise water mass transformations + def constant_plus_diffusion_local_wmt_dlamdz_constant(self, lam): + return np.sin(2*np.pi*lam) + 1. + + def constant_plus_diffusion_local_wmt_dlamdz_linear(self, lam): + return (np.sin(2*np.pi*np.sqrt(lam)) + 1.)/(2*np.sqrt(lam)) + + def constant_plus_diffusion_local_wmt_dlamdz_overturning(self, lam): + return 1/(2*np.sqrt(1-lam)) + + def differential_heating_local_wmt_dlamdz_vanishing(self, lam): + sign = 2*np.float64(lam>0.5)-1 + return sign/(2*np.sqrt(sign*(2*lam-1))) + + # Analytical layer-averaged water mass transformations + def constant_plus_diffusion_layer_wmt_dlamdz_constant(self, lam_bins): + def f(lam): + return -np.cos(2*np.pi*lam)/(2*np.pi) + lam + return np.diff(f(lam_bins))/np.diff(lam_bins) + + def constant_plus_diffusion_layer_wmt_dlamdz_linear(self, lam_bins): + def f(lam): + return -np.cos(2*np.pi*np.sqrt(lam))/(2*np.pi) + np.sqrt(lam) + return np.diff(f(lam_bins))/np.diff(lam_bins) + + def constant_plus_diffusion_layer_wmt_dlamdz_overturning(self, lam_bins): + def f(lam): + return 1 - np.sqrt(1 - lam) + return np.diff(f(lam_bins))/np.diff(lam_bins) + + def differential_heating_layer_wmt_dlamdz_vanishing(self, lam_bins): + def f(lam): + sign = 2*np.float64(lam>0.5)-1 + u = 1 + sign*np.sqrt(sign*(2*lam-1)) + return sign*0.5*u + out = np.diff(f(lam_bins))/np.diff(lam_bins) + out[(lam_bins[:-1]<=0.5)&(0.5<=lam_bins[1:])] = np.nan + return out + + exps = { + "extensive_tendency": [ + "constant_plus_diffusion_tendency", + "constant_plus_diffusion_tendency", + "constant_plus_diffusion_tendency", + "differential_heating_layer" + ], + "lam_profile": [ + "lam_const_dlamdz", + "lam_linear_dlamdz", + "lam_overturning_dlamdz", + "lam_vanishing_dlamdz" + ], + "local_wmt": [ + "constant_plus_diffusion_local_wmt_dlamdz_constant", + "constant_plus_diffusion_local_wmt_dlamdz_linear", + "constant_plus_diffusion_local_wmt_dlamdz_overturning", + "differential_heating_local_wmt_dlamdz_vanishing" + ], + "layer_wmt":[ + "constant_plus_diffusion_layer_wmt_dlamdz_constant", + "constant_plus_diffusion_layer_wmt_dlamdz_linear", + "constant_plus_diffusion_layer_wmt_dlamdz_overturning", + "differential_heating_layer_wmt_dlamdz_vanishing" + ] + } + +@pytest.fixture +def helpers(): + return Helpers() diff --git a/xwmt/tests/test_convergence_to_analytical.py b/xwmt/tests/test_convergence_to_analytical.py index 32f1059..9b696a2 100644 --- a/xwmt/tests/test_convergence_to_analytical.py +++ b/xwmt/tests/test_convergence_to_analytical.py @@ -1,187 +1,37 @@ import pytest import numpy as np -import xarray as xr -import xwmt -import xgcm -def test_analytical_errors(rtol=1.e-5): +def test_analytical_errors(helpers): passing = [] - for (lam, tend, loc, lay) in zip(exps['lam_profile'], exps['extensive_tendency'], exps['local_wmt'], exps['layer_wmt']): + for (lam, tend, loc, lay) in zip( + helpers.exps['lam_profile'], + helpers.exps['extensive_tendency'], + helpers.exps['local_wmt'], + helpers.exps['layer_wmt'] + ): # pick discretizations with no shared multiples so levels do not coincide - wmt = idealized_transformations(tend, lam, Nz=5**9, Nlam=2**10) - err = mean_absolute_relative_errors(wmt, loc, lay)[0] - passing.append(err < rtol) + wmt = helpers.idealized_transformations(tend, lam, Nz=5**9, Nlam=2**10) + err = helpers.mean_absolute_relative_errors(wmt, loc, lay)[0] + passing.append(err < 1.e-5) assert np.all(passing) -def test_analytical_error_convergence(): +def test_analytical_error_convergence(helpers): passing = [] - for (lam, tend, loc, lay) in zip(exps['lam_profile'], exps['extensive_tendency'], exps['local_wmt'], exps['layer_wmt']): - wmt_lo = idealized_transformations(tend, lam, Nz=5**6, Nlam=2**4) - wmt_hi_z = idealized_transformations(tend, lam, Nz=5**9, Nlam=2**4) - wmt_hi_lam = idealized_transformations(tend, lam, Nz=5**6, Nlam=2**8) - err_lo = mean_absolute_relative_errors(wmt_lo, loc, lay) - err_hi_z = mean_absolute_relative_errors(wmt_hi_z, loc, lay) - err_hi_lam = mean_absolute_relative_errors(wmt_hi_lam, loc, lay) + for (lam, tend, loc, lay) in zip( + helpers.exps['lam_profile'], + helpers.exps['extensive_tendency'], + helpers.exps['local_wmt'], + helpers.exps['layer_wmt'] + ): + wmt_lo = helpers.idealized_transformations(tend, lam, Nz=5**6, Nlam=2**4) + wmt_hi_z = helpers.idealized_transformations(tend, lam, Nz=5**9, Nlam=2**4) + wmt_hi_lam = helpers.idealized_transformations(tend, lam, Nz=5**6, Nlam=2**8) + err_lo = helpers.mean_absolute_relative_errors(wmt_lo, loc, lay) + err_hi_z = helpers.mean_absolute_relative_errors(wmt_hi_z, loc, lay) + err_hi_lam = helpers.mean_absolute_relative_errors(wmt_hi_lam, loc, lay) passing.append( (err_hi_z[0] < err_lo[0]) and (err_hi_z[1] < err_lo[1]) and (err_hi_lam[1] < err_lo[1]) ) assert np.all(passing) - -def idealized_transformations(extensive_tendency, lam_profile, Nz=1e3, Nlam=8): - bins = np.linspace(0., 1., int(Nlam)+1) - - ds = xr.Dataset() - ds = ds.assign_coords({ - 'z_i': xr.DataArray(np.linspace(0., 1., int(Nz)+1), dims=("z_i",)), - 'z_l': xr.DataArray(np.linspace(1. /Nz, 1. - 1. /Nz, int(Nz)), dims=("z_l",)), - }) - ds = ds.assign_coords({'dz': xr.DataArray(np.diff(ds.z_i.values), dims=("z_l",))}) - ds['tendency_name'] = xr.DataArray(extensive_tendency(ds.z_i.values), coords=(ds.z_l,))*ds.dz - ds['temperature'] = xr.DataArray(lam_profile(ds.z_l.values), coords=(ds.z_l,)) - - # expand to horizontal dimension and add grid metrics - ds = ds.expand_dims(dim=('x', 'y')).assign_coords({'x':xr.DataArray([1.], dims=('x',)), 'y':xr.DataArray([1.], dims=('y',))}) - ds = ds.assign_coords({'rA': xr.DataArray([[1.]], dims=('x','y',))}) - - metrics = { - ('X', 'Y'): ['rA'] # Areas - } - coords = { - 'X': {'center': 'x',}, - 'Y': {'center': 'y',}, - 'Z': {'center': 'z_l', 'outer': 'z_i'}, - } - grid = xgcm.Grid(ds, coords=coords, metrics=metrics, periodic=['X', 'Y']) - - budget_dict = { - 'heat': { - 'lambda': 'temperature', - 'lhs': {'tendency':'tendency_name'}, - 'rhs': {} - }, - 'salt': { - 'lambda': None, - 'rhs': {}, - 'lhs': {} - } - } - - wmt = xwmt.WaterMassTransformations(ds, grid, budget_dict, t_name='temperature', cp=1., rho_ref=1.) - T = wmt.integrate_transformations("temperature", bins=bins, sum_components=False) - T = T.assign_coords({'temperature_i': xr.DataArray(bins, dims=("temperature_i",))}) - return T - -def mean_absolute_relative_errors(wmt_xwmt, wmt_local_exact, wmt_layer_exact): - def absolute_relative_errors(wmt, wmt_ref): - return np.abs((wmt - wmt_ref)/wmt_ref).where(np.abs(wmt_ref)>1.e-5).mean(skipna=True).values - return ( - absolute_relative_errors( - wmt_xwmt.tendency_name, - wmt_layer_exact(wmt_xwmt.temperature_i.values) - ), - absolute_relative_errors( - wmt_xwmt.tendency_name, - wmt_local_exact(wmt_xwmt.temperature.values) - ) - ) - -# Extensive (layer-integrated) analytical tendency profiles -def diffusive_extensive_tendency(z_i): - def f(z): - return -np.cos(2*np.pi*z)/(2*np.pi) - return np.diff(f(z_i))/np.diff(z_i) - -def constant_extensive_tendency(z_i): - return np.diff(z_i)/np.diff(z_i) - -def constant_plus_diffusion_tendency(z_i): - return diffusive_extensive_tendency(z_i) + constant_extensive_tendency(z_i) - -def differential_heating_layer(z_i): - sign = 2*np.float64(z_i>0.5)-1 - out = np.diff(sign*z_i)/np.diff(z_i) - out[(z_i[:-1]<=0.5)&(0.5<=z_i[1:])] = 0. - return out - -# Stratification profiles -def lam_const_dlamdz(z): - return z - -def lam_linear_dlamdz(z): - return z**2 - -def lam_overturning_dlamdz(z): - return 1 - (2*z - 1)**2 - -def lam_vanishing_dlamdz(z): - sign = 2*np.float64(z>0.5)-1 - return (1 + sign*(2*z - 1)**2)/2. - -# Analytical point-wise water mass transformations -def constant_plus_diffusion_local_wmt_dlamdz_constant(lam): - return np.sin(2*np.pi*lam) + 1. - -def constant_plus_diffusion_local_wmt_dlamdz_linear(lam): - return (np.sin(2*np.pi*np.sqrt(lam)) + 1.)/(2*np.sqrt(lam)) - -def constant_plus_diffusion_local_wmt_dlamdz_overturning(lam): - return 1/(2*np.sqrt(1-lam)) - - -def differential_heating_local_wmt_dlamdz_vanishing(lam): - sign = 2*np.float64(lam>0.5)-1 - return sign/(2*np.sqrt(sign*(2*lam-1))) - -# Analytical layer-averaged water mass transformations -def constant_plus_diffusion_layer_wmt_dlamdz_constant(lam_bins): - def f(lam): - return -np.cos(2*np.pi*lam)/(2*np.pi) + lam - return np.diff(f(lam_bins))/np.diff(lam_bins) - -def constant_plus_diffusion_layer_wmt_dlamdz_linear(lam_bins): - def f(lam): - return -np.cos(2*np.pi*np.sqrt(lam))/(2*np.pi) + np.sqrt(lam) - return np.diff(f(lam_bins))/np.diff(lam_bins) - -def constant_plus_diffusion_layer_wmt_dlamdz_overturning(lam_bins): - def f(lam): - return 1 - np.sqrt(1 - lam) - return np.diff(f(lam_bins))/np.diff(lam_bins) - -def differential_heating_layer_wmt_dlamdz_vanishing(lam_bins): - def f(lam): - sign = 2*np.float64(lam>0.5)-1 - u = 1 + sign*np.sqrt(sign*(2*lam-1)) - return sign*0.5*u - out = np.diff(f(lam_bins))/np.diff(lam_bins) - out[(lam_bins[:-1]<=0.5)&(0.5<=lam_bins[1:])] = np.nan - return out - -exps = { - "extensive_tendency": [ - constant_plus_diffusion_tendency, - constant_plus_diffusion_tendency, - constant_plus_diffusion_tendency, - differential_heating_layer - ], - "lam_profile": [ - lam_const_dlamdz, - lam_linear_dlamdz, - lam_overturning_dlamdz, - lam_vanishing_dlamdz - ], - "local_wmt": [ - constant_plus_diffusion_local_wmt_dlamdz_constant, - constant_plus_diffusion_local_wmt_dlamdz_linear, - constant_plus_diffusion_local_wmt_dlamdz_overturning, - differential_heating_local_wmt_dlamdz_vanishing - ], - "layer_wmt":[ - constant_plus_diffusion_layer_wmt_dlamdz_constant, - constant_plus_diffusion_layer_wmt_dlamdz_linear, - constant_plus_diffusion_layer_wmt_dlamdz_overturning, - differential_heating_layer_wmt_dlamdz_vanishing - ] -} \ No newline at end of file diff --git a/xwmt/tests/test_functional.py b/xwmt/tests/test_functional.py deleted file mode 100644 index d359fad..0000000 --- a/xwmt/tests/test_functional.py +++ /dev/null @@ -1,49 +0,0 @@ -import pytest -import numpy as np -import xarray as xr -import xwmt - -ds = xr.open_dataset("xwmt_test_data.nc", use_cftime=True) -ds = ds.rename({"xh": "x", "yh": "y", "geolat": "lat", "geolon": "lon"}) - -## Default settings -# sigma -def test_functional_sigma0_default(): - total = xwmt.swmt(ds).G("sigma0") - assert np.allclose(total.sum(), -2.1251855e09) - -def test_functional_sigma1_default(): - total = xwmt.swmt(ds).G("sigma1") - assert np.allclose(total.sum(), -1.8154245e09) - -def test_functional_sigma2_default(): - total = xwmt.swmt(ds).G("sigma2") - assert np.allclose(total.sum(), -1.5430248e09) - -def test_functional_sigma3_default(): - total = xwmt.swmt(ds).G("sigma3") - assert np.allclose(total.sum(), -1.32300659e09) - -def test_functional_sigma4_default(): - total = xwmt.swmt(ds).G("sigma4") - assert np.allclose(total.sum(), -1.20211688e09) - -# heat -def test_functional_theta_default(): - total = xwmt.swmt(ds).G("theta") - assert np.allclose(total.sum(), -1.65192249e09) -# salt -def test_functional_salt_default(): - total = xwmt.swmt(ds).G("salt") - assert np.allclose(total.sum(), -3.01411116e08) - -## Tendencies not grouped -def test_functional_sigma0_notgrouped(): - total = xwmt.swmt(ds).G("sigma0",group_tend=False) - assert np.allclose(total["heat"].sum(), -2.8727879e09) - assert np.allclose(total["salt"].sum(), 7.47602401e08) - -## xgcm -def test_functional_sigma0_xgcm(): - total = xwmt.swmt(ds).G("sigma0",method="xgcm") - assert np.allclose(total.sum(), -2.1251855e09) \ No newline at end of file diff --git a/xwmt/tests/test_functional_3d.py b/xwmt/tests/test_functional_3d.py deleted file mode 100644 index 7651188..0000000 --- a/xwmt/tests/test_functional_3d.py +++ /dev/null @@ -1,81 +0,0 @@ -import pytest -import numpy as np -import xarray as xr -import xwmt - -ds = xr.open_dataset("xwmt_test_data_baltic_3d.nc", use_cftime=True) - -## Default settings -# sigma -def test_functional_3d_sigma0_default(): - total = xwmt.wmt(ds).G("sigma0") - assert np.allclose( - np.sum([total[process].sum().values for process in total.keys()]), - 2223515.7150945747, - ) - - -def test_functional_3d_sigma1_default(): - total = xwmt.wmt(ds).G("sigma1") - assert np.allclose( - np.sum([total[process].sum().values for process in total.keys()]), - 2365488.868501793, - ) - - -def test_functional_3d_sigma2_default(): - total = xwmt.wmt(ds).G("sigma2") - assert np.allclose( - np.sum([total[process].sum().values for process in total.keys()]), - 2451837.2042288743, - ) - - -def test_functional_3d_sigma3_default(): - total = xwmt.wmt(ds).G("sigma3") - assert np.allclose( - np.sum([total[process].sum().values for process in total.keys()]), - 2495522.8387764315, - ) - - -def test_functional_3d_sigma4_default(): - total = xwmt.wmt(ds).G("sigma4") - assert np.allclose( - np.sum([total[process].sum().values for process in total.keys()]), - 2573444.982510467, - ) - - -# heat -def test_functional_3d_theta_default(): - total = xwmt.wmt(ds).G("theta") - assert np.allclose( - np.sum([total[process].sum().values for process in total.keys()]), - -342891148.09930146, - ) - - -# salt -def test_functional_3d_salt_default(): - total = xwmt.wmt(ds).G("salt") - assert np.allclose( - np.sum([total[process].sum().values for process in total.keys()]), - -285494.1529950457, - ) - - -## Tendencies not grouped -def test_functional_3d_sigma0_grouped(): - total = xwmt.wmt(ds).G("sigma0", group_tend=True, group_process=True) - assert np.allclose(total["forcing"].sum(), 1713222.37017132) - assert np.allclose(total["diffusion"].sum(), 510293.34492326) - - -## xgcm -def test_functional_3d_sigma0_xgcm(): - total = xwmt.wmt(ds).G("sigma0", method="xgcm") - assert np.allclose( - np.sum([total[process].sum().values for process in total.keys()]), - 2228638.8884341754, - ) diff --git a/xwmt/tests/test_integrate_transformations.py b/xwmt/tests/test_integrate_transformations.py new file mode 100644 index 0000000..ab1c854 --- /dev/null +++ b/xwmt/tests/test_integrate_transformations.py @@ -0,0 +1,81 @@ +import pytest +import numpy as np +import xarray as xr +import xbudget +import xgcm +import xwmt + +ds = xr.open_dataset("xwmb_test_data_Baltic_3d.20230830.nc", use_cftime=True).isel(time=0) +budgets_dict = xbudget.load_preset_budget(model="MOM6") +xbudget.collect_budgets(ds, budgets_dict) +simple_budgets = xbudget.aggregate(budgets_dict) +coords = { + 'X': {'center': 'xh', 'outer': 'xq'}, + 'Y': {'center': 'yh', 'outer': 'yq'}, + 'Z': {'center': 'zl', 'outer': 'zi'}, +} +metrics = { + ('X','Y'): "areacello", +} +grid = xgcm.Grid(ds, coords=coords, metrics=metrics, periodic=None, autoparse_metadata=False) +wmt = xwmt.WaterMassTransformations(grid, simple_budgets, method="xgcm") + +## Default parameters except: wide bin range to cover all cases and group processes +kwargs = {'bins': np.arange(-10, 100, 1.), 'group_processes': True} + +# heat +def test_functional_3d_theta_default(): + total_wmt = wmt.integrate_transformations("heat", **kwargs)['process_material_derivative'] + assert np.isclose( + total_wmt.sum().values, + -7156040943.980093, + ) + + +# salt +def test_functional_3d_salt_default(): + total_wmt = wmt.integrate_transformations("salt", **kwargs)['process_material_derivative'] + assert np.isclose( + total_wmt.sum().values, + 78005966.15053421, + ) + +# sigma +def test_functional_3d_sigma0_default(): + total_wmt = wmt.integrate_transformations("sigma0", **kwargs)['process_material_derivative'] + assert np.isclose( + total_wmt.sum().values, + 550052085.4891472, + ) + + +def test_functional_3d_sigma1_default(): + total_wmt = wmt.integrate_transformations("sigma1", **kwargs)['process_material_derivative'] + assert np.isclose( + total_wmt.sum().values, + 550052085.4891474, + ) + + +def test_functional_3d_sigma2_default(): + total_wmt = wmt.integrate_transformations("sigma2", **kwargs)['process_material_derivative'] + assert np.isclose( + total_wmt.sum().values, + 550065820.7692934, + ) + + +def test_functional_3d_sigma3_default(): + total_wmt = wmt.integrate_transformations("sigma3", **kwargs)['process_material_derivative'] + assert np.isclose( + total_wmt.sum().values, + 550052085.4891478, + ) + + +def test_functional_3d_sigma4_default(): + total_wmt = wmt.integrate_transformations("sigma4", **kwargs)['process_material_derivative'] + assert np.isclose( + total_wmt.sum().values, + 550052085.489147, + )