From a977ae79104540900fecd3844c9b22b5c8312c0e Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 3 Oct 2024 11:53:05 +0200 Subject: [PATCH 01/76] freezing this version as the base comparison for the refactoring of the code --- inputs/rising_bubble.py | 2 -- pyproject.toml | 2 +- src/dycore/physics/low_mach/laplacian.py | 2 +- src/dycore/utils/variable.py | 2 ++ src/utils/user_data.py | 14 +++++++------- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/inputs/rising_bubble.py b/inputs/rising_bubble.py index 8c94527a..748a5b1b 100644 --- a/inputs/rising_bubble.py +++ b/inputs/rising_bubble.py @@ -20,8 +20,6 @@ def __init__(self): self.iny = 80+1 self.inz = 1 - - self.tout = np.arange(0.0,1.01,0.01)[10:] self.stepmax = 10000 diff --git a/pyproject.toml b/pyproject.toml index a29c2eaf..018fa24c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "pyBELLA" version = "0.50.1" dependencies = [ - "dask==2022.7.0", + "dask==2023.6.0", "dill==0.3.6", "h5py==3.7.0", "matplotlib==3.5.1", diff --git a/src/dycore/physics/low_mach/laplacian.py b/src/dycore/physics/low_mach/laplacian.py index c41f5d48..4399569d 100644 --- a/src/dycore/physics/low_mach/laplacian.py +++ b/src/dycore/physics/low_mach/laplacian.py @@ -543,7 +543,7 @@ def lap2D_numba_test(p, dp, dx, dy, coeffs, diag_inv, coriolis, shp): return p.ravel() -@nb.njit(cache=True) +@nb.njit(nopython=True, cache=True) def lap2D_gather_new(p, iicxn, iicyn, coeffs, dx, dy, y_rayleigh, x_wall, y_wall, diag_inv, coriolis): ngnc = (iicxn) * (iicyn) lap = np.zeros((ngnc)) diff --git a/src/dycore/utils/variable.py b/src/dycore/utils/variable.py index 52e5dc93..4e00c176 100644 --- a/src/dycore/utils/variable.py +++ b/src/dycore/utils/variable.py @@ -159,6 +159,8 @@ def __init__(self,size,ud): self.get_dSdy = self.get_dSdy self.get_S0c = self.get_S0c + + def get_dSdy(self, elem, node): if hasattr(self, 'dSdy'): return self.dSdy diff --git a/src/utils/user_data.py b/src/utils/user_data.py index 0455214c..b03f735a 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -19,11 +19,7 @@ def __init__(self,**kwargs): for key, value in vars(gconsts).items(): setattr(self, key, value) - if len(kwargs) > 0: - for key, value in kwargs.items(): - setattr(self, key, value) - - else: + # else: ########################################## # SPATIAL GRID ########################################## @@ -129,6 +125,10 @@ def __init__(self,**kwargs): self.output_suffix = "_%i_%i" %(self.inx-1,self.iny-1) + if len(kwargs) > 0: + for key, value in kwargs.items(): + setattr(self, key, value) + def compute_u_ref(self): self.u_ref = self.h_ref / self.t_ref self.compute_Msq() @@ -226,10 +226,10 @@ def T_ref(self, val): if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): self.compute_gravity() - if all(hasattr(self, attr) for attr in ["u_ref, R_gas", "T_ref"]): + if all(hasattr(self, attr) for attr in ["u_ref", "R_gas", "T_ref"]): self.compute_Msq() - if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): + if all(hasattr(self, attr) for attr in ["p_ref", "R_gas", "T_ref"]): self.compute_rho_ref() if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): From f4ac3b40367aa07b90b6958c63bdc4b59299f3e3 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 18 Dec 2024 22:15:35 +0800 Subject: [PATCH 02/76] checkpoint in restructuring and making the package more pythonic in structure there are still a lot of broken imports and references, so the code does not run yet. --- pyproject.toml | 21 +- run_scripts/test_dycore.py | 21 +- src/__main__.py | 213 +++--------------- {inputs => src/blending}/__init__.py | 0 .../blending.py | 11 +- src/data_assimilation/letkf.py | 9 +- src/data_assimilation/prepare.py | 80 +++++++ src/data_assimilation/utils.py | 6 +- src/dycore/discretisation/grid.py | 2 +- src/dycore/discretisation/time_update.py | 37 +-- src/dycore/physics/gas_dynamics/eos.py | 2 +- src/dycore/physics/gas_dynamics/explicit.py | 6 +- src/dycore/physics/gas_dynamics/recovery.py | 3 +- src/dycore/physics/hydrostatics.py | 3 +- src/dycore/physics/low_mach/laplacian.py | 4 +- src/dycore/physics/low_mach/mpv.py | 3 +- .../physics/low_mach/second_projection.py | 11 +- src/dycore/utils/boundary.py | 2 +- src/dycore/utils/variable.py | 2 + src/inputs/__init__.py | 0 {inputs => src/inputs}/rising_bubble.py | 6 +- src/utils/data_structures.py | 42 ++++ src/utils/io.py | 42 +++- src/utils/prepare.py | 109 +++++++++ src/utils/sim_params.py | 7 + src/utils/user_data.py | 5 +- 26 files changed, 387 insertions(+), 260 deletions(-) rename {inputs => src/blending}/__init__.py (100%) rename src/{data_assimilation => blending}/blending.py (99%) create mode 100644 src/data_assimilation/prepare.py create mode 100644 src/inputs/__init__.py rename {inputs => src/inputs}/rising_bubble.py (95%) create mode 100644 src/utils/data_structures.py create mode 100644 src/utils/prepare.py diff --git a/pyproject.toml b/pyproject.toml index 018fa24c..16f6edf8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,15 +3,15 @@ name = "pyBELLA" version = "0.50.1" dependencies = [ - "dask==2023.6.0", - "dill==0.3.6", - "h5py==3.7.0", - "matplotlib==3.5.1", - "numba==0.56.4", - "numpy==1.22.1", - "PyYAML==6.0", - "scipy==1.7.3", - "termcolor==2.4.0" + "dask", + "dill", + "h5py", + "matplotlib", + "numba", + "numpy", + "PyYAML", + "scipy", + "termcolor" ] @@ -23,6 +23,9 @@ build-backend = "setuptools.build_meta" [tool.setuptools] package-dir = {"pybella" = "src"} +[project.scripts] +pybella = "pybella.__main__:main" + # Change Log [tool.towncrier] diff --git a/run_scripts/test_dycore.py b/run_scripts/test_dycore.py index 3460b199..3e3e340f 100644 --- a/run_scripts/test_dycore.py +++ b/run_scripts/test_dycore.py @@ -6,11 +6,20 @@ ["test_travelling_vortex", "test_internal_long_wave", "test_lamb_wave"]) +# def test_single_run(ic): + # run = subprocess.Popen( + # [sys.executable, "src", "-ic", ic, "-N", "1"], + # stdout=subprocess.PIPE, + # stderr=subprocess.PIPE, + # ) + # _, stderr = run.communicate() + # assert run.returncode == 0, stderr.splitlines()[-3:] + def test_single_run(ic): - run = subprocess.Popen( - [sys.executable, "src/__main__.py", "-ic", ic, "-N", "1"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + result = subprocess.run( + ["pybella", "-ic", ic, "-N", "1"], + capture_output=True, + text=True ) - _, stderr = run.communicate() - assert run.returncode == 0, stderr.splitlines()[-3:] \ No newline at end of file + + assert result.returncode == 0, result.stderr.splitlines()[-3:] \ No newline at end of file diff --git a/src/__main__.py b/src/__main__.py index 211adfbc..d3d02f47 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -1,197 +1,33 @@ -import numpy as np - -# dependencies of the atmospheric flow solver -import dycore.discretisation.grid as dis_grid -import dycore.discretisation.time_update as dis_time_update -import dycore.utils.boundary as bdry -import dycore.utils.variable as var -import dycore.physics.low_mach.mpv as lm_var -import dycore.physics.hydrostatics as hydrostatic -import dycore.physics.gas_dynamics.thermodynamic as gd_thermodynamics - -# dependencies of the parallelisation by dask -from dask.distributed import Client, progress - -# dependencies of the data assimilation subpackag -from data_assimilation import etpf as da_etpf -from data_assimilation import blending as da_blending -from data_assimilation import post_processing as da_post_processing -from data_assimilation import letkf as da_letkf -from data_assimilation import params as da_params -from data_assimilation import utils as da_utils - -# input file -import utils.user_data as user_data -import utils.io as io -import utils.sim_params as params - # some diagnostics -import copy import time -import termcolor import logging -# test module -import tests.diagnostics as diag - -debug =params.debug -da_debug = params.da_debug -output_timesteps = False -if debug == True: - output_timesteps = True -label_type = "TIME" -np.set_printoptions(precision = params.print_precision) - -step = 0 -t = 0.0 - -########################################################## -# Initialisation of data containers and helper classes -########################################################## -# get arguments for initial condition and ensemble size -N, UserData, sol_init, restart, ud_rewrite, dap_rewrite, r_params = io.get_args() -if N == 1: - da_debug = False - -initial_data = vars(UserData()) -ud = user_data.UserDataInit(**initial_data) -if ud_rewrite is not None: - ud.update_ud(ud_rewrite) -if hasattr(ud, "rayleigh_bc"): - ud.rayleigh_bc(ud) -if ud.output_timesteps: - output_timesteps = True -ud.coriolis_strength = np.array(ud.coriolis_strength) - -elem, node = dis_grid.grid_init(ud) - -Sol = var.Vars(elem.sc, ud) - -flux = np.empty((3), dtype=object) -flux[0] = var.States(elem.sfx, ud) -if elem.ndim > 1: - flux[1] = var.States(elem.sfy, ud) -if elem.ndim > 2: - flux[2] = var.States(elem.sfz, ud) - -th = gd_thermodynamics.init(ud) -mpv = lm_var.MPV(elem, node, ud) -bld = da_blending.Blend(ud) - -io.init_logger(ud) - - -########################################################## -# Initialise test module -########################################################## -if ud.diag: - diag_comparison = diag.compare_sol(ud.diag_current_run) - -########################################################## -# Initialisation of data assimilation module -########################################################## - -# possible da_types: -# 1) batch_obs for the LETKF with batch observations -# 2) rloc for LETKF with grid-point localisation -# 3) etpf for the ETPF algorithm -dap = da_params.init(N, da_type="rloc") -if dap_rewrite is not None: - dap.update_dap(dap_rewrite) - -# if elem.ndim == 2: -if dap.da_type == "rloc" and N > 1: - rloc = da_letkf.prepare_rloc(ud, elem, node, dap, N) - -logging.info(termcolor.colored("Generating initial ensemble...", "yellow")) -sol_ens = np.zeros((N), dtype=object) - -# Set random seed for reproducibility -np.random.seed(params.random_seed) - -seeds = np.random.randint(10000, size=N) if N > 1 else None -if seeds is not None and restart == False: - logging.info("Seeds used in generating initial ensemble spread = ", seeds) - for n in range(N): - Sol0 = copy.deepcopy(Sol) - mpv0 = copy.deepcopy(mpv) - Sol0 = sol_init(Sol0, mpv0, elem, node, th, ud, seed=seeds[n]) - sol_ens[n] = [Sol0, copy.deepcopy(flux), mpv0, [-np.inf, step]] -elif restart == False: - sol_ens = [[sol_init(Sol, mpv, elem, node, th, ud), flux, mpv, [-np.inf, step]]] -elif restart == True: - hydrostatic.state(mpv, elem, node, th, ud) - ud.old_suffix = np.copy(ud.output_suffix) - ud.old_suffix = "_ensemble=%i%s" % (N, ud.old_suffix) - Sol0, mpv0, touts = io.sim_restart( - r_params[0], r_params[1], elem, node, ud, Sol, mpv, r_params[2] - ) - sol_ens = [[Sol0, flux, mpv0, [-np.inf, step]]] - # ud.tout = touts[1:] - ud.tout = [touts[-1]] - t = touts[0] - - if ud.bdry_type[1].value == "radiation": - ud.tcy, ud.tny = bdry.get_tau_y(ud, elem, node, 0.5) - -ens = da_utils.ensemble(sol_ens) - -########################################################## -# Load data assimilation observations -########################################################## - -# where are my observations? -if N > 1: - obs = dap.load_obs(dap.obs_path) - # obs_mask, no calculations where entries are True - obs_mask = da_utils.sparse_obs_selector(obs, elem, node, ud, dap) - obs_noisy, obs_covar = da_utils.obs_noiser(obs, obs_mask, dap, rloc, elem) - # obs_noisy_interp, obs_mask = sparse_obs_selector(obs_noisy, elem, node, ud, dap) +import numpy as np +import termcolor +# dependencies of the atmospheric flow solver +from .dycore.discretisation import time_update as dis_time_update +from .dycore.utils import boundary as bdry -# add ensemble info to filename -if ud.autogen_fn: - ud.output_suffix = io.fn_gen(ud, dap, N) -# ud.output_suffix = '_ensemble=%i%s' %(N, ud.output_suffix) +# dependencies of the data assimilation subpackag +from .data_assimilation import etpf as da_etpf +from .data_assimilation import post_processing as da_post_processing +from .data_assimilation import letkf as da_letkf +from .data_assimilation import utils as da_utils -# ud.output_suffix = '%s_%s' %(ud.output_suffix, 'nr') +# input file +from .utils.sim_params import debug +from .utils import prepare +from .utils import io as io ########################################################## # Start main looping ########################################################## -if __name__ == "__main__": +def main(): + sim_state = prepare.initialise() - ###################################################### - # Initialise writer class for I/O operations - ###################################################### - writer = io.init(ud, restart) - writer.check_jar() - writer.jar([ud, mpv, elem, node, dap]) - # sys.exit("Let's just dill the stuff and quit!") - - writer.write_attrs() - wrtr = None - if N > 1: - writer.write_da_attrs(dap) - elif output_timesteps == True: - wrtr = writer - for n in range(N): # write initial ensemble - Sol = ens.members(ens)[n][0] - mpv = ens.members(ens)[n][2] - if label_type == "STEP": - label = "ensemble_mem=%i_%.3d" % (n, step) - else: - label = "ensemble_mem=%i_%.3f" % (n, 0.0) - if not restart: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_ic") - - if da_debug: - # writer.jar([obs,obs_noisy,obs_noisy_interp,obs_mask,obs_covar]) - # obs = obs_noisy_interp - writer.jar([obs, obs_noisy, obs_mask, obs_covar]) + writer, step_writer = io.initialise(sim_state) - # initialise dask parallelisation and timer - # client = Client(threads_per_worker=1, n_workers=1) tic = time.time() ###################################################### @@ -200,7 +36,7 @@ tout_old = -np.inf tout_cnt = 0 outer_step = 0 - for tout in ud.tout: + for tout in sim_state.ud.tout: futures = [] # In ensemble case, do blending for each DA window @@ -217,18 +53,17 @@ # Forecast step ###################################################### logging.info("##############################################") - logging.info(termcolor.colored("Next tout = %.3f" % tout, "yellow")) - logging.info(termcolor.colored("Starting forecast...", "green")) + logging.info("Next tout = %.3f" % tout) + logging.info("Starting forecast...") mem_cnt = 0 for mem in ens.members(ens): - # future = client.submit(time_update, *[mem[0],mem[1],mem[2], t, tout, ud, elem, node, mem[3], th, bld, None, False]) # handling of DA window step counter if N > 1: mem[3][0] = 0 if tout_old in dap.da_times else mem[3][0] if N == 1: mem[3][0] = mem[3][1] - logging.info(termcolor.colored("For ensemble member = %i..." % mem_cnt, "yellow")) + logging.info("For ensemble member = %i..." % mem_cnt) future = dis_time_update.do( mem[0], mem[1], @@ -241,7 +76,7 @@ mem[3], th, blend, - wrtr, + step_writer, debug, ) @@ -398,3 +233,7 @@ logging.info(termcolor.colored("Time taken = %.6f" % (toc - tic), "yellow")) writer.close_everything() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/inputs/__init__.py b/src/blending/__init__.py similarity index 100% rename from inputs/__init__.py rename to src/blending/__init__.py diff --git a/src/data_assimilation/blending.py b/src/blending/blending.py similarity index 99% rename from src/data_assimilation/blending.py rename to src/blending/blending.py index 51f540ff..289abf9f 100644 --- a/src/data_assimilation/blending.py +++ b/src/blending/blending.py @@ -1,12 +1,11 @@ -import numpy as np -from scipy import signal - -import dycore.physics.gas_dynamics.eos as gd_eos - import logging -import termcolor import copy +import termcolor +import numpy as np +from scipy import signal + +from ..dycore.physics.gas_dynamics import eos as gd_eos class Blend(object): """ diff --git a/src/data_assimilation/letkf.py b/src/data_assimilation/letkf.py index 7db1063e..09fbfcee 100644 --- a/src/data_assimilation/letkf.py +++ b/src/data_assimilation/letkf.py @@ -1,3 +1,5 @@ +import logging + import numpy as np import numpy.lib.stride_tricks as st @@ -8,10 +10,9 @@ import dask import matplotlib.pyplot as plt -import logging -import dycore.utils.options as opts -import data_assimilation as da +from ..dycore.utils import options as opts +from . import utils debug_cnt = 0 @@ -244,7 +245,7 @@ def __init__(self, ud, elem, node, dap, N, obs_X=5, obs_Y=5): self.pad_Y = int((self.obs_Y - 1) / 2) # get mask to handle BC. Periodic mask includes ghost cells/nodes and wall masks takes only the inner domain. - self.cmask, self.nmask = da.utils.boundary_mask(ud, elem, node, self.pad_X, self.pad_Y) + self.cmask, self.nmask = utils.boundary_mask(ud, elem, node, self.pad_X, self.pad_Y) # get from da parameters the localisation matrix and inflation factor self.inf_fac = dap.inflation_factor diff --git a/src/data_assimilation/prepare.py b/src/data_assimilation/prepare.py new file mode 100644 index 00000000..4ea199f2 --- /dev/null +++ b/src/data_assimilation/prepare.py @@ -0,0 +1,80 @@ + +import numpy as np + +from ..utils.sim_params import params + +import params as da_params +import letkf as da_letkf + +import logging +# to generate ensemble from one sol init instantiation +from copy import deepcopy + + +def initialise(sst): + ########################################################## + # Initialisation of data assimilation module + ########################################################## + + # possible da_types: + # 1) batch_obs for the LETKF with batch observations + # 2) rloc for LETKF with grid-point localisation + # 3) etpf for the ETPF algorithm + dap = da_params.init(sst.N, da_type="rloc") + if sst.dap_rewrite is not None: + dap.update_dap(sst.dap_rewrite) + + # if elem.ndim == 2: + if dap.da_type == "rloc" and sst.N > 1: + rloc = da_letkf.prepare_rloc(sst.ud, sst.elem, sst.node, dap, sst.N) + + logging.info("Generating initial ensemble...") + sol_ens = np.zeros((sst.N), dtype=object) + + # Set random seed for reproducibility + np.random.seed(params.random_seed) + + seeds = np.random.randint(10000, size=sst.N) if sst.N > 1 else None + if seeds is not None and sst.restart == False: + logging.info("Seeds used in generating initial ensemble spread = ", seeds) + for n in range(sst.N): + Sol0 = deepcopy(sst.Sol) + mpv0 = deepcopy(sst.mpv) + Sol0 = sol_init(Sol0, mpv0, elem, node, th, ud, seed=seeds[n]) + sol_ens[n] = [Sol0, deepcopy(flux), mpv0, [-np.inf, step]] + elif restart == False: + sol_ens = [[sol_init(Sol, mpv, elem, node, th, ud), flux, mpv, [-np.inf, step]]] + elif restart == True: + hydrostatic.state(mpv, elem, node, th, ud) + ud.old_suffix = np.copy(ud.output_suffix) + ud.old_suffix = "_ensemble=%i%s" % (N, ud.old_suffix) + Sol0, mpv0, touts = io.sim_restart( + r_params[0], r_params[1], elem, node, ud, Sol, mpv, r_params[2] + ) + sol_ens = [[Sol0, flux, mpv0, [-np.inf, step]]] + # ud.tout = touts[1:] + ud.tout = [touts[-1]] + t = touts[0] + + if ud.bdry_type[1].value == "radiation": + ud.tcy, ud.tny = bdry.get_tau_y(ud, elem, node, 0.5) + + ens = da_utils.ensemble(sol_ens) + + ########################################################## + # Load data assimilation observations + ########################################################## + + # where are my observations? + if N > 1: + obs = dap.load_obs(dap.obs_path) + # obs_mask, no calculations where entries are True + obs_mask = da_utils.sparse_obs_selector(obs, elem, node, ud, dap) + obs_noisy, obs_covar = da_utils.obs_noiser(obs, obs_mask, dap, rloc, elem) + + + ########################################################## + # Add ensemble info into filename + ########################################################## + if ud.autogen_fn: + ud.output_suffix = io.fn_gen(ud, dap, N) diff --git a/src/data_assimilation/utils.py b/src/data_assimilation/utils.py index f5b04596..57ff5b7d 100644 --- a/src/data_assimilation/utils.py +++ b/src/data_assimilation/utils.py @@ -1,11 +1,11 @@ +import copy + import numpy as np import scipy as sp -import copy import matplotlib.pyplot as plt -import dycore.utils.boundary as bdry -import dycore.utils.options as opts +from ..dycore.utils import options as opts, boundary as bdry class ensemble(object): def __init__(self, input_ensemble=None): diff --git a/src/dycore/discretisation/grid.py b/src/dycore/discretisation/grid.py index 85965bbc..3cac12a4 100644 --- a/src/dycore/discretisation/grid.py +++ b/src/dycore/discretisation/grid.py @@ -1,6 +1,6 @@ import numpy as np -import dycore.utils.options as opts +from ..utils import options as opts def grid_init(ud): """ diff --git a/src/dycore/discretisation/time_update.py b/src/dycore/discretisation/time_update.py index c3432c54..4c1e21cb 100644 --- a/src/dycore/discretisation/time_update.py +++ b/src/dycore/discretisation/time_update.py @@ -1,24 +1,25 @@ -# dependencies of the atmospheric flow solver -import utils.io as io +import copy +import logging -import dycore.utils.boundary as bdry -import dycore.utils.options as opts +import numpy as np +import termcolor -import dycore.physics.gas_dynamics.numerical_flux as gd_flux -import dycore.physics.gas_dynamics.explicit as gd_explicit -import dycore.physics.gas_dynamics.eos as gd_eos -import dycore.physics.gas_dynamics.cfl as gd_cfl +# dependencies of the pyBELLA package +from ...utils import io -import dycore.physics.low_mach.second_projection as lm_sp -import dycore.discretisation.grid as dis_grid +# dependencies of the flow solver subpackage +from ..utils import boundary as bdry, options as opts +from ..physics.gas_dynamics import ( + numerical_flux as gd_flux, + eos as gd_eos, + cfl as gd_cfl +) +from ..physics.gas_dynamics import explicit as gd_explicit +from ..physics.low_mach import second_projection as lm_sp +from . import grid as dis_grid # for blending module -import data_assimilation as da - -import numpy as np -import copy -import termcolor -import logging +from ...blending import blending def data_init(ud): @@ -165,7 +166,7 @@ def do( ###################################################### # Blending : Do blending before timestep ###################################################### - swe_to_lake, Sol, mpv, t = da.blending.blending_before_timestep( + swe_to_lake, Sol, mpv, t = blending.blending_before_timestep( Sol, flux, mpv, @@ -525,7 +526,7 @@ def do( ###################################################### # Blending : Do blending after timestep ###################################################### - Sol, mpv = da.blending.blending_after_timestep( + Sol, mpv = blending.blending_after_timestep( Sol, flux, mpv, diff --git a/src/dycore/physics/gas_dynamics/eos.py b/src/dycore/physics/gas_dynamics/eos.py index 8ee24444..6eda3b35 100644 --- a/src/dycore/physics/gas_dynamics/eos.py +++ b/src/dycore/physics/gas_dynamics/eos.py @@ -1,6 +1,6 @@ import numpy as np -import dycore.utils.boundary as bdry +from ...utils import boundary as bdry def nonhydrostasy(ud,t,step): if step >= 0: diff --git a/src/dycore/physics/gas_dynamics/explicit.py b/src/dycore/physics/gas_dynamics/explicit.py index 283985a6..4efd5323 100644 --- a/src/dycore/physics/gas_dynamics/explicit.py +++ b/src/dycore/physics/gas_dynamics/explicit.py @@ -1,6 +1,6 @@ -import dycore.utils.boundary as bdry -import dycore.physics.gas_dynamics.recovery as gd_recovery -import dycore.physics.gas_dynamics.numerical_flux as gd_flux +from ...utils import boundary as bdry +from . import recovery as gd_recovery +from . import numerical_flux as gd_flux def advect(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None): """ diff --git a/src/dycore/physics/gas_dynamics/recovery.py b/src/dycore/physics/gas_dynamics/recovery.py index 30ee3db3..fe0dc058 100644 --- a/src/dycore/physics/gas_dynamics/recovery.py +++ b/src/dycore/physics/gas_dynamics/recovery.py @@ -1,7 +1,6 @@ import numpy as np -import dycore.utils.options as opts -import dycore.utils.variable as var +from ...utils import options as opts, variable as var def do(Sol, flux, lmbda, ud, th, elem, split_step, tag): """ diff --git a/src/dycore/physics/hydrostatics.py b/src/dycore/physics/hydrostatics.py index 6bc5b538..48fe95d8 100644 --- a/src/dycore/physics/hydrostatics.py +++ b/src/dycore/physics/hydrostatics.py @@ -1,7 +1,8 @@ -import dycore.utils.boundary as bdry import numpy as np import numba as nb +from ..utils import boundary as bdry + def column(HydroState, HydroState_n, Y, Y_n, elem, node, th, ud): Gamma = th.gm1 / th.gamm gamm = th.gamm diff --git a/src/dycore/physics/low_mach/laplacian.py b/src/dycore/physics/low_mach/laplacian.py index 4399569d..4b940ab8 100644 --- a/src/dycore/physics/low_mach/laplacian.py +++ b/src/dycore/physics/low_mach/laplacian.py @@ -2,7 +2,7 @@ import scipy as sp import numba as nb -import dycore.utils.options as opts +from ...utils import options as opts def stencil_9pt(elem,node,mpv,Sol,ud,diag_inv,dt,coriolis_params): igx = elem.igx @@ -543,7 +543,7 @@ def lap2D_numba_test(p, dp, dx, dy, coeffs, diag_inv, coriolis, shp): return p.ravel() -@nb.njit(nopython=True, cache=True) +@nb.njit(cache=True) def lap2D_gather_new(p, iicxn, iicyn, coeffs, dx, dy, y_rayleigh, x_wall, y_wall, diag_inv, coriolis): ngnc = (iicxn) * (iicyn) lap = np.zeros((ngnc)) diff --git a/src/dycore/physics/low_mach/mpv.py b/src/dycore/physics/low_mach/mpv.py index e3d3c069..0803bbe7 100644 --- a/src/dycore/physics/low_mach/mpv.py +++ b/src/dycore/physics/low_mach/mpv.py @@ -1,5 +1,6 @@ import numpy as np -import dycore.utils.variable as var + +from ...utils import variable as var class MPV(object): def __init__(self,elem,node,ud): diff --git a/src/dycore/physics/low_mach/second_projection.py b/src/dycore/physics/low_mach/second_projection.py index 5a87793a..6a7f5958 100644 --- a/src/dycore/physics/low_mach/second_projection.py +++ b/src/dycore/physics/low_mach/second_projection.py @@ -1,12 +1,11 @@ -import numpy as np -import scipy as sp import itertools as it +import logging -import dycore.utils.options as opts -import dycore.utils.boundary as bdry -import dycore.physics.low_mach.laplacian as lm_lp +import numpy as np +import scipy as sp -import logging +from ...utils import options as opts, boundary as bdry +from . import laplacian as lm_lp class solver_counter(object): """ diff --git a/src/dycore/utils/boundary.py b/src/dycore/utils/boundary.py index 9992cddd..7586f59f 100644 --- a/src/dycore/utils/boundary.py +++ b/src/dycore/utils/boundary.py @@ -2,7 +2,7 @@ For more details on this module, refer to the write-up :ref:`boundary_handling`. """ import numpy as np -import dycore.utils.options as opts +from . import options as opts def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): """ diff --git a/src/dycore/utils/variable.py b/src/dycore/utils/variable.py index 4e00c176..4a226735 100644 --- a/src/dycore/utils/variable.py +++ b/src/dycore/utils/variable.py @@ -1,6 +1,8 @@ import numpy as np import scipy as sp + + # equivalent to States_new class Vars(object): """ diff --git a/src/inputs/__init__.py b/src/inputs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/inputs/rising_bubble.py b/src/inputs/rising_bubble.py similarity index 95% rename from inputs/rising_bubble.py rename to src/inputs/rising_bubble.py index 748a5b1b..d33fc28e 100644 --- a/inputs/rising_bubble.py +++ b/src/inputs/rising_bubble.py @@ -1,6 +1,6 @@ import numpy as np -import dycore.physics.hydrostatics as hydrostatic -import dycore.utils.boundary as bdry +from ..dycore.physics import hydrostatics +from ..dycore.utils import boundary as bdry class UserData(object): # Nsq_ref = grav * 1.3e-05 @@ -49,7 +49,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): g = ud.gravity_strength[1] # print(ud.rho_ref) - hydrostatic.state(mpv, elem, node, th, ud) + hydrostatics.state(mpv, elem, node, th, ud) x = elem.x y = elem.y diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py new file mode 100644 index 00000000..4ea417f1 --- /dev/null +++ b/src/utils/data_structures.py @@ -0,0 +1,42 @@ +from typing import Optional, Callable, Any +from dataclasses import dataclass + +@dataclass +class ModelParameters: + elem: Any + node: Any + Sol: Any + flux: Any + mpv: Any + th: Any + bld: Any + +@dataclass +class DataAssimilationParameters: + dap : Any + rloc: Any + sol_ens : Any + + +@dataclass +class RestartParameters: + ud_rewrite: Optional[object] = None + dap_rewrite: Optional[object] = None + r_params: Optional[object] = None + + +@dataclass +class SimulationState: + step: int + t: float + N: int + restart: bool + + ud: object + sol_init: Callable + + model_params: ModelParameters + restart_params: RestartParameters + da_params: Optional[DataAssimilationParameters] = None + + diag_comparison: Optional[object] = None \ No newline at end of file diff --git a/src/utils/io.py b/src/utils/io.py index 0fb2ffe9..2773159c 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -12,10 +12,46 @@ import argparse -import utils.sim_params as params +from . import sim_params as params + + +def initialise(sst): + mp = sst.model_params + dp = sst.da_params + ###################################################### + # Initialise writer class for I/O operations + ###################################################### + writer = hdf5(sst.ud, sst.restart) + writer.check_jar() + writer.jar([mp.ud, mp.mpv, mp.elem, mp.node, dp.dap]) + # sys.exit("Let's just dill the stuff and quit!") + + writer.write_attrs() + wrtr = None + if N > 1: + writer.write_da_attrs(dp.dap) + elif params.output_timesteps == True: + wrtr = writer + for n in range(N): # write initial ensemble + Sol = ens.members(ens)[n][0] + mpv = ens.members(ens)[n][2] + if label_type == "STEP": + label = "ensemble_mem=%i_%.3d" % (n, step) + else: + label = "ensemble_mem=%i_%.3f" % (n, 0.0) + if not restart: + writer.write_all(Sol, mpv, elem, node, th, str(label) + "_ic") + + if params.da_debug: + # writer.jar([obs,obs_noisy,obs_noisy_interp,obs_mask,obs_covar]) + # obs = obs_noisy_interp + writer.jar([obs, obs_noisy, obs_mask, obs_covar]) + + return writer, wrtr + -class init(object): +class hdf5(object): """ HDF5 writer class. Contains methods to create HDF5 file, create data sets and populate them with output variables. @@ -591,7 +627,7 @@ def get_args(): elif ic == "igw_bb": from inputs.igw_baldauf_brdar import UserData, sol_init elif ic == "rb": - from inputs.rising_bubble import UserData, sol_init + from ..inputs.rising_bubble import UserData, sol_init elif ic == "rbc": from inputs.rising_bubble_cold import UserData, sol_init elif ic == "swe_bal_vortex": diff --git a/src/utils/prepare.py b/src/utils/prepare.py new file mode 100644 index 00000000..1dd0b092 --- /dev/null +++ b/src/utils/prepare.py @@ -0,0 +1,109 @@ +import numpy as np + +from . import ( + user_data, + io, + data_structures +) + +from ..dycore.discretisation import grid as dis_grid +from ..dycore.utils import variable as var +from ..dycore.physics.low_mach import mpv as lm_var +from ..dycore.physics.gas_dynamics import thermodynamic as gd_thermodynamics + +from ..blending import blending + +# test module +from ..tests import diagnostics as diag + +def initialise(): + #### + # Initialise simulation state + #### + from . import sim_params as params + + np.set_printoptions(precision = params.print_precision) + + step = 0 + t = 0.0 + + ########################################################## + # Initialisation of data containers and helper classes + ########################################################## + # get arguments for initial condition and ensemble size + N, UserData, sol_init, restart, ud_rewrite, dap_rewrite, r_params = io.get_args() + if N == 1: + params.da_debug = False + + initial_data = vars(UserData()) + ud = user_data.UserDataInit(**initial_data) + if ud_rewrite is not None: + ud.update_ud(ud_rewrite) + if hasattr(ud, "rayleigh_bc"): + ud.rayleigh_bc(ud) + if ud.output_timesteps: + params.output_timesteps = True + ud.coriolis_strength = np.array(ud.coriolis_strength) + + elem, node = dis_grid.grid_init(ud) + + Sol = var.Vars(elem.sc, ud) + + flux = np.empty((3), dtype=object) + flux[0] = var.States(elem.sfx, ud) + if elem.ndim > 1: + flux[1] = var.States(elem.sfy, ud) + if elem.ndim > 2: + flux[2] = var.States(elem.sfz, ud) + + th = gd_thermodynamics.init(ud) + mpv = lm_var.MPV(elem, node, ud) + bld = blending.Blend(ud) + + io.init_logger(ud) + + ########################################################## + # Initialise test module + ########################################################## + if ud.diag: + diag_comparison = diag.compare_sol(ud.diag_current_run) + else: + diag_comparison = None + + + ########################################################## + # Populate data structures + ########################################################## + + model_params = data_structures.ModelParameters( + elem=elem, + node=node, + Sol=Sol, + flux=flux, + mpv=mpv, + th=th, + bld=bld, + ) + + restart_params = data_structures.RestartParameters( + ud_rewrite=ud_rewrite, + dap_rewrite=dap_rewrite, + r_params=r_params, + ) + + sim_st = data_structures.SimulationState( + step=step, + t=t, + N=N, + restart=restart, + + ud=ud, + sol_init=sol_init, + + diag_comparison=diag_comparison, + + model_params=model_params, + restart_params=restart_params + ) + + return sim_st \ No newline at end of file diff --git a/src/utils/sim_params.py b/src/utils/sim_params.py index ae22f7cf..1f8d04bb 100644 --- a/src/utils/sim_params.py +++ b/src/utils/sim_params.py @@ -2,11 +2,18 @@ debug = False da_debug = False +output_timesteps = False +if debug == True: + output_timesteps = True +label_type = "TIME" + random_seed = 888 print_precision = 18 output_path = './outputs' + + # global constants class global_constants(object): def __init__(self): diff --git a/src/utils/user_data.py b/src/utils/user_data.py index b03f735a..279a9a33 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -1,8 +1,7 @@ import numpy as np -import dycore.utils.options as opts -import utils.sim_params as params - +from ..dycore.utils import options as opts +from . import sim_params as params class UserDataInit(object): """ From 5e995b8d8511d50fc4fcdd44b1bdf3ab04c4db37 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 18 Dec 2024 23:05:37 +0800 Subject: [PATCH 03/76] done with restructuring the initialisation and preparation steps in __main__.py still untested as I have to move the analysis steps to the DA subpackage before this will run --- src/__main__.py | 13 +++-- src/data_assimilation/params.py | 8 ++-- src/data_assimilation/prepare.py | 81 ++++++++++++++++++++------------ src/utils/data_structures.py | 10 +++- src/utils/io.py | 20 ++++---- src/utils/prepare.py | 5 ++ src/utils/sim_params.py | 2 - 7 files changed, 87 insertions(+), 52 deletions(-) diff --git a/src/__main__.py b/src/__main__.py index d3d02f47..e0bcf127 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -10,10 +10,13 @@ from .dycore.utils import boundary as bdry # dependencies of the data assimilation subpackag -from .data_assimilation import etpf as da_etpf -from .data_assimilation import post_processing as da_post_processing -from .data_assimilation import letkf as da_letkf -from .data_assimilation import utils as da_utils +from .data_assimilation import ( + prepare as da_prepare, + etpf as da_etpf, + post_processing as da_post_processing, + letkf as da_letkf, + utils as da_utils +) # input file from .utils.sim_params import debug @@ -25,7 +28,7 @@ ########################################################## def main(): sim_state = prepare.initialise() - + da_prepare.initialise(sim_state) writer, step_writer = io.initialise(sim_state) tic = time.time() diff --git a/src/data_assimilation/params.py b/src/data_assimilation/params.py index a9e921bb..cea0086b 100644 --- a/src/data_assimilation/params.py +++ b/src/data_assimilation/params.py @@ -1,10 +1,10 @@ +import logging + +import h5py import numpy as np import scipy as sp -import h5py - -import dycore.utils.boundary as bdry -import logging +from ..dycore.utils import boundary as bdry class init(object): diff --git a/src/data_assimilation/prepare.py b/src/data_assimilation/prepare.py index 4ea199f2..a1dc01c7 100644 --- a/src/data_assimilation/prepare.py +++ b/src/data_assimilation/prepare.py @@ -1,17 +1,23 @@ +import logging +# to generate ensemble from one sol init instantiation +from copy import deepcopy import numpy as np -from ..utils.sim_params import params +from ..dycore.physics import hydrostatics +from ..utils import sim_params as params +from ..utils import io +from ..utils import data_structures -import params as da_params -import letkf as da_letkf - -import logging -# to generate ensemble from one sol init instantiation -from copy import deepcopy +from . import utils as da_utils +from . import params as da_params +from . import letkf as da_letkf def initialise(sst): + mp = sst.model_params + rp = sst.restart_params + ########################################################## # Initialisation of data assimilation module ########################################################## @@ -21,12 +27,14 @@ def initialise(sst): # 2) rloc for LETKF with grid-point localisation # 3) etpf for the ETPF algorithm dap = da_params.init(sst.N, da_type="rloc") - if sst.dap_rewrite is not None: - dap.update_dap(sst.dap_rewrite) + if rp.dap_rewrite is not None: + dap.update_dap(rp.dap_rewrite) # if elem.ndim == 2: if dap.da_type == "rloc" and sst.N > 1: - rloc = da_letkf.prepare_rloc(sst.ud, sst.elem, sst.node, dap, sst.N) + rloc = da_letkf.prepare_rloc(mp.ud, mp.elem, mp.node, dap, sst.N) + else: + rloc = None logging.info("Generating initial ensemble...") sol_ens = np.zeros((sst.N), dtype=object) @@ -40,24 +48,21 @@ def initialise(sst): for n in range(sst.N): Sol0 = deepcopy(sst.Sol) mpv0 = deepcopy(sst.mpv) - Sol0 = sol_init(Sol0, mpv0, elem, node, th, ud, seed=seeds[n]) - sol_ens[n] = [Sol0, deepcopy(flux), mpv0, [-np.inf, step]] - elif restart == False: - sol_ens = [[sol_init(Sol, mpv, elem, node, th, ud), flux, mpv, [-np.inf, step]]] - elif restart == True: - hydrostatic.state(mpv, elem, node, th, ud) - ud.old_suffix = np.copy(ud.output_suffix) - ud.old_suffix = "_ensemble=%i%s" % (N, ud.old_suffix) + Sol0 = sst.sol_init(Sol0, mpv0, mp.elem, mp.node, mp.th, mp.ud, seed=seeds[n]) + sol_ens[n] = [Sol0, deepcopy(mp.flux), mpv0, [-np.inf, sst.step]] + elif sst.restart == False: + sol_ens = [[sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.flux, mp.mpv, [-np.inf, sst.step]]] + elif sst.restart == True: + hydrostatics.state(mp.mpv, mp.elem, mp.node, mp.th, mp.ud) + sst.ud.old_suffix = np.copy(sst.ud.output_suffix) + sst.ud.old_suffix = "_ensemble=%i%s" % (sst.N, sst.ud.old_suffix) Sol0, mpv0, touts = io.sim_restart( - r_params[0], r_params[1], elem, node, ud, Sol, mpv, r_params[2] + rp.r_params[0], rp.r_params[1], mp.elem, mp.node, mp.ud, mp.Sol, mp.mpv, rp.r_params[2] ) - sol_ens = [[Sol0, flux, mpv0, [-np.inf, step]]] + sol_ens = [[Sol0, mp.flux, mpv0, [-np.inf, sst.step]]] # ud.tout = touts[1:] - ud.tout = [touts[-1]] - t = touts[0] - - if ud.bdry_type[1].value == "radiation": - ud.tcy, ud.tny = bdry.get_tau_y(ud, elem, node, 0.5) + sst.ud.tout = [touts[-1]] + sst.t = touts[0] ens = da_utils.ensemble(sol_ens) @@ -66,15 +71,31 @@ def initialise(sst): ########################################################## # where are my observations? - if N > 1: + if sst.N > 1: obs = dap.load_obs(dap.obs_path) # obs_mask, no calculations where entries are True - obs_mask = da_utils.sparse_obs_selector(obs, elem, node, ud, dap) - obs_noisy, obs_covar = da_utils.obs_noiser(obs, obs_mask, dap, rloc, elem) + obs_mask = da_utils.sparse_obs_selector(obs, mp.elem, mp.node, sst.ud, dap) + obs_noisy, obs_covar = da_utils.obs_noiser(obs, obs_mask, dap, rloc, mp.elem) + else: + obs, obs_noisy, obs_mask, obs_covar = None, None, None, None ########################################################## # Add ensemble info into filename ########################################################## - if ud.autogen_fn: - ud.output_suffix = io.fn_gen(ud, dap, N) + if sst.ud.autogen_fn: + sst.ud.output_suffix = io.fn_gen(sst.ud, dap, sst.N) + + ####################### + # Populate DA params + ####################### + + sst.da_params = data_structures.DataAssimilationParameters( + dap=dap, + rloc=rloc, + sol_ens=ens, + obs=obs, + obs_noisy=obs_noisy, + obs_mask=obs_mask, + obs_covar=obs_covar + ) diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index 4ea417f1..731b2256 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -13,10 +13,18 @@ class ModelParameters: @dataclass class DataAssimilationParameters: + # DA user-input parameters dap : Any - rloc: Any + # r-localisation function + rloc : Any + # solution ensemble sol_ens : Any + # observation related attributes + obs : Any + obs_noisy : Any + obs_mask : Any + obs_covar : Any @dataclass class RestartParameters: diff --git a/src/utils/io.py b/src/utils/io.py index 2773159c..2e2339a3 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -23,29 +23,29 @@ def initialise(sst): ###################################################### writer = hdf5(sst.ud, sst.restart) writer.check_jar() - writer.jar([mp.ud, mp.mpv, mp.elem, mp.node, dp.dap]) + writer.jar([sst.ud, mp.mpv, mp.elem, mp.node, dp.dap]) # sys.exit("Let's just dill the stuff and quit!") writer.write_attrs() wrtr = None - if N > 1: + if sst.N > 1: writer.write_da_attrs(dp.dap) elif params.output_timesteps == True: wrtr = writer - for n in range(N): # write initial ensemble - Sol = ens.members(ens)[n][0] - mpv = ens.members(ens)[n][2] - if label_type == "STEP": - label = "ensemble_mem=%i_%.3d" % (n, step) + for n in range(sst.N): # write initial ensemble + Sol = dp.sol_ens.members(dp.sol_ens)[n][0] + mpv = dp.sol_ens.members(dp.sol_ens)[n][2] + if params.label_type == "STEP": + label = "ensemble_mem=%i_%.3d" % (n, sst.step) else: label = "ensemble_mem=%i_%.3f" % (n, 0.0) - if not restart: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_ic") + if not sst.restart: + writer.write_all(Sol, mpv, mp.elem, mp.node, mp.th, str(label) + "_ic") if params.da_debug: # writer.jar([obs,obs_noisy,obs_noisy_interp,obs_mask,obs_covar]) # obs = obs_noisy_interp - writer.jar([obs, obs_noisy, obs_mask, obs_covar]) + writer.jar([dp.obs, dp.obs_noisy, dp.obs_mask, dp.obs_covar]) return writer, wrtr diff --git a/src/utils/prepare.py b/src/utils/prepare.py index 1dd0b092..2d414f3a 100644 --- a/src/utils/prepare.py +++ b/src/utils/prepare.py @@ -8,6 +8,7 @@ from ..dycore.discretisation import grid as dis_grid from ..dycore.utils import variable as var +from ..dycore.utils import boundary as bdry from ..dycore.physics.low_mach import mpv as lm_var from ..dycore.physics.gas_dynamics import thermodynamic as gd_thermodynamics @@ -62,6 +63,10 @@ def initialise(): io.init_logger(ud) + # handle radiative BC + if ud.bdry_type[1].value == "radiation": + ud.tcy, ud.tny = bdry.get_tau_y(ud, elem, node, 0.5) + ########################################################## # Initialise test module ########################################################## diff --git a/src/utils/sim_params.py b/src/utils/sim_params.py index 1f8d04bb..395c2e69 100644 --- a/src/utils/sim_params.py +++ b/src/utils/sim_params.py @@ -12,8 +12,6 @@ output_path = './outputs' - - # global constants class global_constants(object): def __init__(self): From 91008f41c53ac4eebb340dbdc745d412cfa4a122 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 18 Dec 2024 23:30:41 +0800 Subject: [PATCH 04/76] moved blending from main() into its own submodule also created a placeholder for the parallel integrator tests planned --- src/__main__.py | 17 +++++++--------- src/dycore/discretisation/time_update.py | 6 +++--- src/{blending => interfaces}/__init__.py | 0 src/interfaces/dynamics_blending/__init__.py | 0 src/interfaces/dynamics_blending/prepare.py | 20 +++++++++++++++++++ .../dynamics_blending/schemes.py} | 2 +- .../parallel_intergrator/__init__.py | 0 src/utils/data_structures.py | 6 +++++- src/utils/prepare.py | 10 +++++----- 9 files changed, 41 insertions(+), 20 deletions(-) rename src/{blending => interfaces}/__init__.py (100%) create mode 100644 src/interfaces/dynamics_blending/__init__.py create mode 100644 src/interfaces/dynamics_blending/prepare.py rename src/{blending/blending.py => interfaces/dynamics_blending/schemes.py} (99%) create mode 100644 src/interfaces/parallel_intergrator/__init__.py diff --git a/src/__main__.py b/src/__main__.py index e0bcf127..4acb6c5b 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -9,7 +9,10 @@ from .dycore.discretisation import time_update as dis_time_update from .dycore.utils import boundary as bdry -# dependencies of the data assimilation subpackag +# dependencies of the interface subpackage +from .interfaces.dynamics_blending import prepare as blending_prepare + +# dependencies of the data assimilation subpackage from .data_assimilation import ( prepare as da_prepare, etpf as da_etpf, @@ -28,6 +31,8 @@ ########################################################## def main(): sim_state = prepare.initialise() + + blending_prepare.initialise(sim_state) da_prepare.initialise(sim_state) writer, step_writer = io.initialise(sim_state) @@ -42,15 +47,7 @@ def main(): for tout in sim_state.ud.tout: futures = [] - # In ensemble case, do blending for each DA window - if N > 1: - blend = bld if tout_old in dap.da_times else None - else: - blend = bld - - # initial blending? - if ud.initial_blending == True and (outer_step == 0 or outer_step == 1): - blend = bld + blend = blending_prepare.init_da_window(sim_state, tout_old, outer_step) ###################################################### # Forecast step diff --git a/src/dycore/discretisation/time_update.py b/src/dycore/discretisation/time_update.py index 4c1e21cb..6d7a528a 100644 --- a/src/dycore/discretisation/time_update.py +++ b/src/dycore/discretisation/time_update.py @@ -19,7 +19,7 @@ from . import grid as dis_grid # for blending module -from ...blending import blending +from ...interfaces.dynamics_blending import schemes def data_init(ud): @@ -166,7 +166,7 @@ def do( ###################################################### # Blending : Do blending before timestep ###################################################### - swe_to_lake, Sol, mpv, t = blending.blending_before_timestep( + swe_to_lake, Sol, mpv, t = schemes.blending_before_timestep( Sol, flux, mpv, @@ -526,7 +526,7 @@ def do( ###################################################### # Blending : Do blending after timestep ###################################################### - Sol, mpv = blending.blending_after_timestep( + Sol, mpv = schemes.blending_after_timestep( Sol, flux, mpv, diff --git a/src/blending/__init__.py b/src/interfaces/__init__.py similarity index 100% rename from src/blending/__init__.py rename to src/interfaces/__init__.py diff --git a/src/interfaces/dynamics_blending/__init__.py b/src/interfaces/dynamics_blending/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/interfaces/dynamics_blending/prepare.py b/src/interfaces/dynamics_blending/prepare.py new file mode 100644 index 00000000..0bc913d7 --- /dev/null +++ b/src/interfaces/dynamics_blending/prepare.py @@ -0,0 +1,20 @@ +from . import schemes + +def initialise(sst): + bld = schemes.Blend(sst.ud) + + sst.interface_params.bld = bld + + +def init_da_window(sst, tout_old, outer_step): + # In ensemble case, do blending for each DA window + if sst.N > 1: + blend = sst.interface_params.bld if tout_old in sst.da_params.dap.da_times else None + else: + blend = sst.interface_params.bld + + # initial blending? + if sst.ud.initial_blending == True and (outer_step == 0 or outer_step == 1): + blend = sst.interface_params.bld + + return blend \ No newline at end of file diff --git a/src/blending/blending.py b/src/interfaces/dynamics_blending/schemes.py similarity index 99% rename from src/blending/blending.py rename to src/interfaces/dynamics_blending/schemes.py index 289abf9f..782af115 100644 --- a/src/blending/blending.py +++ b/src/interfaces/dynamics_blending/schemes.py @@ -5,7 +5,7 @@ import numpy as np from scipy import signal -from ..dycore.physics.gas_dynamics import eos as gd_eos +from ...dycore.physics.gas_dynamics import eos as gd_eos class Blend(object): """ diff --git a/src/interfaces/parallel_intergrator/__init__.py b/src/interfaces/parallel_intergrator/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index 731b2256..dbcbe0d0 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -9,7 +9,10 @@ class ModelParameters: flux: Any mpv: Any th: Any - bld: Any + +@dataclass +class InterfaceParameters: + bld: Optional[Any] = None @dataclass class DataAssimilationParameters: @@ -45,6 +48,7 @@ class SimulationState: model_params: ModelParameters restart_params: RestartParameters + interface_params : Optional[InterfaceParameters] = None da_params: Optional[DataAssimilationParameters] = None diag_comparison: Optional[object] = None \ No newline at end of file diff --git a/src/utils/prepare.py b/src/utils/prepare.py index 2d414f3a..b4868ef7 100644 --- a/src/utils/prepare.py +++ b/src/utils/prepare.py @@ -12,8 +12,6 @@ from ..dycore.physics.low_mach import mpv as lm_var from ..dycore.physics.gas_dynamics import thermodynamic as gd_thermodynamics -from ..blending import blending - # test module from ..tests import diagnostics as diag @@ -59,7 +57,7 @@ def initialise(): th = gd_thermodynamics.init(ud) mpv = lm_var.MPV(elem, node, ud) - bld = blending.Blend(ud) + io.init_logger(ud) @@ -87,7 +85,6 @@ def initialise(): flux=flux, mpv=mpv, th=th, - bld=bld, ) restart_params = data_structures.RestartParameters( @@ -96,6 +93,8 @@ def initialise(): r_params=r_params, ) + interface_params = data_structures.InterfaceParameters() + sim_st = data_structures.SimulationState( step=step, t=t, @@ -108,7 +107,8 @@ def initialise(): diag_comparison=diag_comparison, model_params=model_params, - restart_params=restart_params + restart_params=restart_params, + interface_params=interface_params ) return sim_st \ No newline at end of file From c72f9a9b27f60840790f35129f0783bb68f9bfa9 Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 19 Dec 2024 00:01:54 +0800 Subject: [PATCH 05/76] code runs until analysis step the restructuring continues --- src/__main__.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/__main__.py b/src/__main__.py index 4acb6c5b..a8e39f83 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -24,7 +24,7 @@ # input file from .utils.sim_params import debug from .utils import prepare -from .utils import io as io +from .utils import io ########################################################## # Start main looping @@ -45,6 +45,12 @@ def main(): tout_cnt = 0 outer_step = 0 for tout in sim_state.ud.tout: + + sst = sim_state + mp = sst.model_params + dp = sst.da_params + ens = dp.sol_ens + futures = [] blend = blending_prepare.init_da_window(sim_state, tout_old, outer_step) @@ -59,30 +65,30 @@ def main(): for mem in ens.members(ens): # handling of DA window step counter - if N > 1: - mem[3][0] = 0 if tout_old in dap.da_times else mem[3][0] - if N == 1: + if sst.N > 1: + mem[3][0] = 0 if tout_old in dp.dap.da_times else mem[3][0] + if sst.N == 1: mem[3][0] = mem[3][1] logging.info("For ensemble member = %i..." % mem_cnt) future = dis_time_update.do( mem[0], mem[1], mem[2], - t, + sst.t, tout, - ud, - elem, - node, + sst.ud, + mp.elem, + mp.node, mem[3], - th, + mp.th, blend, step_writer, debug, ) - if ud.diag: - diag_comparison.test_do( - future[0], future[2].p2_nodes, plot=ud.diag_plot_compare + if sst.ud.diag: + sst.diag_comparison.test_do( + future[0], future[2].p2_nodes, plot=sst.ud.diag_plot_compare ) futures.append(future) @@ -207,7 +213,7 @@ def main(): ###################################################### # Write output at tout ###################################################### - logging.info(termcolor.colored("Starting output...", "yellow")) + logging.info("Starting output...") for n in range(N): Sol = ens.members(ens)[n][0] mpv = ens.members(ens)[n][2] @@ -222,7 +228,7 @@ def main(): # synchronise_variables(mpv, Sol, elem, node, ud, th) t = tout tout_old = np.copy(tout) - logging.info(termcolor.colored("tout = %.3f" % tout, "yellow")) + logging.info("tout = %.3f" % tout) tout_cnt += 1 outer_step += 1 @@ -230,7 +236,7 @@ def main(): break toc = time.time() - logging.info(termcolor.colored("Time taken = %.6f" % (toc - tic), "yellow")) + logging.info("Time taken = %.6f" % (toc - tic)) writer.close_everything() From 61e48c2c60e32aa8ac7699979a9836c8d17ded64 Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 19 Dec 2024 00:33:12 +0800 Subject: [PATCH 06/76] main has been restructured and all three dynamics tests passed DA and blending are not covered in the tests, will look into them after refactoring the flow solver --- src/__main__.py | 136 +++------------------------ src/data_assimilation/analysis.py | 128 +++++++++++++++++++++++++ src/tests/test_internal_long_wave.py | 17 ++-- src/tests/test_lamb_wave.py | 12 ++- src/tests/test_travelling_vortex.py | 12 ++- src/utils/io.py | 6 +- 6 files changed, 169 insertions(+), 142 deletions(-) create mode 100644 src/data_assimilation/analysis.py diff --git a/src/__main__.py b/src/__main__.py index a8e39f83..5fd7ec6a 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -3,11 +3,9 @@ import logging import numpy as np -import termcolor # dependencies of the atmospheric flow solver from .dycore.discretisation import time_update as dis_time_update -from .dycore.utils import boundary as bdry # dependencies of the interface subpackage from .interfaces.dynamics_blending import prepare as blending_prepare @@ -15,16 +13,15 @@ # dependencies of the data assimilation subpackage from .data_assimilation import ( prepare as da_prepare, - etpf as da_etpf, - post_processing as da_post_processing, - letkf as da_letkf, - utils as da_utils + analysis as da_analysis ) -# input file -from .utils.sim_params import debug -from .utils import prepare -from .utils import io +# package imports +from .utils import ( + prepare, + io, + sim_params as params +) ########################################################## # Start main looping @@ -83,7 +80,7 @@ def main(): mp.th, blend, step_writer, - debug, + params.debug, ) if sst.ud.diag: @@ -101,129 +98,22 @@ def main(): results = np.array(results) # s_res = client.scatter(results) - ###################################################### - # Analysis step - ###################################################### - tout = np.around(tout, 3) - if N > 1 and tout in dap.da_times: - futures = [] - - ###################################################### - # Update ensemble with forecast - ###################################################### - for n in range(N): - Sol = results[n][dap.loc_c] - bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - results[n][dap.loc_c] = Sol - p2_nodes = getattr(results[n][dap.loc_n], "p2_nodes") - bdry.set_ghostnodes_p2(p2_nodes, node, ud) - setattr(results[n][dap.loc_n], "p2_nodes", p2_nodes) - - ens.set_members(results, tout) - - ###################################################### - # Write output before assimilating data - ###################################################### - logging.info(termcolor.colored("Starting output...", "yellow")) - for n in range(N): - Sol = ens.members(ens)[n][0] - mpv = ens.members(ens)[n][2] - - if label_type == "STEP": - step = outer_step - label = "ensemble_mem=%i_%.3d" % (n, step) - else: - label = "ensemble_mem=%i_%.3f" % (n, tout) - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_before_da") - - ################################################## - # LETKF with batch observations - ################################################## - if dap.da_type == "batch_obs": - logging.info("Starting analysis... for batch observations") - for attr in dap.obs_attributes: - logging.info("Assimilating %s..." % attr) - logging.info("Assimilating %s..." % attr) - # future = client.submit(da_interface, *[s_res,obs_current,dap.inflation_factor,attr,N,ud,dap.loc[attr]]) - future = da_letkf.da_interface(results, dap, obs, attr, tout, N, ud) - futures.append(future) - - # analysis = client.gather(futures) - analysis = futures - # analysis = np.array(analysis) - - logging.info("Writing analysis...") - cnt = 0 - for attr in dap.obs_attributes: - current = analysis[cnt] - for n in range(N): - setattr(results[:, dap.loc[attr], ...][n], attr, current[n]) - cnt += 1 - - ################################################## - # LETKF with grid-point localisation - ################################################## - elif dap.da_type == "rloc": - logging.info( - termcolor.colored("Starting analysis... for rloc algorithm", "green") - ) - results = da_utils.HSprojector_3t2D(results, elem, dap, N) - results = rloc.analyse(results, obs, obs_covar, obs_mask, N, tout) - results = da_utils.HSprojector_2t3D(results, elem, node, dap, N) - # if hasattr(dap, 'converter'): - # results = dap.converter(results, N, mpv, elem, node, th, ud) - - ################################################## - # ETPF - ################################################## - elif dap.da_type == "etpf": - da_utils.ensemble_inflation(results, dap.attributes, dap.inflation_factor, N) - results = da_etpf.da_interface( - results, - obs, - dap.obs_attributes, - dap.rejuvenation_factor, - dap.da_times, - tout, - N, - ) - - ################################################## - # Post-processing - ################################################## - elif dap.da_type == "pprocess": - results = da_post_processing.interface() - - else: - assert 0, "DA type not implemented: use 'rloc', 'batch_obs' or 'etpf'." - - ###################################################### - # Update ensemble with analysis - ###################################################### - for n in range(N): - Sol = results[n][dap.loc_c] - bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - results[n][dap.loc_c] = Sol - p2_nodes = getattr(results[n][dap.loc_n], "p2_nodes") - bdry.set_ghostnodes_p2(p2_nodes, node, ud) - setattr(results[n][dap.loc_n], "p2_nodes", p2_nodes) - - ens.set_members(results, tout) + da_analysis.do_for_window(tout, outer_step, results, sst, writer) ###################################################### # Write output at tout ###################################################### logging.info("Starting output...") - for n in range(N): + for n in range(sst.N): Sol = ens.members(ens)[n][0] mpv = ens.members(ens)[n][2] - if label_type == "STEP": + if params.label_type == "STEP": step = outer_step label = "ensemble_mem=%i_%.3d" % (n, step) else: label = "ensemble_mem=%i_%.3f" % (n, tout) - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_full_step") + writer.write_all(Sol, mpv, mp.elem, mp.node, mp.th, str(label) + "_after_full_step") # synchronise_variables(mpv, Sol, elem, node, ud, th) t = tout @@ -232,7 +122,7 @@ def main(): tout_cnt += 1 outer_step += 1 - if outer_step > ud.stepmax: + if outer_step > sst.ud.stepmax: break toc = time.time() diff --git a/src/data_assimilation/analysis.py b/src/data_assimilation/analysis.py new file mode 100644 index 00000000..868c52b9 --- /dev/null +++ b/src/data_assimilation/analysis.py @@ -0,0 +1,128 @@ +import logging + +import numpy as np + +from . import( + etpf as da_etpf, + post_processing as da_post_processing, + letkf as da_letkf, + utils as da_utils +) + +from ..dycore.utils import boundary as bdry + +from ..utils import sim_params as params + +def do_for_window(tout, outer_step, results, sst, writer): + mp = sst.model_params + dp = sst.da_params + ens = dp.sol_ens + + ###################################################### + # Analysis step + ###################################################### + tout = np.around(tout, 3) + if sst.N > 1 and tout in dp.dap.da_times: + futures = [] + + ###################################################### + # Update ensemble with forecast + ###################################################### + for n in range(sst.N): + Sol = results[n][dp.dap.loc_c] + bdry.set_explicit_boundary_data(Sol, mp.elem, mp.ud, mp.th, mpv) + results[n][dp.dap.loc_c] = Sol + p2_nodes = getattr(results[n][dp.dap.loc_n], "p2_nodes") + bdry.set_ghostnodes_p2(p2_nodes, mp.node, sst.ud) + setattr(results[n][dp.dap.loc_n], "p2_nodes", p2_nodes) + + ens.set_members(results, tout) + + ###################################################### + # Write output before assimilating data + ###################################################### + logging.info("Starting output...") + for n in range(sst.N): + Sol = ens.members(ens)[n][0] + mpv = ens.members(ens)[n][2] + + if params.label_type == "STEP": + step = outer_step + label = "ensemble_mem=%i_%.3d" % (n, step) + else: + label = "ensemble_mem=%i_%.3f" % (n, tout) + writer.write_all(Sol, mpv, mp.elem, mp.node, mp.th, str(label) + "_before_da") + + ################################################## + # LETKF with batch observations + ################################################## + if dp.dap.da_type == "batch_obs": + logging.info("Starting analysis... for batch observations") + for attr in dp.dap.obs_attributes: + logging.info("Assimilating %s..." % attr) + logging.info("Assimilating %s..." % attr) + # future = client.submit(da_interface, *[s_res,obs_current,dap.inflation_factor,attr,N,ud,dap.loc[attr]]) + future = da_letkf.da_interface(results, dp.dap, dp.obs, attr, tout, sst.N, sst.ud) + futures.append(future) + + # analysis = client.gather(futures) + analysis = futures + # analysis = np.array(analysis) + + logging.info("Writing analysis...") + cnt = 0 + for attr in dp.dap.obs_attributes: + current = analysis[cnt] + for n in range(sst.N): + setattr(results[:, dp.dap.loc[attr], ...][n], attr, current[n]) + cnt += 1 + + ################################################## + # LETKF with grid-point localisation + ################################################## + elif dp.dap.da_type == "rloc": + logging.info( + "Starting analysis... for rloc algorithm" + ) + results = da_utils.HSprojector_3t2D(results, mp.elem, dp.dap, sst.N) + results = dp.rloc.analyse(results, dp.obs, dp.obs_covar, dp.obs_mask, sst.N, tout) + results = da_utils.HSprojector_2t3D(results, mp.elem, mp.node, mp.dap, sst.N) + # if hasattr(dap, 'converter'): + # results = dap.converter(results, N, mpv, elem, node, th, ud) + + ################################################## + # ETPF + ################################################## + elif dp.dap.da_type == "etpf": + da_utils.ensemble_inflation(results, dp.dap.attributes, dp.dap.inflation_factor, sst.N) + results = da_etpf.da_interface( + results, + dp.obs, + dp.dap.obs_attributes, + dp.dap.rejuvenation_factor, + dp.dap.da_times, + tout, + sst.N, + ) + + ################################################## + # Post-processing + ################################################## + elif dp.dap.da_type == "pprocess": + results = da_post_processing.interface() + + else: + assert 0, "DA type not implemented: use 'rloc', 'batch_obs' or 'etpf'." + + ###################################################### + # Update ensemble with analysis + ###################################################### + for n in range(sst.N): + Sol = results[n][dp.dap.loc_c] + bdry.set_explicit_boundary_data(Sol, mp.elem, sst.ud, mp.th, mp.mpv) + results[n][dp.dap.loc_c] = Sol + p2_nodes = getattr(results[n][dp.dap.loc_n], "p2_nodes") + bdry.set_ghostnodes_p2(p2_nodes, mp.node, sst.ud) + setattr(results[n][dp.dap.loc_n], "p2_nodes", p2_nodes) + + ens.set_members(results, tout) \ No newline at end of file diff --git a/src/tests/test_internal_long_wave.py b/src/tests/test_internal_long_wave.py index c59db5db..978d32a1 100644 --- a/src/tests/test_internal_long_wave.py +++ b/src/tests/test_internal_long_wave.py @@ -1,8 +1,11 @@ import numpy as np -import dycore.utils.options as opts -import dycore.utils.boundary as bdry -import dycore.utils.variable as var -import dycore.physics.hydrostatics as hydrostatic + +from ..dycore.utils import( + options as opts, + boundary as bdry, + variable as var +) +from ..dycore.physics import hydrostatics class UserData(object): @@ -188,7 +191,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): xc = 0.0 a = ud.scale_factor * 5.0e3 / ud.h_ref - hydrostatic.state(mpv, elem, node, th, ud) + hydrostatics.state(mpv, elem, node, th, ud) HySt = var.States(node.sc, ud) HyStn = var.States(node.sc, ud) @@ -207,7 +210,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): 1.0 + (xn - xc) ** 2 / (a**2) ) - hydrostatic.column(HySt, HyStn, Y, Yn, elem, node, th, ud) + hydrostatics.column(HySt, HyStn, Y, Yn, elem, node, th, ud) x_idx = slice(None) y_idx = slice(elem.igy, -elem.igy + 1) @@ -238,7 +241,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): mpv.p2_nodes[:, elem.igy : -elem.igy] = HyStn.p20[:, elem.igy : -elem.igy] - hydrostatic.initial_pressure(Sol, mpv, elem, node, ud, th) + hydrostatics.initial_pressure(Sol, mpv, elem, node, ud, th) ud.nonhydrostasy = 1.0 if ud.is_nonhydrostatic == 1 else 0.0 ud.compressibility = 1.0 if ud.is_compressible == 1 else 0.0 diff --git a/src/tests/test_lamb_wave.py b/src/tests/test_lamb_wave.py index bf0fde7c..ced6623c 100644 --- a/src/tests/test_lamb_wave.py +++ b/src/tests/test_lamb_wave.py @@ -1,7 +1,11 @@ import numpy as np -import dycore.utils.options as opts -import dycore.utils.boundary as bdry -import dycore.physics.hydrostatics as hydrostatic + +from ..dycore.utils import ( + options as opts, + boundary as bdry +) + +from ..dycore.physics import hydrostatics class UserData(object): NSPEC = 1 @@ -290,7 +294,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): ud.stratification = ud.stratification(dy) # Use hydrostatically balanced background - hydrostatic.state(mpv, elem, node, th, ud) + hydrostatics.state(mpv, elem, node, th, ud) rhobar = mpv.HydroState.rho0.reshape(1,-1) Ybar = mpv.HydroState.Y0.reshape(1,-1) pibar = mpv.HydroState.p20.reshape(1,-1) * ud.Msq diff --git a/src/tests/test_travelling_vortex.py b/src/tests/test_travelling_vortex.py index b965fada..b8b184c6 100644 --- a/src/tests/test_travelling_vortex.py +++ b/src/tests/test_travelling_vortex.py @@ -1,8 +1,10 @@ import numpy as np -import dycore.utils.options as opts -import dycore.physics.hydrostatics as hydrostatic -import dycore.utils.boundary as bdry -import dycore.physics.low_mach.second_projection as lm_sp +from ..dycore.utils import ( + options as opts, + boundary as bdry +) +from ..dycore.physics import hydrostatics +from ..dycore.physics.low_mach import second_projection as lm_sp import logging @@ -200,7 +202,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): igxn = node.igx igyn = node.igy - hydrostatic.state(mpv, elem, node, th, ud) + hydrostatics.state(mpv, elem, node, th, ud) coe = np.zeros((25)) coe[0] = 1.0 / 24.0 diff --git a/src/utils/io.py b/src/utils/io.py index 2e2339a3..896a4a53 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -639,11 +639,11 @@ def get_args(): elif ic == "swe_dvortex": from inputs.shallow_water_3D_dvortex import UserData, sol_init elif ic == "test_travelling_vortex": - from tests.test_travelling_vortex import UserData, sol_init + from ..tests.test_travelling_vortex import UserData, sol_init elif ic == "test_internal_long_wave": - from tests.test_internal_long_wave import UserData, sol_init + from ..tests.test_internal_long_wave import UserData, sol_init elif ic == "test_lamb_wave": - from tests.test_lamb_wave import UserData, sol_init + from ..tests.test_lamb_wave import UserData, sol_init if UserData is None or sol_init is None: assert 0, "Initial condition file is not well defined." From 3141e13c8b7d892b77fa38cc3b3c2c62fd1d1617 Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 19 Dec 2024 01:06:12 +0800 Subject: [PATCH 07/76] updated readme on how to run a single simulation --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e49da449..8fab2d1a 100644 --- a/README.md +++ b/README.md @@ -71,10 +71,16 @@ The user-defined input parameters are in the [`inputs`](https://github.com/ray-c A simple test can be found in [`run_scripts.test_suite`](https://github.com/ray-chew/pyBELLA/blob/develop/run_scripts/test_dycore.py). To execute this run script from the pyBELLA parent directory: ```console -python3 ./run_scripts/test_dycore.py +pytest ./run_scripts/test_dycore.py ``` -However, the codebase is structured such that the user can easily assemble a run script to define their own experiments. Refer to the documentation for the [available APIs](https://ray-chew.github.io/pyBELLA/apis.html). +To run a simulation: +```console +pybella -ic rb -N 1 +``` +Note that only the rising bubble initial condition is implemented for now with ensemble size of 1. + +The codebase is structured such that the user can easily assemble a run script to define their own experiments. Refer to the documentation for the [available APIs](https://ray-chew.github.io/pyBELLA/apis.html). ## License From 8f5ac665ed2c304abd2eb4b00b617bd88dd87bdc Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 19 Dec 2024 01:18:00 +0800 Subject: [PATCH 08/76] updated changelog --- CHANGELOG.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4660e191..cb7ef4c3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,12 @@ +0.50.6 (2024-12-10) +------------------- + +Changed +^^^^^^^ + +- Cleaned __main__ with restructuring of code (61e48c2c60e32aa8ac7699979a9836c8d17ded64) + + 0.50.5 (2024-03-24) ------------------- From 37cfa63031474dad72284b81bb790f2477dd8566 Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 19 Dec 2024 01:18:37 +0800 Subject: [PATCH 09/76] updated run.py to run rising bubble test case since I removed all initial conditions except this --- run_scripts/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run_scripts/run.py b/run_scripts/run.py index c014579e..acd5c8c7 100644 --- a/run_scripts/run.py +++ b/run_scripts/run.py @@ -7,7 +7,7 @@ class run_params(object): N = 1 tc = "rb" # tc = 'mark' - tc = "tv" + # tc = "tv" def __init__(self): self.N = self.N From 527fcfe6e451af6be739cb3625ac74a509fda165 Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 19 Dec 2024 01:37:22 +0800 Subject: [PATCH 10/76] refactored diagnostics.py a little --- src/tests/diagnostics.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index afa6fd08..7608ad28 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -1,10 +1,12 @@ -# import numpy as np +import logging + import numpy as np import yaml -import termcolor -import logging -import pybella.vis.plotting_tools as vis_pt -import pybella.vis.utils as vis_utils + +from ..vis import ( + utils as vis_utils, + plotting_tools as vis_pt +) class compare_sol(object): @@ -57,9 +59,11 @@ def test_do(self, Sol, p2n, plot=False): test, ) - logging.info(termcolor.colored("##########", "green")) - logging.info(termcolor.colored("Test passed for %s" %self.current_run, "green")) - logging.info(termcolor.colored("##########", "green")) + logging.info(f""" + {'#' * 10} + Test passed for {self.current_run} + {'#' * 10} + """.strip()) def __init(self): path = "./outputs/" From 55a8a169a4d0e747666d5d1e92d1ca1b2857f04d Mon Sep 17 00:00:00 2001 From: raychew Date: Sun, 22 Dec 2024 11:54:03 +0800 Subject: [PATCH 11/76] cleaned up blending related code in the flow solver --- src/dycore/discretisation/time_update.py | 161 +++++++---------------- src/dycore/physics/gas_dynamics/eos.py | 24 ++-- src/dycore/physics/low_mach/mpv.py | 13 -- src/dycore/utils/variable.py | 2 - 4 files changed, 59 insertions(+), 141 deletions(-) diff --git a/src/dycore/discretisation/time_update.py b/src/dycore/discretisation/time_update.py index 6d7a528a..01358409 100644 --- a/src/dycore/discretisation/time_update.py +++ b/src/dycore/discretisation/time_update.py @@ -8,7 +8,11 @@ from ...utils import io # dependencies of the flow solver subpackage -from ..utils import boundary as bdry, options as opts +from . import grid as dis_grid +from ..utils import ( + boundary as bdry, + options as opts +) from ..physics.gas_dynamics import ( numerical_flux as gd_flux, eos as gd_eos, @@ -16,7 +20,6 @@ ) from ..physics.gas_dynamics import explicit as gd_explicit from ..physics.low_mach import second_projection as lm_sp -from . import grid as dis_grid # for blending module from ...interfaces.dynamics_blending import schemes @@ -122,10 +125,6 @@ def do( window_step = steps[0] step = steps[1] swe_to_lake = False - if "best" not in ud.aux: - test_hydrob = True - else: - test_hydrob = False while (t < tout) and (step < ud.stepmax): bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) @@ -156,12 +155,11 @@ def do( ) if c1 or c2: - logging.info(termcolor.colored("nonhydrostatic to hydrostatic conversion...", "blue")) + logging.info("nonhydrostatic to hydrostatic conversion...") ud.is_nonhydrostatic = 0 if test_hydrob == False: dt *= 0.5 - # elif test_hydrob == True: - # dt *= 0.25 + ###################################################### # Blending : Do blending before timestep @@ -187,41 +185,32 @@ def do( ud.is_nonhydrostatic = gd_eos.is_nonhydrostatic(ud, window_step) ud.nonhydrostasy = gd_eos.nonhydrostasy(ud, t, window_step) + + if ud.continuous_blending or ud.initial_blending: + logging.info(f"step = {step}, window_step = {window_step}") - if ud.continuous_blending == True or ud.initial_blending == True: - if window_step >= 0: - logging.info("step = %i, window_step = %i" % (step, window_step)) - else: - logging.info("step = %i, window_step = %f" % (step, window_step)) - logging.info( - "is_compressible = %i, is_nonhydrostatic = %i" - % (ud.is_compressible, ud.is_nonhydrostatic) - ) - logging.info( - "compressibility = %.3f, nonhydrostasy = %.3f" - % (ud.compressibility, ud.nonhydrostasy) - ) - logging.info("-------") + logging.info(f""" + ------- + is_compressible = {ud.is_compressible}, is_nonhydrostatic = {ud.is_nonhydrostatic} + compressibility = {ud.compressibility:.3f}, nonhydrostasy = {ud.nonhydrostasy:.3f} + ------- + """) Sol0 = copy.deepcopy(Sol) - flux0 = copy.deepcopy(flux) - mpv0 = copy.deepcopy(mpv) if debug == True: writer.write_all(Sol, mpv, elem, node, th, str(label) + "_before_flux") gd_flux.recompute_advective_fluxes(flux, Sol) - if debug == True: - writer.populate(str(label) + "_before_advect", "rhoYu", flux[0].rhoY) - if debug == True: - writer.populate(str(label) + "_before_advect", "rhoYv", flux[1].rhoY) - if debug == True and elem.ndim == 3: - writer.populate(str(label) + "_before_advect", "rhoYw", flux[2].rhoY) - if debug == True: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_before_advect") + if debug: + writer.populate(f"{label}_before_advect", "rhoYu", flux[0].rhoY) + writer.populate(f"{label}_before_advect", "rhoYv", flux[1].rhoY) + if elem.ndim == 3: + writer.populate(f"{label}_before_advect", "rhoYw", flux[2].rhoY) + writer.write_all(Sol, mpv, elem, node, th, f"{label}_before_advect") + - # advect(Sol, flux, 0.5*dt, elem, step%2, ud, th, mpv, node, str(label)+'_half', writer) if ud.do_advection: gd_explicit.advect_rk( Sol, @@ -237,46 +226,33 @@ def do( writer, ) - if debug == True: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_advect") - if debug: + writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_advect") writer.populate(str(label) + "_after_full_step", "p2_nodes0", mpv.p2_nodes) mpv.p2_nodes0[...] = mpv.p2_nodes lm_sp.euler_backward_non_advective_expl_part(Sol, mpv, elem, 0.5 * dt, ud, th) + if debug == True: writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_ebnaexp") - if ud.is_compressible == 0: - lm_sp.euler_backward_non_advective_impl_part( - Sol, - mpv, - elem, - node, - ud, - th, - t, - 0.5 * dt, - 1.0, - Sol0=Sol0, - label=str(label + "_after_ebnaimp"), - writer=writer, - ) - else: - lm_sp.euler_backward_non_advective_impl_part( - Sol, - mpv, - elem, - node, - ud, - th, - t, - 0.5 * dt, - 1.0, - label=str(label + "_after_ebnaimp"), - writer=writer, - ) + + Sol0 = Sol0 if ud.is_compressible == 0 else None + + lm_sp.euler_backward_non_advective_impl_part( + Sol, + mpv, + elem, + node, + ud, + th, + t, + 0.5 * dt, + 1.0, + Sol0=Sol0, + label=f"{label}_after_ebnaimp", + writer=writer, + ) if ud.bdry_type[1] == opts.BdryType.RAYLEIGH: # top rayleight damping @@ -294,7 +270,6 @@ def do( Sol_half_new = copy.deepcopy(Sol) mpv_half_new = copy.deepcopy(mpv) - # misusing hydrostatic blending data containers time_tag = "%.3d_after_full_step" % step reader.get_data(Sol_half_new, mpv_half_new, time_tag, half=True) @@ -330,22 +305,17 @@ def do( if debug == True: writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_ebnaimp") - # if test_hydrob == True and writer is not None and step==0: - # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') flux_half_new = copy.deepcopy(flux) gd_flux.recompute_advective_fluxes(flux, Sol) - if debug == True: - writer.populate(str(label) + "_after_half_step", "rhoYu", flux[0].rhoY) - if debug == True: - writer.populate(str(label) + "_after_half_step", "rhoYv", flux[1].rhoY) - if debug == True and elem.ndim == 3: - writer.populate(str(label) + "_after_half_step", "rhoYw", flux[2].rhoY) - - if debug == True: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_half_step") + if debug: + writer.populate(f"{label}_after_half_step", "rhoYu", flux[0].rhoY) + writer.populate(f"{label}_after_half_step", "rhoYv", flux[1].rhoY) + if elem.ndim == 3: + writer.populate(f"{label}_after_half_step", "rhoYw", flux[2].rhoY) + writer.write_all(Sol, mpv, elem, node, th, f"{label}_after_half_step") Sol_half_new = copy.deepcopy(Sol) mpv_half_new = copy.deepcopy(mpv) @@ -358,41 +328,11 @@ def do( # pwchi = np.copy(Sol.pwchi) p2_nodes_half = np.copy(mpv.p2_nodes) - # if test_hydrob == True and writer is not None and step==0: - # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') - # print(dt*0.5) - # takes care of the non-hydrostatic, compressible case - if ud.is_compressible == 1 and ud.is_nonhydrostatic == 1: - mpv.p2_nodes[...] = mpv.p2_nodes0 - Sol = copy.deepcopy(Sol0) - # takes care of the hydrostatic case - elif ud.is_nonhydrostatic == 0: - # if step == 1 : - # Sol.rho = (Sol.rho_half + Sol.rho) * 0.5 - # Sol.rhou = (Sol.rhou_half + Sol.rhou) * 0.5 - # Sol.rhov = (Sol.rhov_half + Sol.rhov) * 0.5 - # Sol.rhow = (Sol.rhow_half + Sol.rhow) * 0.5 - # Sol.rhoX = (Sol.rhoX_half + Sol.rhoX) * 0.5 - # Sol.rhoY = (Sol.rhoY_half + Sol.rhoY) * 0.5 - # v = (Sol.rhov_half / Sol.rho_half + Sol.rhov / Sol.rho) * 0.5 - # mpv.p2_nodes = (mpv.p2_nodes_half + mpv.p2_nodes) * 0.5 - # v = rhov_half / rho_half - # Sol = copy.deepcopy(Sol0) - # Sol.rhov = (Sol.rhov_half + rhov_half) * 0.5 - # Sol.rhov = Sol.rho * v - # mpv.p2_nodes[...] = mpv.p2_nodes0 - # None - # Sol = copy.deepcopy(Sol_tu) - # mpv = copy.deepcopy(mpv_tu) - # None - # else: - Sol = copy.deepcopy(Sol0) + if ud.is_nonhydrostatic == 0 or (ud.is_compressible == 1 and ud.is_nonhydrostatic == 1): mpv.p2_nodes[...] = mpv.p2_nodes0 - # takes care of the pseudo-incompressible case - elif ud.is_compressible == 0: - Sol = copy.deepcopy(Sol0) + Sol = copy.deepcopy(Sol0) # Sol.rhov0 = np.copy(Sol.rhov) Sol.rho_half = rho_half @@ -446,7 +386,6 @@ def do( str(label) + "_full", writer, ) - # advect_rk(Sol, flux, dt, elem, step%2, ud, th, mpv, node, str(label)+'_full', writer) if debug == True: writer.write_all( diff --git a/src/dycore/physics/gas_dynamics/eos.py b/src/dycore/physics/gas_dynamics/eos.py index 6eda3b35..2ada5730 100644 --- a/src/dycore/physics/gas_dynamics/eos.py +++ b/src/dycore/physics/gas_dynamics/eos.py @@ -47,22 +47,16 @@ def is_compressible(ud,step): return ud.is_compressible -def is_nonhydrostatic(ud,step): - # print("is_nonhydrostatic", ud.is_nonhydrostatic) - # print("no_of_nhy_initial:", ud.no_of_hy_initial) - # print("no_of_nhy_transition:", ud.no_of_hy_transition) - if step >= 0: - if ud.continuous_blending == True: - if step < ud.no_of_hy_initial: - return 0 - elif step < (ud.no_of_hy_initial + ud.no_of_hy_transition): - return -1 - else: - return 1 - else: - return ud.is_nonhydrostatic - else: +def is_nonhydrostatic(ud, step): + if step < 0 or not ud.continuous_blending: return ud.is_nonhydrostatic + + if step < ud.no_of_hy_initial: + return 0 + elif step < (ud.no_of_hy_initial + ud.no_of_hy_transition): + return -1 + else: + return 1 def rhoe(rho,u,v,w,p,ud,th): diff --git a/src/dycore/physics/low_mach/mpv.py b/src/dycore/physics/low_mach/mpv.py index 0803bbe7..a45a8ae1 100644 --- a/src/dycore/physics/low_mach/mpv.py +++ b/src/dycore/physics/low_mach/mpv.py @@ -33,16 +33,3 @@ def squeezer(self): for key, value in vars(self).items(): if type(value) == np.ndarray: setattr(self,key,value.squeeze()) - - -# def acoustic_order(ud,t,step): -# if ud.is_compressible == 0: -# return 2.0 -# elif ud.is_compressible == 1: -# return 2.0 -# elif ud.is_compressible == -1: -# current_transition_step = step - ud.no_of_pi_initial -# # return np.linspace(,2.0,ud.no_of_pi_transition+2)[1:-1][current_transition_step] -# return 2.0 -# else: -# assert 0 \ No newline at end of file diff --git a/src/dycore/utils/variable.py b/src/dycore/utils/variable.py index 4a226735..b14674ec 100644 --- a/src/dycore/utils/variable.py +++ b/src/dycore/utils/variable.py @@ -2,8 +2,6 @@ import scipy as sp - -# equivalent to States_new class Vars(object): """ The data container for the solution state variables, i.e. `Sol`. From acdb0bc559eb7409bcd8ec74a828db043c125c90 Mon Sep 17 00:00:00 2001 From: raychew Date: Sun, 22 Dec 2024 12:02:49 +0800 Subject: [PATCH 12/76] renamed the dycore subpackage to flow_solver for consistency --- src/__main__.py | 2 +- src/data_assimilation/analysis.py | 2 +- src/data_assimilation/letkf.py | 2 +- src/data_assimilation/localisation.py | 2 +- src/data_assimilation/params.py | 2 +- src/data_assimilation/prepare.py | 2 +- src/data_assimilation/utils.py | 2 +- src/{dycore => flow_solver}/__init__.py | 0 src/{dycore => flow_solver}/discretisation/__init__.py | 0 src/{dycore => flow_solver}/discretisation/grid.py | 0 .../discretisation/time_update.py | 0 src/{dycore => flow_solver}/physics/__init__.py | 0 .../physics/gas_dynamics/__init__.py | 0 .../physics/gas_dynamics/cfl.py | 0 .../physics/gas_dynamics/eos.py | 0 .../physics/gas_dynamics/explicit.py | 0 .../physics/gas_dynamics/numerical_flux.py | 0 .../physics/gas_dynamics/recovery.py | 0 .../physics/gas_dynamics/thermodynamic.py | 0 src/{dycore => flow_solver}/physics/hydrostatics.py | 0 .../physics/low_mach/__init__.py | 0 .../physics/low_mach/laplacian.py | 0 src/{dycore => flow_solver}/physics/low_mach/mpv.py | 0 .../physics/low_mach/second_projection.py | 0 src/{dycore => flow_solver}/utils/boundary.py | 0 src/{dycore => flow_solver}/utils/options.py | 0 src/{dycore => flow_solver}/utils/variable.py | 0 src/inputs/rising_bubble.py | 4 ++-- src/interfaces/dynamics_blending/schemes.py | 6 +++--- src/tests/test_internal_long_wave.py | 4 ++-- src/tests/test_lamb_wave.py | 4 ++-- src/tests/test_travelling_vortex.py | 6 +++--- src/utils/prepare.py | 10 +++++----- src/utils/user_data.py | 2 +- 34 files changed, 25 insertions(+), 25 deletions(-) rename src/{dycore => flow_solver}/__init__.py (100%) rename src/{dycore => flow_solver}/discretisation/__init__.py (100%) rename src/{dycore => flow_solver}/discretisation/grid.py (100%) rename src/{dycore => flow_solver}/discretisation/time_update.py (100%) rename src/{dycore => flow_solver}/physics/__init__.py (100%) rename src/{dycore => flow_solver}/physics/gas_dynamics/__init__.py (100%) rename src/{dycore => flow_solver}/physics/gas_dynamics/cfl.py (100%) rename src/{dycore => flow_solver}/physics/gas_dynamics/eos.py (100%) rename src/{dycore => flow_solver}/physics/gas_dynamics/explicit.py (100%) rename src/{dycore => flow_solver}/physics/gas_dynamics/numerical_flux.py (100%) rename src/{dycore => flow_solver}/physics/gas_dynamics/recovery.py (100%) rename src/{dycore => flow_solver}/physics/gas_dynamics/thermodynamic.py (100%) rename src/{dycore => flow_solver}/physics/hydrostatics.py (100%) rename src/{dycore => flow_solver}/physics/low_mach/__init__.py (100%) rename src/{dycore => flow_solver}/physics/low_mach/laplacian.py (100%) rename src/{dycore => flow_solver}/physics/low_mach/mpv.py (100%) rename src/{dycore => flow_solver}/physics/low_mach/second_projection.py (100%) rename src/{dycore => flow_solver}/utils/boundary.py (100%) rename src/{dycore => flow_solver}/utils/options.py (100%) rename src/{dycore => flow_solver}/utils/variable.py (100%) diff --git a/src/__main__.py b/src/__main__.py index 5fd7ec6a..ae1335c9 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -5,7 +5,7 @@ import numpy as np # dependencies of the atmospheric flow solver -from .dycore.discretisation import time_update as dis_time_update +from .flow_solver.discretisation import time_update as dis_time_update # dependencies of the interface subpackage from .interfaces.dynamics_blending import prepare as blending_prepare diff --git a/src/data_assimilation/analysis.py b/src/data_assimilation/analysis.py index 868c52b9..4d613738 100644 --- a/src/data_assimilation/analysis.py +++ b/src/data_assimilation/analysis.py @@ -9,7 +9,7 @@ utils as da_utils ) -from ..dycore.utils import boundary as bdry +from ..flow_solver.utils import boundary as bdry from ..utils import sim_params as params diff --git a/src/data_assimilation/letkf.py b/src/data_assimilation/letkf.py index 09fbfcee..e76aca6d 100644 --- a/src/data_assimilation/letkf.py +++ b/src/data_assimilation/letkf.py @@ -11,7 +11,7 @@ import matplotlib.pyplot as plt -from ..dycore.utils import options as opts +from ..flow_solver.utils import options as opts from . import utils debug_cnt = 0 diff --git a/src/data_assimilation/localisation.py b/src/data_assimilation/localisation.py index 6069a342..82064ae5 100644 --- a/src/data_assimilation/localisation.py +++ b/src/data_assimilation/localisation.py @@ -1,5 +1,5 @@ import numpy as np -import dycore.utils.options as opts +import flow_solver.utils.options as opts def rlocal_5pt(elem,node,ud): igx = elem.igx diff --git a/src/data_assimilation/params.py b/src/data_assimilation/params.py index cea0086b..a0c22aaa 100644 --- a/src/data_assimilation/params.py +++ b/src/data_assimilation/params.py @@ -4,7 +4,7 @@ import numpy as np import scipy as sp -from ..dycore.utils import boundary as bdry +from ..flow_solver.utils import boundary as bdry class init(object): diff --git a/src/data_assimilation/prepare.py b/src/data_assimilation/prepare.py index a1dc01c7..0337bdf9 100644 --- a/src/data_assimilation/prepare.py +++ b/src/data_assimilation/prepare.py @@ -4,7 +4,7 @@ import numpy as np -from ..dycore.physics import hydrostatics +from ..flow_solver.physics import hydrostatics from ..utils import sim_params as params from ..utils import io from ..utils import data_structures diff --git a/src/data_assimilation/utils.py b/src/data_assimilation/utils.py index 57ff5b7d..ac815f5e 100644 --- a/src/data_assimilation/utils.py +++ b/src/data_assimilation/utils.py @@ -5,7 +5,7 @@ import matplotlib.pyplot as plt -from ..dycore.utils import options as opts, boundary as bdry +from ..flow_solver.utils import options as opts, boundary as bdry class ensemble(object): def __init__(self, input_ensemble=None): diff --git a/src/dycore/__init__.py b/src/flow_solver/__init__.py similarity index 100% rename from src/dycore/__init__.py rename to src/flow_solver/__init__.py diff --git a/src/dycore/discretisation/__init__.py b/src/flow_solver/discretisation/__init__.py similarity index 100% rename from src/dycore/discretisation/__init__.py rename to src/flow_solver/discretisation/__init__.py diff --git a/src/dycore/discretisation/grid.py b/src/flow_solver/discretisation/grid.py similarity index 100% rename from src/dycore/discretisation/grid.py rename to src/flow_solver/discretisation/grid.py diff --git a/src/dycore/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py similarity index 100% rename from src/dycore/discretisation/time_update.py rename to src/flow_solver/discretisation/time_update.py diff --git a/src/dycore/physics/__init__.py b/src/flow_solver/physics/__init__.py similarity index 100% rename from src/dycore/physics/__init__.py rename to src/flow_solver/physics/__init__.py diff --git a/src/dycore/physics/gas_dynamics/__init__.py b/src/flow_solver/physics/gas_dynamics/__init__.py similarity index 100% rename from src/dycore/physics/gas_dynamics/__init__.py rename to src/flow_solver/physics/gas_dynamics/__init__.py diff --git a/src/dycore/physics/gas_dynamics/cfl.py b/src/flow_solver/physics/gas_dynamics/cfl.py similarity index 100% rename from src/dycore/physics/gas_dynamics/cfl.py rename to src/flow_solver/physics/gas_dynamics/cfl.py diff --git a/src/dycore/physics/gas_dynamics/eos.py b/src/flow_solver/physics/gas_dynamics/eos.py similarity index 100% rename from src/dycore/physics/gas_dynamics/eos.py rename to src/flow_solver/physics/gas_dynamics/eos.py diff --git a/src/dycore/physics/gas_dynamics/explicit.py b/src/flow_solver/physics/gas_dynamics/explicit.py similarity index 100% rename from src/dycore/physics/gas_dynamics/explicit.py rename to src/flow_solver/physics/gas_dynamics/explicit.py diff --git a/src/dycore/physics/gas_dynamics/numerical_flux.py b/src/flow_solver/physics/gas_dynamics/numerical_flux.py similarity index 100% rename from src/dycore/physics/gas_dynamics/numerical_flux.py rename to src/flow_solver/physics/gas_dynamics/numerical_flux.py diff --git a/src/dycore/physics/gas_dynamics/recovery.py b/src/flow_solver/physics/gas_dynamics/recovery.py similarity index 100% rename from src/dycore/physics/gas_dynamics/recovery.py rename to src/flow_solver/physics/gas_dynamics/recovery.py diff --git a/src/dycore/physics/gas_dynamics/thermodynamic.py b/src/flow_solver/physics/gas_dynamics/thermodynamic.py similarity index 100% rename from src/dycore/physics/gas_dynamics/thermodynamic.py rename to src/flow_solver/physics/gas_dynamics/thermodynamic.py diff --git a/src/dycore/physics/hydrostatics.py b/src/flow_solver/physics/hydrostatics.py similarity index 100% rename from src/dycore/physics/hydrostatics.py rename to src/flow_solver/physics/hydrostatics.py diff --git a/src/dycore/physics/low_mach/__init__.py b/src/flow_solver/physics/low_mach/__init__.py similarity index 100% rename from src/dycore/physics/low_mach/__init__.py rename to src/flow_solver/physics/low_mach/__init__.py diff --git a/src/dycore/physics/low_mach/laplacian.py b/src/flow_solver/physics/low_mach/laplacian.py similarity index 100% rename from src/dycore/physics/low_mach/laplacian.py rename to src/flow_solver/physics/low_mach/laplacian.py diff --git a/src/dycore/physics/low_mach/mpv.py b/src/flow_solver/physics/low_mach/mpv.py similarity index 100% rename from src/dycore/physics/low_mach/mpv.py rename to src/flow_solver/physics/low_mach/mpv.py diff --git a/src/dycore/physics/low_mach/second_projection.py b/src/flow_solver/physics/low_mach/second_projection.py similarity index 100% rename from src/dycore/physics/low_mach/second_projection.py rename to src/flow_solver/physics/low_mach/second_projection.py diff --git a/src/dycore/utils/boundary.py b/src/flow_solver/utils/boundary.py similarity index 100% rename from src/dycore/utils/boundary.py rename to src/flow_solver/utils/boundary.py diff --git a/src/dycore/utils/options.py b/src/flow_solver/utils/options.py similarity index 100% rename from src/dycore/utils/options.py rename to src/flow_solver/utils/options.py diff --git a/src/dycore/utils/variable.py b/src/flow_solver/utils/variable.py similarity index 100% rename from src/dycore/utils/variable.py rename to src/flow_solver/utils/variable.py diff --git a/src/inputs/rising_bubble.py b/src/inputs/rising_bubble.py index d33fc28e..d16f2c4d 100644 --- a/src/inputs/rising_bubble.py +++ b/src/inputs/rising_bubble.py @@ -1,6 +1,6 @@ import numpy as np -from ..dycore.physics import hydrostatics -from ..dycore.utils import boundary as bdry +from ..flow_solver.physics import hydrostatics +from ..flow_solver.utils import boundary as bdry class UserData(object): # Nsq_ref = grav * 1.3e-05 diff --git a/src/interfaces/dynamics_blending/schemes.py b/src/interfaces/dynamics_blending/schemes.py index 782af115..c2042bcb 100644 --- a/src/interfaces/dynamics_blending/schemes.py +++ b/src/interfaces/dynamics_blending/schemes.py @@ -5,7 +5,7 @@ import numpy as np from scipy import signal -from ...dycore.physics.gas_dynamics import eos as gd_eos +from ...flow_solver.physics.gas_dynamics import eos as gd_eos class Blend(object): """ @@ -117,7 +117,7 @@ def do_comp_to_psinc_conv(Sol, mpv, bld, elem, node, th, ud, label, writer): def do_psinc_to_comp_conv( Sol, flux, mpv, bld, elem, node, th, ud, label, writer, step, window_step, t, dt ): - from dycore.discretisation import time_update + from flow_solver.discretisation import time_update logging.info(termcolor.colored("Blending... step = %i" % step, "blue")) Sol_freeze = copy.deepcopy(Sol) @@ -215,7 +215,7 @@ def do_swe_to_lake_conv(Sol, mpv, elem, node, ud, th, writer, label, debug): def do_lake_to_swe_conv( Sol, flux, mpv, elem, node, ud, th, writer, label, debug, step, window_step, t, dt ): - from dycore.discretisation import time_update + from flow_solver.discretisation import time_update if debug == True: writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_lake_time_step") diff --git a/src/tests/test_internal_long_wave.py b/src/tests/test_internal_long_wave.py index 978d32a1..c0374224 100644 --- a/src/tests/test_internal_long_wave.py +++ b/src/tests/test_internal_long_wave.py @@ -1,11 +1,11 @@ import numpy as np -from ..dycore.utils import( +from ..flow_solver.utils import( options as opts, boundary as bdry, variable as var ) -from ..dycore.physics import hydrostatics +from ..flow_solver.physics import hydrostatics class UserData(object): diff --git a/src/tests/test_lamb_wave.py b/src/tests/test_lamb_wave.py index ced6623c..381f8c6b 100644 --- a/src/tests/test_lamb_wave.py +++ b/src/tests/test_lamb_wave.py @@ -1,11 +1,11 @@ import numpy as np -from ..dycore.utils import ( +from ..flow_solver.utils import ( options as opts, boundary as bdry ) -from ..dycore.physics import hydrostatics +from ..flow_solver.physics import hydrostatics class UserData(object): NSPEC = 1 diff --git a/src/tests/test_travelling_vortex.py b/src/tests/test_travelling_vortex.py index b8b184c6..9145d488 100644 --- a/src/tests/test_travelling_vortex.py +++ b/src/tests/test_travelling_vortex.py @@ -1,10 +1,10 @@ import numpy as np -from ..dycore.utils import ( +from ..flow_solver.utils import ( options as opts, boundary as bdry ) -from ..dycore.physics import hydrostatics -from ..dycore.physics.low_mach import second_projection as lm_sp +from ..flow_solver.physics import hydrostatics +from ..flow_solver.physics.low_mach import second_projection as lm_sp import logging diff --git a/src/utils/prepare.py b/src/utils/prepare.py index b4868ef7..143f7973 100644 --- a/src/utils/prepare.py +++ b/src/utils/prepare.py @@ -6,11 +6,11 @@ data_structures ) -from ..dycore.discretisation import grid as dis_grid -from ..dycore.utils import variable as var -from ..dycore.utils import boundary as bdry -from ..dycore.physics.low_mach import mpv as lm_var -from ..dycore.physics.gas_dynamics import thermodynamic as gd_thermodynamics +from ..flow_solver.discretisation import grid as dis_grid +from ..flow_solver.utils import variable as var +from ..flow_solver.utils import boundary as bdry +from ..flow_solver.physics.low_mach import mpv as lm_var +from ..flow_solver.physics.gas_dynamics import thermodynamic as gd_thermodynamics # test module from ..tests import diagnostics as diag diff --git a/src/utils/user_data.py b/src/utils/user_data.py index 279a9a33..d6a5d8b2 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -1,6 +1,6 @@ import numpy as np -from ..dycore.utils import options as opts +from ..flow_solver.utils import options as opts from . import sim_params as params class UserDataInit(object): From 7f0b676b9bbe085c197aaf711158b861badf9de1 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 23 Dec 2024 12:12:52 +0800 Subject: [PATCH 13/76] updated data structures for a proper sol_ens and simulation integration time --- src/data_assimilation/prepare.py | 19 +++++++---- src/utils/data_structures.py | 56 ++++++++++++++++++++++++-------- src/utils/prepare.py | 40 +++++++++++++---------- 3 files changed, 78 insertions(+), 37 deletions(-) diff --git a/src/data_assimilation/prepare.py b/src/data_assimilation/prepare.py index 0337bdf9..4f3268bc 100644 --- a/src/data_assimilation/prepare.py +++ b/src/data_assimilation/prepare.py @@ -15,7 +15,7 @@ def initialise(sst): - mp = sst.model_params + mp = sst.model_state rp = sst.restart_params ########################################################## @@ -37,7 +37,7 @@ def initialise(sst): rloc = None logging.info("Generating initial ensemble...") - sol_ens = np.zeros((sst.N), dtype=object) + sol_ens = data_structures.EnsembleState() # Set random seed for reproducibility np.random.seed(params.random_seed) @@ -49,9 +49,13 @@ def initialise(sst): Sol0 = deepcopy(sst.Sol) mpv0 = deepcopy(sst.mpv) Sol0 = sst.sol_init(Sol0, mpv0, mp.elem, mp.node, mp.th, mp.ud, seed=seeds[n]) - sol_ens[n] = [Sol0, deepcopy(mp.flux), mpv0, [-np.inf, sst.step]] + # sol_ens[n] = [Sol0, deepcopy(mp.flux), mpv0, [-np.inf, mp.step]] + sol_ens.update_member(mp.elem, mp.node, Sol0, mpv0, deepcopy(mp.flux), mp.th) elif sst.restart == False: - sol_ens = [[sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.flux, mp.mpv, [-np.inf, sst.step]]] + # sol_ens = [[sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.flux, mp.mpv, [-np.inf, sst.step]]] + sol_ens.update_member(mp.elem, mp.node, sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.mpv, deepcopy(mp.flux), mp.th) + for n in range(sst.N): + sol_ens.get_member(n).time.t = -np.inf elif sst.restart == True: hydrostatics.state(mp.mpv, mp.elem, mp.node, mp.th, mp.ud) sst.ud.old_suffix = np.copy(sst.ud.output_suffix) @@ -64,7 +68,8 @@ def initialise(sst): sst.ud.tout = [touts[-1]] sst.t = touts[0] - ens = da_utils.ensemble(sol_ens) + # ens = da_utils.ensemble(sol_ens) + ens = sol_ens ########################################################## # Load data assimilation observations @@ -93,9 +98,11 @@ def initialise(sst): sst.da_params = data_structures.DataAssimilationParameters( dap=dap, rloc=rloc, - sol_ens=ens, + # sol_ens=ens, obs=obs, obs_noisy=obs_noisy, obs_mask=obs_mask, obs_covar=obs_covar ) + + diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index dbcbe0d0..c04a2d45 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -1,14 +1,29 @@ -from typing import Optional, Callable, Any -from dataclasses import dataclass +from typing import Optional, Callable, List, Any +from dataclasses import dataclass, field + +from ..flow_solver.discretisation.grid import Grid +from ..flow_solver.utils.variable import Vars +from ..flow_solver.physics.low_mach.mpv import MPV +from ..flow_solver.physics.gas_dynamics.thermodynamics import ThermodynamicalQuantities @dataclass -class ModelParameters: - elem: Any - node: Any - Sol: Any - flux: Any - mpv: Any - th: Any +class IntegrationTime: + step : int = 0 + t : float = 0.0 + window_step : int = 0 + +@dataclass +class ModelState: + elem: Grid + node: Grid + Sol: Vars + flux: List[Vars] + mpv: MPV + th: ThermodynamicalQuantities + time: IntegrationTime = field(init=False) + + def __post_init__(self): + self.time = IntegrationTime(0,0) @dataclass class InterfaceParameters: @@ -21,7 +36,7 @@ class DataAssimilationParameters: # r-localisation function rloc : Any # solution ensemble - sol_ens : Any + # sol_ens : Any # observation related attributes obs : Any @@ -35,20 +50,33 @@ class RestartParameters: dap_rewrite: Optional[object] = None r_params: Optional[object] = None +@dataclass +class EnsembleState: + members: List[ModelState] = field(default_factory=list) + + def update_member(self, elem: Grid, node: Grid, sol: Vars, mpv: MPV, flux: List[Vars], th: ThermodynamicalQuantities): + new_state = ModelState(elem, node, sol, flux, mpv, th) + self.members.append(new_state) + + def get_member(self, index: int) -> ModelState: + return self.members[index] + + def get_all_members(self) -> List[ModelState]: + return self.members + @dataclass class SimulationState: - step: int - t: float N: int restart: bool ud: object sol_init: Callable - model_params: ModelParameters + ensemble_state: EnsembleState restart_params: RestartParameters interface_params : Optional[InterfaceParameters] = None da_params: Optional[DataAssimilationParameters] = None - diag_comparison: Optional[object] = None \ No newline at end of file + diag_comparison: Optional[object] = None + diff --git a/src/utils/prepare.py b/src/utils/prepare.py index 143f7973..290ff56f 100644 --- a/src/utils/prepare.py +++ b/src/utils/prepare.py @@ -10,7 +10,7 @@ from ..flow_solver.utils import variable as var from ..flow_solver.utils import boundary as bdry from ..flow_solver.physics.low_mach import mpv as lm_var -from ..flow_solver.physics.gas_dynamics import thermodynamic as gd_thermodynamics +from ..flow_solver.physics.gas_dynamics import thermodynamics as gd_thermodynamics # test module from ..tests import diagnostics as diag @@ -23,9 +23,6 @@ def initialise(): np.set_printoptions(precision = params.print_precision) - step = 0 - t = 0.0 - ########################################################## # Initialisation of data containers and helper classes ########################################################## @@ -46,7 +43,7 @@ def initialise(): elem, node = dis_grid.grid_init(ud) - Sol = var.Vars(elem.sc, ud) + sol = var.Vars(elem.sc, ud) flux = np.empty((3), dtype=object) flux[0] = var.States(elem.sfx, ud) @@ -55,7 +52,7 @@ def initialise(): if elem.ndim > 2: flux[2] = var.States(elem.sfz, ud) - th = gd_thermodynamics.init(ud) + th = gd_thermodynamics.ThermodynamicalQuantities(ud) mpv = lm_var.MPV(elem, node, ud) @@ -78,14 +75,24 @@ def initialise(): # Populate data structures ########################################################## - model_params = data_structures.ModelParameters( - elem=elem, - node=node, - Sol=Sol, - flux=flux, - mpv=mpv, - th=th, - ) + # member_state = data_structures.MemberState( + # elem=elem, + # node=node, + # Sol=Sol, + # flux=flux, + # mpv=mpv, + # th=th, + # ) + + ensemble_state = data_structures.EnsembleState() + ensemble_state.update_member( + elem=elem, + node=node, + sol=sol, + flux=flux, + mpv=mpv, + th=th, + ) restart_params = data_structures.RestartParameters( ud_rewrite=ud_rewrite, @@ -96,17 +103,16 @@ def initialise(): interface_params = data_structures.InterfaceParameters() sim_st = data_structures.SimulationState( - step=step, - t=t, N=N, restart=restart, ud=ud, sol_init=sol_init, + ensemble_state=ensemble_state, + diag_comparison=diag_comparison, - model_params=model_params, restart_params=restart_params, interface_params=interface_params ) From ee51566485eb26da1b5d97e7a24a00721cd61201 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 23 Dec 2024 12:13:14 +0800 Subject: [PATCH 14/76] updated thermodynamics data structure. --- .../gas_dynamics/{thermodynamic.py => thermodynamics.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/flow_solver/physics/gas_dynamics/{thermodynamic.py => thermodynamics.py} (92%) diff --git a/src/flow_solver/physics/gas_dynamics/thermodynamic.py b/src/flow_solver/physics/gas_dynamics/thermodynamics.py similarity index 92% rename from src/flow_solver/physics/gas_dynamics/thermodynamic.py rename to src/flow_solver/physics/gas_dynamics/thermodynamics.py index f4a330d7..c958f230 100644 --- a/src/flow_solver/physics/gas_dynamics/thermodynamic.py +++ b/src/flow_solver/physics/gas_dynamics/thermodynamics.py @@ -1,4 +1,4 @@ -class init(object): +class ThermodynamicalQuantities(object): """ Data container for thermodynamical quantities. From 91a1018bb495555bd737cbd7865b7aa01d8cd274 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 23 Dec 2024 13:58:43 +0800 Subject: [PATCH 15/76] done refactoring the preparation and initialisation steps this is with the new ensemble data structure; the flow solver runs; yet to be tested. --- src/__main__.py | 46 ++++++++----------- src/data_assimilation/prepare.py | 40 ++++++---------- src/flow_solver/discretisation/time_update.py | 26 +++++------ src/utils/data_structures.py | 14 ++++-- src/utils/io.py | 14 +++--- src/utils/prepare.py | 24 +++++++++- 6 files changed, 89 insertions(+), 75 deletions(-) diff --git a/src/__main__.py b/src/__main__.py index ae1335c9..86519791 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -28,9 +28,12 @@ ########################################################## def main(): sim_state = prepare.initialise() - blending_prepare.initialise(sim_state) da_prepare.initialise(sim_state) + + if sim_state.restart: + prepare.overwrite_init_with_restart(sim_state) + writer, step_writer = io.initialise(sim_state) tic = time.time() @@ -44,12 +47,12 @@ def main(): for tout in sim_state.ud.tout: sst = sim_state - mp = sst.model_params + es = sst.ensemble_state dp = sst.da_params - ens = dp.sol_ens futures = [] + # based on the initial blending parameter, define if we want to blend for this assimilation window or simulaiton run. blend = blending_prepare.init_da_window(sim_state, tout_old, outer_step) ###################################################### @@ -58,26 +61,19 @@ def main(): logging.info("##############################################") logging.info("Next tout = %.3f" % tout) logging.info("Starting forecast...") - mem_cnt = 0 - for mem in ens.members(ens): - + for cnt, mem in enumerate(es): # handling of DA window step counter if sst.N > 1: - mem[3][0] = 0 if tout_old in dp.dap.da_times else mem[3][0] + if tout_old in dp.dap.da_times: + mem.time.window_step = 0 if sst.N == 1: - mem[3][0] = mem[3][1] - logging.info("For ensemble member = %i..." % mem_cnt) - future = dis_time_update.do( - mem[0], - mem[1], - mem[2], - sst.t, + mem.time.window_step = mem.time.step + + logging.info("For ensemble member = %i..." % cnt) + mem = dis_time_update.do( + sst, + mem, tout, - sst.ud, - mp.elem, - mp.node, - mem[3], - mp.th, blend, step_writer, params.debug, @@ -85,18 +81,14 @@ def main(): if sst.ud.diag: sst.diag_comparison.test_do( - future[0], future[2].p2_nodes, plot=sst.ud.diag_plot_compare + mem.sol, mem.mpv.p2_nodes, plot=sst.ud.diag_plot_compare ) - futures.append(future) - mem_cnt += 1 + futures.append(mem) # Dask commands, used only when parallelisation is # enabled - # results = client.gather(futures) - results = np.copy(futures) - results = np.array(results) - # s_res = client.scatter(results) + results = np.array(futures) da_analysis.do_for_window(tout, outer_step, results, sst, writer) @@ -116,7 +108,7 @@ def main(): writer.write_all(Sol, mpv, mp.elem, mp.node, mp.th, str(label) + "_after_full_step") # synchronise_variables(mpv, Sol, elem, node, ud, th) - t = tout + # sst.t = tout tout_old = np.copy(tout) logging.info("tout = %.3f" % tout) diff --git a/src/data_assimilation/prepare.py b/src/data_assimilation/prepare.py index 4f3268bc..78b500d6 100644 --- a/src/data_assimilation/prepare.py +++ b/src/data_assimilation/prepare.py @@ -4,7 +4,6 @@ import numpy as np -from ..flow_solver.physics import hydrostatics from ..utils import sim_params as params from ..utils import io from ..utils import data_structures @@ -15,7 +14,7 @@ def initialise(sst): - mp = sst.model_state + es = sst.ensemble_state rp = sst.restart_params ########################################################## @@ -32,7 +31,7 @@ def initialise(sst): # if elem.ndim == 2: if dap.da_type == "rloc" and sst.N > 1: - rloc = da_letkf.prepare_rloc(mp.ud, mp.elem, mp.node, dap, sst.N) + rloc = da_letkf.prepare_rloc(es.ud, es.elem, es.node, dap, sst.N) else: rloc = None @@ -43,33 +42,24 @@ def initialise(sst): np.random.seed(params.random_seed) seeds = np.random.randint(10000, size=sst.N) if sst.N > 1 else None - if seeds is not None and sst.restart == False: + + if sst.N > 1: logging.info("Seeds used in generating initial ensemble spread = ", seeds) for n in range(sst.N): Sol0 = deepcopy(sst.Sol) mpv0 = deepcopy(sst.mpv) - Sol0 = sst.sol_init(Sol0, mpv0, mp.elem, mp.node, mp.th, mp.ud, seed=seeds[n]) - # sol_ens[n] = [Sol0, deepcopy(mp.flux), mpv0, [-np.inf, mp.step]] - sol_ens.update_member(mp.elem, mp.node, Sol0, mpv0, deepcopy(mp.flux), mp.th) - elif sst.restart == False: + Sol0 = sst.sol_init(Sol0, mpv0, es.elem, es.node, es.th, es.ud, seed=seeds[n]) + # sol_ens[n] = [Sol0, deepcopy(es.flux), mpv0, [-np.inf, es.step]] + sol_ens.update_member(es.elem, es.node, Sol0, mpv0, deepcopy(es.flux), es.th) + + sst.ensembble_state = sol_ens + # elif sst.restart == False: # sol_ens = [[sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.flux, mp.mpv, [-np.inf, sst.step]]] - sol_ens.update_member(mp.elem, mp.node, sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.mpv, deepcopy(mp.flux), mp.th) - for n in range(sst.N): - sol_ens.get_member(n).time.t = -np.inf - elif sst.restart == True: - hydrostatics.state(mp.mpv, mp.elem, mp.node, mp.th, mp.ud) - sst.ud.old_suffix = np.copy(sst.ud.output_suffix) - sst.ud.old_suffix = "_ensemble=%i%s" % (sst.N, sst.ud.old_suffix) - Sol0, mpv0, touts = io.sim_restart( - rp.r_params[0], rp.r_params[1], mp.elem, mp.node, mp.ud, mp.Sol, mp.mpv, rp.r_params[2] - ) - sol_ens = [[Sol0, mp.flux, mpv0, [-np.inf, sst.step]]] - # ud.tout = touts[1:] - sst.ud.tout = [touts[-1]] - sst.t = touts[0] + # sol_ens.update_member(mp.elem, mp.node, sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.mpv, deepcopy(mp.flux), mp.th) + # for n in range(sst.N): + # sol_ens.get_member(n).time.t = -np.inf # ens = da_utils.ensemble(sol_ens) - ens = sol_ens ########################################################## # Load data assimilation observations @@ -79,8 +69,8 @@ def initialise(sst): if sst.N > 1: obs = dap.load_obs(dap.obs_path) # obs_mask, no calculations where entries are True - obs_mask = da_utils.sparse_obs_selector(obs, mp.elem, mp.node, sst.ud, dap) - obs_noisy, obs_covar = da_utils.obs_noiser(obs, obs_mask, dap, rloc, mp.elem) + obs_mask = da_utils.sparse_obs_selector(obs, es.elem, es.node, sst.ud, dap) + obs_noisy, obs_covar = da_utils.obs_noiser(obs, obs_mask, dap, rloc, es.elem) else: obs, obs_noisy, obs_mask, obs_covar = None, None, None, None diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 01358409..803477db 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -61,16 +61,9 @@ def data_init(ud): def do( - Sol, - flux, - mpv, - t, + sst, + mem, tout, - ud, - elem, - node, - steps, - th, bld=None, writer=None, debug=False, @@ -121,9 +114,12 @@ def do( list A list of `[Sol,flux,mpv,[window_step,step]]` data containers at time `tout`. """ + ud = sst.ud + elem, node, Sol, flux, mpv, th, time = mem - window_step = steps[0] - step = steps[1] + window_step = time.window_step + step = time.step + t = time.t swe_to_lake = False while (t < tout) and (step < ud.stepmax): @@ -332,7 +328,7 @@ def do( if ud.is_nonhydrostatic == 0 or (ud.is_compressible == 1 and ud.is_nonhydrostatic == 1): mpv.p2_nodes[...] = mpv.p2_nodes0 - Sol = copy.deepcopy(Sol0) + # Sol = copy.deepcopy(Sol0) # Sol.rhov0 = np.copy(Sol.rhov) Sol.rho_half = rho_half @@ -645,4 +641,8 @@ def do( step += 1 window_step += 1 - return [Sol, flux, mpv, [window_step, step]] + time.step = step + time.window_step = window_step + + return mem + # return [Sol, flux, mpv, [window_step, step]] diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index c04a2d45..d5cf47d8 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -1,5 +1,7 @@ from typing import Optional, Callable, List, Any -from dataclasses import dataclass, field +from dataclasses import dataclass, field, fields + +import numpy as np from ..flow_solver.discretisation.grid import Grid from ..flow_solver.utils.variable import Vars @@ -9,7 +11,7 @@ @dataclass class IntegrationTime: step : int = 0 - t : float = 0.0 + t : float = -np.inf window_step : int = 0 @dataclass @@ -23,7 +25,10 @@ class ModelState: time: IntegrationTime = field(init=False) def __post_init__(self): - self.time = IntegrationTime(0,0) + self.time = IntegrationTime() + + def __iter__(self): + return iter(getattr(self, field.name) for field in fields(self)) @dataclass class InterfaceParameters: @@ -63,6 +68,9 @@ def get_member(self, index: int) -> ModelState: def get_all_members(self) -> List[ModelState]: return self.members + + def __getitem__(self, index): + return self.members[index] @dataclass diff --git a/src/utils/io.py b/src/utils/io.py index 896a4a53..bd4b65a6 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -16,14 +16,14 @@ def initialise(sst): - mp = sst.model_params + es = sst.ensemble_state dp = sst.da_params ###################################################### # Initialise writer class for I/O operations ###################################################### writer = hdf5(sst.ud, sst.restart) writer.check_jar() - writer.jar([sst.ud, mp.mpv, mp.elem, mp.node, dp.dap]) + writer.jar([sst.ud, es[0].elem, es[0].node, dp.dap]) # sys.exit("Let's just dill the stuff and quit!") writer.write_attrs() @@ -32,15 +32,14 @@ def initialise(sst): writer.write_da_attrs(dp.dap) elif params.output_timesteps == True: wrtr = writer + for n in range(sst.N): # write initial ensemble - Sol = dp.sol_ens.members(dp.sol_ens)[n][0] - mpv = dp.sol_ens.members(dp.sol_ens)[n][2] if params.label_type == "STEP": label = "ensemble_mem=%i_%.3d" % (n, sst.step) else: label = "ensemble_mem=%i_%.3f" % (n, 0.0) if not sst.restart: - writer.write_all(Sol, mpv, mp.elem, mp.node, mp.th, str(label) + "_ic") + writer.write_all(es[n], str(label) + "_ic") if params.da_debug: # writer.jar([obs,obs_noisy,obs_noisy_interp,obs_mask,obs_covar]) @@ -161,7 +160,7 @@ def io_create_file(self, paths, restart): file.close() - def write_all(self, Sol, mpv, elem, node, th, name): + def write_all(self, model_state, name): """ At a given time, write output from `Sol` and `mpv` to the HDF5 file. @@ -181,6 +180,9 @@ def write_all(self, Sol, mpv, elem, node, th, name): The time and additional suffix label for the dataset, e.g. "_10.0_after_full_step", where 10.0 is the time and "after_full_step" denotes when the output was made. """ + + _, _, Sol, _, mpv, _, _ = model_state + logging.info("writing hdf output..." + name) # rho self.populate(name, "rho", Sol.rho) diff --git a/src/utils/prepare.py b/src/utils/prepare.py index 290ff56f..6c5006fe 100644 --- a/src/utils/prepare.py +++ b/src/utils/prepare.py @@ -9,6 +9,7 @@ from ..flow_solver.discretisation import grid as dis_grid from ..flow_solver.utils import variable as var from ..flow_solver.utils import boundary as bdry +from ..flow_solver.physics import hydrostatics from ..flow_solver.physics.low_mach import mpv as lm_var from ..flow_solver.physics.gas_dynamics import thermodynamics as gd_thermodynamics @@ -85,6 +86,9 @@ def initialise(): # ) ensemble_state = data_structures.EnsembleState() + + sol = sol_init(sol, mpv, elem, node, th, ud) + ensemble_state.update_member( elem=elem, node=node, @@ -117,4 +121,22 @@ def initialise(): interface_params=interface_params ) - return sim_st \ No newline at end of file + return sim_st + + +def overwrite_init_with_restart(sst): + es = sst.ensemble_state + rp = sst.restart_params + + hydrostatics.state(es.mpv, es.elem, es.node, es.th, es.ud) + sst.ud.old_suffix = np.copy(sst.ud.output_suffix) + sst.ud.old_suffix = "_ensemble=%i%s" % (sst.N, sst.ud.old_suffix) + Sol0, mpv0, touts = io.sim_restart( + rp.r_params[0], rp.r_params[1], es.elem, es.node, es.ud, es.Sol, es.mpv, rp.r_params[2] + ) + sol_ens = [[Sol0, es.flux, mpv0, [-np.inf, sst.step]]] + # ud.tout = touts[1:] + sst.ud.tout = [touts[-1]] + sst.t = touts[0] + + sst.ensemble_state = sol_ens \ No newline at end of file From 468f10c000b2114bdd7f1201523bbc7f4d4e0ff7 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 23 Dec 2024 15:43:12 +0800 Subject: [PATCH 16/76] updated analysis with new ensemble structure --- src/__main__.py | 7 ++--- src/data_assimilation/analysis.py | 47 ++++++++++++++----------------- src/tests/diagnostics.py | 1 + src/utils/data_structures.py | 16 ++++++++--- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/__main__.py b/src/__main__.py index 86519791..de053f6b 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -96,16 +96,13 @@ def main(): # Write output at tout ###################################################### logging.info("Starting output...") - for n in range(sst.N): - Sol = ens.members(ens)[n][0] - mpv = ens.members(ens)[n][2] - + for n, mem in enumerate(es): if params.label_type == "STEP": step = outer_step label = "ensemble_mem=%i_%.3d" % (n, step) else: label = "ensemble_mem=%i_%.3f" % (n, tout) - writer.write_all(Sol, mpv, mp.elem, mp.node, mp.th, str(label) + "_after_full_step") + writer.write_all(mem, str(label) + "_after_full_step") # synchronise_variables(mpv, Sol, elem, node, ud, th) # sst.t = tout diff --git a/src/data_assimilation/analysis.py b/src/data_assimilation/analysis.py index 4d613738..217470b7 100644 --- a/src/data_assimilation/analysis.py +++ b/src/data_assimilation/analysis.py @@ -14,9 +14,9 @@ from ..utils import sim_params as params def do_for_window(tout, outer_step, results, sst, writer): - mp = sst.model_params + # mp = sst.model_params dp = sst.da_params - ens = dp.sol_ens + # ens = dp.sol_ens ###################################################### # Analysis step @@ -28,30 +28,26 @@ def do_for_window(tout, outer_step, results, sst, writer): ###################################################### # Update ensemble with forecast ###################################################### - for n in range(sst.N): - Sol = results[n][dp.dap.loc_c] - bdry.set_explicit_boundary_data(Sol, mp.elem, mp.ud, mp.th, mpv) - results[n][dp.dap.loc_c] = Sol - p2_nodes = getattr(results[n][dp.dap.loc_n], "p2_nodes") - bdry.set_ghostnodes_p2(p2_nodes, mp.node, sst.ud) - setattr(results[n][dp.dap.loc_n], "p2_nodes", p2_nodes) + for mem in results: + elem, node, sol, _, mpv, th, _ = mem + bdry.set_explicit_boundary_data(sol, elem, sst.ud, th, mpv) + bdry.set_ghostnodes_p2(mpv.p2_nodes,node, sst.ud) - ens.set_members(results, tout) + # ens.set_members(results, tout) + sst.ensemble_state.set_members(results) ###################################################### # Write output before assimilating data ###################################################### logging.info("Starting output...") - for n in range(sst.N): - Sol = ens.members(ens)[n][0] - mpv = ens.members(ens)[n][2] - + for mem in sst.ensemble_state: + elem, node, sol, _, mpv, th, _ = mem if params.label_type == "STEP": step = outer_step label = "ensemble_mem=%i_%.3d" % (n, step) else: label = "ensemble_mem=%i_%.3f" % (n, tout) - writer.write_all(Sol, mpv, mp.elem, mp.node, mp.th, str(label) + "_before_da") + writer.write_all(sol, mpv, elem, node, th, str(label) + "_before_da") ################################################## # LETKF with batch observations @@ -84,9 +80,10 @@ def do_for_window(tout, outer_step, results, sst, writer): logging.info( "Starting analysis... for rloc algorithm" ) - results = da_utils.HSprojector_3t2D(results, mp.elem, dp.dap, sst.N) + elem, node = sst.ensemble_state.get_grid() + results = da_utils.HSprojector_3t2D(results, elem, dp.dap, sst.N) results = dp.rloc.analyse(results, dp.obs, dp.obs_covar, dp.obs_mask, sst.N, tout) - results = da_utils.HSprojector_2t3D(results, mp.elem, mp.node, mp.dap, sst.N) + results = da_utils.HSprojector_2t3D(results, elem, node, dp.dap, sst.N) # if hasattr(dap, 'converter'): # results = dap.converter(results, N, mpv, elem, node, th, ud) @@ -117,12 +114,10 @@ def do_for_window(tout, outer_step, results, sst, writer): ###################################################### # Update ensemble with analysis ###################################################### - for n in range(sst.N): - Sol = results[n][dp.dap.loc_c] - bdry.set_explicit_boundary_data(Sol, mp.elem, sst.ud, mp.th, mp.mpv) - results[n][dp.dap.loc_c] = Sol - p2_nodes = getattr(results[n][dp.dap.loc_n], "p2_nodes") - bdry.set_ghostnodes_p2(p2_nodes, mp.node, sst.ud) - setattr(results[n][dp.dap.loc_n], "p2_nodes", p2_nodes) - - ens.set_members(results, tout) \ No newline at end of file + for mem in results: + elem, node, Sol, _, mpv, th, _ = mem + bdry.set_explicit_boundary_data(Sol, elem, sst.ud, th, mpv) + p2_nodes = mpv.p2_nodes + bdry.set_ghostnodes_p2(p2_nodes, node, sst.ud) + + sst.ensemble_state.set_members(results) \ No newline at end of file diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index 7608ad28..0dc693ed 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -58,6 +58,7 @@ def test_do(self, Sol, p2n, plot=False): ref, test, ) + print(f"test passed for {key}") logging.info(f""" {'#' * 10} diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index d5cf47d8..988ed7d3 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -1,8 +1,6 @@ from typing import Optional, Callable, List, Any from dataclasses import dataclass, field, fields -import numpy as np - from ..flow_solver.discretisation.grid import Grid from ..flow_solver.utils.variable import Vars from ..flow_solver.physics.low_mach.mpv import MPV @@ -11,14 +9,14 @@ @dataclass class IntegrationTime: step : int = 0 - t : float = -np.inf + t : float = 0.0 window_step : int = 0 @dataclass class ModelState: elem: Grid node: Grid - Sol: Vars + sol: Vars flux: List[Vars] mpv: MPV th: ThermodynamicalQuantities @@ -63,12 +61,22 @@ def update_member(self, elem: Grid, node: Grid, sol: Vars, mpv: MPV, flux: List[ new_state = ModelState(elem, node, sol, flux, mpv, th) self.members.append(new_state) + def set_members(self, members : List[ModelState]): + assert len(self.set_members == members) + self.members = members + def get_member(self, index: int) -> ModelState: return self.members[index] def get_all_members(self) -> List[ModelState]: return self.members + def get_grid(self) -> tuple[Grid, Grid]: + # Assuming identical underlying grid for all ensemble memebers + elem = self.memebers[0].elem + node = self.memebers[0].node + return elem, node + def __getitem__(self, index): return self.members[index] From 23a7817db225fe2188bcf3045cfdc863435b6888 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 23 Dec 2024 15:44:18 +0800 Subject: [PATCH 17/76] reinstated a few changes in time_update; updating mem with solution arrays at the end of the flow solver's looping this is because the tests were failing with a discrepancy. --- src/flow_solver/discretisation/time_update.py | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 803477db..f704f72b 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -128,7 +128,7 @@ def do( label = "%.3d" % step if step == 0 and writer != None: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_ic") + writer.write_all(mem, str(label) + "_ic") dt, cfl, cfl_ac = gd_cfl.dynamic_timestep(Sol, t, tout, elem, ud, th, step) @@ -193,9 +193,11 @@ def do( """) Sol0 = copy.deepcopy(Sol) + flux0 = copy.deepcopy(flux) + mpv0 = copy.deepcopy(mpv) if debug == True: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_before_flux") + writer.write_all(mem, str(label) + "_before_flux") gd_flux.recompute_advective_fluxes(flux, Sol) @@ -204,7 +206,7 @@ def do( writer.populate(f"{label}_before_advect", "rhoYv", flux[1].rhoY) if elem.ndim == 3: writer.populate(f"{label}_before_advect", "rhoYw", flux[2].rhoY) - writer.write_all(Sol, mpv, elem, node, th, f"{label}_before_advect") + writer.write_all(mem, f"{label}_before_advect") if ud.do_advection: @@ -223,7 +225,7 @@ def do( ) if debug: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_advect") + writer.write_all(mem, str(label) + "_after_advect") writer.populate(str(label) + "_after_full_step", "p2_nodes0", mpv.p2_nodes) mpv.p2_nodes0[...] = mpv.p2_nodes @@ -231,9 +233,9 @@ def do( lm_sp.euler_backward_non_advective_expl_part(Sol, mpv, elem, 0.5 * dt, ud, th) if debug == True: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_ebnaexp") + writer.write_all(mem, str(label) + "_after_ebnaexp") - Sol0 = Sol0 if ud.is_compressible == 0 else None + Sol0_increment = Sol0 if ud.is_compressible == 0 else None lm_sp.euler_backward_non_advective_impl_part( Sol, @@ -245,7 +247,7 @@ def do( t, 0.5 * dt, 1.0, - Sol0=Sol0, + Sol0=Sol0_increment, label=f"{label}_after_ebnaimp", writer=writer, ) @@ -299,7 +301,7 @@ def do( bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) if debug == True: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_ebnaimp") + writer.write_all(mem, str(label) + "_after_ebnaimp") flux_half_new = copy.deepcopy(flux) @@ -311,7 +313,7 @@ def do( writer.populate(f"{label}_after_half_step", "rhoYv", flux[1].rhoY) if elem.ndim == 3: writer.populate(f"{label}_after_half_step", "rhoYw", flux[2].rhoY) - writer.write_all(Sol, mpv, elem, node, th, f"{label}_after_half_step") + writer.write_all(mem, f"{label}_after_half_step") Sol_half_new = copy.deepcopy(Sol) mpv_half_new = copy.deepcopy(mpv) @@ -328,7 +330,7 @@ def do( if ud.is_nonhydrostatic == 0 or (ud.is_compressible == 1 and ud.is_nonhydrostatic == 1): mpv.p2_nodes[...] = mpv.p2_nodes0 - # Sol = copy.deepcopy(Sol0) + Sol = copy.deepcopy(Sol0) # Sol.rhov0 = np.copy(Sol.rhov) Sol.rho_half = rho_half @@ -366,7 +368,7 @@ def do( ) if debug == True: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_efna") + writer.write_all(mem, str(label) + "_after_efna") if ud.do_advection: gd_explicit.advect( @@ -385,14 +387,14 @@ def do( if debug == True: writer.write_all( - Sol, mpv, elem, node, th, str(label) + "_after_full_advect" + mem, str(label) + "_after_full_advect" ) lm_sp.euler_backward_non_advective_expl_part(Sol, mpv, elem, 0.5 * dt, ud, th) if debug == True: writer.write_all( - Sol, mpv, elem, node, th, str(label) + "_after_full_ebnaexp" + mem, str(label) + "_after_full_ebnaexp" ) lm_sp.euler_backward_non_advective_impl_part( @@ -483,7 +485,7 @@ def do( if c1 or c2: logging.info(termcolor.colored("hydrostatic to nonhydrostatic conversion...", "blue")) - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_half_full") + writer.write_all(mem, str(label) + "_half_full") writer.populate(str(label) + "_ic", "pwchi", Sol.pwchi) if test_hydrob == False: @@ -491,7 +493,7 @@ def do( # mpv = copy.deepcopy(mpv_half_old) logging.info(termcolor.colored("test_hydrob == False", "red")) - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_quarter") + writer.write_all(mem, str(label) + "_quarter") writer.populate(str(label) + "_quarter", "pwchi", Sol.pwchi) @@ -525,7 +527,7 @@ def do( # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_half") + writer.write_all(mem, str(label) + "_half") writer.populate(str(label) + "_half", "pwchi", Sol.pwchi) @@ -554,7 +556,7 @@ def do( # mpv = copy.deepcopy(mpv_half_old) logging.info(termcolor.colored("test_hydrob == False", "red")) - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_quarter") + writer.write_all(mem, str(label) + "_quarter") # writer.populate(str(label)+'_quarter', 'pwchi', Sol.pwchi) @@ -625,7 +627,7 @@ def do( if writer != None: writer.time = t - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_full_step") + writer.write_all(mem, str(label) + "_after_full_step") # writer.populate(str(label)+'_after_full_step', 'pwchi', Sol.pwchi) logging.info( "###############################################################################################" @@ -644,5 +646,9 @@ def do( time.step = step time.window_step = window_step + mem.sol = Sol + mem.flux = flux + mem.mpv = mpv + return mem # return [Sol, flux, mpv, [window_step, step]] From 5ca4174288e9f464615d6d04927889f036bcece4 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 23 Dec 2024 16:04:05 +0800 Subject: [PATCH 18/76] updated docs from dycore to flow_solver --- .../source/apis/src.dycore.discretisation.rst | 32 ----------------- .../apis/src.dycore.physics.gas_dynamics.rst | 36 ------------------- .../apis/src.dycore.physics.low_mach.rst | 33 ----------------- docs/source/apis/src.dycore.physics.rst | 33 ----------------- ...> src.flow_solver.discretisation.grid.rst} | 4 +-- .../apis/src.flow_solver.discretisation.rst | 32 +++++++++++++++++ ...low_solver.discretisation.time_update.rst} | 4 +-- ....flow_solver.physics.gas_dynamics.cfl.rst} | 4 +-- ....flow_solver.physics.gas_dynamics.eos.rst} | 4 +-- ..._solver.physics.gas_dynamics.explicit.rst} | 4 +-- ...r.physics.gas_dynamics.numerical_flux.rst} | 4 +-- ..._solver.physics.gas_dynamics.recovery.rst} | 4 +-- .../src.flow_solver.physics.gas_dynamics.rst | 36 +++++++++++++++++++ ...er.physics.gas_dynamics.thermodynamic.rst} | 4 +-- ... src.flow_solver.physics.hydrostatics.rst} | 4 +-- ...low_solver.physics.low_mach.laplacian.rst} | 4 +-- ... src.flow_solver.physics.low_mach.mpv.rst} | 4 +-- .../apis/src.flow_solver.physics.low_mach.rst | 33 +++++++++++++++++ ...er.physics.low_mach.second_projection.rst} | 4 +-- docs/source/apis/src.flow_solver.physics.rst | 33 +++++++++++++++++ .../{src.dycore.rst => src.flow_solver.rst} | 8 ++--- docs/source/apis/src.rst | 2 +- 22 files changed, 163 insertions(+), 163 deletions(-) delete mode 100644 docs/source/apis/src.dycore.discretisation.rst delete mode 100644 docs/source/apis/src.dycore.physics.gas_dynamics.rst delete mode 100644 docs/source/apis/src.dycore.physics.low_mach.rst delete mode 100644 docs/source/apis/src.dycore.physics.rst rename docs/source/apis/{src.dycore.discretisation.grid.rst => src.flow_solver.discretisation.grid.rst} (75%) create mode 100644 docs/source/apis/src.flow_solver.discretisation.rst rename docs/source/apis/{src.dycore.discretisation.time_update.rst => src.flow_solver.discretisation.time_update.rst} (62%) rename docs/source/apis/{src.dycore.physics.gas_dynamics.cfl.rst => src.flow_solver.physics.gas_dynamics.cfl.rst} (63%) rename docs/source/apis/{src.dycore.physics.gas_dynamics.eos.rst => src.flow_solver.physics.gas_dynamics.eos.rst} (73%) rename docs/source/apis/{src.dycore.physics.gas_dynamics.explicit.rst => src.flow_solver.physics.gas_dynamics.explicit.rst} (65%) rename docs/source/apis/{src.dycore.physics.gas_dynamics.numerical_flux.rst => src.flow_solver.physics.gas_dynamics.numerical_flux.rst} (63%) rename docs/source/apis/{src.dycore.physics.gas_dynamics.recovery.rst => src.flow_solver.physics.gas_dynamics.recovery.rst} (66%) create mode 100644 docs/source/apis/src.flow_solver.physics.gas_dynamics.rst rename docs/source/apis/{src.dycore.physics.gas_dynamics.thermodynamic.rst => src.flow_solver.physics.gas_dynamics.thermodynamic.rst} (58%) rename docs/source/apis/{src.dycore.physics.hydrostatics.rst => src.flow_solver.physics.hydrostatics.rst} (67%) rename docs/source/apis/{src.dycore.physics.low_mach.laplacian.rst => src.flow_solver.physics.low_mach.laplacian.rst} (81%) rename docs/source/apis/{src.dycore.physics.low_mach.mpv.rst => src.flow_solver.physics.low_mach.mpv.rst} (61%) create mode 100644 docs/source/apis/src.flow_solver.physics.low_mach.rst rename docs/source/apis/{src.dycore.physics.low_mach.second_projection.rst => src.flow_solver.physics.low_mach.second_projection.rst} (81%) create mode 100644 docs/source/apis/src.flow_solver.physics.rst rename docs/source/apis/{src.dycore.rst => src.flow_solver.rst} (55%) diff --git a/docs/source/apis/src.dycore.discretisation.rst b/docs/source/apis/src.dycore.discretisation.rst deleted file mode 100644 index f45c9533..00000000 --- a/docs/source/apis/src.dycore.discretisation.rst +++ /dev/null @@ -1,32 +0,0 @@ -src.dycore.discretisation -========================= - -.. automodule:: src.dycore.discretisation - - - - - - - - - - - - - - - - - - - -.. rubric:: Modules - -.. autosummary:: - :toctree: - :recursive: - - src.dycore.discretisation.grid - src.dycore.discretisation.time_update - diff --git a/docs/source/apis/src.dycore.physics.gas_dynamics.rst b/docs/source/apis/src.dycore.physics.gas_dynamics.rst deleted file mode 100644 index c6e2eec4..00000000 --- a/docs/source/apis/src.dycore.physics.gas_dynamics.rst +++ /dev/null @@ -1,36 +0,0 @@ -src.dycore.physics.gas\_dynamics -================================ - -.. automodule:: src.dycore.physics.gas_dynamics - - - - - - - - - - - - - - - - - - - -.. rubric:: Modules - -.. autosummary:: - :toctree: - :recursive: - - src.dycore.physics.gas_dynamics.cfl - src.dycore.physics.gas_dynamics.eos - src.dycore.physics.gas_dynamics.explicit - src.dycore.physics.gas_dynamics.numerical_flux - src.dycore.physics.gas_dynamics.recovery - src.dycore.physics.gas_dynamics.thermodynamic - diff --git a/docs/source/apis/src.dycore.physics.low_mach.rst b/docs/source/apis/src.dycore.physics.low_mach.rst deleted file mode 100644 index 64652733..00000000 --- a/docs/source/apis/src.dycore.physics.low_mach.rst +++ /dev/null @@ -1,33 +0,0 @@ -src.dycore.physics.low\_mach -============================ - -.. automodule:: src.dycore.physics.low_mach - - - - - - - - - - - - - - - - - - - -.. rubric:: Modules - -.. autosummary:: - :toctree: - :recursive: - - src.dycore.physics.low_mach.laplacian - src.dycore.physics.low_mach.mpv - src.dycore.physics.low_mach.second_projection - diff --git a/docs/source/apis/src.dycore.physics.rst b/docs/source/apis/src.dycore.physics.rst deleted file mode 100644 index 2fa44ee6..00000000 --- a/docs/source/apis/src.dycore.physics.rst +++ /dev/null @@ -1,33 +0,0 @@ -src.dycore.physics -================== - -.. automodule:: src.dycore.physics - - - - - - - - - - - - - - - - - - - -.. rubric:: Modules - -.. autosummary:: - :toctree: - :recursive: - - src.dycore.physics.gas_dynamics - src.dycore.physics.hydrostatics - src.dycore.physics.low_mach - diff --git a/docs/source/apis/src.dycore.discretisation.grid.rst b/docs/source/apis/src.flow_solver.discretisation.grid.rst similarity index 75% rename from docs/source/apis/src.dycore.discretisation.grid.rst rename to docs/source/apis/src.flow_solver.discretisation.grid.rst index 05d2afdc..e00ef993 100644 --- a/docs/source/apis/src.dycore.discretisation.grid.rst +++ b/docs/source/apis/src.flow_solver.discretisation.grid.rst @@ -1,7 +1,7 @@ -src.dycore.discretisation.grid +src.flow_solver.discretisation.grid ============================== -.. automodule:: src.dycore.discretisation.grid +.. automodule:: src.flow_solver.discretisation.grid diff --git a/docs/source/apis/src.flow_solver.discretisation.rst b/docs/source/apis/src.flow_solver.discretisation.rst new file mode 100644 index 00000000..54d80d3d --- /dev/null +++ b/docs/source/apis/src.flow_solver.discretisation.rst @@ -0,0 +1,32 @@ +src.flow_solver.discretisation +========================= + +.. automodule:: src.flow_solver.discretisation + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :recursive: + + src.flow_solver.discretisation.grid + src.flow_solver.discretisation.time_update + diff --git a/docs/source/apis/src.dycore.discretisation.time_update.rst b/docs/source/apis/src.flow_solver.discretisation.time_update.rst similarity index 62% rename from docs/source/apis/src.dycore.discretisation.time_update.rst rename to docs/source/apis/src.flow_solver.discretisation.time_update.rst index fe2d9a50..f8b3c193 100644 --- a/docs/source/apis/src.dycore.discretisation.time_update.rst +++ b/docs/source/apis/src.flow_solver.discretisation.time_update.rst @@ -1,7 +1,7 @@ -src.dycore.discretisation.time\_update +src.flow_solver.discretisation.time\_update ====================================== -.. automodule:: src.dycore.discretisation.time_update +.. automodule:: src.flow_solver.discretisation.time_update diff --git a/docs/source/apis/src.dycore.physics.gas_dynamics.cfl.rst b/docs/source/apis/src.flow_solver.physics.gas_dynamics.cfl.rst similarity index 63% rename from docs/source/apis/src.dycore.physics.gas_dynamics.cfl.rst rename to docs/source/apis/src.flow_solver.physics.gas_dynamics.cfl.rst index 1a639956..32a0164f 100644 --- a/docs/source/apis/src.dycore.physics.gas_dynamics.cfl.rst +++ b/docs/source/apis/src.flow_solver.physics.gas_dynamics.cfl.rst @@ -1,7 +1,7 @@ -src.dycore.physics.gas\_dynamics.cfl +src.flow_solver.physics.gas\_dynamics.cfl ==================================== -.. automodule:: src.dycore.physics.gas_dynamics.cfl +.. automodule:: src.flow_solver.physics.gas_dynamics.cfl diff --git a/docs/source/apis/src.dycore.physics.gas_dynamics.eos.rst b/docs/source/apis/src.flow_solver.physics.gas_dynamics.eos.rst similarity index 73% rename from docs/source/apis/src.dycore.physics.gas_dynamics.eos.rst rename to docs/source/apis/src.flow_solver.physics.gas_dynamics.eos.rst index fd93d49d..bf1829a0 100644 --- a/docs/source/apis/src.dycore.physics.gas_dynamics.eos.rst +++ b/docs/source/apis/src.flow_solver.physics.gas_dynamics.eos.rst @@ -1,7 +1,7 @@ -src.dycore.physics.gas\_dynamics.eos +src.flow_solver.physics.gas\_dynamics.eos ==================================== -.. automodule:: src.dycore.physics.gas_dynamics.eos +.. automodule:: src.flow_solver.physics.gas_dynamics.eos diff --git a/docs/source/apis/src.dycore.physics.gas_dynamics.explicit.rst b/docs/source/apis/src.flow_solver.physics.gas_dynamics.explicit.rst similarity index 65% rename from docs/source/apis/src.dycore.physics.gas_dynamics.explicit.rst rename to docs/source/apis/src.flow_solver.physics.gas_dynamics.explicit.rst index e4306f28..5bde211e 100644 --- a/docs/source/apis/src.dycore.physics.gas_dynamics.explicit.rst +++ b/docs/source/apis/src.flow_solver.physics.gas_dynamics.explicit.rst @@ -1,7 +1,7 @@ -src.dycore.physics.gas\_dynamics.explicit +src.flow_solver.physics.gas\_dynamics.explicit ========================================= -.. automodule:: src.dycore.physics.gas_dynamics.explicit +.. automodule:: src.flow_solver.physics.gas_dynamics.explicit diff --git a/docs/source/apis/src.dycore.physics.gas_dynamics.numerical_flux.rst b/docs/source/apis/src.flow_solver.physics.gas_dynamics.numerical_flux.rst similarity index 63% rename from docs/source/apis/src.dycore.physics.gas_dynamics.numerical_flux.rst rename to docs/source/apis/src.flow_solver.physics.gas_dynamics.numerical_flux.rst index 637efaaa..18faffc9 100644 --- a/docs/source/apis/src.dycore.physics.gas_dynamics.numerical_flux.rst +++ b/docs/source/apis/src.flow_solver.physics.gas_dynamics.numerical_flux.rst @@ -1,7 +1,7 @@ -src.dycore.physics.gas\_dynamics.numerical\_flux +src.flow_solver.physics.gas\_dynamics.numerical\_flux ================================================ -.. automodule:: src.dycore.physics.gas_dynamics.numerical_flux +.. automodule:: src.flow_solver.physics.gas_dynamics.numerical_flux diff --git a/docs/source/apis/src.dycore.physics.gas_dynamics.recovery.rst b/docs/source/apis/src.flow_solver.physics.gas_dynamics.recovery.rst similarity index 66% rename from docs/source/apis/src.dycore.physics.gas_dynamics.recovery.rst rename to docs/source/apis/src.flow_solver.physics.gas_dynamics.recovery.rst index 577eda1a..20f16205 100644 --- a/docs/source/apis/src.dycore.physics.gas_dynamics.recovery.rst +++ b/docs/source/apis/src.flow_solver.physics.gas_dynamics.recovery.rst @@ -1,7 +1,7 @@ -src.dycore.physics.gas\_dynamics.recovery +src.flow_solver.physics.gas\_dynamics.recovery ========================================= -.. automodule:: src.dycore.physics.gas_dynamics.recovery +.. automodule:: src.flow_solver.physics.gas_dynamics.recovery diff --git a/docs/source/apis/src.flow_solver.physics.gas_dynamics.rst b/docs/source/apis/src.flow_solver.physics.gas_dynamics.rst new file mode 100644 index 00000000..ed8ade27 --- /dev/null +++ b/docs/source/apis/src.flow_solver.physics.gas_dynamics.rst @@ -0,0 +1,36 @@ +src.flow_solver.physics.gas\_dynamics +================================ + +.. automodule:: src.flow_solver.physics.gas_dynamics + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :recursive: + + src.flow_solver.physics.gas_dynamics.cfl + src.flow_solver.physics.gas_dynamics.eos + src.flow_solver.physics.gas_dynamics.explicit + src.flow_solver.physics.gas_dynamics.numerical_flux + src.flow_solver.physics.gas_dynamics.recovery + src.flow_solver.physics.gas_dynamics.thermodynamic + diff --git a/docs/source/apis/src.dycore.physics.gas_dynamics.thermodynamic.rst b/docs/source/apis/src.flow_solver.physics.gas_dynamics.thermodynamic.rst similarity index 58% rename from docs/source/apis/src.dycore.physics.gas_dynamics.thermodynamic.rst rename to docs/source/apis/src.flow_solver.physics.gas_dynamics.thermodynamic.rst index 012c83ec..b43d9272 100644 --- a/docs/source/apis/src.dycore.physics.gas_dynamics.thermodynamic.rst +++ b/docs/source/apis/src.flow_solver.physics.gas_dynamics.thermodynamic.rst @@ -1,7 +1,7 @@ -src.dycore.physics.gas\_dynamics.thermodynamic +src.flow_solver.physics.gas\_dynamics.thermodynamic ============================================== -.. automodule:: src.dycore.physics.gas_dynamics.thermodynamic +.. automodule:: src.flow_solver.physics.gas_dynamics.thermodynamic diff --git a/docs/source/apis/src.dycore.physics.hydrostatics.rst b/docs/source/apis/src.flow_solver.physics.hydrostatics.rst similarity index 67% rename from docs/source/apis/src.dycore.physics.hydrostatics.rst rename to docs/source/apis/src.flow_solver.physics.hydrostatics.rst index ae2e2adb..79e833ef 100644 --- a/docs/source/apis/src.dycore.physics.hydrostatics.rst +++ b/docs/source/apis/src.flow_solver.physics.hydrostatics.rst @@ -1,7 +1,7 @@ -src.dycore.physics.hydrostatics +src.flow_solver.physics.hydrostatics =============================== -.. automodule:: src.dycore.physics.hydrostatics +.. automodule:: src.flow_solver.physics.hydrostatics diff --git a/docs/source/apis/src.dycore.physics.low_mach.laplacian.rst b/docs/source/apis/src.flow_solver.physics.low_mach.laplacian.rst similarity index 81% rename from docs/source/apis/src.dycore.physics.low_mach.laplacian.rst rename to docs/source/apis/src.flow_solver.physics.low_mach.laplacian.rst index acb21b8a..53bfa5e4 100644 --- a/docs/source/apis/src.dycore.physics.low_mach.laplacian.rst +++ b/docs/source/apis/src.flow_solver.physics.low_mach.laplacian.rst @@ -1,7 +1,7 @@ -src.dycore.physics.low\_mach.laplacian +src.flow_solver.physics.low\_mach.laplacian ====================================== -.. automodule:: src.dycore.physics.low_mach.laplacian +.. automodule:: src.flow_solver.physics.low_mach.laplacian diff --git a/docs/source/apis/src.dycore.physics.low_mach.mpv.rst b/docs/source/apis/src.flow_solver.physics.low_mach.mpv.rst similarity index 61% rename from docs/source/apis/src.dycore.physics.low_mach.mpv.rst rename to docs/source/apis/src.flow_solver.physics.low_mach.mpv.rst index 2a96391f..abfa1b22 100644 --- a/docs/source/apis/src.dycore.physics.low_mach.mpv.rst +++ b/docs/source/apis/src.flow_solver.physics.low_mach.mpv.rst @@ -1,7 +1,7 @@ -src.dycore.physics.low\_mach.mpv +src.flow_solver.physics.low\_mach.mpv ================================ -.. automodule:: src.dycore.physics.low_mach.mpv +.. automodule:: src.flow_solver.physics.low_mach.mpv diff --git a/docs/source/apis/src.flow_solver.physics.low_mach.rst b/docs/source/apis/src.flow_solver.physics.low_mach.rst new file mode 100644 index 00000000..3df4d745 --- /dev/null +++ b/docs/source/apis/src.flow_solver.physics.low_mach.rst @@ -0,0 +1,33 @@ +src.flow_solver.physics.low\_mach +============================ + +.. automodule:: src.flow_solver.physics.low_mach + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :recursive: + + src.flow_solver.physics.low_mach.laplacian + src.flow_solver.physics.low_mach.mpv + src.flow_solver.physics.low_mach.second_projection + diff --git a/docs/source/apis/src.dycore.physics.low_mach.second_projection.rst b/docs/source/apis/src.flow_solver.physics.low_mach.second_projection.rst similarity index 81% rename from docs/source/apis/src.dycore.physics.low_mach.second_projection.rst rename to docs/source/apis/src.flow_solver.physics.low_mach.second_projection.rst index 9d9cb675..e725be47 100644 --- a/docs/source/apis/src.dycore.physics.low_mach.second_projection.rst +++ b/docs/source/apis/src.flow_solver.physics.low_mach.second_projection.rst @@ -1,7 +1,7 @@ -src.dycore.physics.low\_mach.second\_projection +src.flow_solver.physics.low\_mach.second\_projection =============================================== -.. automodule:: src.dycore.physics.low_mach.second_projection +.. automodule:: src.flow_solver.physics.low_mach.second_projection diff --git a/docs/source/apis/src.flow_solver.physics.rst b/docs/source/apis/src.flow_solver.physics.rst new file mode 100644 index 00000000..3ef67ab3 --- /dev/null +++ b/docs/source/apis/src.flow_solver.physics.rst @@ -0,0 +1,33 @@ +src.flow_solver.physics +================== + +.. automodule:: src.flow_solver.physics + + + + + + + + + + + + + + + + + + + +.. rubric:: Modules + +.. autosummary:: + :toctree: + :recursive: + + src.flow_solver.physics.gas_dynamics + src.flow_solver.physics.hydrostatics + src.flow_solver.physics.low_mach + diff --git a/docs/source/apis/src.dycore.rst b/docs/source/apis/src.flow_solver.rst similarity index 55% rename from docs/source/apis/src.dycore.rst rename to docs/source/apis/src.flow_solver.rst index e622abfd..527cd633 100644 --- a/docs/source/apis/src.dycore.rst +++ b/docs/source/apis/src.flow_solver.rst @@ -1,7 +1,7 @@ -src.dycore +src.flow_solver ========== -.. automodule:: src.dycore +.. automodule:: src.flow_solver @@ -27,6 +27,6 @@ src.dycore :toctree: :recursive: - src.dycore.discretisation - src.dycore.physics + src.flow_solver.discretisation + src.flow_solver.physics diff --git a/docs/source/apis/src.rst b/docs/source/apis/src.rst index c7df569f..233812ee 100644 --- a/docs/source/apis/src.rst +++ b/docs/source/apis/src.rst @@ -28,7 +28,7 @@ :recursive: src.data_assimilation - src.dycore + src.flow_solver src.tests src.utils src.vis From bd2ede2dbf2a1810eb18e60172765ae79edf9ca9 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 23 Dec 2024 16:07:05 +0800 Subject: [PATCH 19/76] updated changelog --- CHANGELOG.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index cb7ef4c3..f2058adb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,12 @@ +0.60.0 (2024-12-23) +------------------- + +Changed +^^^^^^^ + +- Restructured outermost looping in main() (23a7817db225fe2188bcf3045cfdc863435b6888) + + 0.50.6 (2024-12-10) ------------------- From a153fafb2166a0f67fd31ce54cfb97032853f5b0 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 23 Dec 2024 16:22:55 +0800 Subject: [PATCH 20/76] #6 diagnostics now compute either the sum or the norm as a target --- src/tests/diagnostics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index 0dc693ed..a9ba8331 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -143,7 +143,7 @@ def __get_ens(tc, params, attribute, summed=False): if summed: return ens.sum() else: - return ens + return np.linalg.norm(ens) class test_params(object): From 9b32880c4b7712f2cce746308977685f7b469046 Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 3 Jan 2025 19:50:17 +0800 Subject: [PATCH 21/76] reinstated run.py with refactored package structure --- run_scripts/run.py | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/run_scripts/run.py b/run_scripts/run.py index acd5c8c7..3b388906 100644 --- a/run_scripts/run.py +++ b/run_scripts/run.py @@ -2,7 +2,6 @@ import subprocess import logging - class run_params(object): N = 1 tc = "rb" @@ -18,27 +17,27 @@ def __init__(self): self.restart = False def single_run(self): - subprocess.call( - [sys.executable, "src/__main__.py", "-ic", self.tc, "-N", "%i" % self.N] - ) + subprocess.run( + ["pybella", "-ic", self.tc, "-N", "1"] + ) def queue_run(self): if self.ud is None and self.dap is None: assert 0, "ud or params must be defined" - subprocess.call( - [ - sys.executable, - "src/__main__.py", - "-ic", - self.tc, - "-N", - "%i" % self.N, - "queue", - "-w", - self.ud, - self.dap, - ] - ) + subprocess.run( + [ + "pybella", + "-ic", + self.tc, + "-N", + f"{self.N}", + "queue", + "-w", + self.ud, + self.dap, + ] + ) + def restart_set(self, path, fn, name, ts, te, ti): path += fn From 7aba2e143dfc3d45548740e56b070d29b93f7a7b Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 3 Jan 2025 19:51:49 +0800 Subject: [PATCH 22/76] renamed test_dycore to test_flow_solver --- run_scripts/{test_dycore.py => test_flow_solver.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename run_scripts/{test_dycore.py => test_flow_solver.py} (100%) diff --git a/run_scripts/test_dycore.py b/run_scripts/test_flow_solver.py similarity index 100% rename from run_scripts/test_dycore.py rename to run_scripts/test_flow_solver.py From e6e043d1b37e4aaa7f3a6f18dd25863150c13f7a Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 3 Jan 2025 20:05:07 +0800 Subject: [PATCH 23/76] commented out validation attempt in user_data validation step will be moved to dataclass structure --- src/utils/user_data.py | 262 ++++++++++++++++++++--------------------- 1 file changed, 131 insertions(+), 131 deletions(-) diff --git a/src/utils/user_data.py b/src/utils/user_data.py index d6a5d8b2..dda94f7f 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -128,194 +128,194 @@ def __init__(self,**kwargs): for key, value in kwargs.items(): setattr(self, key, value) - def compute_u_ref(self): - self.u_ref = self.h_ref / self.t_ref - self.compute_Msq() + # def compute_u_ref(self): + # self.u_ref = self.h_ref / self.t_ref + # self.compute_Msq() - def compute_Msq(self): - self.Msq = self.u_ref * self.u_ref / (self.R_gas * self.T_ref) + # def compute_Msq(self): + # self.Msq = self.u_ref * self.u_ref / (self.R_gas * self.T_ref) - def compute_gravity(self): - self.i_gravity = np.zeros((3)) - self.gravity_strength = np.zeros((3)) + # def compute_gravity(self): + # self.i_gravity = np.zeros((3)) + # self.gravity_strength = np.zeros((3)) - self.gravity_strength[1] = self.grav * self.h_ref / (self.R_gas * self.T_ref) + # self.gravity_strength[1] = self.grav * self.h_ref / (self.R_gas * self.T_ref) - for i in range(3): - if (self.gravity_strength[i] > 0.0) or (i == 1): - self.i_gravity[i] = 1 - self.gravity_direction = i + # for i in range(3): + # if (self.gravity_strength[i] > 0.0) or (i == 1): + # self.i_gravity[i] = 1 + # self.gravity_direction = i - def compute_coriolis(self): - self.i_coriolis = np.zeros((3)) - self.coriolis_strength = np.zeros((3)) + # def compute_coriolis(self): + # self.i_coriolis = np.zeros((3)) + # self.coriolis_strength = np.zeros((3)) - self.coriolis_strength[0] = self.omega * self.t_ref - self.coriolis_strength[2] = self.omega * self.t_ref + # self.coriolis_strength[0] = self.omega * self.t_ref + # self.coriolis_strength[2] = self.omega * self.t_ref - def compute_cp_gas(self): - self.cp_gas = self.gamm * self.R_gas / (self.gamm-1.0) + # def compute_cp_gas(self): + # self.cp_gas = self.gamm * self.R_gas / (self.gamm-1.0) - if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): - self.compute_N_ref() + # if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): + # self.compute_N_ref() - def compute_rho_ref(self): - self.rho_ref = self.p_ref / (self.R_gas * self.T_ref) + # def compute_rho_ref(self): + # self.rho_ref = self.p_ref / (self.R_gas * self.T_ref) - def compute_N_ref(self): - self.N_ref = self.grav / np.sqrt(self.cp_gas * self.T_ref) - self.Nsq_ref = self.N_ref * self.N_ref + # def compute_N_ref(self): + # self.N_ref = self.grav / np.sqrt(self.cp_gas * self.T_ref) + # self.Nsq_ref = self.N_ref * self.N_ref - def compute_Cs(self): - self.Cs = np.sqrt(self.gamm * self.R_gas * self.T_ref) + # def compute_Cs(self): + # self.Cs = np.sqrt(self.gamm * self.R_gas * self.T_ref) - @staticmethod - def stratification_function(y): - return 1.0 + # @staticmethod + # def stratification_function(y): + # return 1.0 - def update_ud(self, obj): - for key, value in obj.items(): - setattr(self, key, value) + # def update_ud(self, obj): + # for key, value in obj.items(): + # setattr(self, key, value) - ########################################## - # SETTER FUNCTIONS - ########################################## + # ########################################## + # # SETTER FUNCTIONS + # ########################################## - # gravity and Msq arguments - @property - def R_gas(self): - return self._R_gas + # # gravity and Msq arguments + # @property + # def R_gas(self): + # return self._R_gas - @R_gas.setter - def R_gas(self, val): - self._R_gas = val + # @R_gas.setter + # def R_gas(self, val): + # self._R_gas = val - if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): - self.compute_gravity() + # if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): + # self.compute_gravity() - if all(hasattr(self, attr) for attr in ["u_ref, R_gas", "T_ref"]): - self.compute_Msq() + # if all(hasattr(self, attr) for attr in ["u_ref, R_gas", "T_ref"]): + # self.compute_Msq() - if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): - self.compute_cp_gas() + # if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): + # self.compute_cp_gas() - if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): - self.compute_rho_ref() + # if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): + # self.compute_rho_ref() - if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): - self.compute_Cs() + # if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): + # self.compute_Cs() - @property - def T_ref(self): - return self._T_ref + # @property + # def T_ref(self): + # return self._T_ref - @T_ref.setter - def T_ref(self, val): - self._T_ref = val + # @T_ref.setter + # def T_ref(self, val): + # self._T_ref = val - if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): - self.compute_gravity() + # if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): + # self.compute_gravity() - if all(hasattr(self, attr) for attr in ["u_ref", "R_gas", "T_ref"]): - self.compute_Msq() + # if all(hasattr(self, attr) for attr in ["u_ref", "R_gas", "T_ref"]): + # self.compute_Msq() - if all(hasattr(self, attr) for attr in ["p_ref", "R_gas", "T_ref"]): - self.compute_rho_ref() + # if all(hasattr(self, attr) for attr in ["p_ref", "R_gas", "T_ref"]): + # self.compute_rho_ref() - if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): - self.compute_N_ref() + # if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): + # self.compute_N_ref() - if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): - self.compute_Cs() + # if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): + # self.compute_Cs() - # gravity arguments - @property - def grav(self): - return self._grav + # # gravity arguments + # @property + # def grav(self): + # return self._grav - @grav.setter - def grav(self, val): - self._grav = val + # @grav.setter + # def grav(self, val): + # self._grav = val - if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): - self.compute_gravity() + # if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): + # self.compute_gravity() - if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): - self.compute_N_ref() + # if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): + # self.compute_N_ref() - @property - def h_ref(self): - return self._h_ref + # @property + # def h_ref(self): + # return self._h_ref - @h_ref.setter - def h_ref(self, val): - self._h_ref = val + # @h_ref.setter + # def h_ref(self, val): + # self._h_ref = val - if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): - self.compute_u_ref() + # if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): + # self.compute_u_ref() - if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): - self.compute_gravity() + # if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): + # self.compute_gravity() - # coriolis arguments - @property - def t_ref(self): - return self._t_ref + # # coriolis arguments + # @property + # def t_ref(self): + # return self._t_ref - @t_ref.setter - def t_ref(self, val): - self._t_ref = val + # @t_ref.setter + # def t_ref(self, val): + # self._t_ref = val - if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): - self.compute_u_ref() + # if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): + # self.compute_u_ref() - if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): - self.compute_coriolis() + # if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): + # self.compute_coriolis() - @property - def omega(self): - return self._omega + # @property + # def omega(self): + # return self._omega - @omega.setter - def omega(self, val): - self._omega = val + # @omega.setter + # def omega(self, val): + # self._omega = val - if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): - self.compute_coriolis() + # if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): + # self.compute_coriolis() - # Cs and cp_gas argument - @property - def gamm(self): - return self._gamm + # # Cs and cp_gas argument + # @property + # def gamm(self): + # return self._gamm - @gamm.setter - def gamm(self, val): - self._gamm = val + # @gamm.setter + # def gamm(self, val): + # self._gamm = val - if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): - self.compute_cp_gas() + # if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): + # self.compute_cp_gas() - if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): - self.compute_Cs() + # if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): + # self.compute_Cs() - # rho_ref argument - @property - def p_ref(self): - return self._p_ref + # # rho_ref argument + # @property + # def p_ref(self): + # return self._p_ref - @p_ref.setter - def p_ref(self, val): - self._p_ref = val + # @p_ref.setter + # def p_ref(self, val): + # self._p_ref = val - if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): - self.compute_rho_ref() \ No newline at end of file + # if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): + # self.compute_rho_ref() \ No newline at end of file From 2165bed4ee231e34f8ad460d46877585d44fc737 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 6 Jan 2025 18:20:09 +0800 Subject: [PATCH 24/76] working towards a first test case for the blending module --- run_scripts/test_blending.py | 13 +++ src/tests/diagnostics.py | 22 ++---- src/tests/test_blending_warm_bubble.py | 105 +++++++++++++++++++++++++ src/utils/data_structures.py | 15 ++++ src/utils/io.py | 2 + src/utils/user_data.py | 12 +-- 6 files changed, 149 insertions(+), 20 deletions(-) create mode 100644 run_scripts/test_blending.py create mode 100644 src/tests/test_blending_warm_bubble.py diff --git a/run_scripts/test_blending.py b/run_scripts/test_blending.py new file mode 100644 index 00000000..6fd38336 --- /dev/null +++ b/run_scripts/test_blending.py @@ -0,0 +1,13 @@ +import pytest +import subprocess + +@pytest.mark.parametrize("ic", + ["test_travelling_vortex",]) +def test_single_run(ic): + result = subprocess.run( + ["pybella", "-ic", ic, "-N", "1"], + capture_output=True, + text=True + ) + + assert result.returncode == 0, result.stderr.splitlines()[-3:] \ No newline at end of file diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index a9ba8331..f8838c54 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -3,6 +3,8 @@ import numpy as np import yaml +from ..utils.data_structures import DiagnosticState + from ..vis import ( utils as vis_utils, plotting_tools as vis_pt @@ -27,7 +29,7 @@ def update_targets(self): self.__get_ens(tc, tp, attribute, summed=True) ) - with open("./src/tests/test_targets.yml", "w") as outfile: + with open("./src/tests/test_targets.yml", "a") as outfile: yaml.dump(self.arr_dump, outfile, default_flow_style=False) def test_do(self, Sol, p2n, plot=False): @@ -66,21 +68,13 @@ def test_do(self, Sol, p2n, plot=False): {'#' * 10} """.strip()) - def __init(self): - path = "./outputs/" + def __init(self, ds: DiagnosticState + ): - tv_2D = test_params( - "test_travelling_vortex", path, "target_travelling_vortex", 64, 64, [100] - ) - igw = test_params( - "test_internal_long_wave", path, "target_internal_long_wave", 301, 10, [30] - ) - lmbw = test_params("test_lamb_wave", path, "target_lamb_wave", 151, 15, [30]) + tp = test_params(ds) self.tps = { - "test_travelling_vortex": tv_2D, - "test_internal_long_wave": igw, - "test_lamb_wave": lmbw, + ds.test_name: tp, } # self.tps = [tv_2D] @@ -151,7 +145,7 @@ def __init__(self, name, path, fn, Nx, Ny, times): self.name = name self.dir = path + fn + "/" - self.fn = "%s_%i_%i" % (fn, Nx, Ny) + self.fn = f"{fn}_{Nx}_{Ny}" self.Nx = Nx self.Ny = Ny diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py new file mode 100644 index 00000000..7d6b73dc --- /dev/null +++ b/src/tests/test_blending_warm_bubble.py @@ -0,0 +1,105 @@ +import numpy as np +from ..flow_solver.physics import hydrostatics +from ..flow_solver.utils import boundary as bdry + +class UserData(object): + # Nsq_ref = grav * 1.3e-05 + + def __init__(self): + self.grav = 10.0 # [m/s^2] + self.t_ref = 1000.0 # [s] + + ########################################## + # NUMERICS + ########################################## + self.CFL = 0.5 + self.dtfixed0 = 100.0 + self.dtfixed = 100.0 + + self.inx = 160+1 + self.iny = 80+1 + self.inz = 1 + + self.tout = np.arange(0.0,1.01,0.01)[10:] + self.stepmax = 10000 + + self.output_base_name = "_rising_bubble" + # if self.is_compressible == 1: + # self.output_suffix = "_%i_%i_%.1f_comp" %(self.inx-1,self.iny-1,self.tout[-1]) + # if self.is_compressible == 0: + # self.output_suffix = "_%i_%i_%.1f_psinc" %(self.inx-1,self.iny-1,self.tout[-1]) + # if self.continuous_blending == True: + # self.output_suffix = "_%i_%i_%.1f" %(self.inx-1,self.iny-1,self.tout[-1]) + + self.continuous_blending = False + self.no_of_pi_initial = 1 + self.no_of_pi_transition = 0 + self.no_of_hy_initial = 0 + self.no_of_hy_transition = 0 + + self.initial_blending = True + + aux = 'debug_imbal_CFLfixed' + self.aux = aux + # self.output_suffix = "_%i_%i_%.1f_%s" %(self.inx-1,self.iny-1,self.tout[-1],aux) + # self.output_suffix += '_w=%i-%i' %(self.blending_weight*16.0,16.0-(self.blending_weight*16.0)) + + +def sol_init(Sol, mpv, elem, node, th, ud, seed=None): + u0 = ud.u_wind_speed + v0 = ud.v_wind_speed + w0 = ud.w_wind_speed + delth = 2.0 # [K] + + y0 = 0.2 + r0 = 0.2 + + g = ud.gravity_strength[1] + # print(ud.rho_ref) + + hydrostatics.state(mpv, elem, node, th, ud) + + x = elem.x + y = elem.y + + x, y = np.meshgrid(x,y) + + if seed != None: + np.random.seed(seed) + # y0 += (np.random.random()-.5)/2.0 + # delth += 10.0*(np.random.random()-.5) + delth += 10.0*(np.random.random()) + + if 'truth' in ud.aux: + np.random.seed(1234) + # delth += 10.0*(np.random.random()-.5) + delth += 10.0*(np.random.random()) + print(delth) + + r = np.sqrt((x)**2 + (y-y0)**2) / r0 + + p = np.repeat(mpv.HydroState.p0.reshape(1,-1),elem.icx,axis=0) + rhoY = np.repeat(mpv.HydroState.rhoY0.reshape(1,-1),elem.icx,axis=0) + + perturbation = (delth/300.0) * (np.cos(0.5 * np.pi * r)**2) + perturbation[np.where(r > 1.0)] = 0.0 + rho = rhoY / (ud.stratification(y) + perturbation.T) + + x_idx = slice(None) + y_idx = slice(None) + + u, v, w = u0, v0, w0 + + Sol.rho[x_idx,y_idx] = rho + Sol.rhou[x_idx,y_idx] = rho * u + Sol.rhov[x_idx,y_idx] = rho * v + Sol.rhow[x_idx,y_idx] = rho * w + Sol.rhoY[x_idx,y_idx] = rhoY + + p = mpv.HydroState_n.p0[0] + rhoY = mpv.HydroState_n.rhoY0[0] + mpv.p2_nodes[...] = (p - mpv.HydroState_n.p0[0]) / rhoY / ud.Msq + + bdry.set_explicit_boundary_data(Sol,elem,ud,th,mpv) + + return Sol \ No newline at end of file diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index 988ed7d3..8a95fab1 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -79,6 +79,21 @@ def get_grid(self) -> tuple[Grid, Grid]: def __getitem__(self, index): return self.members[index] + + +@dataclass +class DiagnosticState: + """ + Initialise diagnostic state for tests + + Consider removing run-specific parameters, e.g., (Nx, Ny), in future. + """ + test_name: str + file_name: str + Nx: int + Ny: int + steps: list + path: str = "./outputs/" @dataclass diff --git a/src/utils/io.py b/src/utils/io.py index bd4b65a6..f38876bc 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -646,6 +646,8 @@ def get_args(): from ..tests.test_internal_long_wave import UserData, sol_init elif ic == "test_lamb_wave": from ..tests.test_lamb_wave import UserData, sol_init + elif ic == "test_blending_warm_bubble": + from ..tests.test_blending_warm_bubble import UserData, sol_init if UserData is None or sol_init is None: assert 0, "Initial condition file is not well defined." diff --git a/src/utils/user_data.py b/src/utils/user_data.py index dda94f7f..c2565717 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -177,14 +177,14 @@ def __init__(self,**kwargs): # self.Cs = np.sqrt(self.gamm * self.R_gas * self.T_ref) - # @staticmethod - # def stratification_function(y): - # return 1.0 + @staticmethod + def stratification_function(y): + return 1.0 - # def update_ud(self, obj): - # for key, value in obj.items(): - # setattr(self, key, value) + def update_ud(self, obj): + for key, value in obj.items(): + setattr(self, key, value) # ########################################## # # SETTER FUNCTIONS From 9433f762f257e72b3350623443230edd1ade4a0d Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 6 Jan 2025 22:39:57 +0800 Subject: [PATCH 25/76] flow solver tests now work with the new diagnostics data structure more cleaning up is due for the diagnostics modules, but at least now the tests are no longer hardcoded. the blending has potential problems with failing tests, will look into this next. --- run_scripts/test_blending.py | 2 +- src/__main__.py | 2 +- src/flow_solver/discretisation/time_update.py | 274 +++++++++--------- src/tests/diagnostics.py | 21 +- src/tests/test_blending_warm_bubble.py | 11 + src/tests/test_internal_long_wave.py | 11 +- src/tests/test_lamb_wave.py | 12 +- src/tests/test_travelling_vortex.py | 12 +- src/utils/data_structures.py | 1 + src/utils/io.py | 1 + src/utils/prepare.py | 2 +- src/utils/user_data.py | 246 ++++++++-------- 12 files changed, 316 insertions(+), 279 deletions(-) diff --git a/run_scripts/test_blending.py b/run_scripts/test_blending.py index 6fd38336..8d976208 100644 --- a/run_scripts/test_blending.py +++ b/run_scripts/test_blending.py @@ -2,7 +2,7 @@ import subprocess @pytest.mark.parametrize("ic", - ["test_travelling_vortex",]) + ["test_blending_warm_bubble",]) def test_single_run(ic): result = subprocess.run( ["pybella", "-ic", ic, "-N", "1"], diff --git a/src/__main__.py b/src/__main__.py index de053f6b..49705324 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -81,7 +81,7 @@ def main(): if sst.ud.diag: sst.diag_comparison.test_do( - mem.sol, mem.mpv.p2_nodes, plot=sst.ud.diag_plot_compare + mem.sol, mem.mpv.p2_nodes, plot=sst.ud.diag_state.plot_compare ) futures.append(mem) diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index f704f72b..7906a76f 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -153,8 +153,8 @@ def do( if c1 or c2: logging.info("nonhydrostatic to hydrostatic conversion...") ud.is_nonhydrostatic = 0 - if test_hydrob == False: - dt *= 0.5 + # if test_hydrob == False: + # dt *= 0.5 ###################################################### @@ -485,141 +485,141 @@ def do( if c1 or c2: logging.info(termcolor.colored("hydrostatic to nonhydrostatic conversion...", "blue")) - writer.write_all(mem, str(label) + "_half_full") - writer.populate(str(label) + "_ic", "pwchi", Sol.pwchi) - - if test_hydrob == False: - Sol = copy.deepcopy(Sol_half_old) - # mpv = copy.deepcopy(mpv_half_old) - - logging.info(termcolor.colored("test_hydrob == False", "red")) - writer.write_all(mem, str(label) + "_quarter") - - writer.populate(str(label) + "_quarter", "pwchi", Sol.pwchi) - - logging.info("quarter dt = %.8f" % (dt * 0.5)) - - ret = do( - Sol_half_old, - flux_half_old, - mpv_half_old, - dt - 0.5 * dt, - dt + 0.5 * dt, - ud, - elem, - node, - [0, 0], - th, - bld=None, - writer=None, - debug=False, - ) - - Sol_tu = copy.deepcopy(ret[0]) - # mpv_tu = copy.deepcopy(ret[2]) - Sol.rho[...] = Sol_tu.rho_half - Sol.rhou[...] = Sol_tu.rhou_half - Sol.rhov[...] = Sol_tu.rhov_half - Sol.rhow[...] = Sol_tu.rhow_half - Sol.rhoX[...] = Sol_tu.rhoX_half - Sol.rhoY[...] = Sol_tu.rhoY_half - Sol.pwchi[...] = Sol_tu.pwchi - - # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half - - writer.write_all(mem, str(label) + "_half") - - writer.populate(str(label) + "_half", "pwchi", Sol.pwchi) - - ret = do( - Sol, - flux, - mpv, - dt, - 2.0 * dt, - ud, - elem, - node, - [0, 0], - th, - bld=None, - writer=None, - debug=False, - ) - - Sol = copy.deepcopy(ret[0]) - flux = copy.deepcopy(ret[1]) - mpv = copy.deepcopy(ret[2]) - - if test_hydrob == True: - Sol = copy.deepcopy(Sol_half_old) - # mpv = copy.deepcopy(mpv_half_old) - - logging.info(termcolor.colored("test_hydrob == False", "red")) - writer.write_all(mem, str(label) + "_quarter") - - # writer.populate(str(label)+'_quarter', 'pwchi', Sol.pwchi) - - logging.info("quarter dt = %.8f" % (dt * 0.5)) - - ret = do( - Sol_half_old, - flux_half_old, - mpv_half_old, - dt - 0.5 * dt, - dt + 0.5 * dt, - ud, - elem, - node, - [0, 0], - th, - bld=None, - writer=None, - debug=False, - ) - - Sol_tu = copy.deepcopy(ret[0]) - # mpv_tu = copy.deepcopy(ret[2]) - Sol.rho[...] = Sol_tu.rho_half - Sol.rhou[...] = Sol_tu.rhou_half - Sol.rhov[...] = Sol_tu.rhov_half - Sol.rhow[...] = Sol_tu.rhow_half - Sol.rhoX[...] = Sol_tu.rhoX_half - Sol.rhoY[...] = Sol_tu.rhoY_half - Sol.pwchi[...] = Sol_tu.pwchi - - # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half - - # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') - - # writer.populate(str(label)+'_half', 'pwchi', Sol.pwchi) - - ret = do( - Sol, - flux, - mpv, - dt, - 2.0 * dt, - ud, - elem, - node, - [0, 0], - th, - bld=None, - writer=None, - debug=False, - ) - - Sol = copy.deepcopy(ret[0]) - flux = copy.deepcopy(ret[1]) - mpv = copy.deepcopy(ret[2]) - # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') - # writer.populate(str(label)+'_half', 'pwchi', Sol.pwchi) - - logging.info(termcolor.colored("test_hydrob == True", "red")) - - if test_hydrob == False: - dt *= 2.0 + # writer.write_all(mem, str(label) + "_half_full") + # writer.populate(str(label) + "_ic", "pwchi", Sol.pwchi) + + # if test_hydrob == False: + # Sol = copy.deepcopy(Sol_half_old) + # # mpv = copy.deepcopy(mpv_half_old) + + # logging.info(termcolor.colored("test_hydrob == False", "red")) + # writer.write_all(mem, str(label) + "_quarter") + + # writer.populate(str(label) + "_quarter", "pwchi", Sol.pwchi) + + # logging.info("quarter dt = %.8f" % (dt * 0.5)) + + # ret = do( + # Sol_half_old, + # flux_half_old, + # mpv_half_old, + # dt - 0.5 * dt, + # dt + 0.5 * dt, + # ud, + # elem, + # node, + # [0, 0], + # th, + # bld=None, + # writer=None, + # debug=False, + # ) + + # Sol_tu = copy.deepcopy(ret[0]) + # # mpv_tu = copy.deepcopy(ret[2]) + # Sol.rho[...] = Sol_tu.rho_half + # Sol.rhou[...] = Sol_tu.rhou_half + # Sol.rhov[...] = Sol_tu.rhov_half + # Sol.rhow[...] = Sol_tu.rhow_half + # Sol.rhoX[...] = Sol_tu.rhoX_half + # Sol.rhoY[...] = Sol_tu.rhoY_half + # Sol.pwchi[...] = Sol_tu.pwchi + + # # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half + + # writer.write_all(mem, str(label) + "_half") + + # writer.populate(str(label) + "_half", "pwchi", Sol.pwchi) + + # ret = do( + # Sol, + # flux, + # mpv, + # dt, + # 2.0 * dt, + # ud, + # elem, + # node, + # [0, 0], + # th, + # bld=None, + # writer=None, + # debug=False, + # ) + + # Sol = copy.deepcopy(ret[0]) + # flux = copy.deepcopy(ret[1]) + # mpv = copy.deepcopy(ret[2]) + + # if test_hydrob == True: + # Sol = copy.deepcopy(Sol_half_old) + # # mpv = copy.deepcopy(mpv_half_old) + + # logging.info(termcolor.colored("test_hydrob == False", "red")) + # writer.write_all(mem, str(label) + "_quarter") + + # # writer.populate(str(label)+'_quarter', 'pwchi', Sol.pwchi) + + # logging.info("quarter dt = %.8f" % (dt * 0.5)) + + # ret = do( + # Sol_half_old, + # flux_half_old, + # mpv_half_old, + # dt - 0.5 * dt, + # dt + 0.5 * dt, + # ud, + # elem, + # node, + # [0, 0], + # th, + # bld=None, + # writer=None, + # debug=False, + # ) + + # Sol_tu = copy.deepcopy(ret[0]) + # # mpv_tu = copy.deepcopy(ret[2]) + # Sol.rho[...] = Sol_tu.rho_half + # Sol.rhou[...] = Sol_tu.rhou_half + # Sol.rhov[...] = Sol_tu.rhov_half + # Sol.rhow[...] = Sol_tu.rhow_half + # Sol.rhoX[...] = Sol_tu.rhoX_half + # Sol.rhoY[...] = Sol_tu.rhoY_half + # Sol.pwchi[...] = Sol_tu.pwchi + + # # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half + + # # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') + + # # writer.populate(str(label)+'_half', 'pwchi', Sol.pwchi) + + # ret = do( + # Sol, + # flux, + # mpv, + # dt, + # 2.0 * dt, + # ud, + # elem, + # node, + # [0, 0], + # th, + # bld=None, + # writer=None, + # debug=False, + # ) + + # Sol = copy.deepcopy(ret[0]) + # flux = copy.deepcopy(ret[1]) + # mpv = copy.deepcopy(ret[2]) + # # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') + # # writer.populate(str(label)+'_half', 'pwchi', Sol.pwchi) + + # logging.info(termcolor.colored("test_hydrob == True", "red")) + + # if test_hydrob == False: + # dt *= 2.0 if c2: ud.is_nonhydrostatic = 1 diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index f8838c54..959dc344 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -12,9 +12,10 @@ class compare_sol(object): - def __init__(self, current_run): - self.current_run = current_run - self.__init() + def __init__(self, diag_state: DiagnosticState): + self.diag_state = diag_state + self.current_run = diag_state.test_name + self.__init(diag_state) self.__get_tc() def update_targets(self): @@ -141,16 +142,16 @@ def __get_ens(tc, params, attribute, summed=False): class test_params(object): - def __init__(self, name, path, fn, Nx, Ny, times): + def __init__(self, ds: DiagnosticState): - self.name = name - self.dir = path + fn + "/" - self.fn = f"{fn}_{Nx}_{Ny}" + self.name = ds.test_name + self.dir = ds.path + ds.file_name + "/" + self.fn = f"{ds.file_name}_{ds.Nx}_{ds.Ny}" - self.Nx = Nx - self.Ny = Ny + self.Nx = ds.Nx + self.Ny = ds.Ny - self.times = times + self.times = ds.steps self.l_typ = "WINDOW_STEP" self.attributes = ["rho", "rhou", "rhov", "rhow", "rhoY", "rhoX", "p2_nodes"] diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 7d6b73dc..49f20afe 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -2,6 +2,8 @@ from ..flow_solver.physics import hydrostatics from ..flow_solver.utils import boundary as bdry +from ..utils.data_structures import DiagnosticState + class UserData(object): # Nsq_ref = grav * 1.3e-05 @@ -44,6 +46,15 @@ def __init__(self): # self.output_suffix = "_%i_%i_%.1f_%s" %(self.inx-1,self.iny-1,self.tout[-1],aux) # self.output_suffix += '_w=%i-%i' %(self.blending_weight*16.0,16.0-(self.blending_weight*16.0)) + self.diag = True + + self.diag_state = DiagnosticState( + test_name="test_blending_warm_bubble", + file_name="test_blending_warm_bubble", + Nx=self.inx, + Ny=self.iny, + steps=[self.stepmax], + ) def sol_init(Sol, mpv, elem, node, th, ud, seed=None): u0 = ud.u_wind_speed diff --git a/src/tests/test_internal_long_wave.py b/src/tests/test_internal_long_wave.py index c0374224..230d910e 100644 --- a/src/tests/test_internal_long_wave.py +++ b/src/tests/test_internal_long_wave.py @@ -7,6 +7,7 @@ ) from ..flow_solver.physics import hydrostatics +from ..utils.data_structures import DiagnosticState class UserData(object): NSPEC = 1 @@ -157,8 +158,14 @@ def __init__(self): self.rhoe = self.rhoe_method self.diag = True - self.diag_current_run = "test_internal_long_wave" - self.diag_plot_compare = False + + self.diag_state = DiagnosticState( + test_name="test_internal_long_wave", + file_name="test_internal_long_wave", + Nx=self.inx, + Ny=self.iny, + steps=[self.stepmax], + ) def stratification_function(self, y): Nsq = self.Nsq_ref * self.t_ref * self.t_ref diff --git a/src/tests/test_lamb_wave.py b/src/tests/test_lamb_wave.py index 381f8c6b..ef2bff9c 100644 --- a/src/tests/test_lamb_wave.py +++ b/src/tests/test_lamb_wave.py @@ -7,6 +7,8 @@ from ..flow_solver.physics import hydrostatics +from .. utils.data_structures import DiagnosticState + class UserData(object): NSPEC = 1 grav = 9.81 # [m s^{-2}] @@ -140,8 +142,14 @@ def __init__(self): self.output_suffix = "_%i_%i" %(self.inx-1,self.iny-1) self.diag = True - self.diag_current_run = 'test_lamb_wave' - self.diag_plot_compare = False + self.diag_state = DiagnosticState( + test_name="test_lamb_wave", + file_name="test_lamb_wave", + Nx=self.inx, + Ny=self.iny, + steps=[self.stepmax], + ) + self.stratification = self.stratification_wrapper self.rayleigh_bc = self.rayleigh_bc_function diff --git a/src/tests/test_travelling_vortex.py b/src/tests/test_travelling_vortex.py index 9145d488..10d47361 100644 --- a/src/tests/test_travelling_vortex.py +++ b/src/tests/test_travelling_vortex.py @@ -6,6 +6,8 @@ from ..flow_solver.physics import hydrostatics from ..flow_solver.physics.low_mach import second_projection as lm_sp +from .. utils.data_structures import DiagnosticState + import logging @@ -144,8 +146,14 @@ def __init__(self): self.output_timesteps = True self.diag = True - self.diag_current_run = "test_travelling_vortex" - self.diag_plot_compare = False + + self.diag_state = DiagnosticState( + test_name="test_travelling_vortex", + file_name="test_travelling_vortex", + Nx=self.inx, + Ny=self.iny, + steps=[self.stepmax], + ) self.autogen_fn = False diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index 8a95fab1..f218dfd5 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -94,6 +94,7 @@ class DiagnosticState: Ny: int steps: list path: str = "./outputs/" + plot_compare: bool = False @dataclass diff --git a/src/utils/io.py b/src/utils/io.py index f38876bc..9635e90f 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -560,6 +560,7 @@ def get_args(): "test_travelling_vortex", "test_internal_long_wave", "test_lamb_wave", + "test_blending_warm_bubble", }, ) diff --git a/src/utils/prepare.py b/src/utils/prepare.py index 6c5006fe..0700443a 100644 --- a/src/utils/prepare.py +++ b/src/utils/prepare.py @@ -67,7 +67,7 @@ def initialise(): # Initialise test module ########################################################## if ud.diag: - diag_comparison = diag.compare_sol(ud.diag_current_run) + diag_comparison = diag.compare_sol(ud.diag_state) else: diag_comparison = None diff --git a/src/utils/user_data.py b/src/utils/user_data.py index c2565717..54615fb1 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -112,7 +112,7 @@ def __init__(self,**kwargs): # DIAGNOSTICS ########################################## self.diag = False - self.diag_plot_compare = False + self.diag_state = None ########################################## @@ -128,53 +128,53 @@ def __init__(self,**kwargs): for key, value in kwargs.items(): setattr(self, key, value) - # def compute_u_ref(self): - # self.u_ref = self.h_ref / self.t_ref - # self.compute_Msq() + def compute_u_ref(self): + self.u_ref = self.h_ref / self.t_ref + self.compute_Msq() - # def compute_Msq(self): - # self.Msq = self.u_ref * self.u_ref / (self.R_gas * self.T_ref) + def compute_Msq(self): + self.Msq = self.u_ref * self.u_ref / (self.R_gas * self.T_ref) - # def compute_gravity(self): - # self.i_gravity = np.zeros((3)) - # self.gravity_strength = np.zeros((3)) + def compute_gravity(self): + self.i_gravity = np.zeros((3)) + self.gravity_strength = np.zeros((3)) - # self.gravity_strength[1] = self.grav * self.h_ref / (self.R_gas * self.T_ref) + self.gravity_strength[1] = self.grav * self.h_ref / (self.R_gas * self.T_ref) - # for i in range(3): - # if (self.gravity_strength[i] > 0.0) or (i == 1): - # self.i_gravity[i] = 1 - # self.gravity_direction = i + for i in range(3): + if (self.gravity_strength[i] > 0.0) or (i == 1): + self.i_gravity[i] = 1 + self.gravity_direction = i - # def compute_coriolis(self): - # self.i_coriolis = np.zeros((3)) - # self.coriolis_strength = np.zeros((3)) + def compute_coriolis(self): + self.i_coriolis = np.zeros((3)) + self.coriolis_strength = np.zeros((3)) - # self.coriolis_strength[0] = self.omega * self.t_ref - # self.coriolis_strength[2] = self.omega * self.t_ref + self.coriolis_strength[0] = self.omega * self.t_ref + self.coriolis_strength[2] = self.omega * self.t_ref - # def compute_cp_gas(self): - # self.cp_gas = self.gamm * self.R_gas / (self.gamm-1.0) + def compute_cp_gas(self): + self.cp_gas = self.gamm * self.R_gas / (self.gamm-1.0) - # if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): - # self.compute_N_ref() + if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): + self.compute_N_ref() - # def compute_rho_ref(self): - # self.rho_ref = self.p_ref / (self.R_gas * self.T_ref) + def compute_rho_ref(self): + self.rho_ref = self.p_ref / (self.R_gas * self.T_ref) - # def compute_N_ref(self): - # self.N_ref = self.grav / np.sqrt(self.cp_gas * self.T_ref) - # self.Nsq_ref = self.N_ref * self.N_ref + def compute_N_ref(self): + self.N_ref = self.grav / np.sqrt(self.cp_gas * self.T_ref) + self.Nsq_ref = self.N_ref * self.N_ref - # def compute_Cs(self): - # self.Cs = np.sqrt(self.gamm * self.R_gas * self.T_ref) + def compute_Cs(self): + self.Cs = np.sqrt(self.gamm * self.R_gas * self.T_ref) @staticmethod @@ -190,132 +190,132 @@ def update_ud(self, obj): # # SETTER FUNCTIONS # ########################################## - # # gravity and Msq arguments - # @property - # def R_gas(self): - # return self._R_gas + # gravity and Msq arguments + @property + def R_gas(self): + return self._R_gas - # @R_gas.setter - # def R_gas(self, val): - # self._R_gas = val + @R_gas.setter + def R_gas(self, val): + self._R_gas = val - # if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): - # self.compute_gravity() + if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): + self.compute_gravity() - # if all(hasattr(self, attr) for attr in ["u_ref, R_gas", "T_ref"]): - # self.compute_Msq() + if all(hasattr(self, attr) for attr in ["u_ref, R_gas", "T_ref"]): + self.compute_Msq() - # if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): - # self.compute_cp_gas() + if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): + self.compute_cp_gas() - # if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): - # self.compute_rho_ref() + if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): + self.compute_rho_ref() - # if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): - # self.compute_Cs() + if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): + self.compute_Cs() - # @property - # def T_ref(self): - # return self._T_ref + @property + def T_ref(self): + return self._T_ref - # @T_ref.setter - # def T_ref(self, val): - # self._T_ref = val + @T_ref.setter + def T_ref(self, val): + self._T_ref = val - # if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): - # self.compute_gravity() + if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): + self.compute_gravity() - # if all(hasattr(self, attr) for attr in ["u_ref", "R_gas", "T_ref"]): - # self.compute_Msq() + if all(hasattr(self, attr) for attr in ["u_ref", "R_gas", "T_ref"]): + self.compute_Msq() - # if all(hasattr(self, attr) for attr in ["p_ref", "R_gas", "T_ref"]): - # self.compute_rho_ref() + if all(hasattr(self, attr) for attr in ["p_ref", "R_gas", "T_ref"]): + self.compute_rho_ref() - # if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): - # self.compute_N_ref() + if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): + self.compute_N_ref() - # if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): - # self.compute_Cs() + if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): + self.compute_Cs() - # # gravity arguments - # @property - # def grav(self): - # return self._grav + # gravity arguments + @property + def grav(self): + return self._grav - # @grav.setter - # def grav(self, val): - # self._grav = val + @grav.setter + def grav(self, val): + self._grav = val - # if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): - # self.compute_gravity() + if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): + self.compute_gravity() - # if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): - # self.compute_N_ref() + if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): + self.compute_N_ref() - # @property - # def h_ref(self): - # return self._h_ref + @property + def h_ref(self): + return self._h_ref - # @h_ref.setter - # def h_ref(self, val): - # self._h_ref = val + @h_ref.setter + def h_ref(self, val): + self._h_ref = val - # if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): - # self.compute_u_ref() + if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): + self.compute_u_ref() - # if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): - # self.compute_gravity() + if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): + self.compute_gravity() - # # coriolis arguments - # @property - # def t_ref(self): - # return self._t_ref + # coriolis arguments + @property + def t_ref(self): + return self._t_ref - # @t_ref.setter - # def t_ref(self, val): - # self._t_ref = val + @t_ref.setter + def t_ref(self, val): + self._t_ref = val - # if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): - # self.compute_u_ref() + if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): + self.compute_u_ref() - # if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): - # self.compute_coriolis() + if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): + self.compute_coriolis() - # @property - # def omega(self): - # return self._omega + @property + def omega(self): + return self._omega - # @omega.setter - # def omega(self, val): - # self._omega = val + @omega.setter + def omega(self, val): + self._omega = val - # if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): - # self.compute_coriolis() + if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): + self.compute_coriolis() - # # Cs and cp_gas argument - # @property - # def gamm(self): - # return self._gamm + # Cs and cp_gas argument + @property + def gamm(self): + return self._gamm - # @gamm.setter - # def gamm(self, val): - # self._gamm = val + @gamm.setter + def gamm(self, val): + self._gamm = val - # if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): - # self.compute_cp_gas() + if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): + self.compute_cp_gas() - # if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): - # self.compute_Cs() + if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): + self.compute_Cs() - # # rho_ref argument - # @property - # def p_ref(self): - # return self._p_ref + # rho_ref argument + @property + def p_ref(self): + return self._p_ref - # @p_ref.setter - # def p_ref(self, val): - # self._p_ref = val + @p_ref.setter + def p_ref(self, val): + self._p_ref = val - # if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): - # self.compute_rho_ref() \ No newline at end of file + if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): + self.compute_rho_ref() \ No newline at end of file From c7ff474a1c3861c31391b9a20f787242c114b222 Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 10 Jan 2025 19:01:28 +0800 Subject: [PATCH 26/76] cleaned up blending module; do_blending_bef_timestep accepts mem data container --- src/flow_solver/discretisation/time_update.py | 7 +--- src/interfaces/dynamics_blending/schemes.py | 35 +++++++++---------- src/tests/test_blending_warm_bubble.py | 2 +- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 7906a76f..027c9383 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -161,13 +161,8 @@ def do( # Blending : Do blending before timestep ###################################################### swe_to_lake, Sol, mpv, t = schemes.blending_before_timestep( - Sol, - flux, - mpv, + mem, bld, - elem, - node, - th, ud, label, writer, diff --git a/src/interfaces/dynamics_blending/schemes.py b/src/interfaces/dynamics_blending/schemes.py index c2042bcb..58dd3958 100644 --- a/src/interfaces/dynamics_blending/schemes.py +++ b/src/interfaces/dynamics_blending/schemes.py @@ -1,7 +1,6 @@ import logging import copy -import termcolor import numpy as np from scipy import signal @@ -105,7 +104,7 @@ def update_p2n(self, Sol, mpv, node, th, ud): def do_comp_to_psinc_conv(Sol, mpv, bld, elem, node, th, ud, label, writer): - logging.info(termcolor.colored("Converting COMP to PSINC", "blue")) + logging.info("Converting COMP to PSINC") dp2n = mpv.p2_nodes bld.convert_p2n(dp2n) bld.update_Sol(Sol, elem, node, th, ud, mpv, "bef", label=label, writer=writer) @@ -117,13 +116,13 @@ def do_comp_to_psinc_conv(Sol, mpv, bld, elem, node, th, ud, label, writer): def do_psinc_to_comp_conv( Sol, flux, mpv, bld, elem, node, th, ud, label, writer, step, window_step, t, dt ): - from flow_solver.discretisation import time_update + from ...flow_solver.discretisation import time_update - logging.info(termcolor.colored("Blending... step = %i" % step, "blue")) + logging.info(f"Blending... step = {step}") Sol_freeze = copy.deepcopy(Sol) mpv_freeze = copy.deepcopy(mpv) - ret = time_update.time_update( + ret = time_update.do( Sol, flux, mpv, @@ -162,7 +161,7 @@ def do_psinc_to_comp_conv( if writer != None: writer.populate(str(label) + "_after_full_step", "dp2n", dp2n) - logging.info(termcolor.colored("Converting PSINC to COMP", "blue")) + logging.info("Converting PSINC to COMP") bld.convert_p2n(dp2n) bld.update_Sol(Sol, elem, node, th, ud, mpv, "aft", label=label, writer=writer) bld.update_p2n(Sol, mpv, node, th, ud) @@ -176,7 +175,7 @@ def do_psinc_to_comp_conv( def do_swe_to_lake_conv(Sol, mpv, elem, node, ud, th, writer, label, debug): - logging.info(termcolor.colored("swe to lake conversion...", "blue")) + logging.info("swe to lake conversion...") H1 = Sol.rho[ :, @@ -215,7 +214,7 @@ def do_swe_to_lake_conv(Sol, mpv, elem, node, ud, th, writer, label, debug): def do_lake_to_swe_conv( Sol, flux, mpv, elem, node, ud, th, writer, label, debug, step, window_step, t, dt ): - from flow_solver.discretisation import time_update + from ...flow_solver.discretisation import time_update if debug == True: writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_lake_time_step") @@ -223,7 +222,7 @@ def do_lake_to_swe_conv( Sol_freeze = copy.deepcopy(Sol) mpv_freeze = copy.deepcopy(mpv) - logging.info(termcolor.colored("doing lake-to-swe time-update...", "blue")) + logging.info("doing lake-to-swe time-update...") ret = time_update.time_update( Sol, flux, @@ -259,7 +258,7 @@ def do_lake_to_swe_conv( mpv.p2_nodes[...] = dp2n H10 = mpv.p2_nodes[:, 2:-2, :].mean(axis=1) - logging.info(termcolor.colored("lake to swe conversion...", "blue")) + logging.info("lake to swe conversion...") H10 -= H10.mean() # define 2D kernel @@ -294,7 +293,7 @@ def do_nonhydro_to_hydro_conv( Sol, flux, mpv, bld, elem, node, th, ud, label, writer, step, window_step, t, dt ): - logging.info(termcolor.colored("nonhydrostatic to hydrostatic conversion...", "blue")) + logging.info("nonhydrostatic to hydrostatic conversion...") # bld.convert_p2n(mpv.p2_nodes) # bld.update_Sol(Sol,elem,node,th,ud,mpv,'bef',label=label,writer=writer) # Sol.rhov = Sol.rhov_half @@ -324,8 +323,8 @@ def do_hydro_to_nonhydro_conv( Sol, flux, mpv, bld, elem, node, th, ud, label, writer, step, window_step, t, dt ): - logging.info(termcolor.colored("hydrostatic to nonhydrostatic conversion...", "blue")) - logging.info(termcolor.colored("Blending... step = %i" % step, "blue")) + logging.info("hydrostatic to nonhydrostatic conversion...") + logging.info(f"Blending... step = {step}") # Sol_tmp = deepcopy(Sol) # flux_tmp = deepcopy(flux) @@ -383,13 +382,8 @@ def do_hydro_to_nonhydro_conv( # Blending calls from data.py ###################################################### def blending_before_timestep( - Sol, - flux, - mpv, + mem, bld, - elem, - node, - th, ud, label, writer, @@ -403,6 +397,9 @@ def blending_before_timestep( ###################################################### # Blending : Do full regime to limit regime conversion ###################################################### + # do unpacking + elem, node, Sol, flux, mpv, th, time = mem + # these make sure that we are the correct window step if bld is not None and window_step == 0: # these make sure that blending switches are on diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 49f20afe..8ae59970 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -41,7 +41,7 @@ def __init__(self): self.initial_blending = True - aux = 'debug_imbal_CFLfixed' + aux = 'CFLfixed' self.aux = aux # self.output_suffix = "_%i_%i_%.1f_%s" %(self.inx-1,self.iny-1,self.tout[-1],aux) # self.output_suffix += '_w=%i-%i' %(self.blending_weight*16.0,16.0-(self.blending_weight*16.0)) From a4c7b5cc3171519ed9df22b4ac93e9866bc88888 Mon Sep 17 00:00:00 2001 From: raychew Date: Sun, 12 Jan 2025 15:35:27 +0800 Subject: [PATCH 27/76] fixed failing flow solver tests I was not updating mem attributes in the time update while loop. This means that everytime the blending scheme sees mem, it resets the solution fields to the beginning of the assimilation window. --- src/flow_solver/discretisation/time_update.py | 14 ++++++++++---- src/interfaces/dynamics_blending/schemes.py | 8 +++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 027c9383..167d2f28 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -161,8 +161,14 @@ def do( # Blending : Do blending before timestep ###################################################### swe_to_lake, Sol, mpv, t = schemes.blending_before_timestep( - mem, + # Sol, + # flux, + # mpv, bld, + mem, + # elem, + # node, + # th, ud, label, writer, @@ -641,9 +647,9 @@ def do( time.step = step time.window_step = window_step - mem.sol = Sol - mem.flux = flux - mem.mpv = mpv + mem.sol = Sol + mem.flux = flux + mem.mpv = mpv return mem # return [Sol, flux, mpv, [window_step, step]] diff --git a/src/interfaces/dynamics_blending/schemes.py b/src/interfaces/dynamics_blending/schemes.py index 58dd3958..1f3e7597 100644 --- a/src/interfaces/dynamics_blending/schemes.py +++ b/src/interfaces/dynamics_blending/schemes.py @@ -382,8 +382,14 @@ def do_hydro_to_nonhydro_conv( # Blending calls from data.py ###################################################### def blending_before_timestep( - mem, + # Sol, + # flux, + # mpv, bld, + mem, + # elem, + # node, + # th, ud, label, writer, From 8068cd2151b5915834412e1c099148d832058050 Mon Sep 17 00:00:00 2001 From: raychew Date: Sun, 12 Jan 2025 17:07:24 +0800 Subject: [PATCH 28/76] blending routine runs with new data structures I have not yet checked if the initial blending results are correct; will do this via the diagnostics module, but it does not work yet, as I have not yet generalised the target generation features. --- src/flow_solver/discretisation/time_update.py | 10 +-- src/interfaces/dynamics_blending/schemes.py | 76 ++++++++----------- 2 files changed, 33 insertions(+), 53 deletions(-) diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 167d2f28..9dbbf3a0 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -161,15 +161,9 @@ def do( # Blending : Do blending before timestep ###################################################### swe_to_lake, Sol, mpv, t = schemes.blending_before_timestep( - # Sol, - # flux, - # mpv, - bld, + sst, mem, - # elem, - # node, - # th, - ud, + bld, label, writer, step, diff --git a/src/interfaces/dynamics_blending/schemes.py b/src/interfaces/dynamics_blending/schemes.py index 1f3e7597..596f672d 100644 --- a/src/interfaces/dynamics_blending/schemes.py +++ b/src/interfaces/dynamics_blending/schemes.py @@ -114,34 +114,32 @@ def do_comp_to_psinc_conv(Sol, mpv, bld, elem, node, th, ud, label, writer): def do_psinc_to_comp_conv( - Sol, flux, mpv, bld, elem, node, th, ud, label, writer, step, window_step, t, dt + sst, mem, bld, label, writer, step, tout, ): from ...flow_solver.discretisation import time_update logging.info(f"Blending... step = {step}") - Sol_freeze = copy.deepcopy(Sol) - mpv_freeze = copy.deepcopy(mpv) + Sol_freeze = copy.deepcopy(mem.sol) + mpv_freeze = copy.deepcopy(mem.mpv) + + mem.time.step -= 1 + mem.time.window_step = 0 ret = time_update.do( - Sol, - flux, - mpv, - t, - t + dt, - ud, - elem, - node, - [0, step - 1], - th, + sst, + mem, + tout, bld=None, writer=None, debug=False, ) + ud = sst.ud + fac_old = ud.blending_weight fac_new = 1.0 - fac_old - dp2n_0 = fac_new * ret[2].p2_nodes_half + fac_old * mpv_freeze.p2_nodes_half - dp2n_1 = fac_new * ret[2].p2_nodes + fac_old * mpv_freeze.p2_nodes + dp2n_0 = fac_new * ret.mpv.p2_nodes_half + fac_old * mpv_freeze.p2_nodes_half + dp2n_1 = fac_new * ret.mpv.p2_nodes + fac_old * mpv_freeze.p2_nodes if ud.blending_type == "half": dp2n = dp2n_0 @@ -159,6 +157,8 @@ def do_psinc_to_comp_conv( Sol = Sol_freeze mpv = mpv_freeze + elem, node, _, _, _, th, _ = mem + if writer != None: writer.populate(str(label) + "_after_full_step", "dp2n", dp2n) logging.info("Converting PSINC to COMP") @@ -382,15 +382,9 @@ def do_hydro_to_nonhydro_conv( # Blending calls from data.py ###################################################### def blending_before_timestep( - # Sol, - # flux, - # mpv, - bld, + sst, mem, - # elem, - # node, - # th, - ud, + bld, label, writer, step, @@ -404,7 +398,8 @@ def blending_before_timestep( # Blending : Do full regime to limit regime conversion ###################################################### # do unpacking - elem, node, Sol, flux, mpv, th, time = mem + elem, node, Sol, flux, mpv, th, _ = mem + ud = sst.ud # these make sure that we are the correct window step if bld is not None and window_step == 0: @@ -419,6 +414,10 @@ def blending_before_timestep( Sol, mpv, bld, elem, node, th, ud, label, writer ) + + mem.Sol = Sol + mem.mpv = mpv + ###################################################### # Blending : Do full steps or transition steps? ###################################################### @@ -434,21 +433,15 @@ def blending_before_timestep( if c_init and bld.cb and ud.blending_conv is not None: # distinguish between Euler and SWE blending if ud.blending_conv != "swe": - Sol, mpv = do_psinc_to_comp_conv( - Sol, - flux, - mpv, + do_psinc_to_comp_conv( + sst, + mem, bld, - elem, - node, - th, ud, label, writer, step, - window_step, - t, - dt, + t + dt, ) ###################################################### @@ -496,21 +489,14 @@ def blending_before_timestep( ): # Distinguish between SWE and Euler blendings if ud.blending_conv != "swe": - Sol, mpv = do_psinc_to_comp_conv( - Sol, - flux, - mpv, + do_psinc_to_comp_conv( + sst, + mem, bld, - elem, - node, - th, - ud, label, writer, step, - window_step, - t, - dt, + t + dt, ) ud.is_compressible = 1 ud.compressibility = 1.0 From 613a20f9f0dfcc044e5c13b0a22a55a52e2c6311 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 13 Jan 2025 01:47:05 +0800 Subject: [PATCH 29/76] WIP: generalised generate target for diagnostics and reinstated plot_compare nothing really works yet, because there seems to be a discrepancy between the target saved and the test values computed and compared against the target values. This has something to do with how the time steps are counted. Will need to carry on debugging. --- run_scripts/test_blending.py | 7 ++- src/__main__.py | 11 ++-- src/flow_solver/discretisation/time_update.py | 5 +- src/interfaces/dynamics_blending/schemes.py | 54 +++++++++--------- src/tests/diagnostics.py | 34 +++++++----- src/tests/test_blending_warm_bubble.py | 55 ++++++++----------- src/tests/test_internal_long_wave.py | 1 + 7 files changed, 88 insertions(+), 79 deletions(-) diff --git a/run_scripts/test_blending.py b/run_scripts/test_blending.py index 8d976208..619ecc60 100644 --- a/run_scripts/test_blending.py +++ b/run_scripts/test_blending.py @@ -1,7 +1,7 @@ import pytest import subprocess -@pytest.mark.parametrize("ic", +@pytest.mark.parametrize("ic", ["test_blending_warm_bubble",]) def test_single_run(ic): result = subprocess.run( @@ -10,4 +10,9 @@ def test_single_run(ic): text=True ) + # result = subprocess.run( + # ["python3", "-m", "pdb", "pybella", "-ic", ic, "-N", "1"], + # capture_output=False, + # text=True + # ) assert result.returncode == 0, result.stderr.splitlines()[-3:] \ No newline at end of file diff --git a/src/__main__.py b/src/__main__.py index 49705324..199c6ebe 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -80,10 +80,13 @@ def main(): ) if sst.ud.diag: - sst.diag_comparison.test_do( - mem.sol, mem.mpv.p2_nodes, plot=sst.ud.diag_state.plot_compare - ) - + if sst.ud.diag_updt_targets: + sst.diag_comparison.update_targets() + else: + sst.diag_comparison.test_do( + mem.sol, mem.mpv.p2_nodes, plot=sst.ud.diag_state.plot_compare + ) + futures.append(mem) # Dask commands, used only when parallelisation is diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 9dbbf3a0..7cc1dd12 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -638,8 +638,9 @@ def do( step += 1 window_step += 1 - time.step = step - time.window_step = window_step + mem.time.step = step + mem.time.window_step = window_step + mem.time.t = t mem.sol = Sol mem.flux = flux diff --git a/src/interfaces/dynamics_blending/schemes.py b/src/interfaces/dynamics_blending/schemes.py index 596f672d..b0071348 100644 --- a/src/interfaces/dynamics_blending/schemes.py +++ b/src/interfaces/dynamics_blending/schemes.py @@ -47,11 +47,15 @@ def convert_p2n(self, p2n): return dp2c - def update_Sol(self, Sol, elem, node, th, ud, mpv, sgn, label=None, writer=None): + def update_sol(self, mem, ud, sgn, label=None, writer=None): if writer != None: writer.populate(str(label) + "_before_blending", "dp2n", self.dp2n) if writer != None: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_before_blending") + writer.write_all(mem, str(label) + "_before_blending") + + Sol = mem.sol + mpv = mem.mpv + th = mem.th if sgn == "bef": sign = -1.0 @@ -92,9 +96,9 @@ def update_Sol(self, Sol, elem, node, th, ud, mpv, sgn, label=None, writer=None) assert 0, "ud.blending_conv undefined." if writer != None: - writer.write_all(Sol, mpv, elem, node, th, str(label) + "_after_blending") + writer.write_all(mem, str(label) + "_after_blending") - def update_p2n(self, Sol, mpv, node, th, ud): + def update_p2n(self, mpv): mpv.p2_nodes = self.dp2n @@ -103,14 +107,14 @@ def update_p2n(self, Sol, mpv, node, th, ud): ###################################################### -def do_comp_to_psinc_conv(Sol, mpv, bld, elem, node, th, ud, label, writer): +def do_comp_to_psinc_conv(mem, bld, ud, label, writer): logging.info("Converting COMP to PSINC") - dp2n = mpv.p2_nodes + dp2n = mem.mpv.p2_nodes bld.convert_p2n(dp2n) - bld.update_Sol(Sol, elem, node, th, ud, mpv, "bef", label=label, writer=writer) - bld.update_p2n(Sol, mpv, node, th, ud) + bld.update_sol(mem, ud, "bef", label=label, writer=writer) + bld.update_p2n(mem.mpv) - return Sol, mpv + return mem def do_psinc_to_comp_conv( @@ -122,9 +126,6 @@ def do_psinc_to_comp_conv( Sol_freeze = copy.deepcopy(mem.sol) mpv_freeze = copy.deepcopy(mem.mpv) - mem.time.step -= 1 - mem.time.window_step = 0 - ret = time_update.do( sst, mem, @@ -153,20 +154,23 @@ def do_psinc_to_comp_conv( str(label) + "_after_full_step", "p2_start", mpv_freeze.p2_nodes ) if writer != None: - writer.populate(str(label) + "_after_full_step", "p2_end", ret[2].p2_nodes) - Sol = Sol_freeze - mpv = mpv_freeze + writer.populate(str(label) + "_after_full_step", "p2_end", ret.mpv.p2_nodes) + mem.Sol = Sol_freeze + mem.mpv = mpv_freeze - elem, node, _, _, _, th, _ = mem + # elem, node, _, _, _, th, _ = mem if writer != None: writer.populate(str(label) + "_after_full_step", "dp2n", dp2n) logging.info("Converting PSINC to COMP") bld.convert_p2n(dp2n) - bld.update_Sol(Sol, elem, node, th, ud, mpv, "aft", label=label, writer=writer) - bld.update_p2n(Sol, mpv, node, th, ud) + bld.update_sol(mem, ud, "aft", label=label, writer=writer) + bld.update_p2n(mem.mpv) - return Sol, mpv + # mem.time.step -= 1 + # mem.time.window_step -= 1 + + return mem ###################################################### @@ -410,14 +414,10 @@ def blending_before_timestep( do_swe_to_lake_conv(Sol, mpv, elem, node, ud, th, writer, label, debug) swe_to_lake = True else: - Sol, mpv = do_comp_to_psinc_conv( - Sol, mpv, bld, elem, node, th, ud, label, writer + mem = do_comp_to_psinc_conv( + mem, bld, ud, label, writer ) - - mem.Sol = Sol - mem.mpv = mpv - ###################################################### # Blending : Do full steps or transition steps? ###################################################### @@ -454,8 +454,8 @@ def blending_before_timestep( if bld.psinc_init > 0: ud.is_compressible = 0 ud.compressibility = 0.0 - Sol, mpv = do_comp_to_psinc_conv( - Sol, mpv, bld, elem, node, th, ud, label, writer + mem = do_comp_to_psinc_conv( + mem, bld, ud, label, writer ) elif bld.hydro_init > 0: Sol, mpv, t = do_nonhydro_to_hydro_conv( diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index 959dc344..4abfbaa1 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -11,7 +11,7 @@ ) -class compare_sol(object): +class CompareSol(object): def __init__(self, diag_state: DiagnosticState): self.diag_state = diag_state self.current_run = diag_state.test_name @@ -52,16 +52,20 @@ def test_do(self, Sol, p2n, plot=False): else: test = p2n.astype("float32").sum() - ## use try and except - assert ( - np.isclose(ref, test) - ), "sum for attribute %s of %s changed with discrepancy:\n%.6f\n%.6f" % ( - key, - self.current_run, - ref, - test, - ) - print(f"test passed for {key}") + + try: + assert ( + np.isclose(ref, test) + ), "sum for attribute %s of %s changed with discrepancy:\n%.16f\n%.16f" % ( + key, + self.current_run, + ref, + test, + ) + logging.info(f"test passed for {key}") + except AssertionError as e: + logging.info(str(e)) + raise logging.info(f""" {'#' * 10} @@ -98,7 +102,7 @@ def __plot_comparison(self, Sol, p2n): for attribute in tp.attributes: arr_plots = [] - ref_sol = self.__get_ens(tc, tp, attribute).T + ref_sol = self.__get_ens(tc, tp, attribute, summed=False).T if attribute != "p2_nodes": test_sol = getattr(Sol, attribute).T @@ -114,7 +118,7 @@ def __plot_comparison(self, Sol, p2n): pl.img.savefig(tp.dir + attribute + ".png") @staticmethod - def __get_ens(tc, params, attribute, summed=False): + def __get_ens(tc, params, attribute, summed=True, normed=False): times = params.times l_typ = params.l_typ @@ -137,8 +141,10 @@ def __get_ens(tc, params, attribute, summed=False): if summed: return ens.sum() - else: + elif normed: return np.linalg.norm(ens) + else: + return ens class test_params(object): diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 8ae59970..45b989f0 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -14,18 +14,19 @@ def __init__(self): ########################################## # NUMERICS ########################################## - self.CFL = 0.5 - self.dtfixed0 = 100.0 - self.dtfixed = 100.0 + self.CFL = 0.9 + self.dtfixed0 = 0.01 + self.dtfixed = 0.01 - self.inx = 160+1 - self.iny = 80+1 + self.inx = 64+1 + self.iny = 48+1 self.inz = 1 - self.tout = np.arange(0.0,1.01,0.01)[10:] - self.stepmax = 10000 + self.tout = [100.0] + self.stepmax = 31 + + self.is_compressible = 1 - self.output_base_name = "_rising_bubble" # if self.is_compressible == 1: # self.output_suffix = "_%i_%i_%.1f_comp" %(self.inx-1,self.iny-1,self.tout[-1]) # if self.is_compressible == 0: @@ -34,28 +35,35 @@ def __init__(self): # self.output_suffix = "_%i_%i_%.1f" %(self.inx-1,self.iny-1,self.tout[-1]) self.continuous_blending = False - self.no_of_pi_initial = 1 + self.no_of_pi_initial = 0 self.no_of_pi_transition = 0 self.no_of_hy_initial = 0 self.no_of_hy_transition = 0 - self.initial_blending = True + self.initial_blending = False - aux = 'CFLfixed' - self.aux = aux - # self.output_suffix = "_%i_%i_%.1f_%s" %(self.inx-1,self.iny-1,self.tout[-1],aux) - # self.output_suffix += '_w=%i-%i' %(self.blending_weight*16.0,16.0-(self.blending_weight*16.0)) + self.output_base_name = "_blending_warm_bubble" + self.output_type = "test" + self.aux = '' + + self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) + + self.output_timesteps = True self.diag = True + self.diag_updt_targets = False self.diag_state = DiagnosticState( test_name="test_blending_warm_bubble", file_name="test_blending_warm_bubble", - Nx=self.inx, - Ny=self.iny, + Nx=self.inx-1, + Ny=self.iny-1, steps=[self.stepmax], + plot_compare=True ) + self.autogen_fn = False + def sol_init(Sol, mpv, elem, node, th, ud, seed=None): u0 = ud.u_wind_speed v0 = ud.v_wind_speed @@ -65,27 +73,12 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): y0 = 0.2 r0 = 0.2 - g = ud.gravity_strength[1] - # print(ud.rho_ref) - hydrostatics.state(mpv, elem, node, th, ud) x = elem.x y = elem.y x, y = np.meshgrid(x,y) - - if seed != None: - np.random.seed(seed) - # y0 += (np.random.random()-.5)/2.0 - # delth += 10.0*(np.random.random()-.5) - delth += 10.0*(np.random.random()) - - if 'truth' in ud.aux: - np.random.seed(1234) - # delth += 10.0*(np.random.random()-.5) - delth += 10.0*(np.random.random()) - print(delth) r = np.sqrt((x)**2 + (y-y0)**2) / r0 diff --git a/src/tests/test_internal_long_wave.py b/src/tests/test_internal_long_wave.py index 230d910e..d2c7faf7 100644 --- a/src/tests/test_internal_long_wave.py +++ b/src/tests/test_internal_long_wave.py @@ -158,6 +158,7 @@ def __init__(self): self.rhoe = self.rhoe_method self.diag = True + self.diag_updt_targets = False self.diag_state = DiagnosticState( test_name="test_internal_long_wave", From bc67edc0c2e4b46bfdc81f1fe9b5136c460aa00b Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 13 Jan 2025 03:04:55 +0800 Subject: [PATCH 30/76] minor refactoring of utils.io and utils.prepare --- src/utils/io.py | 3 ++- src/utils/prepare.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/io.py b/src/utils/io.py index 9635e90f..d1bf9173 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -181,7 +181,8 @@ def write_all(self, model_state, name): """ - _, _, Sol, _, mpv, _, _ = model_state + Sol = model_state.sol + mpv = model_state.mpv logging.info("writing hdf output..." + name) # rho diff --git a/src/utils/prepare.py b/src/utils/prepare.py index 0700443a..3189acde 100644 --- a/src/utils/prepare.py +++ b/src/utils/prepare.py @@ -67,7 +67,7 @@ def initialise(): # Initialise test module ########################################################## if ud.diag: - diag_comparison = diag.compare_sol(ud.diag_state) + diag_comparison = diag.CompareSol(ud.diag_state) else: diag_comparison = None From 035e8a078cc9ceb8b60b124957933bc0b8878f15 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 13 Jan 2025 03:06:04 +0800 Subject: [PATCH 31/76] fixed bug with discrepancy between generated target and test values the generalised target generation in the diagnostics module now works, the problem was with writing the output before the mem attributes were correctly updated. --- src/flow_solver/discretisation/time_update.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 7cc1dd12..2c067c40 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -618,7 +618,9 @@ def do( if c2: ud.is_nonhydrostatic = 1 - t += dt + mem.sol = Sol + mem.flux = flux + mem.mpv = mpv if writer != None: writer.time = t @@ -635,16 +637,13 @@ def do( "###############################################################################################" ) + t += dt step += 1 window_step += 1 - mem.time.step = step - mem.time.window_step = window_step - mem.time.t = t - - mem.sol = Sol - mem.flux = flux - mem.mpv = mpv + mem.time.t = t + mem.time.step = step + mem.time.window_step = window_step return mem # return [Sol, flux, mpv, [window_step, step]] From 823c1a7bc7cedbcb1e3553cc27c81b15217e839f Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 13 Jan 2025 03:07:26 +0800 Subject: [PATCH 32/76] update all test ICs to support updating target; test_targets.yml updated with warm bubble test values blending is still switched off, but this commit allows for blending to be tested as a next step. woohoo. --- src/tests/test_blending_warm_bubble.py | 2 +- src/tests/test_internal_long_wave.py | 6 +++--- src/tests/test_lamb_wave.py | 8 +++++--- src/tests/test_targets.yml | 8 ++++++++ src/tests/test_travelling_vortex.py | 7 ++++--- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 45b989f0..5d0a9bc8 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -58,7 +58,7 @@ def __init__(self): file_name="test_blending_warm_bubble", Nx=self.inx-1, Ny=self.iny-1, - steps=[self.stepmax], + steps=[self.stepmax-1], plot_compare=True ) diff --git a/src/tests/test_internal_long_wave.py b/src/tests/test_internal_long_wave.py index d2c7faf7..ebd1dcd2 100644 --- a/src/tests/test_internal_long_wave.py +++ b/src/tests/test_internal_long_wave.py @@ -163,9 +163,9 @@ def __init__(self): self.diag_state = DiagnosticState( test_name="test_internal_long_wave", file_name="test_internal_long_wave", - Nx=self.inx, - Ny=self.iny, - steps=[self.stepmax], + Nx=self.inx-1, + Ny=self.iny-1, + steps=[self.stepmax-1], ) def stratification_function(self, y): diff --git a/src/tests/test_lamb_wave.py b/src/tests/test_lamb_wave.py index ef2bff9c..ae71b1fa 100644 --- a/src/tests/test_lamb_wave.py +++ b/src/tests/test_lamb_wave.py @@ -142,12 +142,14 @@ def __init__(self): self.output_suffix = "_%i_%i" %(self.inx-1,self.iny-1) self.diag = True + self.diag_updt_targets = False + self.diag_state = DiagnosticState( test_name="test_lamb_wave", file_name="test_lamb_wave", - Nx=self.inx, - Ny=self.iny, - steps=[self.stepmax], + Nx=self.inx-1, + Ny=self.iny-1, + steps=[self.stepmax-1], ) diff --git a/src/tests/test_targets.yml b/src/tests/test_targets.yml index f314e7db..4676cc09 100644 --- a/src/tests/test_targets.yml +++ b/src/tests/test_targets.yml @@ -22,3 +22,11 @@ test_travelling_vortex: rhou: 4422.43359375 rhov: 4408.03857421875 rhow: 0.0 +test_blending_warm_bubble: + p2_nodes: -16146.2158203125 + rho: 2415.7255859375 + rhoX: 289.7033386230469 + rhoY: 2416.049072265625 + rhou: -9.5367431640625e-07 + rhov: 554.5759887695312 + rhow: 0.0 diff --git a/src/tests/test_travelling_vortex.py b/src/tests/test_travelling_vortex.py index 10d47361..18094e4d 100644 --- a/src/tests/test_travelling_vortex.py +++ b/src/tests/test_travelling_vortex.py @@ -146,13 +146,14 @@ def __init__(self): self.output_timesteps = True self.diag = True + self.diag_updt_targets = False self.diag_state = DiagnosticState( test_name="test_travelling_vortex", file_name="test_travelling_vortex", - Nx=self.inx, - Ny=self.iny, - steps=[self.stepmax], + Nx=self.inx-1, + Ny=self.iny-1, + steps=[self.stepmax-1], ) self.autogen_fn = False From 228a2aa900176b0f0e113cc196d0e4d4ef5b6714 Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 13 Jan 2025 13:12:42 +0800 Subject: [PATCH 33/76] added comments for DiagnosticState attributes --- src/utils/data_structures.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index f218dfd5..29973de3 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -88,12 +88,17 @@ class DiagnosticState: Consider removing run-specific parameters, e.g., (Nx, Ny), in future. """ + # the name to look up in test_targets.yml test_name: str + # filename of the reference (if updt_target = True or plot_compare = True) file_name: str + # details related to loading the reference fields Nx: int Ny: int steps: list path: str = "./outputs/" + + # plot the comparison? plot_compare: bool = False From 2fdade979681704c4bfeea042b0b1a87a4220c8e Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 15 Jan 2025 14:12:35 +0800 Subject: [PATCH 34/76] extended diagnostics module to output more sensible plots specifically, the primitive variables and the pressure perturbation. But the pressure perturbation computations are incorrect, and the background pressure distribution is still visible, I have no idea why... --- src/__main__.py | 2 +- src/flow_solver/utils/__init__.py | 0 src/flow_solver/utils/solver_diagnostics.py | 22 +++++++++ src/tests/diagnostics.py | 51 +++++++++++++++++---- src/tests/test_blending_warm_bubble.py | 8 ++-- src/utils/user_data.py | 2 +- 6 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 src/flow_solver/utils/__init__.py create mode 100644 src/flow_solver/utils/solver_diagnostics.py diff --git a/src/__main__.py b/src/__main__.py index 199c6ebe..afe9cd5a 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -84,7 +84,7 @@ def main(): sst.diag_comparison.update_targets() else: sst.diag_comparison.test_do( - mem.sol, mem.mpv.p2_nodes, plot=sst.ud.diag_state.plot_compare + mem, sst.ud, plot=sst.ud.diag_state.plot_compare ) futures.append(mem) diff --git a/src/flow_solver/utils/__init__.py b/src/flow_solver/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/flow_solver/utils/solver_diagnostics.py b/src/flow_solver/utils/solver_diagnostics.py new file mode 100644 index 00000000..79927d18 --- /dev/null +++ b/src/flow_solver/utils/solver_diagnostics.py @@ -0,0 +1,22 @@ +import numpy as np +import scipy as sp + +def get_p_from_pressure_related_fields(mem, ud, psinc=False): + p2n = mem.mpv.p2_nodes + rhoY = mem.sol.rhoY + dp2n = (p2n - p2n.mean()) * ud.Msq + + th = mem.th + + kernel = np.ones((2,2)) + dp2c = sp.signal.fftconvolve(dp2n, kernel, mode='valid') / kernel.sum() + + if psinc: + P0 = (rhoY**(th.gamm-1.0) + dp2c)**(1.0/(th.gamm-1.0)) + p = P0**(th.gamm) + else: + P0 = (rhoY**(th.gamm-1.0) - dp2c)**(1.0/(th.gamm-1.0)) + p = rhoY**(th.gamm) - P0**(th.gamm) + + # non-dimensionalised p/p_ref + return p \ No newline at end of file diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index 4abfbaa1..aa778761 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -1,9 +1,11 @@ import logging +import copy import numpy as np import yaml from ..utils.data_structures import DiagnosticState +from ..flow_solver.utils.solver_diagnostics import get_p_from_pressure_related_fields from ..vis import ( utils as vis_utils, @@ -33,7 +35,10 @@ def update_targets(self): with open("./src/tests/test_targets.yml", "a") as outfile: yaml.dump(self.arr_dump, outfile, default_flow_style=False) - def test_do(self, Sol, p2n, plot=False): + def test_do(self, mem, ud, plot=False): + Sol = mem.sol + mpv = mem.mpv + self.__read_yaml() try: @@ -42,7 +47,7 @@ def test_do(self, Sol, p2n, plot=False): assert 0, "test %s has no target for comparison" % (self.current_run) if plot: - self.__plot_comparison(Sol, p2n) + self.__plot_comparison(mem, ud) for key, value in target_values.items(): ref = value @@ -50,7 +55,7 @@ def test_do(self, Sol, p2n, plot=False): if key != "p2_nodes": test = getattr(Sol, key).astype("float32").sum() else: - test = p2n.astype("float32").sum() + test = mpv.p2_nodes.astype("float32").sum() try: @@ -95,19 +100,23 @@ def __read_yaml(self): with open("./src/tests/test_targets.yml", "r") as infile: self.target = yaml.safe_load(infile) - def __plot_comparison(self, Sol, p2n): + def __plot_comparison(self, mem, ud): tc = self.tcs[self.current_run] tp = self.tps[self.current_run] + ref_mem = copy.deepcopy(mem) for attribute in tp.attributes: - arr_plots = [] - - ref_sol = self.__get_ens(tc, tp, attribute, summed=False).T if attribute != "p2_nodes": - test_sol = getattr(Sol, attribute).T + setattr(ref_mem.sol, attribute, self.__get_ens(tc, tp, attribute, summed=False)) else: - test_sol = p2n.T + setattr(ref_mem.mpv, attribute, self.__get_ens(tc, tp, attribute, summed=False)) + + for attribute in tp.attributes: + arr_plots = [] + + test_sol = self.__get_sol_for_comparison(mem, ud, attribute) + ref_sol = self.__get_sol_for_comparison(ref_mem, ud, attribute) arr_plots.append([ref_sol, "ref"]) arr_plots.append([test_sol, "test"]) @@ -115,7 +124,29 @@ def __plot_comparison(self, Sol, p2n): pl = vis_pt.plotter(arr_plots, ncols=3, figsize=(12, 3), sharey=False) _ = pl.plot(method="contour", lvls=None, suptitle=attribute) - pl.img.savefig(tp.dir + attribute + ".png") + pl.img.savefig(tp.dir.replace("target", "test") + attribute + ".png") + + del ref_mem + + @staticmethod + def __get_sol_for_comparison(mem, ud, attribute): + Sol = mem.sol + mpv = mem.mpv + if attribute != "p2_nodes": + test_sol = getattr(Sol, attribute).T + if attribute != 'rho': + rho = getattr(Sol, 'rho').T + test_sol /= rho + + # if attribute == 'rhoY': + # test_sol -= mpv.HydroState.Y0[:,np.newaxis] + + else: + test_sol = mpv.p2_nodes.T * ud.Msq + test_sol -= mpv.HydroState_n.pi0[:,np.newaxis] + # test_sol = get_p_from_pressure_related_fields(mem, ud).T + + return test_sol @staticmethod def __get_ens(tc, params, attribute, summed=True, normed=False): diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 5d0a9bc8..6be36e01 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -15,8 +15,8 @@ def __init__(self): # NUMERICS ########################################## self.CFL = 0.9 - self.dtfixed0 = 0.01 - self.dtfixed = 0.01 + self.dtfixed0 = 1.0 + self.dtfixed = 1.0 self.inx = 64+1 self.iny = 48+1 @@ -55,7 +55,7 @@ def __init__(self): self.diag_state = DiagnosticState( test_name="test_blending_warm_bubble", - file_name="test_blending_warm_bubble", + file_name="target_blending_warm_bubble", Nx=self.inx-1, Ny=self.iny-1, steps=[self.stepmax-1], @@ -102,7 +102,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): p = mpv.HydroState_n.p0[0] rhoY = mpv.HydroState_n.rhoY0[0] - mpv.p2_nodes[...] = (p - mpv.HydroState_n.p0[0]) / rhoY / ud.Msq + mpv.p2_nodes[...] = 1.0 # (p - mpv.HydroState_n.p0[0]) / rhoY / ud.Msq bdry.set_explicit_boundary_data(Sol,elem,ud,th,mpv) diff --git a/src/utils/user_data.py b/src/utils/user_data.py index 54615fb1..ffc0b70d 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -63,7 +63,7 @@ def __init__(self,**kwargs): self.is_nonhydrostatic = 1 self.is_compressible = 1 - self.compressibility = 0.0 + self.compressibility = 1.0 ########################################## From 6957aa09c4f57bfd2eb4dc2c6348c478449a03fa Mon Sep 17 00:00:00 2001 From: raychew Date: Mon, 26 May 2025 23:19:10 -0700 Subject: [PATCH 35/76] black formatted whole repo --- docs/source/conf.py | 36 +- run_scripts/{run.py => driver.py} | 30 +- run_scripts/test_blending.py | 15 +- run_scripts/test_flow_solver.py | 29 +- run_scripts/test_suite.py | 2 +- src/__init__.py | 2 +- src/__main__.py | 21 +- src/data_assimilation/analysis.py | 25 +- src/data_assimilation/etpf.py | 93 +- src/data_assimilation/letkf.py | 429 +++-- src/data_assimilation/localisation.py | 36 +- src/data_assimilation/params.py | 128 +- src/data_assimilation/post_processing.py | 2 +- src/data_assimilation/prepare.py | 24 +- src/data_assimilation/utils.py | 266 ++-- src/flow_solver/discretisation/grid.py | 76 +- src/flow_solver/discretisation/time_update.py | 39 +- src/flow_solver/physics/gas_dynamics/cfl.py | 27 +- src/flow_solver/physics/gas_dynamics/eos.py | 32 +- .../physics/gas_dynamics/explicit.py | 81 +- .../physics/gas_dynamics/numerical_flux.py | 91 +- .../physics/gas_dynamics/recovery.py | 120 +- .../physics/gas_dynamics/thermodynamics.py | 4 +- src/flow_solver/physics/hydrostatics.py | 188 ++- src/flow_solver/physics/low_mach/laplacian.py | 1377 ++++++++++------- src/flow_solver/physics/low_mach/mpv.py | 13 +- .../physics/low_mach/second_projection.py | 393 +++-- src/flow_solver/utils/boundary.py | 280 ++-- src/flow_solver/utils/options.py | 12 +- src/flow_solver/utils/solver_diagnostics.py | 15 +- src/flow_solver/utils/variable.py | 46 +- src/inputs/rising_bubble.py | 55 +- src/interfaces/dynamics_blending/prepare.py | 7 +- src/interfaces/dynamics_blending/schemes.py | 21 +- src/tests/diagnostics.py | 63 +- src/tests/test_blending_warm_bubble.py | 68 +- src/tests/test_internal_long_wave.py | 13 +- src/tests/test_lamb_wave.py | 225 +-- src/tests/test_targets.yml | 16 + src/tests/test_travelling_vortex.py | 15 +- src/utils/data_structures.py | 48 +- src/utils/io.py | 19 +- src/utils/prepare.py | 50 +- src/utils/sim_params.py | 18 +- src/utils/user_data.py | 90 +- src/vis/plotting_tools.py | 388 +++-- src/vis/utils.py | 423 +++-- 47 files changed, 3206 insertions(+), 2245 deletions(-) rename run_scripts/{run.py => driver.py} (85%) diff --git a/docs/source/conf.py b/docs/source/conf.py index a3f661f0..35360dc7 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,9 +20,9 @@ # -- Project information ----------------------------------------------------- -project = 'pyBELLA' -copyright = '2024, Ray Chew, Tommaso Benacchio, Rupert Klein' -author = 'Ray Chew, Tommaso Benacchio, Rupert Klein' +project = "pyBELLA" +copyright = "2024, Ray Chew, Tommaso Benacchio, Rupert Klein" +author = "Ray Chew, Tommaso Benacchio, Rupert Klein" # The full version, including alpha/beta/rc tags release = "v0.50.1" @@ -33,26 +33,26 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.autosummary', - 'sphinx_changelog', - 'sphinx.ext.doctest', - 'sphinx.ext.graphviz', - 'sphinx.ext.imgconverter', - 'sphinx.ext.todo', - 'sphinx_math_dollar', - 'sphinx.ext.mathjax' + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx_changelog", + "sphinx.ext.doctest", + "sphinx.ext.graphviz", + "sphinx.ext.imgconverter", + "sphinx.ext.todo", + "sphinx_math_dollar", + "sphinx.ext.mathjax", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = 'en' +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -89,9 +89,9 @@ # see details: https://www.sympy.org/sphinx-math-dollar/ mathjax3_config = { - 'tex2jax': { - 'inlineMath': [ ["\\(","\\)"] ], - 'displayMath': [["\\[","\\]"] ], + "tex2jax": { + "inlineMath": [["\\(", "\\)"]], + "displayMath": [["\\[", "\\]"]], }, } @@ -101,4 +101,4 @@ # -- Options for todo extension ---------------------------------------------- # If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True \ No newline at end of file +todo_include_todos = True diff --git a/run_scripts/run.py b/run_scripts/driver.py similarity index 85% rename from run_scripts/run.py rename to run_scripts/driver.py index 3b388906..672dea3a 100644 --- a/run_scripts/run.py +++ b/run_scripts/driver.py @@ -2,6 +2,7 @@ import subprocess import logging + class run_params(object): N = 1 tc = "rb" @@ -17,27 +18,24 @@ def __init__(self): self.restart = False def single_run(self): - subprocess.run( - ["pybella", "-ic", self.tc, "-N", "1"] - ) + subprocess.run(["pybella", "-ic", self.tc, "-N", "1"]) def queue_run(self): if self.ud is None and self.dap is None: assert 0, "ud or params must be defined" subprocess.run( - [ - "pybella", - "-ic", - self.tc, - "-N", - f"{self.N}", - "queue", - "-w", - self.ud, - self.dap, - ] - ) - + [ + "pybella", + "-ic", + self.tc, + "-N", + f"{self.N}", + "queue", + "-w", + self.ud, + self.dap, + ] + ) def restart_set(self, path, fn, name, ts, te, ti): path += fn diff --git a/run_scripts/test_blending.py b/run_scripts/test_blending.py index 619ecc60..6734a944 100644 --- a/run_scripts/test_blending.py +++ b/run_scripts/test_blending.py @@ -1,13 +1,16 @@ import pytest import subprocess -@pytest.mark.parametrize("ic", - ["test_blending_warm_bubble",]) + +@pytest.mark.parametrize( + "ic", + [ + "test_blending_warm_bubble", + ], +) def test_single_run(ic): result = subprocess.run( - ["pybella", "-ic", ic, "-N", "1"], - capture_output=True, - text=True + ["pybella", "-ic", ic, "-N", "1"], capture_output=True, text=True ) # result = subprocess.run( @@ -15,4 +18,4 @@ def test_single_run(ic): # capture_output=False, # text=True # ) - assert result.returncode == 0, result.stderr.splitlines()[-3:] \ No newline at end of file + assert result.returncode == 0, result.stderr.splitlines()[-3:] diff --git a/run_scripts/test_flow_solver.py b/run_scripts/test_flow_solver.py index 3e3e340f..2059ad06 100644 --- a/run_scripts/test_flow_solver.py +++ b/run_scripts/test_flow_solver.py @@ -2,24 +2,23 @@ import sys import subprocess -@pytest.mark.parametrize("ic", - ["test_travelling_vortex", - "test_internal_long_wave", - "test_lamb_wave"]) + +@pytest.mark.parametrize( + "ic", ["test_travelling_vortex", "test_internal_long_wave", "test_lamb_wave"] +) # def test_single_run(ic): - # run = subprocess.Popen( - # [sys.executable, "src", "-ic", ic, "-N", "1"], - # stdout=subprocess.PIPE, - # stderr=subprocess.PIPE, - # ) - # _, stderr = run.communicate() - # assert run.returncode == 0, stderr.splitlines()[-3:] +# run = subprocess.Popen( +# [sys.executable, "src", "-ic", ic, "-N", "1"], +# stdout=subprocess.PIPE, +# stderr=subprocess.PIPE, +# ) +# _, stderr = run.communicate() +# assert run.returncode == 0, stderr.splitlines()[-3:] + def test_single_run(ic): result = subprocess.run( - ["pybella", "-ic", ic, "-N", "1"], - capture_output=True, - text=True + ["pybella", "-ic", ic, "-N", "1"], capture_output=True, text=True ) - assert result.returncode == 0, result.stderr.splitlines()[-3:] \ No newline at end of file + assert result.returncode == 0, result.stderr.splitlines()[-3:] diff --git a/run_scripts/test_suite.py b/run_scripts/test_suite.py index c5b97e7c..eabe324a 100644 --- a/run_scripts/test_suite.py +++ b/run_scripts/test_suite.py @@ -1,5 +1,5 @@ # %% -from run import run_params as rp +from .driver import run_params as rp import pybella.tests.diagnostics as td import json diff --git a/src/__init__.py b/src/__init__.py index 8d1c8b69..8b137891 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1 +1 @@ - + diff --git a/src/__main__.py b/src/__main__.py index afe9cd5a..67bebed4 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -5,23 +5,17 @@ import numpy as np # dependencies of the atmospheric flow solver -from .flow_solver.discretisation import time_update as dis_time_update +from .flow_solver.discretisation import time_update as dis_time_update # dependencies of the interface subpackage from .interfaces.dynamics_blending import prepare as blending_prepare # dependencies of the data assimilation subpackage -from .data_assimilation import ( - prepare as da_prepare, - analysis as da_analysis -) +from .data_assimilation import prepare as da_prepare, analysis as da_analysis # package imports -from .utils import ( - prepare, - io, - sim_params as params -) +from .utils import prepare, io, sim_params as params + ########################################################## # Start main looping @@ -45,7 +39,6 @@ def main(): tout_cnt = 0 outer_step = 0 for tout in sim_state.ud.tout: - sst = sim_state es = sst.ensemble_state dp = sst.da_params @@ -65,7 +58,7 @@ def main(): # handling of DA window step counter if sst.N > 1: if tout_old in dp.dap.da_times: - mem.time.window_step = 0 + mem.time.window_step = 0 if sst.N == 1: mem.time.window_step = mem.time.step @@ -86,7 +79,7 @@ def main(): sst.diag_comparison.test_do( mem, sst.ud, plot=sst.ud.diag_state.plot_compare ) - + futures.append(mem) # Dask commands, used only when parallelisation is @@ -124,4 +117,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/src/data_assimilation/analysis.py b/src/data_assimilation/analysis.py index 217470b7..69d2e7fd 100644 --- a/src/data_assimilation/analysis.py +++ b/src/data_assimilation/analysis.py @@ -2,17 +2,18 @@ import numpy as np -from . import( +from . import ( etpf as da_etpf, post_processing as da_post_processing, letkf as da_letkf, - utils as da_utils + utils as da_utils, ) from ..flow_solver.utils import boundary as bdry from ..utils import sim_params as params + def do_for_window(tout, outer_step, results, sst, writer): # mp = sst.model_params dp = sst.da_params @@ -31,7 +32,7 @@ def do_for_window(tout, outer_step, results, sst, writer): for mem in results: elem, node, sol, _, mpv, th, _ = mem bdry.set_explicit_boundary_data(sol, elem, sst.ud, th, mpv) - bdry.set_ghostnodes_p2(mpv.p2_nodes,node, sst.ud) + bdry.set_ghostnodes_p2(mpv.p2_nodes, node, sst.ud) # ens.set_members(results, tout) sst.ensemble_state.set_members(results) @@ -58,7 +59,9 @@ def do_for_window(tout, outer_step, results, sst, writer): logging.info("Assimilating %s..." % attr) logging.info("Assimilating %s..." % attr) # future = client.submit(da_interface, *[s_res,obs_current,dap.inflation_factor,attr,N,ud,dap.loc[attr]]) - future = da_letkf.da_interface(results, dp.dap, dp.obs, attr, tout, sst.N, sst.ud) + future = da_letkf.da_interface( + results, dp.dap, dp.obs, attr, tout, sst.N, sst.ud + ) futures.append(future) # analysis = client.gather(futures) @@ -77,12 +80,12 @@ def do_for_window(tout, outer_step, results, sst, writer): # LETKF with grid-point localisation ################################################## elif dp.dap.da_type == "rloc": - logging.info( - "Starting analysis... for rloc algorithm" - ) + logging.info("Starting analysis... for rloc algorithm") elem, node = sst.ensemble_state.get_grid() results = da_utils.HSprojector_3t2D(results, elem, dp.dap, sst.N) - results = dp.rloc.analyse(results, dp.obs, dp.obs_covar, dp.obs_mask, sst.N, tout) + results = dp.rloc.analyse( + results, dp.obs, dp.obs_covar, dp.obs_mask, sst.N, tout + ) results = da_utils.HSprojector_2t3D(results, elem, node, dp.dap, sst.N) # if hasattr(dap, 'converter'): # results = dap.converter(results, N, mpv, elem, node, th, ud) @@ -91,7 +94,9 @@ def do_for_window(tout, outer_step, results, sst, writer): # ETPF ################################################## elif dp.dap.da_type == "etpf": - da_utils.ensemble_inflation(results, dp.dap.attributes, dp.dap.inflation_factor, sst.N) + da_utils.ensemble_inflation( + results, dp.dap.attributes, dp.dap.inflation_factor, sst.N + ) results = da_etpf.da_interface( results, dp.obs, @@ -120,4 +125,4 @@ def do_for_window(tout, outer_step, results, sst, writer): p2_nodes = mpv.p2_nodes bdry.set_ghostnodes_p2(p2_nodes, node, sst.ud) - sst.ensemble_state.set_members(results) \ No newline at end of file + sst.ensemble_state.set_members(results) diff --git a/src/data_assimilation/etpf.py b/src/data_assimilation/etpf.py index 0f0dfbc3..9a058350 100644 --- a/src/data_assimilation/etpf.py +++ b/src/data_assimilation/etpf.py @@ -1,50 +1,69 @@ import numpy as np import logging + def da_interface(results, obs, obs_attributes, delta, times, tout, N, loc=0): ig = 2 - inner = (slice(ig,-ig),slice(ig,-ig)) - + inner = (slice(ig, -ig), slice(ig, -ig)) # local_ens = np.array([getattr(results[:,loc,...][n],attr) for n in range(N)]) # local_ens = np.array([mem[inner] for mem in local_ens]) # local_ens = analysis(local_ens,attr) # print(results[:,0,...][0].rho) - attributes = ['rho','rhou','rhov','rhow','rhoY','rhoX'] + attributes = ["rho", "rhou", "rhov", "rhow", "rhoY", "rhoX"] # attributes = ['rho', 'rhou', 'rhov'] - tmp = np.array([getattr(results[:,loc,...][n],obs_attributes[0])[inner] for n in range(N)]) - tmp = tmp[:,np.newaxis,...] + tmp = np.array( + [getattr(results[:, loc, ...][n], obs_attributes[0])[inner] for n in range(N)] + ) + tmp = tmp[:, np.newaxis, ...] + + ensemble = np.array( + [getattr(results[:, loc, ...][n], attributes[0])[inner] for n in range(N)] + ) + ensemble = ensemble[:, np.newaxis, ...] - ensemble = np.array([getattr(results[:,loc,...][n],attributes[0])[inner] for n in range(N)]) - ensemble = ensemble[:,np.newaxis,...] + obs_current = np.array( + obs[np.where(np.isclose(times, tout))[0][0]][obs_attributes[0]] + )[inner] - obs_current = np.array(obs[np.where(np.isclose(times,tout))[0][0]][obs_attributes[0]])[inner] - # obs_current = bin_func(obs_current,(Nx,Ny)) - obs_current = obs_current[np.newaxis,...] - + obs_current = obs_current[np.newaxis, ...] + for attr in obs_attributes[1:]: - tmp = np.hstack((tmp,np.array([getattr(results[:,loc,...][n],attr)[inner] for n in range(N)])[:,np.newaxis,...])) - tmp01 = np.array(obs[np.where(np.isclose(times,tout))[0][0]][attr])[inner] + tmp = np.hstack( + ( + tmp, + np.array( + [getattr(results[:, loc, ...][n], attr)[inner] for n in range(N)] + )[:, np.newaxis, ...], + ) + ) + tmp01 = np.array(obs[np.where(np.isclose(times, tout))[0][0]][attr])[inner] # tmp01 = bin_func(tmp01,(Nx,Ny)) # print(tmp01.shape) - tmp01 = tmp01[np.newaxis,...] - obs_current = np.vstack((obs_current,tmp01)) + tmp01 = tmp01[np.newaxis, ...] + obs_current = np.vstack((obs_current, tmp01)) for attr in attributes[1:]: - ensemble = np.hstack((ensemble,np.array([getattr(results[:,loc,...][n],attr)[inner] for n in range(N)])[:,np.newaxis,...])) - - - obs_current = obs_current[np.newaxis,...] + ensemble = np.hstack( + ( + ensemble, + np.array( + [getattr(results[:, loc, ...][n], attr)[inner] for n in range(N)] + )[:, np.newaxis, ...], + ) + ) + + obs_current = obs_current[np.newaxis, ...] # r = tmp - obs_current - Hx = tmp.reshape(N,-1) + Hx = tmp.reshape(N, -1) obs_current = obs_current.reshape(-1) # ensemble = ensemble.reshape(N,-1) # print(ensemble.shape) - + etpf = analysis(ensemble, delta) - etpf.analyse(obs_current,1.0,Hx,N) + etpf.analyse(obs_current, 1.0, Hx, N) analysis_ens = etpf.get_ensemble_from_X() @@ -53,14 +72,15 @@ def da_interface(results, obs, obs_attributes, delta, times, tout, N, loc=0): current = analysis_ens[n] for attr in attributes: data = current[cnt] - data = np.pad(data,2,mode='wrap') - - setattr(results[:,loc,...][n],attr,data) + data = np.pad(data, 2, mode="wrap") + + setattr(results[:, loc, ...][n], attr, data) cnt += 1 return results + class analysis(object): - def __init__(self,ensemble,delta,identifier=None): + def __init__(self, ensemble, delta, identifier=None): self.ensemble = np.array(ensemble) self.ensemble_shape = self.ensemble.shape @@ -70,37 +90,38 @@ def __init__(self,ensemble,delta,identifier=None): # rejuvenation factor self.delta = delta - def analyse(self,obs_current,obs_covar,Hx,N): + def analyse(self, obs_current, obs_covar, Hx, N): import pyemd + logging.info("starting ETPF analysis...") - r = (Hx - obs_current)**2 + r = (Hx - obs_current) ** 2 r = np.sum(r, axis=1) # print(r.shape) - ww = np.exp(-r / (2. * obs_covar)) + ww = np.exp(-r / (2.0 * obs_covar)) ww /= np.sum(ww) # print(ww) Co = self.X @ self.X.T diag = np.diag(Co) - Co = diag * np.ones((1,N)) - 2. * Co + np.ones((N,1)) * diag.T + Co = diag * np.ones((1, N)) - 2.0 * Co + np.ones((N, 1)) * diag.T # print(Co) - _, T = pyemd.emd_with_flow(ww,np.ones(N)/N, Co, -1) + _, T = pyemd.emd_with_flow(ww, np.ones(N) / N, Co, -1) T = np.array(T) - T = T*N + T = T * N - self.X = np.dot(self.X.T,T).T #+ self.delta * np.random.randn(self.X.shape[0],self.X.shape[1]) + self.X = np.dot( + self.X.T, T + ).T # + self.delta * np.random.randn(self.X.shape[0],self.X.shape[1]) # print(self.X.shape) @staticmethod def state_vector(ensemble): - return ensemble.reshape(ensemble.shape[0],-1) + return ensemble.reshape(ensemble.shape[0], -1) def get_ensemble_from_X(self): return self.X.reshape(self.ensemble_shape) - - \ No newline at end of file diff --git a/src/data_assimilation/letkf.py b/src/data_assimilation/letkf.py index e76aca6d..07ef0fa4 100644 --- a/src/data_assimilation/letkf.py +++ b/src/data_assimilation/letkf.py @@ -16,7 +16,8 @@ debug_cnt = 0 -def da_interface(results,dap,obs,attr,tout,N,ud): + +def da_interface(results, dap, obs, attr, tout, N, ud): """ Interface for batch-observations localisation with LETKF. @@ -26,24 +27,31 @@ def da_interface(results,dap,obs,attr,tout,N,ud): inf_fac = dap.inflation_factor loc = dap.loc[attr] - inner = (slice(None,),slice(None,)) + inner = ( + slice( + None, + ), + slice( + None, + ), + ) - local_ens = np.array([getattr(results[:,loc,...][n],attr) for n in range(N)]) + local_ens = np.array([getattr(results[:, loc, ...][n], attr) for n in range(N)]) local_ens = np.array([mem[inner] for mem in local_ens]) - local_ens = analysis(local_ens,inf_fac,attr) + local_ens = analysis(local_ens, inf_fac, attr) obs_current = obs_current[inner] - + x_obs, y_obs = obs_current.shape - - forward_operator = lambda ensemble : ensemble # state space == observation space + + forward_operator = lambda ensemble: ensemble # state space == observation space # forward_operator = dap.forward_operator # localisation_matrix = dap.localisation_matrix # localisation_matrix = np.ones_like(obs_current.flatten()) local_ens.forward(forward_operator) # local_ens.localisation(localisation_matrix) - obs_covar = sp.sparse.eye((x_obs*y_obs), (x_obs*y_obs), format='csr') + obs_covar = sp.sparse.eye((x_obs * y_obs), (x_obs * y_obs), format="csr") X = local_ens.analyse(obs_current.reshape(-1), obs_covar) local_ens.ensemble = local_ens.to_array(X) @@ -56,12 +64,12 @@ def da_interface(results,dap,obs,attr,tout,N,ud): # let me ust put the forward operator here for now - will need to tidy stuff up.... -def interpolation_func(ensemble,x_obs,y_obs,ud): +def interpolation_func(ensemble, x_obs, y_obs, ud): if ud.bdry_type[0] == opts.BdryType.WALL or ud.bdry_type[1] == opts.BdryType.WALL: - assert("WALL NOT IMPLEMENTED!") + assert "WALL NOT IMPLEMENTED!" x_ens, y_ens = ensemble[0].shape - x = np.linspace(0,x_ens,x_obs) - y = np.linspace(0,y_ens,y_obs) + x = np.linspace(0, x_ens, x_obs) + y = np.linspace(0, y_ens, y_obs) # x = np.linspace(-0.5,0.5,x_ens) # y = np.linspace(-0.5,0.5,y_ens) @@ -73,28 +81,34 @@ def interpolation_func(ensemble,x_obs,y_obs,ud): # ensemble = [interpn((x,y),mem,pts, method='splinef2d').reshape(x_obs,y_obs) for mem in ensemble] - x,y = np.meshgrid(x,y) - ensemble = [ndimage.map_coordinates(mem,[y,x],mode='wrap', order=3) for mem in ensemble] + x, y = np.meshgrid(x, y) + ensemble = [ + ndimage.map_coordinates(mem, [y, x], mode="wrap", order=3) for mem in ensemble + ] return np.array(ensemble) -def bin_func(obs,ens_mem_shape): - obs = obs.reshape(ens_mem_shape[0],obs.shape[0]//ens_mem_shape[0], - ens_mem_shape[1],obs.shape[1]//ens_mem_shape[1]) - return obs.mean(axis=(1,3)) +def bin_func(obs, ens_mem_shape): + obs = obs.reshape( + ens_mem_shape[0], + obs.shape[0] // ens_mem_shape[0], + ens_mem_shape[1], + obs.shape[1] // ens_mem_shape[1], + ) + return obs.mean(axis=(1, 3)) def none_func(ensemble): - return lambda ensemble : ensemble + return lambda ensemble: ensemble class analysis(object): """ - LETKF Analysis based on (Hunt et al., 2007). + LETKF Analysis based on (Hunt et al., 2007). """ - def __init__(self,ensemble, rho, X_mean, Y_mean, identifier=None): + def __init__(self, ensemble, rho, X_mean, Y_mean, identifier=None): self.ensemble = np.array(ensemble) self.X = self.state_vector(ensemble) self.no_of_members = self.ensemble.shape[0] @@ -112,13 +126,13 @@ def __init__(self,ensemble, rho, X_mean, Y_mean, identifier=None): self.X_mean = X_mean self.Y_mean = Y_mean - def forward(self,forward_operator): + def forward(self, forward_operator): self.forward_operator = forward_operator - def localisation(self,localisation_matrix): + def localisation(self, localisation_matrix): self.localisation_matrix = localisation_matrix - def analyse(self,obs,obs_covar): + def analyse(self, obs, obs_covar): """ Analysis method. 'l' is the observation space. 'm' the state space, 'k' the ensemble size. @@ -144,48 +158,57 @@ def analyse(self,obs,obs_covar): # self.X -= self.X_mean # R in (m x k) # This is step 4 of the algorithm in Hunt et. al., 2007. - C = sp.spsolve(obs_covar, self.Y.T).T # R in (k x l) + C = sp.spsolve(obs_covar, self.Y.T).T # R in (k x l) # This applies the localisation function to the local region. if self.localisation_matrix is not None: C[...] = ((np.array(self.localisation_matrix)) @ C.T).T # The next three lines are step 5 of the algorithm. - Pa = (self.no_of_members - 1.) * np.eye(self.no_of_members) / self.rho + (C @ self.Y.T) + Pa = (self.no_of_members - 1.0) * np.eye(self.no_of_members) / self.rho + ( + C @ self.Y.T + ) Lambda, P = sp.linalg.eigh(Pa) - Pa = P @ (np.diag(1./Lambda) @ P.T) + Pa = P @ (np.diag(1.0 / Lambda) @ P.T) # This is step 6 of the algorithm. - Wa = np.sqrt(self.no_of_members - 1.) * P @ (np.diag(np.sqrt(1./Lambda)) @ P.T) + Wa = ( + np.sqrt(self.no_of_members - 1.0) + * P + @ (np.diag(np.sqrt(1.0 / Lambda)) @ P.T) + ) # The following two lines are step 7 of the algorithm. wa = Pa @ (C @ (obs - self.Y_mean)) Wa += wa # This is step 8 of the algorithm. - return (np.dot(self.X.T , Wa.T) + self.X_mean.reshape(-1,1)).T - + return (np.dot(self.X.T, Wa.T) + self.X_mean.reshape(-1, 1)).T - def get_mean(self,vec): + def get_mean(self, vec): return np.array(vec).mean(axis=0) - + # More readable method needed - seems to be most efficient though. @staticmethod def state_vector(ensemble): return np.array([mem.reshape(-1) for mem in ensemble]) - def to_array(self,X): + def to_array(self, X): return np.array([x.reshape(self.member_shape) for x in X]) def debug(self, obs_current, suffix=""): global debug_cnt N = self.ensemble.shape[0] ens_mean = self.ensemble.mean(axis=0) - _, ax = plt.subplots(ncols=N+1, figsize=(15,4)) + _, ax = plt.subplots(ncols=N + 1, figsize=(15, 4)) for n in range(N): ax[n].imshow(self.ensemble[n]) - ax[n+1].imshow(obs_current) - plt.savefig("./output_images/da_debug_%s_%i_%s" %(self.identifier,debug_cnt // 3,suffix), bbox_inches='tight') + ax[n + 1].imshow(obs_current) + plt.savefig( + "./output_images/da_debug_%s_%i_%s" + % (self.identifier, debug_cnt // 3, suffix), + bbox_inches="tight", + ) plt.close() debug_cnt += 1 @@ -193,8 +216,9 @@ def debug(self, obs_current, suffix=""): class prepare_rloc(object): """ Helper class to get grid-based localisation for LETKF. Used only when da_type=='rloc' is True. - + """ + def __init__(self, ud, elem, node, dap, N, obs_X=5, obs_Y=5): # get grid properties self.iicx = elem.iicx @@ -206,8 +230,15 @@ def __init__(self, ud, elem, node, dap, N, obs_X=5, obs_Y=5): self.N = N # define inner and outer domains - self.i2 = (slice(elem.igx,-elem.igx),slice(elem.igy,-elem.igy)) - self.i0 = (slice(None,),slice(None,)) + self.i2 = (slice(elem.igx, -elem.igx), slice(elem.igy, -elem.igy)) + self.i0 = ( + slice( + None, + ), + slice( + None, + ), + ) # get da parameters self.attr_len = len(dap.obs_attributes) @@ -231,9 +262,9 @@ def __init__(self, ud, elem, node, dap, N, obs_X=5, obs_Y=5): # make sure that subdomain is not larger than inner cellular grid assert self.obs_X < elem.iicx, "obs_X > iicx" - if elem.iicy == 1: # implying horizontal slice + if elem.iicy == 1: # implying horizontal slice assert self.obs_Y < elem.iicz, "obs_Y > iicz" - else: + else: assert self.obs_Y < elem.iicy, "obs_Y > iicy" # make sure that subdomain size is odd @@ -245,12 +276,13 @@ def __init__(self, ud, elem, node, dap, N, obs_X=5, obs_Y=5): self.pad_Y = int((self.obs_Y - 1) / 2) # get mask to handle BC. Periodic mask includes ghost cells/nodes and wall masks takes only the inner domain. - self.cmask, self.nmask = utils.boundary_mask(ud, elem, node, self.pad_X, self.pad_Y) + self.cmask, self.nmask = utils.boundary_mask( + ud, elem, node, self.pad_X, self.pad_Y + ) # get from da parameters the localisation matrix and inflation factor self.inf_fac = dap.inflation_factor self.loc_mat = dap.localisation_matrix - def sort_locs(self): """ @@ -262,28 +294,44 @@ def sort_locs(self): """ - cell_attributes = [key for key,value in self.loc.items() if value == self.loc_c and key in self.oa] - node_attributes = [key for key,value in self.loc.items() if value == self.loc_n and key in self.oa] - face_attributes = [key for key,value in self.loc.items() if value == self.loc_f and key in self.oa] + cell_attributes = [ + key + for key, value in self.loc.items() + if value == self.loc_c and key in self.oa + ] + node_attributes = [ + key + for key, value in self.loc.items() + if value == self.loc_n and key in self.oa + ] + face_attributes = [ + key + for key, value in self.loc.items() + if value == self.loc_f and key in self.oa + ] if len(face_attributes) > 0: assert 0, "r-localisation for values on faces not supported." return cell_attributes, node_attributes - def analyse(self,results,obs,covar,mask,N,tout): + def analyse(self, results, obs, covar, mask, N, tout): """ Wrapper to do analysis by grid-type. """ if self.cattr_len > 0: - results = self.analyse_by_grid_type(results,obs,covar[0],mask,N,tout,'cell') + results = self.analyse_by_grid_type( + results, obs, covar[0], mask, N, tout, "cell" + ) if self.nattr_len > 0: - results = self.analyse_by_grid_type(results,obs,covar[1],mask,N,tout,'node') + results = self.analyse_by_grid_type( + results, obs, covar[1], mask, N, tout, "node" + ) return results - def analyse_by_grid_type(self,results,obs,covar,mask,N,tout,grid_type): + def analyse_by_grid_type(self, results, obs, covar, mask, N, tout, grid_type): """ Do analysis by grid-type. Wrapper of the LETKF analysis. @@ -291,7 +339,7 @@ def analyse_by_grid_type(self,results,obs,covar,mask,N,tout,grid_type): """ - logging.info("Analysis grid type = %s" %grid_type) + logging.info("Analysis grid type = %s" % grid_type) # get properties from class attributes Nx, Ny, obs_attr, attr_len, loc = self.get_properties(grid_type) @@ -300,35 +348,44 @@ def analyse_by_grid_type(self,results,obs,covar,mask,N,tout,grid_type): # get stacked state space and observation # this prepares X, and Y_obs - state_p, obs_p, mask_p = self.stack(results,obs,mask,obs_attr,tout) + state_p, obs_p, mask_p = self.stack(results, obs, mask, obs_attr, tout) # get boundary mask # this does the BC handling - bc_mask,mask_n = self.get_bc_mask(mask_p, grid_type, Nx, Ny, obs_X, obs_Y,attr_len) - - # Here, the 2D arrays are split into local counterparts, say of (5x5) arrays. - X, X_bar = self.get_state(state_p,mask_p,Nx,Ny,attr_len) # X in R in ((Nx * Ny) x k x m) and X_bar in ((Nx * Ny) * m) - obs_p = self.get_obs(obs_p,mask_p,obs_X,obs_Y,Nx,Ny,attr_len) # R in ((Nx * Ny) x l) - Y, Y_bar = self.get_state_in_obs_space(results,mask_p,obs_attr,obs_X,obs_Y,Nx,Ny,attr_len) # Y in R in ((Nx * Ny) x k x l) and Y_bar in ((Nx * Ny) * l) + bc_mask, mask_n = self.get_bc_mask( + mask_p, grid_type, Nx, Ny, obs_X, obs_Y, attr_len + ) + + # Here, the 2D arrays are split into local counterparts, say of (5x5) arrays. + X, X_bar = self.get_state( + state_p, mask_p, Nx, Ny, attr_len + ) # X in R in ((Nx * Ny) x k x m) and X_bar in ((Nx * Ny) * m) + obs_p = self.get_obs( + obs_p, mask_p, obs_X, obs_Y, Nx, Ny, attr_len + ) # R in ((Nx * Ny) x l) + Y, Y_bar = self.get_state_in_obs_space( + results, mask_p, obs_attr, obs_X, obs_Y, Nx, Ny, attr_len + ) # Y in R in ((Nx * Ny) x k x l) and Y_bar in ((Nx * Ny) * l) analysis_res = np.zeros_like(X) # covariance handling if covar is None: # use identity for observation covariance - obs_covar_current = sp.sparse.eye(attr_len*obs_X*obs_Y,attr_len*obs_X*obs_Y, format='csr') + obs_covar_current = sp.sparse.eye( + attr_len * obs_X * obs_Y, attr_len * obs_X * obs_Y, format="csr" + ) else: # get covar at current time covar = covar[list(self.da_times).index(tout)] - + # expand obs covar to size of the subdomain - covar = np.expand_dims(covar,axis=-1) + covar = np.expand_dims(covar, axis=-1) covar = np.repeat(covar, obs_X, axis=-1) - covar = np.expand_dims(covar,axis=-1) + covar = np.expand_dims(covar, axis=-1) covar = np.repeat(covar, obs_Y, axis=-1) - # Note: I implemented the easiest and laziest way to make the LETKF work with large localisation regions. # However, this link: # https://github.com/dask/dask/issues/7589 @@ -336,13 +393,15 @@ def analyse_by_grid_type(self,results,obs,covar,mask,N,tout,grid_type): # Calculate chunk size such that largest chunk takes 180mb of memory: mem_size = 180 - mb=Y.nbytes/1024/1024 # Y is our largest array - chunks = int(np.ceil(mb/mem_size)) - chunk_size = int(np.ceil((Nx*Ny) / chunks)) + mb = Y.nbytes / 1024 / 1024 # Y is our largest array + chunks = int(np.ceil(mb / mem_size)) + chunk_size = int(np.ceil((Nx * Ny) / chunks)) logging.info("\n===================") - logging.info("To split DA problem into %i chunks at %s mb each" %(chunks,mem_size)) - logging.info("with analysis of %i grid points per chunk" %chunk_size) + logging.info( + "To split DA problem into %i chunks at %s mb each" % (chunks, mem_size) + ) + logging.info("with analysis of %i grid points per chunk" % chunk_size) logging.info("") # Now we chunkify our dask arrays: @@ -357,7 +416,23 @@ def analyse_by_grid_type(self,results,obs,covar,mask,N,tout,grid_type): # Now for each chunk, we get the analysis: analysis_by_chunk = [] for chunk in range(chunks): - analysis_by_chunk.append(darr.from_delayed(self.do_analysis(attr_len, covar, bc_mask[chunk], mask_n[chunk], obs_p[chunk], X[chunk], X_bar[chunk], Y[chunk], Y_bar[chunk]), shape=(attr_len,self.N,chunk_size), dtype=np.int64)) + analysis_by_chunk.append( + darr.from_delayed( + self.do_analysis( + attr_len, + covar, + bc_mask[chunk], + mask_n[chunk], + obs_p[chunk], + X[chunk], + X_bar[chunk], + Y[chunk], + Y_bar[chunk], + ), + shape=(attr_len, self.N, chunk_size), + dtype=np.int64, + ) + ) # Put the results of the chunks together analysis_res = darr.concatenate(analysis_by_chunk, axis=2) @@ -376,16 +451,15 @@ def analyse_by_grid_type(self,results,obs,covar,mask,N,tout,grid_type): for n in range(N): data = current[n] data = data.reshape(Nx, Ny) - - data = np.pad(data,2,mode='constant') - setattr(results[:,loc,...][n],attr,data) + data = np.pad(data, 2, mode="constant") - return results + setattr(results[:, loc, ...][n], attr, data) + return results # loop through all grid-points, selecting either the grid-point or its corresponding local region - # This is step 3 of the LETKF algorithm in Hunt et. al. 2007. + # This is step 3 of the LETKF algorithm in Hunt et. al. 2007. @dask.delayed def do_analysis(self, attr_len, covar, bc_mask, mask_n, obs_p, X, X_bar, Y, Y_bar): analysis_res = np.zeros_like(X) @@ -395,71 +469,74 @@ def do_analysis(self, attr_len, covar, bc_mask, mask_n, obs_p, X, X_bar, Y, Y_ba # For each of the quantities in the local observation space, Y, Y_bar, Y_obs, covar and loc_mat, remove the NaNs corresponding to grid-points without observations. # using forward operator as a projection of the state into observation space. - forward_operator = lambda ensemble : np.array([mem[~np.isnan(mem)] for mem in Y[n]]) + forward_operator = lambda ensemble: np.array( + [mem[~np.isnan(mem)] for mem in Y[n]] + ) Y_mean = Y_bar[n][~np.isnan(Y_bar[n])] # setup LETKF class with local state vector - local_ens = analysis(X[n],self.inf_fac,X_bar[n],Y_mean) + local_ens = analysis(X[n], self.inf_fac, X_bar[n], Y_mean) # setup forward operator method in LETKF class local_ens.forward(forward_operator) - + # get the localisation matrix with BC handling # BC is handled by localisation matrix. Observations on wall ghost cells have zero influence. - loc_mat = self.get_loc_mat(bc_mask,mask_n,n,attr_len) + loc_mat = self.get_loc_mat(bc_mask, mask_n, n, attr_len) local_ens.localisation_matrix = loc_mat # get masked covariance in local domain - covar_current = np.ma.array(covar,mask=mask_n[n]).filled(fill_value=np.nan) + covar_current = np.ma.array(covar, mask=mask_n[n]).filled(fill_value=np.nan) covar_current = covar_current[~np.isnan(covar_current)] - obs_covar_current = sp.sparse.diags(covar_current.flatten(), format='csr') + obs_covar_current = sp.sparse.diags(covar_current.flatten(), format="csr") # get obs according to sparsity structure obs_pn = obs_p[n][~np.isnan(obs_p[n])] # do analysis given observations and obs covar. - analysis_ens = local_ens.analyse(obs_pn,obs_covar_current) + analysis_ens = local_ens.analyse(obs_pn, obs_covar_current) # This is step 9 of the algorithm, where the grid-points are re-assembled. analysis_res[n] = analysis_ens - analysis_res = np.swapaxes(analysis_res,0,2) + analysis_res = np.swapaxes(analysis_res, 0, 2) return analysis_res - def stack(self,results,obs,mask,obs_attr,tout): + def stack(self, results, obs, mask, obs_attr, tout): """ On each grid-point, stack all the quantities to be assimilated. This stacking is done separately for cells and nodes. Quantities, e.g. {rho, rhou, ...}. """ - state = self.get_quantity(results,obs_attr[0]) - state = state[:,np.newaxis,...] + state = self.get_quantity(results, obs_attr[0]) + state = state[:, np.newaxis, ...] obs_stack = np.array(obs[list(self.da_times).index(tout)][obs_attr[0]])[self.i2] - obs_stack = obs_stack[np.newaxis,...] + obs_stack = obs_stack[np.newaxis, ...] - mask_stack = np.array(mask[list(self.da_times).index(tout)][obs_attr[0]])[self.i2] - mask_stack = mask_stack[np.newaxis,...] + mask_stack = np.array(mask[list(self.da_times).index(tout)][obs_attr[0]])[ + self.i2 + ] + mask_stack = mask_stack[np.newaxis, ...] for attr in obs_attr[1:]: - next_attr = self.get_quantity(results,attr)[:,np.newaxis,...] - state = np.hstack((state,next_attr)) + next_attr = self.get_quantity(results, attr)[:, np.newaxis, ...] + state = np.hstack((state, next_attr)) next_obs = np.array(obs[list(self.da_times).index(tout)][attr])[self.i2] - next_obs = next_obs[np.newaxis,...] + next_obs = next_obs[np.newaxis, ...] - obs_stack = np.vstack((obs_stack,next_obs)) + obs_stack = np.vstack((obs_stack, next_obs)) next_mask = np.array(mask[list(self.da_times).index(tout)][attr])[self.i2] - next_mask = next_mask[np.newaxis,...] + next_mask = next_mask[np.newaxis, ...] - mask_stack = np.vstack((mask_stack,next_mask)) + mask_stack = np.vstack((mask_stack, next_mask)) return state, obs_stack, mask_stack - - def get_state(self,state,mask,Nx,Ny,attr_len): + def get_state(self, state, mask, Nx, Ny, attr_len): """ Get state vector in grid-localised view. This is step 1 of the LETKF algorithm in Hunt et. al. (2007). Prepares global X and \bar{X}. @@ -473,21 +550,25 @@ def get_state(self,state,mask,Nx,Ny,attr_len): # Decompose X[G] and bar{X[G]} into the local regions view # X = np.array([dau.st.sliding_window_view(mem, (1,1), (1,1)).reshape(Nx*Ny,attr_len) for mem in state]) - # X_bar = np.array([dau.st.sliding_window_view(mem, (1,1), (1,1)).reshape(Nx*Ny,attr_len) for mem in X_bar]) + # X_bar = np.array([dau.st.sliding_window_view(mem, (1,1), (1,1)).reshape(Nx*Ny,attr_len) for mem in X_bar]) state = darr.from_array(state) - X = st.sliding_window_view(state, (1,1), axis=(2,3)).reshape(self.N,attr_len,Nx*Ny) + X = st.sliding_window_view(state, (1, 1), axis=(2, 3)).reshape( + self.N, attr_len, Nx * Ny + ) X_bar = darr.from_array(X_bar) - X_bar = st.sliding_window_view(X_bar, (1,1), axis=(2,3)).reshape(1,attr_len,Nx*Ny) + X_bar = st.sliding_window_view(X_bar, (1, 1), axis=(2, 3)).reshape( + 1, attr_len, Nx * Ny + ) - X = np.swapaxes(X,1,2) - X_bar = np.swapaxes(X_bar,1,2) + X = np.swapaxes(X, 1, 2) + X_bar = np.swapaxes(X_bar, 1, 2) # Make first index the local regions - X = np.swapaxes(X,0,1) + X = np.swapaxes(X, 0, 1) return X, X_bar[0] - def get_obs(self,obs,mask,obs_X,obs_Y,Nx,Ny,attr_len): + def get_obs(self, obs, mask, obs_X, obs_Y, Nx, Ny, attr_len): """ Get observations vector in grid-localised view. @@ -496,52 +577,53 @@ def get_obs(self,obs,mask,obs_X,obs_Y,Nx,Ny,attr_len): x_pad = int((obs_X - 1) / 2) y_pad = int((obs_Y - 1) / 2) pads = [[x_pad, x_pad], [y_pad, y_pad]] - obs = np.array([np.pad(obs_attr,pads,mode='wrap') for obs_attr in obs]) - mask = np.array([np.pad(mask_attr, pads, mode='wrap') for mask_attr in mask]) + obs = np.array([np.pad(obs_attr, pads, mode="wrap") for obs_attr in obs]) + mask = np.array([np.pad(mask_attr, pads, mode="wrap") for mask_attr in mask]) - obs = np.ma.array(obs,mask=mask).filled(fill_value=np.nan) + obs = np.ma.array(obs, mask=mask).filled(fill_value=np.nan) # obs = np.array([dau.st.sliding_window_view(obs_attr, (obs_X,obs_Y), (1,1)) for obs_attr in obs]) obs = darr.from_array(obs) - obs = st.sliding_window_view(obs, (obs_X,obs_Y), axis=(1,2)) + obs = st.sliding_window_view(obs, (obs_X, obs_Y), axis=(1, 2)) - obs = np.swapaxes(obs,0,2) - obs = np.swapaxes(obs,0,1) - obs = obs.reshape(Nx*Ny,attr_len,obs_X,obs_Y) + obs = np.swapaxes(obs, 0, 2) + obs = np.swapaxes(obs, 0, 1) + obs = obs.reshape(Nx * Ny, attr_len, obs_X, obs_Y) return obs - - def get_state_in_obs_space(self,state,mask,obs_attr,obs_X,obs_Y,Nx,Ny,attr_len): + def get_state_in_obs_space( + self, state, mask, obs_attr, obs_X, obs_Y, Nx, Ny, attr_len + ): """ Get state vector projected onto observation space, in grid-localised view. This is step 1 of the LETKF algorithm in Hunt et. al., 2007. """ # Prepare data structure for Y[G] calculation - # stack grid by attributes - sios = self.get_quantity(state,obs_attr[0],inner=False) + # stack grid by attributes + sios = self.get_quantity(state, obs_attr[0], inner=False) - sios = sios[:,np.newaxis,...] + sios = sios[:, np.newaxis, ...] for attr in obs_attr[1:]: - next_attr = self.get_quantity(state,attr,inner=False) + next_attr = self.get_quantity(state, attr, inner=False) # next_attr = np.ma.array(next_attr,mask=mask).filled(fill_value=np.nan) - next_attr = next_attr[:,np.newaxis,...] - sios = np.hstack((sios,next_attr)) + next_attr = next_attr[:, np.newaxis, ...] + sios = np.hstack((sios, next_attr)) # prepare mask array # grid-points where there are observations is 0 x_pad = int((obs_X - 1) / 2) y_pad = int((obs_Y - 1) / 2) pads = [[x_pad, x_pad], [y_pad, y_pad]] - mask = np.array([np.pad(mask_attr, pads, mode='wrap') for mask_attr in mask]) + mask = np.array([np.pad(mask_attr, pads, mode="wrap") for mask_attr in mask]) - # apply mask to get Y[G]. Now Y[G] is in observation space. - sios = np.ma.array([np.ma.array(mem,mask=mask) for mem in sios]) + # apply mask to get Y[G]. Now Y[G] is in observation space. + sios = np.ma.array([np.ma.array(mem, mask=mask) for mem in sios]) # Get bar{y[G]}, i.e. ensemble averages of the states in obs space. - Y_bar = sios.mean(axis=0,keepdims=True) + Y_bar = sios.mean(axis=0, keepdims=True) # Get anomaly for Y[G] sios -= Y_bar @@ -554,16 +636,20 @@ def get_state_in_obs_space(self,state,mask,obs_attr,obs_X,obs_Y,Nx,Ny,attr_len): # Y_bar = np.array([st.sliding_window_view(mem, (obs_X,obs_Y), axis=(1,2)).reshape(Nx*Ny,attr_len,obs_X,obs_Y) for mem in Y_bar]) sios = darr.from_array(sios) - sios = st.sliding_window_view(sios, (obs_X,obs_Y), axis=(2,3)).reshape(self.N,attr_len,Nx*Ny,obs_X,obs_Y) + sios = st.sliding_window_view(sios, (obs_X, obs_Y), axis=(2, 3)).reshape( + self.N, attr_len, Nx * Ny, obs_X, obs_Y + ) Y_bar = darr.from_array(Y_bar) - Y_bar = st.sliding_window_view(Y_bar, (obs_X,obs_Y), axis=(2,3)).reshape(1,attr_len,Nx*Ny,obs_X,obs_Y) + Y_bar = st.sliding_window_view(Y_bar, (obs_X, obs_Y), axis=(2, 3)).reshape( + 1, attr_len, Nx * Ny, obs_X, obs_Y + ) ############################### # from skimage.util import view_as_windows # sios_tmp = np.zeros((10,attr_len,Nx*Ny,obs_X,obs_Y)) # Y_bar_tmp = np.zeros((1,attr_len,Nx*Ny,obs_X,obs_Y)) - + # # sios_tmp = darr.from_array(sios_tmp) # sios = darr.from_array(sios) @@ -577,13 +663,11 @@ def get_state_in_obs_space(self,state,mask,obs_attr,obs_X,obs_Y,Nx,Ny,attr_len): # print(idx) # sios_tmp[idx] = st.sliding_window_view(sios[idx], (obs_X,obs_Y),axis=(1,2)).reshape(attr_len,Nx*Ny,obs_X,obs_Y) - # sios_tmp00 = np.zeros((5,attr_len,Nx*Ny,obs_X,obs_Y)) # for idx in range(0,self.N-hN): # print(idx+hN) # sios_tmp00[idx] = st.sliding_window_view(sios[idx+hN], (obs_X,obs_Y),axis=(1,2)).reshape(attr_len,Nx*Ny,obs_X,obs_Y) - #################################### @@ -592,55 +676,51 @@ def get_state_in_obs_space(self,state,mask,obs_attr,obs_X,obs_Y,Nx,Ny,attr_len): # sios_tmp = view_as_windows(sios, (self.N,attr_len,obs_X,obs_Y)).reshape(self.N,Nx*Ny,attr_len,obs_X,obs_Y) # Y_bar_tmp[0] = st.sliding_window_view(Y_bar[0], (obs_X,obs_Y),axis=(1,2)).reshape(attr_len,Nx*Ny,obs_X,obs_Y) - - + # sios = np.array([st.sliding_window_view(mem, (obs_X,obs_Y), axis=(1,2)).reshape(attr_len,Nx*Ny,obs_X,obs_Y) for mem in sios]) # Y_bar = np.array([st.sliding_window_view(mem, (obs_X,obs_Y), axis=(1,2)).reshape(attr_len,Nx*Ny,obs_X,obs_Y) for mem in Y_bar]) - # sios = np.array([view_as_windows(mem, (attr_len, obs_X,obs_Y)).reshape(attr_len,Nx*Ny,obs_X,obs_Y) for mem in sios]) # Y_bar = np.array([view_as_windows(mem, (attr_len, obs_X,obs_Y)).reshape(attr_len,Nx*Ny,obs_X,obs_Y) for mem in Y_bar]) # sios = sios_tmp # Y_bar = Y_bar_tmp - # Y_bar = np.array([dau.st.sliding_window_view(mem, (obs_X,obs_Y), (1,1)).reshape(Nx*Ny,attr_len,obs_X,obs_Y) for mem in Y_bar]) - sios = np.swapaxes(sios,1,2) - Y_bar = np.swapaxes(Y_bar,1,2) + sios = np.swapaxes(sios, 1, 2) + Y_bar = np.swapaxes(Y_bar, 1, 2) # Make local region the first axis index - sios = np.swapaxes(sios,0,1) + sios = np.swapaxes(sios, 0, 1) # sios = sios.rechunk(chunks=(self.N,100,attr_len,obs_X,obs_Y)) # print(sios.chunks) return sios, Y_bar[0] - - def get_bc_mask(self, mask, type, Nx, Ny, obs_X, obs_Y,attr_len): + def get_bc_mask(self, mask, type, Nx, Ny, obs_X, obs_Y, attr_len): """ Mask handling the boundary condition for cell or node grids in the local subdomains. """ - if type == 'cell' and self.iicy > 1: - bc_mask = np.ones((self.iicx,self.iicy)) - elif type == 'cell' and self.iicy == 1: - bc_mask = np.ones((self.iicx,self.iicz)) - elif type == 'node' and self.iicyn > 2: - bc_mask = np.ones((self.iicxn,self.iicyn)) - elif type == 'node' and self.iicyn == 2: - bc_mask = np.ones((self.iicxn,self.iiczn)) + if type == "cell" and self.iicy > 1: + bc_mask = np.ones((self.iicx, self.iicy)) + elif type == "cell" and self.iicy == 1: + bc_mask = np.ones((self.iicx, self.iicz)) + elif type == "node" and self.iicyn > 2: + bc_mask = np.ones((self.iicxn, self.iicyn)) + elif type == "node" and self.iicyn == 2: + bc_mask = np.ones((self.iicxn, self.iiczn)) # bc_mask = np.pad(bc_mask, 2, mode='constant', constant_values=(1.0)) - pads = ((self.pad_X,self.pad_X),(self.pad_Y,self.pad_Y)) + pads = ((self.pad_X, self.pad_X), (self.pad_Y, self.pad_Y)) - bc_mask = np.pad(bc_mask, pads, mode='constant', constant_values=(1.0)) + bc_mask = np.pad(bc_mask, pads, mode="constant", constant_values=(1.0)) - mask = np.array([np.pad(attr, pads, mode='wrap') for attr in mask]) + mask = np.array([np.pad(attr, pads, mode="wrap") for attr in mask]) - if type == 'cell': + if type == "cell": bc_mask *= self.cmask else: bc_mask *= self.nmask @@ -650,17 +730,20 @@ def get_bc_mask(self, mask, type, Nx, Ny, obs_X, obs_Y,attr_len): # mask_n = np.array(dau.st.sliding_window_view(mask, (obs_X,obs_Y), (1,1))).reshape(Nx*Ny,attr_len,obs_X,obs_Y) bc_mask = darr.from_array(bc_mask) - bc_mask = st.sliding_window_view(bc_mask, (obs_X,obs_Y)).reshape(Nx*Ny,obs_X,obs_Y) + bc_mask = st.sliding_window_view(bc_mask, (obs_X, obs_Y)).reshape( + Nx * Ny, obs_X, obs_Y + ) mask = darr.from_array(mask) - mask_n = st.sliding_window_view(mask, (obs_X,obs_Y), axis=(1,2)).reshape(attr_len,Nx*Ny,obs_X,obs_Y) + mask_n = st.sliding_window_view(mask, (obs_X, obs_Y), axis=(1, 2)).reshape( + attr_len, Nx * Ny, obs_X, obs_Y + ) - mask_n = np.swapaxes(mask_n,0,1) + mask_n = np.swapaxes(mask_n, 0, 1) return bc_mask, mask_n - - def get_properties(self,type): + def get_properties(self, type): """ For a given grid-type (cell / node), return the 2D grid-size (Nx,Ny), the attributes {rho, rhou...} observed on this grid (obs_attr), the number of attributes (attr_len), and the index location of its data container. @@ -673,49 +756,51 @@ def get_properties(self,type): loc : int """ - if type != 'cell' and type != 'node': + if type != "cell" and type != "node": assert 0, "rloc: grid-type not supported" - Nx = self.iicx if type == 'cell' else self.iicxn + Nx = self.iicx if type == "cell" else self.iicxn if self.iicy > 1: - Ny = self.iicy if type == 'cell' else self.iicyn + Ny = self.iicy if type == "cell" else self.iicyn else: - Ny = self.iicz if type == 'cell' else self.iiczn - obs_attr = self.ca if type == 'cell' else self.na - attr_len = self.cattr_len if type == 'cell' else self.nattr_len - loc = self.loc_c if type == 'cell' else self.loc_n + Ny = self.iicz if type == "cell" else self.iiczn + obs_attr = self.ca if type == "cell" else self.na + attr_len = self.cattr_len if type == "cell" else self.nattr_len + loc = self.loc_c if type == "cell" else self.loc_n return Nx, Ny, obs_attr, attr_len, loc - - def get_quantity(self,results,quantity,inner=True): + def get_quantity(self, results, quantity, inner=True): """ Get ensemble representation of {rho, rhou...}. """ slc = self.i2 loc = self.loc[quantity] - pads = ((self.pad_X,self.pad_X),(self.pad_Y,self.pad_Y)) + pads = ((self.pad_X, self.pad_X), (self.pad_Y, self.pad_Y)) if inner: - attribute_array = [getattr(results[:,loc,...][n],quantity)[slc] for n in range(self.N)] + attribute_array = [ + getattr(results[:, loc, ...][n], quantity)[slc] for n in range(self.N) + ] else: - attribute_array = [np.pad(getattr(results[:,loc,...][n],quantity)[slc],pads, mode='wrap') for n in range(self.N)] + attribute_array = [ + np.pad( + getattr(results[:, loc, ...][n], quantity)[slc], pads, mode="wrap" + ) + for n in range(self.N) + ] return np.array(attribute_array) - - def get_loc_mat(self,bc_mask,mask_n,n,attr_len): + def get_loc_mat(self, bc_mask, mask_n, n, attr_len): loc_mat = self.loc_mat * bc_mask[n] - loc_mat = np.expand_dims(loc_mat,axis=0) + loc_mat = np.expand_dims(loc_mat, axis=0) loc_mat = np.repeat(loc_mat, attr_len, axis=0) - loc_mat = np.ma.array(loc_mat,mask=mask_n[n]).filled(fill_value=np.nan) + loc_mat = np.ma.array(loc_mat, mask=mask_n[n]).filled(fill_value=np.nan) loc_mat = loc_mat[~np.isnan(loc_mat)] loc_mat = np.diag(loc_mat.flatten()) return loc_mat - - - diff --git a/src/data_assimilation/localisation.py b/src/data_assimilation/localisation.py index 82064ae5..8c61c6af 100644 --- a/src/data_assimilation/localisation.py +++ b/src/data_assimilation/localisation.py @@ -1,7 +1,8 @@ import numpy as np import flow_solver.utils.options as opts -def rlocal_5pt(elem,node,ud): + +def rlocal_5pt(elem, node, ud): igx = elem.igx igy = elem.igy @@ -19,7 +20,10 @@ def rlocal_5pt(elem,node,ud): x_wall = ud.bdry_type[1] == opts.BdryType.WALL y_wall = ud.bdry_type[0] == opts.BdryType.WALL - return lambda covar : rlocal_5pt_stencil(covar, iicxn, iicyn, x_periodic, y_periodic, x_wall, y_wall) + return lambda covar: rlocal_5pt_stencil( + covar, iicxn, iicyn, x_periodic, y_periodic, x_wall, y_wall + ) + # @jit(nopython=True, nogil=True, cache=True) def rlocal_5pt_stencil(covar, iicxn, iicyn, x_periodic, y_periodic, x_wall, y_wall): @@ -52,20 +56,20 @@ def rlocal_5pt_stencil(covar, iicxn, iicyn, x_periodic, y_periodic, x_wall, y_wa botmid_idx -= iicxn - 1 if cnt_y == 0: - topmid_idx += ((iicxn) * (iicyn - 1)) + topmid_idx += (iicxn) * (iicyn - 1) if y_periodic: - midleft_idx += ((iicxn) * (iicyn - 1)) - midmid_idx += ((iicxn) * (iicyn - 1)) - midright_idx += ((iicxn) * (iicyn - 1)) + midleft_idx += (iicxn) * (iicyn - 1) + midmid_idx += (iicxn) * (iicyn - 1) + midright_idx += (iicxn) * (iicyn - 1) if cnt_y == (iicyn - 1): - botmid_idx -= ((iicxn) * (iicyn - 1)) + botmid_idx -= (iicxn) * (iicyn - 1) if y_periodic: - midleft_idx -= ((iicxn) * (iicyn - 1)) - midmid_idx -= ((iicxn) * (iicyn - 1)) - midright_idx -= ((iicxn) * (iicyn - 1)) + midleft_idx -= (iicxn) * (iicyn - 1) + midmid_idx -= (iicxn) * (iicyn - 1) + midright_idx -= (iicxn) * (iicyn - 1) midleft = covar[midleft_idx] topmid = covar[topmid_idx] @@ -81,15 +85,17 @@ def rlocal_5pt_stencil(covar, iicxn, iicyn, x_periodic, y_periodic, x_wall, y_wa # if y_wall and (cnt_y == 0): # topmid = 0.0 - + # if y_wall and (cnt_y == (iicyn - 1)): # botmid = 0.0 - - R[idx] = (0.5 * midleft + 1.0 * midmid + 0.5 * midright) + (0.5 * topmid + 1.0 * midmid + 0.5 * botmid) + + R[idx] = (0.5 * midleft + 1.0 * midmid + 0.5 * midright) + ( + 0.5 * topmid + 1.0 * midmid + 0.5 * botmid + ) cnt_x += 1 if cnt_x % iicxn == 0: cnt_y += 1 cnt_x = 0 - - return R \ No newline at end of file + + return R diff --git a/src/data_assimilation/params.py b/src/data_assimilation/params.py index a0c22aaa..8eb4f995 100644 --- a/src/data_assimilation/params.py +++ b/src/data_assimilation/params.py @@ -6,22 +6,22 @@ from ..flow_solver.utils import boundary as bdry -class init(object): - def __init__(self,N,da_type='rloc'): +class init(object): + def __init__(self, N, da_type="rloc"): # number of ensemble members self.N = N - self._da_times = np.arange(0.0,3.25,0.25)[1:] + self._da_times = np.arange(0.0, 3.25, 0.25)[1:] # self._da_times = np.arange(5.0,10.5,0.5)/10.0 # self._da_times = [0.1] - self._da_times = np.around(self.da_times,3) - - self.obs_attributes = ['rho','rhou', 'rhov', 'rhoY', 'p2_nodes'] + self._da_times = np.around(self.da_times, 3) + + self.obs_attributes = ["rho", "rhou", "rhov", "rhoY", "p2_nodes"] # self.obs_attributes = ['rhou','rhov'] # which attributes to inflate in ensemble inflation? - self.attributes = ['rho', 'rhou', 'rhov'] + self.attributes = ["rho", "rhou", "rhov"] # self.obs_path = './output_travelling_vortex/output_travelling_vortex_ensemble=1_32_32_6.0_truthgen.h5' # self.obs_path = './output_rising_bubble/output_rising_bubble_ensemble=1_100_50_10.0_psinc_ref.h5' @@ -32,7 +32,7 @@ def __init__(self,N,da_type='rloc'): # self.obs_path = './output_swe_vortex/output_swe_vortex_ensemble=1_64_1_64_3.0_comp_1.0_pps_tra_truth.h5' # self.obs_path = './output_swe_vortex/output_swe_vortex_ensemble=1_64_1_64_3.0_neg_comp_1.0_pp_tra_truth_ip.h5' # self.obs_path = './output_travelling_vortex/output_travelling_vortex_ensemble=1_64_64_3.0_comp_1.0_pp_tra_truth_ip.h5' - self.obs_path = './output_travelling_vortex/output_travelling_vortex_ensemble=1_64_64_3.0_obs.h5' + self.obs_path = "./output_travelling_vortex/output_travelling_vortex_ensemble=1_64_64_3.0_obs.h5" # forward operator (projector from state space to observation space) self.forward_operator = np.eye(N) @@ -47,14 +47,14 @@ def __init__(self,N,da_type='rloc'): if self.sparse_obs_by_attr: assert 0, "Not yet implemented." - self.obs_frac = 0.10 # fraction of the observations to pick. + self.obs_frac = 0.10 # fraction of the observations to pick. self.gen_obs_sparse() ############################################ # Parameters for measurement noise ############################################ self.add_obs_noise = True - self.noise_type = 'VarCov' + self.noise_type = "VarCov" self._noise_percentage = 0.05 self.obs_noise = {} @@ -68,7 +68,7 @@ def __init__(self,N,da_type='rloc'): self.obs_Y = 11 # constants, linear, gaussian - self.localisation_matrix = self.get_loc_mat('gaussian') + self.localisation_matrix = self.get_loc_mat("gaussian") self.da_type = da_type @@ -78,19 +78,19 @@ def __init__(self,N,da_type='rloc'): # rejuvenation factor for ETPF self.rejuvenation_factor = 0.001 - self.loc_c = 0 # container list location of cell-based arrays - self.loc_f = 1 # ... of face-based arrays - self.loc_n = 2 # ... of node-based arrays + self.loc_c = 0 # container list location of cell-based arrays + self.loc_f = 1 # ... of face-based arrays + self.loc_n = 2 # ... of node-based arrays # in which data container are the attributes involved in the DA procedure? self.loc = { - 'rho' : 0, - 'rhou' : 0, - 'rhov' : 0, - 'rhow' : 0, - 'rhoY' : 0, - 'rhoX' : 0, - 'p2_nodes' : 2, + "rho": 0, + "rhou": 0, + "rhov": 0, + "rhow": 0, + "rhoY": 0, + "rhoX": 0, + "p2_nodes": 2, } def gen_obs_sparse(self): @@ -105,62 +105,64 @@ def gen_obs_sparse(self): if len(self.sparse_obs_seeds) > 1: self.sparse_obs_seeds = self.sparse_obs_seeds.squeeze() - def gen_obs_noise(self): for cnt, key in enumerate(self.obs_attributes): - if self.noise_type == 'FixCov': - assert self.std_dev is not None, "std_dev keyword argument must be a list equal in size to dap.obs_attributes" - assert len(self.std_dev) == len(self.obs_attributes), "std_dev keyword argument must be a list equal in size to dap.obs_attributes" + if self.noise_type == "FixCov": + assert ( + self.std_dev is not None + ), "std_dev keyword argument must be a list equal in size to dap.obs_attributes" + assert len(self.std_dev) == len( + self.obs_attributes + ), "std_dev keyword argument must be a list equal in size to dap.obs_attributes" self.obs_noise[key] = float(self.std_dev[cnt]) logging.info(self.std_dev[cnt]) cnt += 1 - else: + else: self.obs_noise[key] = self._noise_percentage da_depth = len(self.obs_attributes) np.random.seed(888) if da_depth > 1: - self.obs_noise_seeds = np.random.randint(10000,size=(da_depth)).squeeze() + self.obs_noise_seeds = np.random.randint(10000, size=(da_depth)).squeeze() else: self.obs_noise_seeds = [np.random.randint(10000)] @staticmethod def converter(results, N, mpv, elem, node, th, ud): - ''' + """ Do this after data assimilation for HS balanced vortex. - ''' + """ logging.info("Post DA conversion...") g = ud.g0 for n in range(N): - bdry.set_explicit_boundary_data(results[n][0],elem,ud,th,mpv) - results[n][0].rhoY[...] = (g / 2.0 * results[n][0].rho**2)**th.gamminv + bdry.set_explicit_boundary_data(results[n][0], elem, ud, th, mpv) + results[n][0].rhoY[...] = (g / 2.0 * results[n][0].rho ** 2) ** th.gamminv igy = elem.igy - kernel = np.ones((2,2)) + kernel = np.ones((2, 2)) kernel /= kernel.sum() - pn = sp.signal.convolve(results[n][0].rhoY[:,igy,:], kernel, mode='valid') + pn = sp.signal.convolve(results[n][0].rhoY[:, igy, :], kernel, mode="valid") - bdry.set_explicit_boundary_data(results[n][0],elem,ud,th,mpv) + bdry.set_explicit_boundary_data(results[n][0], elem, ud, th, mpv) pn = np.expand_dims(pn, 1) pn = np.repeat(pn, node.icy, axis=1) - results[n][2].p2_nodes[1:-1,:,1:-1] = pn - bdry.set_ghostnodes_p2(results[n][2].p2_nodes,node,ud) + results[n][2].p2_nodes[1:-1, :, 1:-1] = pn + bdry.set_ghostnodes_p2(results[n][2].p2_nodes, node, ud) - pn = np.expand_dims(results[n][2].p2_nodes[:,igy,:], 1) + pn = np.expand_dims(results[n][2].p2_nodes[:, igy, :], 1) results[n][2].p2_nodes[...] = np.repeat(pn[...], node.icy, axis=1) return results - - def load_obs(self,obs_path,loc=0): + def load_obs(self, obs_path, loc=0): if self.N > 1: - obs_file = h5py.File(obs_path, 'r') + obs_file = h5py.File(obs_path, "r") obs_attributes = self.obs_attributes #### when were these observations taken? @@ -172,42 +174,39 @@ def load_obs(self,obs_path,loc=0): t_cnt = 0 for t in times: #### how were these dataset called? - label = '_ensemble_mem=0_%.3f_after_full_step' %t + label = "_ensemble_mem=0_%.3f_after_full_step" % t #### axis 1 stores the attributes obs[t_cnt] = {} for attribute in obs_attributes: data = obs_file[str(attribute)][str(attribute) + str(label)][:] - if data.ndim == 3: # implying horizontal slice... - data = data[:,0,:] - dict_attr = { - attribute: data - } + if data.ndim == 3: # implying horizontal slice... + data = data[:, 0, :] + dict_attr = {attribute: data} obs[t_cnt].update(dict_attr) t_cnt += 1 obs = np.array(obs) obs_file.close() return obs - def get_loc_mat(self, type, c=1.0): - x = (np.linspace(0,1,self.obs_X) - 0.5) - y = (np.linspace(0,1,self.obs_Y) - 0.5) + x = np.linspace(0, 1, self.obs_X) - 0.5 + y = np.linspace(0, 1, self.obs_Y) - 0.5 - X,Y = np.meshgrid(x,y) - if type == 'constants': + X, Y = np.meshgrid(x, y) + if type == "constants": Z = np.ones((self.obs_X, self.obs_Y)) return Z.flatten() * c - - elif type == 'linear': - Z = (np.sqrt(X**2 + Y**2)) + + elif type == "linear": + Z = np.sqrt(X**2 + Y**2) Z = Z.max() - Z return Z.flatten() * c - elif type == 'gaussian': - pos = np.array([X.flatten(),Y.flatten()]).T - norm = sp.stats.multivariate_normal([0,0],[[0.05,0.0],[0.0,0.05]]) - Z = norm.pdf(pos).reshape(X.shape[0],X.shape[1]) + elif type == "gaussian": + pos = np.array([X.flatten(), Y.flatten()]).T + norm = sp.stats.multivariate_normal([0, 0], [[0.05, 0.0], [0.0, 0.05]]) + Z = norm.pdf(pos).reshape(X.shape[0], X.shape[1]) Z = Z - Z.min() Z /= Z.max() @@ -217,7 +216,6 @@ def update_dap(self, params): for key, value in params.items(): setattr(self, key, value) - # setter functions @property def noise_percentage(self): @@ -249,11 +247,10 @@ def da_times(self): @da_times.setter def da_times(self, lst): self._da_times = lst - self._da_times = np.around(self._da_times,3) + self._da_times = np.around(self._da_times, 3) if self.sparse_obs: self.gen_obs_sparse() - @property def loc_setter(self): return self.loc_setter @@ -263,17 +260,16 @@ def loc_setter(self, tpl): self.obs_X = tpl[0] self.obs_Y = tpl[1] # constants, linear, gaussian - self.localisation_matrix = self.get_loc_mat('gaussian') - + self.localisation_matrix = self.get_loc_mat("gaussian") @property def sd_setter(self): return self.sd_setter - + @sd_setter.setter - def sd_setter(self,lst): + def sd_setter(self, lst): self.std_dev = lst - self.noise_type = 'FixCov' + self.noise_type = "FixCov" if self.add_obs_noise: self.gen_obs_noise() diff --git a/src/data_assimilation/post_processing.py b/src/data_assimilation/post_processing.py index 6525fbf1..2360ddec 100644 --- a/src/data_assimilation/post_processing.py +++ b/src/data_assimilation/post_processing.py @@ -3,4 +3,4 @@ ## Interface function def interface(): - return None \ No newline at end of file + return None diff --git a/src/data_assimilation/prepare.py b/src/data_assimilation/prepare.py index 78b500d6..f50ddb1e 100644 --- a/src/data_assimilation/prepare.py +++ b/src/data_assimilation/prepare.py @@ -1,6 +1,7 @@ import logging + # to generate ensemble from one sol init instantiation -from copy import deepcopy +from copy import deepcopy import numpy as np @@ -48,16 +49,20 @@ def initialise(sst): for n in range(sst.N): Sol0 = deepcopy(sst.Sol) mpv0 = deepcopy(sst.mpv) - Sol0 = sst.sol_init(Sol0, mpv0, es.elem, es.node, es.th, es.ud, seed=seeds[n]) + Sol0 = sst.sol_init( + Sol0, mpv0, es.elem, es.node, es.th, es.ud, seed=seeds[n] + ) # sol_ens[n] = [Sol0, deepcopy(es.flux), mpv0, [-np.inf, es.step]] - sol_ens.update_member(es.elem, es.node, Sol0, mpv0, deepcopy(es.flux), es.th) + sol_ens.update_member( + es.elem, es.node, Sol0, mpv0, deepcopy(es.flux), es.th + ) sst.ensembble_state = sol_ens # elif sst.restart == False: - # sol_ens = [[sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.flux, mp.mpv, [-np.inf, sst.step]]] - # sol_ens.update_member(mp.elem, mp.node, sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.mpv, deepcopy(mp.flux), mp.th) - # for n in range(sst.N): - # sol_ens.get_member(n).time.t = -np.inf + # sol_ens = [[sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.flux, mp.mpv, [-np.inf, sst.step]]] + # sol_ens.update_member(mp.elem, mp.node, sst.sol_init(mp.Sol, mp.mpv, mp.elem, mp.node, mp.th, sst.ud), mp.mpv, deepcopy(mp.flux), mp.th) + # for n in range(sst.N): + # sol_ens.get_member(n).time.t = -np.inf # ens = da_utils.ensemble(sol_ens) @@ -74,7 +79,6 @@ def initialise(sst): else: obs, obs_noisy, obs_mask, obs_covar = None, None, None, None - ########################################################## # Add ensemble info into filename ########################################################## @@ -92,7 +96,5 @@ def initialise(sst): obs=obs, obs_noisy=obs_noisy, obs_mask=obs_mask, - obs_covar=obs_covar + obs_covar=obs_covar, ) - - diff --git a/src/data_assimilation/utils.py b/src/data_assimilation/utils.py index ac815f5e..f81dc133 100644 --- a/src/data_assimilation/utils.py +++ b/src/data_assimilation/utils.py @@ -7,32 +7,32 @@ from ..flow_solver.utils import options as opts, boundary as bdry + class ensemble(object): def __init__(self, input_ensemble=None): if input_ensemble is not None: cnt = 0 for mem in input_ensemble: - setattr(self,'mem_' + str(cnt),mem) + setattr(self, "mem_" + str(cnt), mem) # self.debug_im(mem[0].rho, cnt) cnt += 1 else: None - - def initialise_members(self,ic,N): + def initialise_members(self, ic, N): for cnt in range(N): mem = [copy.deepcopy(arr) for arr in ic] # mem = sampler(mem) - setattr(self,'mem_' + str(cnt),mem) + setattr(self, "mem_" + str(cnt), mem) # def state_vector(self,ensemble): # N = self.members(ensemble).shape[0] # return self.members(ensemble).reshape(N,-1) - def set_members(self,analysis_ensemble, tout): + def set_members(self, analysis_ensemble, tout): cnt = 0 for xi in analysis_ensemble: - setattr(self,'mem_' + str(cnt),np.array(xi)) + setattr(self, "mem_" + str(cnt), np.array(xi)) # self.debug_im(xi[0].rho, cnt, tout) cnt += 1 @@ -42,107 +42,129 @@ def ensemble_spreading(self, ens, sampler, attributes, loc=0): np.random.seed(555) for attribute in attributes: for n in range(N): - mem = getattr(self,'mem_' + str(n)) - value = getattr(mem[loc],attribute) + mem = getattr(self, "mem_" + str(n)) + value = getattr(mem[loc], attribute) # self.debug_im(sampler(value), n) - setattr(mem[loc],attribute,sampler(value)) + setattr(mem[loc], attribute, sampler(value)) @staticmethod def members(ensemble): - return np.array(list(ensemble.__dict__.values()),dtype='object') + return np.array(list(ensemble.__dict__.values()), dtype="object") @staticmethod def debug_im(value, n, tout): plt.figure() - plt.imshow(value, origin='lower') - plt.savefig("./output_images/ensemble_snapshots/%.3f_%03d.png" %(tout,n), bbox_inches='tight') + plt.imshow(value, origin="lower") + plt.savefig( + "./output_images/ensemble_snapshots/%.3f_%03d.png" % (tout, n), + bbox_inches="tight", + ) plt.close() + def ensemble_inflation(results, attributes, factor, N, loc=0): for attribute in attributes: - mean = [getattr(results[n][loc],attribute) for n in range(N)] + mean = [getattr(results[n][loc], attribute) for n in range(N)] mean = np.array(mean) - mean = np.mean(mean,axis=0) + mean = np.mean(mean, axis=0) for n in range(N): - inflation = mean + factor * (getattr(results[n][loc],attribute) - mean) - setattr(results[n][loc],attribute,inflation) + inflation = mean + factor * (getattr(results[n][loc], attribute) - mean) + setattr(results[n][loc], attribute, inflation) + -def set_p2_nodes(analysis,results,N,th,node,ud,loc_c=0,loc_n=2): +def set_p2_nodes(analysis, results, N, th, node, ud, loc_c=0, loc_n=2): for n in range(N): rhoY = analysis[n] - p2_n = getattr(results[n][loc_n],'p2_nodes') + p2_n = getattr(results[n][loc_n], "p2_nodes") rhoY_n = np.zeros_like(p2_n) - kernel = np.array([[1.,1.],[1.,1.]]) - rhoY_n[1:-1,1:-1] = sp.signal.fftconvolve(rhoY,kernel,mode='valid') / kernel.sum() - bdry.set_ghostnodes_p2(rhoY_n,node,ud) + kernel = np.array([[1.0, 1.0], [1.0, 1.0]]) + rhoY_n[1:-1, 1:-1] = ( + sp.signal.fftconvolve(rhoY, kernel, mode="valid") / kernel.sum() + ) + bdry.set_ghostnodes_p2(rhoY_n, node, ud) p2_n = rhoY_n**th.gm1 - 1.0 + (p2_n - p2_n.mean()) # p2_n = rhoY_n**th.gm1 - 1.0 p2_n -= p2_n.mean() # p2_n = np.pad(p2_n,2,mode='wrap') - bdry.set_ghostnodes_p2(p2_n,node,ud) - setattr(results[n][loc_n],'p2_nodes',p2_n) + bdry.set_ghostnodes_p2(p2_n, node, ud) + setattr(results[n][loc_n], "p2_nodes", p2_n) -def set_rhoY_cells(analysis,results,N,th,ud,loc_c=0,loc_n=2): + +def set_rhoY_cells(analysis, results, N, th, ud, loc_c=0, loc_n=2): for n in range(N): p2n = analysis[n] - rhoYc0 = getattr(results[n][loc_c], 'rhoY') - kernel = np.array([[1.,1.],[1.,1.]]) - p2c = sp.signal.fftconvolve(p2n,kernel,mode='valid') / kernel.sum() + rhoYc0 = getattr(results[n][loc_c], "rhoY") + kernel = np.array([[1.0, 1.0], [1.0, 1.0]]) + p2c = sp.signal.fftconvolve(p2n, kernel, mode="valid") / kernel.sum() p2c -= p2c.mean() - rhoYc = (rhoYc0**th.gm1 + ud.Msq*p2c)**th.gm1inv - setattr(results[n][loc_c], 'rhoYc', rhoYc) - -def boundary_mask(ud,elem,node,pad_X,pad_Y): + rhoYc = (rhoYc0**th.gm1 + ud.Msq * p2c) ** th.gm1inv + setattr(results[n][loc_c], "rhoYc", rhoYc) + + +def boundary_mask(ud, elem, node, pad_X, pad_Y): """ - Returns a mask for the underlying cellular and nodal grids padded such that the size of the local subdomain has been accounted for. For ghost cells on wall boundaries, values are 0.0 and 1.0 for periodic. + Returns a mask for the underlying cellular and nodal grids padded such that the size of the local subdomain has been accounted for. For ghost cells on wall boundaries, values are 0.0 and 1.0 for periodic. """ - pads = [pad_X,pad_Y] + pads = [pad_X, pad_Y] if elem.iicy > 1: cmask = np.ones(elem.iisc).squeeze() nmask = np.ones(node.iisc).squeeze() for dim in range(elem.ndim): - ghost_padding = [[0,0]] * elem.ndim + ghost_padding = [[0, 0]] * elem.ndim # ghost_padding[dim] = [elem.igs[dim],elem.igs[dim]] - ghost_padding[dim] = [pads[dim],pads[dim]] + ghost_padding[dim] = [pads[dim], pads[dim]] if ud.bdry_type[dim] == opts.BdryType.PERIODIC: - cmask = np.pad(cmask, ghost_padding, mode='constant', constant_values=(1.0)) - nmask = np.pad(nmask, ghost_padding, mode='constant', constant_values=(1.0)) + cmask = np.pad( + cmask, ghost_padding, mode="constant", constant_values=(1.0) + ) + nmask = np.pad( + nmask, ghost_padding, mode="constant", constant_values=(1.0) + ) elif ud.bdry_type[dim] == opts.BdryType.WALL: - cmask = np.pad(cmask, ghost_padding, mode='constant', constant_values=(0.0)) - nmask = np.pad(nmask, ghost_padding, mode='constant', constant_values=(0.0)) - - elif elem.iicy == 1: # implying horizontal slices + cmask = np.pad( + cmask, ghost_padding, mode="constant", constant_values=(0.0) + ) + nmask = np.pad( + nmask, ghost_padding, mode="constant", constant_values=(0.0) + ) + + elif elem.iicy == 1: # implying horizontal slices cmask = np.ones(elem.iisc).squeeze() - nmask = np.ones(node.iisc)[:,0,:] + nmask = np.ones(node.iisc)[:, 0, :] ndim = elem.ndim - 1 for dim in range(ndim): - ghost_padding = [[0,0]] * ndim + ghost_padding = [[0, 0]] * ndim # ghost_padding[dim] = [elem.igs[dim],elem.igs[dim]] - ghost_padding[dim] = [pads[dim],pads[dim]] + ghost_padding[dim] = [pads[dim], pads[dim]] if ud.bdry_type[dim] == opts.BdryType.PERIODIC: - cmask = np.pad(cmask, ghost_padding, mode='constant', constant_values=(1.0)) - nmask = np.pad(nmask, ghost_padding, mode='constant', constant_values=(1.0)) + cmask = np.pad( + cmask, ghost_padding, mode="constant", constant_values=(1.0) + ) + nmask = np.pad( + nmask, ghost_padding, mode="constant", constant_values=(1.0) + ) elif ud.bdry_type[dim] == opts.BdryType.WALL: - cmask = np.pad(cmask, ghost_padding, mode='constant', constant_values=(0.0)) - nmask = np.pad(nmask, ghost_padding, mode='constant', constant_values=(0.0)) - - return cmask.astype('bool'), nmask.astype('bool') - - + cmask = np.pad( + cmask, ghost_padding, mode="constant", constant_values=(0.0) + ) + nmask = np.pad( + nmask, ghost_padding, mode="constant", constant_values=(0.0) + ) + return cmask.astype("bool"), nmask.astype("bool") # ref: https://gist.github.com/meowklaski/4bda7c86c6168f3557657d5fb0b5395a def sliding_window_view(arr, window_shape, steps): - """ + """ Produce a view from a sliding, striding window over `arr`. The window is only placed in 'valid' positions - no overlapping over the boundary. @@ -208,9 +230,10 @@ def sliding_window_view(arr, window_shape, steps): >>> conv_out = conv_out.transpose([3,0,1,2]) """ - + from numpy.lib.stride_tricks import as_strided - in_shape = np.array(arr.shape[-len(steps):]) # [x, (...), z] + + in_shape = np.array(arr.shape[-len(steps) :]) # [x, (...), z] window_shape = np.array(window_shape) # [Wx, (...), Wz] steps = np.array(steps) # [Sx, (...), Sz] nbytes = arr.strides[-1] # size (bytes) of an element in `arr` @@ -218,13 +241,13 @@ def sliding_window_view(arr, window_shape, steps): # number of per-byte steps to take to fill window window_strides = tuple(np.cumprod(arr.shape[:0:-1])[::-1]) + (1,) # number of per-byte steps to take to place window - step_strides = tuple(window_strides[-len(steps):] * steps) + step_strides = tuple(window_strides[-len(steps) :] * steps) # number of bytes to step to populate sliding window view strides = tuple(int(i) * nbytes for i in step_strides + window_strides) outshape = tuple((in_shape - window_shape) // steps + 1) # outshape: ([X, (...), Z], ..., [Wx, (...), Wz]) - outshape = outshape + arr.shape[:-len(steps)] + tuple(window_shape) + outshape = outshape + arr.shape[: -len(steps)] + tuple(window_shape) return as_strided(arr, shape=outshape, strides=strides, writeable=False) @@ -235,7 +258,7 @@ def HSprojector_3t2D(results, elem, dap, N): Parameters ---------- results : nd.array - An array of ensemble size k. Each ensemble member has [Sol,flux,mpv,[window_step,step]]. + An array of ensemble size k. Each ensemble member has [Sol,flux,mpv,[window_step,step]]. dap : data assimilation input class . N : int @@ -247,19 +270,28 @@ def HSprojector_3t2D(results, elem, dap, N): """ - slc = (slice(None,), 2, slice(None,)) + slc = ( + slice( + None, + ), + 2, + slice( + None, + ), + ) # implying horizontal slice... - if elem.ndim == 3 and elem.iicy == 1: + if elem.ndim == 3 and elem.iicy == 1: for key, value in dap.loc.items(): - # only reshape data arrays that are involved in DA. - if key in dap.obs_attributes: + # only reshape data arrays that are involved in DA. + if key in dap.obs_attributes: for n in range(N): - p_arr = getattr(results[n][value],key)[slc] - setattr(results[n][value],key, p_arr) + p_arr = getattr(results[n][value], key)[slc] + setattr(results[n][value], key, p_arr) return results + def HSprojector_2t3D(results, elem, node, dap, N): """ Projection method from 2D array to 3D horizontal slice. To be used after data assimilation. @@ -268,39 +300,46 @@ def HSprojector_2t3D(results, elem, node, dap, N): if elem.ndim == 3 and elem.iicy == 1: for key, value in dap.loc.items(): if key in dap.obs_attributes: - if value == 0: # cell container + if value == 0: # cell container ys = elem.icy - if value == 2: # node container + if value == 2: # node container ys = node.icy for n in range(N): - p_arr = getattr(results[n][value],key)[:,np.newaxis,:] + p_arr = getattr(results[n][value], key)[:, np.newaxis, :] p_arr = np.repeat(p_arr, ys, axis=1) - setattr(results[n][value],key, p_arr) + setattr(results[n][value], key, p_arr) return results - + def sparse_obs_selector(obs, elem, node, ud, dap): sparse_obs = dap.sparse_obs if not sparse_obs or len(dap.da_times) == 0: mask = copy.deepcopy(obs) - for tt,mask_t in enumerate(mask): + for tt, mask_t in enumerate(mask): for key, _ in mask_t.items(): mask[tt][key][...] = 0.0 return obs, mask - + else: sparse_obs_by_attr = dap.sparse_obs_by_attr seeds = dap.sparse_obs_seeds K = dap.obs_frac # define inner and outer domains in 2D - i2 = (slice(elem.igx,-elem.igx),slice(elem.igy,-elem.igy)) - i0 = (slice(None,),slice(None,)) + i2 = (slice(elem.igx, -elem.igx), slice(elem.igy, -elem.igy)) + i0 = ( + slice( + None, + ), + slice( + None, + ), + ) # get inner domain size - if elem.iicy == 1: # implying horizontal slice + if elem.iicy == 1: # implying horizontal slice Ncx, Ncy = elem.iicx, elem.iicz Nnx, Nny = node.iicx, node.iicz else: @@ -314,12 +353,12 @@ def sparse_obs_selector(obs, elem, node, ud, dap): Kc = int(np.ceil(Kc)) Kn = int(np.ceil(Kn)) - if elem.iicy == 1: # implying horizontal slice + if elem.iicy == 1: # implying horizontal slice Xc, Yc = elem.x, elem.z Xc, Yc = np.meshgrid(Xc, Yc) Xn, Yn = node.x, node.z Xn, Yn = np.meshgrid(Xn, Yn) - else: # implying vertical slice + else: # implying vertical slice Xc, Yc = elem.x, elem.y Xc, Yc = np.meshgrid(Xc, Yc) Xn, Yn = node.x, node.y @@ -329,10 +368,10 @@ def sparse_obs_selector(obs, elem, node, ud, dap): # obs_noisy_interp = deepcopy(obs) # obs is a list of dictionaries, list length da_len, dictionary length attr_len. - for tt,obs_t in enumerate(obs): + for tt, obs_t in enumerate(obs): attr_cnt = tt for key, value in obs_t.items(): - if key == 'p2_nodes': + if key == "p2_nodes": grid_x, grid_y = Xn[i0], Yn[i0] K, N = Kn, Nn Nx, Ny = Nnx, Nny @@ -347,10 +386,10 @@ def sparse_obs_selector(obs, elem, node, ud, dap): # https://stackoverflow.com/questions/19597473/binary-random-array-with-a-specific-proportion-of-ones/19597805 # append mask array with new seed - mask = np.array([0] * K + [1] * (N-K)) + mask = np.array([0] * K + [1] * (N - K)) np.random.shuffle(mask) - mask = mask.reshape(Nx,Ny) - mask = np.pad(mask,(2,2),mode='constant',constant_values=0.0) + mask = mask.reshape(Nx, Ny) + mask = np.pad(mask, (2, 2), mode="constant", constant_values=0.0) # values = np.ma.array(value[i0], mask=mask).compressed() # X = np.ma.array(grid_x, mask=mask).compressed() @@ -361,83 +400,88 @@ def sparse_obs_selector(obs, elem, node, ud, dap): # points[:,1] = Y[...].flatten() # values = griddata(points, values, (grid_x, grid_y), method='cubic') - + # if dap.obs_frac < 1.0: - # obs_noisy_interp[tt][key][...] = 0.0 - # obs_noisy_interp[tt][key][i0] = values + # obs_noisy_interp[tt][key][...] = 0.0 + # obs_noisy_interp[tt][key][i0] = values mask_arr[tt][key][...] = 1 mask_arr[tt][key][i2] = mask[i2] - + if sparse_obs_by_attr: attr_cnt += 1 for mask_at_t in mask_arr: for key, mask in mask_at_t.items(): - if key == 'p2_nodes': + if key == "p2_nodes": Nx, Ny = Nnx, Nny else: Nx, Ny = Ncx, Ncy - assert (mask.shape[0] * mask.shape[1]) - mask.sum() == np.ceil(Nx*Ny*dap.obs_frac), "Mask sparsity does not match obs_frac defined" + assert (mask.shape[0] * mask.shape[1]) - mask.sum() == np.ceil( + Nx * Ny * dap.obs_frac + ), "Mask sparsity does not match obs_frac defined" # return obs_noisy_interp, mask_arr return mask_arr -def obs_noiser(obs,mask,dap,rloc,elem): +def obs_noiser(obs, mask, dap, rloc, elem): if dap.add_obs_noise: assert isinstance(dap.obs_noise, dict), "obs_noise has to be dict" - assert len(dap.obs_noise) == len(dap.obs_attributes), "obs_noise length has to be equal to obs_attributes len" + assert len(dap.obs_noise) == len( + dap.obs_attributes + ), "obs_noise length has to be equal to obs_attributes len" - obs_covar_c = np.zeros((len(dap.da_times),rloc.cattr_len)) - obs_covar_n = np.zeros((len(dap.da_times),rloc.nattr_len)) + obs_covar_c = np.zeros((len(dap.da_times), rloc.cattr_len)) + obs_covar_n = np.zeros((len(dap.da_times), rloc.nattr_len)) obs_noisy = copy.deepcopy(obs) - std_dev = np.zeros((obs.shape[0],len(dap.obs_noise_seeds))) + std_dev = np.zeros((obs.shape[0], len(dap.obs_noise_seeds))) # define inner domain in 2D VS - i2 = (slice(elem.igx,-elem.igx),slice(elem.igy,-elem.igy)) + i2 = (slice(elem.igx, -elem.igx), slice(elem.igy, -elem.igy)) for tt, obs_t in enumerate(obs): attr_cnt = 0 for key, value in obs_t.items(): - # Get inner 2D domain of sparse obs field value = value[i2] mask_at_t = mask[tt][key][i2] - value = np.ma.array(value,mask=mask_at_t) + value = np.ma.array(value, mask=mask_at_t) seed = dap.obs_noise_seeds[attr_cnt] np.random.seed(seed) - - if dap.noise_type == 'AmpCov': - field_var = (dap.obs_noise[key] * np.abs(value.max() - value.min())) + + if dap.noise_type == "AmpCov": + field_var = dap.obs_noise[key] * np.abs(value.max() - value.min()) field_sd = field_var**0.5 - elif dap.noise_type == 'VarCov': - field_var = (dap.obs_noise[key] * ((value - value.mean())**2).mean()) + elif dap.noise_type == "VarCov": + field_var = ( + dap.obs_noise[key] * ((value - value.mean()) ** 2).mean() + ) field_sd = field_var**0.5 - elif dap.noise_type == 'FixCov': + elif dap.noise_type == "FixCov": field_sd = 1.0 * dap.obs_noise[key] # here, we take the fraction defined by obs_noise multiplied by the maximum value of the observation as the standard deviation of the measurement noise. - - std_dev[tt,attr_cnt] = field_sd + + std_dev[tt, attr_cnt] = field_sd attr_cnt += 1 # var = std_dev**2 - if dap.noise_type == 'VarCov' or dap.noise_type == 'AmpCov': - sd = std_dev.mean(axis=0,keepdims=True) - std_dev[:,...] = sd + if dap.noise_type == "VarCov" or dap.noise_type == "AmpCov": + sd = std_dev.mean(axis=0, keepdims=True) + std_dev[:, ...] = sd for tt, obs_t in enumerate(obs): ccnt, ncnt, attr_cnt = 0, 0, 0 for key, value in obs_t.items(): shp = value.shape - sd = std_dev[tt,attr_cnt] - + sd = std_dev[tt, attr_cnt] + # print(tt, key, sd**2, np.abs(value.max()-value.min())) # generate gaussian noise for observations. @@ -451,13 +495,13 @@ def obs_noiser(obs,mask,dap,rloc,elem): if var == 0: var = -np.inf if key in rloc.ca: - obs_covar_c[tt,ccnt] = var + obs_covar_c[tt, ccnt] = var ccnt += 1 else: - obs_covar_n[tt,ncnt] = var + obs_covar_n[tt, ncnt] = var ncnt += 1 attr_cnt += 1 - + obs_covar = [obs_covar_c, obs_covar_n] return obs_noisy, obs_covar diff --git a/src/flow_solver/discretisation/grid.py b/src/flow_solver/discretisation/grid.py index 3cac12a4..b95bc7a1 100644 --- a/src/flow_solver/discretisation/grid.py +++ b/src/flow_solver/discretisation/grid.py @@ -2,6 +2,7 @@ from ..utils import options as opts + def grid_init(ud): """ Helper function to initialise the `elem` and `node` grids, corresponding to the cell and node grids, from a given user iniital data file. @@ -29,20 +30,22 @@ def grid_init(ud): z0 = ud.zmin z1 = ud.zmax - grid = Grid(inx,iny,inz,x0,x1,y0,y1,z0,z1) + grid = Grid(inx, iny, inz, x0, x1, y0, y1, z0, z1) elem = ElemSpaceDiscr(grid, ud) node = NodeSpaceDiscr(grid, ud) return elem, node + class Grid(object): # def __init__(self, inx,iny,inz,x0,x1,y0,y1,z0,z1,left,right,bottom,top,back,front): """ Base grid class, defines the extent of grid and the grid spacing. """ - def __init__(self, inx,iny,inz,x0,x1,y0,y1,z0,z1): + + def __init__(self, inx, iny, inz, x0, x1, y0, y1, z0, z1): """ Parameters ---------- @@ -63,8 +66,8 @@ def __init__(self, inx,iny,inz,x0,x1,y0,y1,z0,z1): z0 : float Minimum extent in the z direction z1 : float - Maximum extent in the z direction - + Maximum extent in the z direction + """ assert inx > 1 assert iny >= 1 @@ -76,15 +79,15 @@ def __init__(self, inx,iny,inz,x0,x1,y0,y1,z0,z1): self.ndim = 2 else: self.ndim = 1 - + self.inx = inx self.iny = iny self.inz = inz - self.dx = (x1 - x0) / (inx - 1.) - self.dy = (y1 - y0) / (iny - 1.) if iny > 1 else 0.0 - self.dz = (z1 - z0) / (inz - 1.) if inz > 1 else 0.0 - + self.dx = (x1 - x0) / (inx - 1.0) + self.dy = (y1 - y0) / (iny - 1.0) if iny > 1 else 0.0 + self.dz = (z1 - z0) / (inz - 1.0) if inz > 1 else 0.0 + assert self.dx > 0.0 assert self.dy >= 0.0 assert self.dz >= 0.0 @@ -107,7 +110,10 @@ def __init__(self, inx,iny,inz,x0,x1,y0,y1,z0,z1): # self.back = back # self.front = front + big = 1.0 + + class SpaceDiscr(object): """ For a given grid extent and number of grid-points, this class returns an equidistant discretised grid. @@ -119,7 +125,7 @@ class SpaceDiscr(object): stride = np.zeros((3)) dxyz = np.zeros((3)) - def __init__(self,g): + def __init__(self, g): """ Parameters ---------- @@ -149,9 +155,9 @@ def __init__(self,g): self.nc = self.icx * self.icy * self.icz self.iisc = (self.iicx, self.iicy, self.iicz) - self.isc = (self.iicx+self.igx, self.iicy+self.igy, self.iicz+self.igz) + self.isc = (self.iicx + self.igx, self.iicy + self.igy, self.iicz + self.igz) self.sc = (self.icx, self.icy, self.icz) - self.igs = [self.igx,self.igy,self.igz] + self.igs = [self.igx, self.igy, self.igz] self.ifx = self.icx + 1 self.ify = self.icy + 1 if g.iny > 1 else 0 @@ -161,16 +167,16 @@ def __init__(self,g): self.nfy = self.icx * self.ify * self.icz self.nfz = self.icx * self.icy * self.ifz - self.sfx = (self.icy , self.icz , self.ifx) - self.sfy = (self.icz , self.icx , self.ify) - self.sfz = (self.icx , self.icy , self.ifz) + self.sfx = (self.icy, self.icz, self.ifx) + self.sfy = (self.icz, self.icx, self.ify) + self.sfz = (self.icx, self.icy, self.ifz) self.nf = self.nfx + self.nfy + self.nfz self.dx = g.dx self.dy = g.dy if self.icy > 1 else big self.dz = g.dz if self.icz > 1 else big - + self.dxyz[0] = self.dx self.dxyz[1] = self.dy self.dxyz[2] = self.dz @@ -178,16 +184,15 @@ def __init__(self,g): assert self.dx > 0.0 assert self.dy > 0.0 assert self.dz > 0.0 - - i1 = np.empty(self.ndim, dtype='object') - i2 = np.empty(self.ndim, dtype='object') + i1 = np.empty(self.ndim, dtype="object") + i2 = np.empty(self.ndim, dtype="object") for dim in range(self.ndim): - i1[dim] = slice(1,-1) - i2[dim] = slice(self.igs[dim],-self.igs[dim]) + i1[dim] = slice(1, -1) + i2[dim] = slice(self.igs[dim], -self.igs[dim]) self.i1 = tuple(i1) self.i2 = tuple(i2) - + class ElemSpaceDiscr(SpaceDiscr): """ @@ -195,7 +200,7 @@ class ElemSpaceDiscr(SpaceDiscr): """ - def __init__(self,g, ud): + def __init__(self, g, ud): """ Parameters ---------- @@ -225,10 +230,10 @@ def get_p_indim(self, ud): p_isc = [] pp1_isc = [] - eindim = np.empty((ndim),dtype='object') + eindim = np.empty((ndim), dtype="object") for dim in range(ndim): is_periodic = ud.bdry_type[dim] == opts.BdryType.PERIODIC - eindim[dim] = slice(igs[dim]-is_periodic,-igs[dim]+is_periodic-1) + eindim[dim] = slice(igs[dim] - is_periodic, -igs[dim] + is_periodic - 1) p_isc.append(self.isc[dim] + 2 * is_periodic) pp1_isc.append(self.isc[dim] + 2 * is_periodic + 2) @@ -236,14 +241,15 @@ def get_p_indim(self, ud): self.periodic_indim = tuple(eindim) self.p_isc = tuple(p_isc) self.pp1_isc = tuple(pp1_isc) - - + + class NodeSpaceDiscr(SpaceDiscr): """ Inherits the class :class:`discretization.kgrid.SpaceDiscr`. For a given grid extent and number of grid-points, this class returns an equidistant discretised node-based grid. """ - def __init__(self,g, ud): + + def __init__(self, g, ud): """ Parameters ---------- @@ -268,9 +274,9 @@ def __init__(self,g, ud): self.y = y0 + self.dy * np.arange(self.icy) self.z = z0 + self.dz * np.arange(self.icz) - self.iisc = (self.iicx , self.iicy , self.iicz) - self.isc = (self.iicx+self.igx , self.iicy+self.igy , self.iicz+self.igz) - self.sc = (self.icx , self.icy , self.icz) + self.iisc = (self.iicx, self.iicy, self.iicz) + self.isc = (self.iicx + self.igx, self.iicy + self.igy, self.iicz + self.igz) + self.sc = (self.icx, self.icy, self.icz) self.get_p_indim(ud) @@ -285,14 +291,14 @@ def get_p_indim(self, ud): p_isc = [] pp1_isc = [] - nindim = np.empty((ndim),dtype='object') + nindim = np.empty((ndim), dtype="object") for dim in range(ndim): is_periodic = ud.bdry_type[dim] == opts.BdryType.PERIODIC - nindim[dim] = slice(igs[dim]-is_periodic,-igs[dim]+is_periodic) - + nindim[dim] = slice(igs[dim] - is_periodic, -igs[dim] + is_periodic) + p_isc.append(self.isc[dim] + 2 * is_periodic) pp1_isc.append(self.isc[dim] + 2 * is_periodic + 2) self.periodic_indim = tuple(nindim) self.p_isc = tuple(p_isc) - self.pp1_isc = tuple(pp1_isc) \ No newline at end of file + self.pp1_isc = tuple(pp1_isc) diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 2c067c40..bbf4acb6 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -9,14 +9,11 @@ # dependencies of the flow solver subpackage from . import grid as dis_grid -from ..utils import ( - boundary as bdry, - options as opts -) +from ..utils import boundary as bdry, options as opts from ..physics.gas_dynamics import ( numerical_flux as gd_flux, eos as gd_eos, - cfl as gd_cfl + cfl as gd_cfl, ) from ..physics.gas_dynamics import explicit as gd_explicit from ..physics.low_mach import second_projection as lm_sp @@ -156,7 +153,6 @@ def do( # if test_hydrob == False: # dt *= 0.5 - ###################################################### # Blending : Do blending before timestep ###################################################### @@ -176,16 +172,18 @@ def do( ud.is_nonhydrostatic = gd_eos.is_nonhydrostatic(ud, window_step) ud.nonhydrostasy = gd_eos.nonhydrostasy(ud, t, window_step) - + if ud.continuous_blending or ud.initial_blending: logging.info(f"step = {step}, window_step = {window_step}") - logging.info(f""" + logging.info( + f""" ------- is_compressible = {ud.is_compressible}, is_nonhydrostatic = {ud.is_nonhydrostatic} compressibility = {ud.compressibility:.3f}, nonhydrostasy = {ud.nonhydrostasy:.3f} ------- - """) + """ + ) Sol0 = copy.deepcopy(Sol) flux0 = copy.deepcopy(flux) @@ -203,7 +201,6 @@ def do( writer.populate(f"{label}_before_advect", "rhoYw", flux[2].rhoY) writer.write_all(mem, f"{label}_before_advect") - if ud.do_advection: gd_explicit.advect_rk( Sol, @@ -254,7 +251,6 @@ def do( # bottom rayleigh forcing if hasattr(ud, "rayleigh_forcing"): if ud.rayleigh_forcing: - if ud.rayleigh_forcing_type == "file": reader = io.read_input( ud.rayleigh_forcing_fn, ud.rayleigh_forcing_path @@ -298,7 +294,6 @@ def do( if debug == True: writer.write_all(mem, str(label) + "_after_ebnaimp") - flux_half_new = copy.deepcopy(flux) gd_flux.recompute_advective_fluxes(flux, Sol) @@ -321,8 +316,9 @@ def do( # pwchi = np.copy(Sol.pwchi) p2_nodes_half = np.copy(mpv.p2_nodes) - - if ud.is_nonhydrostatic == 0 or (ud.is_compressible == 1 and ud.is_nonhydrostatic == 1): + if ud.is_nonhydrostatic == 0 or ( + ud.is_compressible == 1 and ud.is_nonhydrostatic == 1 + ): mpv.p2_nodes[...] = mpv.p2_nodes0 Sol = copy.deepcopy(Sol0) @@ -381,16 +377,12 @@ def do( ) if debug == True: - writer.write_all( - mem, str(label) + "_after_full_advect" - ) + writer.write_all(mem, str(label) + "_after_full_advect") lm_sp.euler_backward_non_advective_expl_part(Sol, mpv, elem, 0.5 * dt, ud, th) if debug == True: - writer.write_all( - mem, str(label) + "_after_full_ebnaexp" - ) + writer.write_all(mem, str(label) + "_after_full_ebnaexp") lm_sp.euler_backward_non_advective_impl_part( Sol, @@ -413,9 +405,7 @@ def do( # bottom rayleigh forcing if hasattr(ud, "rayleigh_forcing"): if ud.rayleigh_forcing: - if ud.rayleigh_forcing_type == "file": - reader = io.read_input( ud.rayleigh_forcing_fn, ud.rayleigh_forcing_path ) @@ -440,7 +430,6 @@ def do( ) elif ud.rayleigh_forcing_type == "func": - s = 5.0e-3 + 1e-4 + 0e-5 ud.rf_bot.eigenfunction((t + dt), s) up, vp, Yp, pi = ud.rf_bot.dehatter(th) @@ -478,7 +467,9 @@ def do( ) if c1 or c2: - logging.info(termcolor.colored("hydrostatic to nonhydrostatic conversion...", "blue")) + logging.info( + termcolor.colored("hydrostatic to nonhydrostatic conversion...", "blue") + ) # writer.write_all(mem, str(label) + "_half_full") # writer.populate(str(label) + "_ic", "pwchi", Sol.pwchi) diff --git a/src/flow_solver/physics/gas_dynamics/cfl.py b/src/flow_solver/physics/gas_dynamics/cfl.py index 01e70ee2..1badfcf4 100644 --- a/src/flow_solver/physics/gas_dynamics/cfl.py +++ b/src/flow_solver/physics/gas_dynamics/cfl.py @@ -2,6 +2,7 @@ machine_epsilon = np.finfo(float).eps + def dynamic_timestep(Sol, time, time_output, elem, ud, th, step): global machine_epsilon @@ -28,21 +29,21 @@ def dynamic_timestep(Sol, time, time_output, elem, ud, th, step): v_max = max(v.max(), v_max) w_max = max(w.max(), w_max) - upc_max = max((u+c).max(), upc_max) - vpc_max = max((v+c).max(), vpc_max) - wpc_max = max((w+c).max(), wpc_max) + upc_max = max((u + c).max(), upc_max) + vpc_max = max((v + c).max(), vpc_max) + wpc_max = max((w + c).max(), wpc_max) - if (ud.acoustic_timestep == 1): + if ud.acoustic_timestep == 1: dtx = CFL * elem.dx / upc_max dty = CFL * elem.dy / vpc_max dtz = CFL * elem.dz / wpc_max dt_cfl = min(min(dtx, dty), dtz) - dt = min(dt_cfl, ud.dtfixed0 + min(step, 1.) * (ud.dtfixed - ud.dtfixed0)) + dt = min(dt_cfl, ud.dtfixed0 + min(step, 1.0) * (ud.dtfixed - ud.dtfixed0)) # if (2.0*dt > time_output - time): # dt = 0.5 * (time_output - time) + machine_epsilon - if (dt > (time_output - time)): + if dt > (time_output - time): dt = (time_output - time) + machine_epsilon return dt @@ -57,8 +58,8 @@ def dynamic_timestep(Sol, time, time_output, elem, ud, th, step): dt_cfl = min(min(dtx, dty), dtz) # dt = min(dt_cfl, ud.dtfixed0 + min(step, 1.) * (ud.dtfixed - ud.dtfixed0)) if step >= 0: - dt = min(dt_cfl, ud.dtfixed0 + min(step, 1.) * (ud.dtfixed - ud.dtfixed0)) - dt *= min(float(step+1), 1.0) + dt = min(dt_cfl, ud.dtfixed0 + min(step, 1.0) * (ud.dtfixed - ud.dtfixed0)) + dt *= min(float(step + 1), 1.0) # else: # dt = min(dt_cfl, ud.dtfixed0 + 1. * (ud.dtfixed - ud.dtfixed0)) @@ -66,10 +67,12 @@ def dynamic_timestep(Sol, time, time_output, elem, ud, th, step): # f.write(str(dt_cfl) + "\n") # f.close() - if (dt > (time_output - time)): - dt = (time_output - time) #+ machine_epsilon + if dt > (time_output - time): + dt = time_output - time # + machine_epsilon cfl = CFL * dt / dt_cfl - cfl_ac = max(dt * upc_max / elem.dx, dt * vpc_max / elem.dy, dt * wpc_max / elem.dz) + cfl_ac = max( + dt * upc_max / elem.dx, dt * vpc_max / elem.dy, dt * wpc_max / elem.dz + ) - return dt, cfl, cfl_ac \ No newline at end of file + return dt, cfl, cfl_ac diff --git a/src/flow_solver/physics/gas_dynamics/eos.py b/src/flow_solver/physics/gas_dynamics/eos.py index 2ada5730..f7c00226 100644 --- a/src/flow_solver/physics/gas_dynamics/eos.py +++ b/src/flow_solver/physics/gas_dynamics/eos.py @@ -2,7 +2,8 @@ from ...utils import boundary as bdry -def nonhydrostasy(ud,t,step): + +def nonhydrostasy(ud, t, step): if step >= 0: if ud.is_nonhydrostatic == 0: return 0.0 @@ -12,11 +13,14 @@ def nonhydrostasy(ud,t,step): current_transition_step = step - ud.no_of_hy_initial # print("current_transition_step =", step - ud.no_of_hy_initial) # print(np.linspace(0.0,1.0,ud.no_of_hy_transition+2)[1:-1][current_transition_step]) - return np.linspace(0.0,1.0,ud.no_of_hy_transition+2)[1:-1][current_transition_step] + return np.linspace(0.0, 1.0, ud.no_of_hy_transition + 2)[1:-1][ + current_transition_step + ] else: return float(ud.is_nonhydrostatic) -def compressibility(ud,t,step): + +def compressibility(ud, t, step): if step >= 0: if ud.is_compressible == 0: if step < ud.no_of_pi_initial: @@ -25,14 +29,17 @@ def compressibility(ud,t,step): return 0.0 else: current_transition_step = step - ud.no_of_pi_initial - return np.linspace(0.0,1.0,ud.no_of_pi_transition+2)[1:-1][current_transition_step] + return np.linspace(0.0, 1.0, ud.no_of_pi_transition + 2)[1:-1][ + current_transition_step + ] elif ud.is_compressible == 1: return 1.0 # elif ud.is_compressible == 0: else: return ud.compressibility -def is_compressible(ud,step): + +def is_compressible(ud, step): if step >= 0: if ud.continuous_blending == True: if step < ud.no_of_pi_initial: @@ -45,12 +52,12 @@ def is_compressible(ud,step): return ud.is_compressible else: return ud.is_compressible - + def is_nonhydrostatic(ud, step): if step < 0 or not ud.continuous_blending: return ud.is_nonhydrostatic - + if step < ud.no_of_hy_initial: return 0 elif step < (ud.no_of_hy_initial + ud.no_of_hy_transition): @@ -59,18 +66,19 @@ def is_nonhydrostatic(ud, step): return 1 -def rhoe(rho,u,v,w,p,ud,th): +def rhoe(rho, u, v, w, p, ud, th): Msq = ud.compressibility * ud.Msq gm1inv = th.gm1inv return p * gm1inv + 0.5 * Msq * rho * (u**2 + v**2 + w**2) + def synchronise_variables(mpv, Sol, elem, node, ud, th): scale_factor = 1.0 / ud.Msq - if (ud.is_compressible): - p2bg = mpv.HydroState.p20[0,:].reshape(1,-1) - p2bg = np.repeat(p2bg, elem.icx,axis=0) + if ud.is_compressible: + p2bg = mpv.HydroState.p20[0, :].reshape(1, -1) + p2bg = np.repeat(p2bg, elem.icx, axis=0) mpv.p2_cells = scale_factor * Sol.rhoY**th.gm1 - p2bg - bdry.set_ghostcells_p2(mpv.p2_cells, elem, ud) \ No newline at end of file + bdry.set_ghostcells_p2(mpv.p2_cells, elem, ud) diff --git a/src/flow_solver/physics/gas_dynamics/explicit.py b/src/flow_solver/physics/gas_dynamics/explicit.py index 4efd5323..2d205416 100644 --- a/src/flow_solver/physics/gas_dynamics/explicit.py +++ b/src/flow_solver/physics/gas_dynamics/explicit.py @@ -2,13 +2,14 @@ from . import recovery as gd_recovery from . import numerical_flux as gd_flux -def advect(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None): + +def advect(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer=None): """ Function that runs the advection routine with Strang-splitting. This function updates the `Sol` solution container with the advected solution in-place. Parameters ---------- - Sol : :py:class:`management.variable.Vars` + Sol : :py:class:`management.variable.Vars` Solution data container. flux : :py:class:`management.variable.States` Fluxes data container @@ -38,48 +39,66 @@ def advect(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None): # Sol.rhoX -= Sol.rho * mpv.HydroState.S0 - if (odd): + if odd: for split in range(ndim): lmbda = time_step / elem.dxyz[split] Sol.flip_forward() - if elem.iisc[split] > 1: - explicit_step_and_flux(Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv) + if elem.iisc[split] > 1: + explicit_step_and_flux( + Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv + ) else: for i_split in range(ndim): split = elem.ndim - 1 - i_split lmbda = time_step / elem.dxyz[split] if elem.iisc[split] > 1: - explicit_step_and_flux(Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv, [writer,node,label]) + explicit_step_and_flux( + Sol, + flux[split], + lmbda, + elem, + split, + stage, + ud, + th, + mpv, + [writer, node, label], + ) Sol.flip_backward() stage = 1 - if (odd): + if odd: for i_split in range(ndim): split = elem.ndim - 1 - i_split lmbda = time_step / elem.dxyz[split] if elem.iisc[split] > 1: - explicit_step_and_flux(Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv) + explicit_step_and_flux( + Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv + ) Sol.flip_backward() else: for split in range(ndim): lmbda = time_step / elem.dxyz[split] Sol.flip_forward() if elem.iisc[split] > 1: - explicit_step_and_flux(Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv) - + explicit_step_and_flux( + Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv + ) + # Sol.rhoX += Sol.rho * mpv.HydroState.S0 bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - -def explicit_step_and_flux(Sol, flux, lmbda, elem, split_step, stage, ud, th, mpv, writer=None, tag=None): +def explicit_step_and_flux( + Sol, flux, lmbda, elem, split_step, stage, ud, th, mpv, writer=None, tag=None +): """ For each advection substep, solve the advection problem. For more details, see :ref:`advection_routine`. This function updates the solution `Sol` container in-place if a Strang-splitting is used, or returns the `flux` data container if a Runge-Kutta method is used. Parameters ---------- - Sol : :py:class:`management.variable.Vars` + Sol : :py:class:`management.variable.Vars` Solution data container. flux : :py:class:`management.variable.States` Fluxes data container @@ -145,35 +164,35 @@ def explicit_step_and_flux(Sol, flux, lmbda, elem, split_step, stage, ud, th, mp # skipped check_flux_bcs for now; first debug other functions # check_flux_bcs(Lefts, Rights, elem, split_step, ud) - flux = gd_flux.hll_solver(flux,Lefts,Rights,Sol, lmbda, ud, th) + flux = gd_flux.hll_solver(flux, Lefts, Rights, Sol, lmbda, ud, th) ndim = elem.ndim left_idx, right_idx = [slice(None)] * ndim, [slice(None)] * ndim - right_idx[-1] = slice(1,None) - left_idx[-1] = slice(0,-1) + right_idx[-1] = slice(1, None) + left_idx[-1] = slice(0, -1) left_idx, right_idx = tuple(left_idx), tuple(right_idx) - if tag != 'rk': + if tag != "rk": Sol.rho += lmbda * (flux.rho[left_idx] - flux.rho[right_idx]) Sol.rhou += lmbda * (flux.rhou[left_idx] - flux.rhou[right_idx]) Sol.rhov += lmbda * (flux.rhov[left_idx] - flux.rhov[right_idx]) Sol.rhow += lmbda * (flux.rhow[left_idx] - flux.rhow[right_idx]) Sol.rhoX += lmbda * (flux.rhoX[left_idx] - flux.rhoX[right_idx]) Sol.rhoY += lmbda * (flux.rhoY[left_idx] - flux.rhoY[right_idx]) - + bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=split_step) - if tag == 'rk': + if tag == "rk": return flux -def advect_rk(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None): +def advect_rk(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer=None): """ Function that runs the advection routine with a first-order Runge-Kutta update. This function updates the `Sol` solution container with the advected solution in-place. Parameters ---------- - Sol : :py:class:`management.variable.Vars` + Sol : :py:class:`management.variable.Vars` Solution data container. flux : :py:class:`management.variable.States` Fluxes data container @@ -195,7 +214,7 @@ def advect_rk(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None) Tag label for the output array writer : :py:class:`management.io.io`, optional Writer class for I/O operations, by default None - + Attention --------- This function is not usually called unless commented out in the :py:meth:`management.data.time_update` routine. @@ -210,13 +229,15 @@ def advect_rk(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None) for split in range(ndim): lmbda = time_step / elem.dxyz[split] Sol.flip_forward() - if elem.iisc[split] > 1: - flux[split] = explicit_step_and_flux(Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv, tag='rk') + if elem.iisc[split] > 1: + flux[split] = explicit_step_and_flux( + Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv, tag="rk" + ) ndim = elem.ndim left_idx, right_idx = [slice(None)] * ndim, [slice(None)] * ndim - right_idx[-1] = slice(1,None) - left_idx[-1] = slice(0,-1) + right_idx[-1] = slice(1, None) + left_idx[-1] = slice(0, -1) left_idx, right_idx = tuple(left_idx), tuple(right_idx) for dim in range(ndim): @@ -229,9 +250,9 @@ def advect_rk(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None) Sol.rhoX += lmbda * (flux[dim].rhoX[left_idx] - flux[dim].rhoX[right_idx]) Sol.rhoY += lmbda * (flux[dim].rhoY[left_idx] - flux[dim].rhoY[right_idx]) - if dim == 1: # vertical axis + if dim == 1: # vertical axis updt = lmbda * (flux[dim].rhoX[left_idx] - flux[dim].rhoX[right_idx]) - setattr(Sol, 'pwchi', updt) + setattr(Sol, "pwchi", updt) bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) @@ -239,7 +260,7 @@ def advect_rk(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None) # for split in range(ndim): # lmbda = dt / elem.dxyz[split] # Sol.flip_forward() - # if elem.iisc[split] > 1: + # if elem.iisc[split] > 1: # flux[split] = explicit_step_and_flux(Sol, flux[split], lmbda, elem, split, stage, ud, th, mpv, tag='rk') # Sol = deepcopy(Sol0) @@ -253,5 +274,5 @@ def advect_rk(Sol, flux, dt, elem, odd, ud, th, mpv, node, label, writer = None) # Sol.rhow += lmbda * (flux[dim].rhow[left_idx] - flux[dim].rhow[right_idx]) # Sol.rhoX += lmbda * (flux[dim].rhoX[left_idx] - flux[dim].rhoX[right_idx]) # Sol.rhoY += lmbda * (flux[dim].rhoY[left_idx] - flux[dim].rhoY[right_idx]) - + # set_explicit_boundary_data(Sol, elem, ud, th, mpv) diff --git a/src/flow_solver/physics/gas_dynamics/numerical_flux.py b/src/flow_solver/physics/gas_dynamics/numerical_flux.py index 548e8ad0..3d5098a6 100644 --- a/src/flow_solver/physics/gas_dynamics/numerical_flux.py +++ b/src/flow_solver/physics/gas_dynamics/numerical_flux.py @@ -2,6 +2,7 @@ import numpy as np import scipy as sp + def recompute_advective_fluxes(flux, Sol, *args, **kwargs): """ Recompute the advective fluxes at the cell interfaces, i.e. the faces. This function updates the `flux` container in-place. @@ -19,32 +20,43 @@ def recompute_advective_fluxes(flux, Sol, *args, **kwargs): """ ndim = Sol.rho.ndim - inner_idx = tuple([slice(1,-1)] * ndim) + inner_idx = tuple([slice(1, -1)] * ndim) if ndim == 2: - kernel_u = np.array([[0.5,1.,0.5],[0.5,1.,0.5]]) + kernel_u = np.array([[0.5, 1.0, 0.5], [0.5, 1.0, 0.5]]) kernel_v = kernel_u.T elif ndim == 3: - kernel_u = np.array([[[1,2,1],[2,4,2],[1,2,1]],[[1,2,1],[2,4,2],[1,2,1]]]) - kernel_v = np.swapaxes(kernel_u,1,0) - kernel_w = np.swapaxes(kernel_u,2,0) + kernel_u = np.array( + [[[1, 2, 1], [2, 4, 2], [1, 2, 1]], [[1, 2, 1], [2, 4, 2], [1, 2, 1]]] + ) + kernel_v = np.swapaxes(kernel_u, 1, 0) + kernel_w = np.swapaxes(kernel_u, 2, 0) rhoYw = Sol.rhoY * Sol.rhow / Sol.rho - flux[2].rhoY[inner_idx] = sp.signal.fftconvolve(rhoYw, kernel_w, mode='valid') / kernel_w.sum() + flux[2].rhoY[inner_idx] = ( + sp.signal.fftconvolve(rhoYw, kernel_w, mode="valid") / kernel_w.sum() + ) else: assert 0, "Unsupported dimension in recompute_advective_flux" - rhoYu = kwargs.get('u',Sol.rhoY * Sol.rhou / Sol.rho) + rhoYu = kwargs.get("u", Sol.rhoY * Sol.rhou / Sol.rho) - flux[0].rhoY[inner_idx] = np.moveaxis(sp.signal.fftconvolve(rhoYu, kernel_u, mode='valid') / kernel_u.sum(), 0, -1) + flux[0].rhoY[inner_idx] = np.moveaxis( + sp.signal.fftconvolve(rhoYu, kernel_u, mode="valid") / kernel_u.sum(), 0, -1 + ) - rhoYv = kwargs.get('v',Sol.rhoY * Sol.rhov / Sol.rho) + rhoYv = kwargs.get("v", Sol.rhoY * Sol.rhov / Sol.rho) if ndim == 2: - flux[1].rhoY[inner_idx] = sp.signal.fftconvolve(rhoYv, kernel_v, mode='valid') / kernel_v.sum() + flux[1].rhoY[inner_idx] = ( + sp.signal.fftconvolve(rhoYv, kernel_v, mode="valid") / kernel_v.sum() + ) elif ndim == 3: - flux[1].rhoY[inner_idx] = np.moveaxis(sp.signal.fftconvolve(rhoYv, kernel_v, mode='valid') / kernel_v.sum(), -1,0) + flux[1].rhoY[inner_idx] = np.moveaxis( + sp.signal.fftconvolve(rhoYv, kernel_v, mode="valid") / kernel_v.sum(), -1, 0 + ) # flux[1].rhoY[...,-1] = 0. + def hll_solver(flux, Lefts, Rights, Sol, lmbda, ud, th): """ HLL solver for the Riemann problem. Chooses the advected quantities from `Lefts` or `Rights` based on the direction given by `flux`. @@ -72,28 +84,51 @@ def hll_solver(flux, Lefts, Rights, Sol, lmbda, ud, th): `flux` data container with the solution of the Riemann problem. """ # flux: index 1 to end = Left[inner_idx]: index 0 to -1 = Right[inner_idx]: index 1 to end - - ndim = Sol.rho.ndim - left_idx, right_idx, remove_cols_idx = [slice(None)] * ndim, [slice(None)] * ndim, [slice(None)] * ndim - - remove_cols_idx[-1] = slice(1,-1) - left_idx[-1] = slice(0,-1) - right_idx[-1] = slice(1,None) - left_idx, right_idx, remove_cols_idx = tuple(left_idx), tuple(right_idx), tuple(remove_cols_idx) + ndim = Sol.rho.ndim + left_idx, right_idx, remove_cols_idx = ( + [slice(None)] * ndim, + [slice(None)] * ndim, + [slice(None)] * ndim, + ) + + remove_cols_idx[-1] = slice(1, -1) + left_idx[-1] = slice(0, -1) + right_idx[-1] = slice(1, None) + + left_idx, right_idx, remove_cols_idx = ( + tuple(left_idx), + tuple(right_idx), + tuple(remove_cols_idx), + ) Lefts.primitives(th) Rights.primitives(th) - + upwind = 0.5 * (1.0 + np.sign(flux.rhoY)) upl = upwind[right_idx] - upr = (1.0 - upwind[left_idx]) - - flux.rhou[remove_cols_idx] = flux.rhoY[remove_cols_idx] * (upl[left_idx] / Lefts.Y[left_idx] * Lefts.u[left_idx] + upr[right_idx] / Rights.Y[right_idx] * Rights.u[right_idx]) - flux.rho[remove_cols_idx] = flux.rhoY[remove_cols_idx] * (upl[left_idx] / Lefts.Y[left_idx] * 1.0 + upr[right_idx] / Rights.Y[right_idx] * 1.0) - - flux.rhov[remove_cols_idx] = flux.rhoY[remove_cols_idx] * (upl[left_idx] / Lefts.Y[left_idx] * Lefts.v[left_idx] + upr[right_idx] / Rights.Y[right_idx] * Rights.v[right_idx]) - flux.rhow[remove_cols_idx] = flux.rhoY[remove_cols_idx] * (upl[left_idx] / Lefts.Y[left_idx] * Lefts.w[left_idx] + upr[right_idx] / Rights.Y[right_idx] * Rights.w[right_idx]) - flux.rhoX[remove_cols_idx] = flux.rhoY[remove_cols_idx] * (upl[left_idx] / Lefts.Y[left_idx] * Lefts.X[left_idx] + upr[right_idx] / Rights.Y[right_idx] * Rights.X[right_idx]) + upr = 1.0 - upwind[left_idx] + + flux.rhou[remove_cols_idx] = flux.rhoY[remove_cols_idx] * ( + upl[left_idx] / Lefts.Y[left_idx] * Lefts.u[left_idx] + + upr[right_idx] / Rights.Y[right_idx] * Rights.u[right_idx] + ) + flux.rho[remove_cols_idx] = flux.rhoY[remove_cols_idx] * ( + upl[left_idx] / Lefts.Y[left_idx] * 1.0 + + upr[right_idx] / Rights.Y[right_idx] * 1.0 + ) + + flux.rhov[remove_cols_idx] = flux.rhoY[remove_cols_idx] * ( + upl[left_idx] / Lefts.Y[left_idx] * Lefts.v[left_idx] + + upr[right_idx] / Rights.Y[right_idx] * Rights.v[right_idx] + ) + flux.rhow[remove_cols_idx] = flux.rhoY[remove_cols_idx] * ( + upl[left_idx] / Lefts.Y[left_idx] * Lefts.w[left_idx] + + upr[right_idx] / Rights.Y[right_idx] * Rights.w[right_idx] + ) + flux.rhoX[remove_cols_idx] = flux.rhoY[remove_cols_idx] * ( + upl[left_idx] / Lefts.Y[left_idx] * Lefts.X[left_idx] + + upr[right_idx] / Rights.Y[right_idx] * Rights.X[right_idx] + ) return flux diff --git a/src/flow_solver/physics/gas_dynamics/recovery.py b/src/flow_solver/physics/gas_dynamics/recovery.py index fe0dc058..3bfb9030 100644 --- a/src/flow_solver/physics/gas_dynamics/recovery.py +++ b/src/flow_solver/physics/gas_dynamics/recovery.py @@ -2,6 +2,7 @@ from ...utils import options as opts, variable as var + def do(Sol, flux, lmbda, ud, th, elem, split_step, tag): """ Reconstruct the limited slopes at the cell interfaces. @@ -22,7 +23,7 @@ def do(Sol, flux, lmbda, ud, th, elem, split_step, tag): Class container for the cell-grid. split_step : int Tracks the substep in the Strang-splitting. - tag : `None` or `rk` + tag : `None` or `rk` Default is `None` which uses a second-order Strang-splitting. `rk` toggles a first-order Runge-Kutta update for the advection scheme. Returns @@ -32,56 +33,78 @@ def do(Sol, flux, lmbda, ud, th, elem, split_step, tag): """ gamm = th.gamm - - order_two = 1 # always 1 + + order_two = 1 # always 1 Sol.primitives(th) - if tag == 'rk': + if tag == "rk": lmbda = 0.0 ndim = elem.ndim - lefts_idx, rights_idx, inner_idx = [slice(None,)] * ndim, [slice(None,)] * ndim, [slice(1,-1)] * ndim - lefts_idx[-1] = slice(0,-1) - rights_idx[-1] = slice(1,None) - lefts_idx, rights_idx, inner_idx = tuple(lefts_idx), tuple(rights_idx), tuple(inner_idx) + lefts_idx, rights_idx, inner_idx = ( + [ + slice( + None, + ) + ] + * ndim, + [ + slice( + None, + ) + ] + * ndim, + [slice(1, -1)] * ndim, + ) + lefts_idx[-1] = slice(0, -1) + rights_idx[-1] = slice(1, None) + lefts_idx, rights_idx, inner_idx = ( + tuple(lefts_idx), + tuple(rights_idx), + tuple(inner_idx), + ) # inner_idx here are where the interface fluxes are calculated with non-zero values. face_inner_idx = inner_idx u = np.zeros_like(Sol.rhoY) - u[inner_idx] = 0.5 * (flux.rhoY[face_inner_idx][lefts_idx] + flux.rhoY[face_inner_idx][rights_idx]) / Sol.rhoY[inner_idx] + u[inner_idx] = ( + 0.5 + * (flux.rhoY[face_inner_idx][lefts_idx] + flux.rhoY[face_inner_idx][rights_idx]) + / Sol.rhoY[inner_idx] + ) shape = Sol.u.shape - Diffs = var.States(shape,ud) + Diffs = var.States(shape, ud) Ampls = var.Characters(shape) Lefts = var.States(shape, ud) Rights = var.States(shape, ud) - Diffs.u[...,:-1] = Sol.u[rights_idx] - Sol.u[lefts_idx] - Diffs.v[...,:-1] = Sol.v[rights_idx] - Sol.v[lefts_idx] - Diffs.w[...,:-1] = Sol.w[rights_idx] - Sol.w[lefts_idx] - Diffs.X[...,:-1] = Sol.X[rights_idx] - Sol.X[lefts_idx] - Diffs.Y[...,:-1] = 1.0 / Sol.Y[rights_idx] - 1.0 / Sol.Y[lefts_idx] + Diffs.u[..., :-1] = Sol.u[rights_idx] - Sol.u[lefts_idx] + Diffs.v[..., :-1] = Sol.v[rights_idx] - Sol.v[lefts_idx] + Diffs.w[..., :-1] = Sol.w[rights_idx] - Sol.w[lefts_idx] + Diffs.X[..., :-1] = Sol.X[rights_idx] - Sol.X[lefts_idx] + Diffs.Y[..., :-1] = 1.0 / Sol.Y[rights_idx] - 1.0 / Sol.Y[lefts_idx] Slopes = slopes(Sol, Diffs, ud, elem) - Ampls.u[...] = 0.5 * Slopes.u * (1. - lmbda * u) - Ampls.v[...] = 0.5 * Slopes.v * (1. - lmbda * u) - Ampls.w[...] = 0.5 * Slopes.w * (1. - lmbda * u) - Ampls.X[...] = 0.5 * Slopes.X * (1. - lmbda * u) - Ampls.Y[...] = 0.5 * Slopes.Y * (1. - lmbda * u) - + Ampls.u[...] = 0.5 * Slopes.u * (1.0 - lmbda * u) + Ampls.v[...] = 0.5 * Slopes.v * (1.0 - lmbda * u) + Ampls.w[...] = 0.5 * Slopes.w * (1.0 - lmbda * u) + Ampls.X[...] = 0.5 * Slopes.X * (1.0 - lmbda * u) + Ampls.Y[...] = 0.5 * Slopes.Y * (1.0 - lmbda * u) + Lefts.u[...] = Sol.u + order_two * Ampls.u Lefts.v[...] = Sol.v + order_two * Ampls.v Lefts.w[...] = Sol.w + order_two * Ampls.w Lefts.X[...] = Sol.X + order_two * Ampls.X Lefts.Y[...] = 1.0 / (1.0 / Sol.Y + order_two * Ampls.Y) - Ampls.u[...] = -0.5 * Slopes.u * (1. + lmbda * u) - Ampls.v[...] = -0.5 * Slopes.v * (1. + lmbda * u) - Ampls.w[...] = -0.5 * Slopes.w * (1. + lmbda * u) - Ampls.X[...] = -0.5 * Slopes.X * (1. + lmbda * u) - Ampls.Y[...] = -0.5 * Slopes.Y * (1. + lmbda * u) + Ampls.u[...] = -0.5 * Slopes.u * (1.0 + lmbda * u) + Ampls.v[...] = -0.5 * Slopes.v * (1.0 + lmbda * u) + Ampls.w[...] = -0.5 * Slopes.w * (1.0 + lmbda * u) + Ampls.X[...] = -0.5 * Slopes.X * (1.0 + lmbda * u) + Ampls.Y[...] = -0.5 * Slopes.Y * (1.0 + lmbda * u) Rights.u[...] = Sol.u + order_two * Ampls.u Rights.v[...] = Sol.v + order_two * Ampls.v @@ -89,14 +112,18 @@ def do(Sol, flux, lmbda, ud, th, elem, split_step, tag): Rights.X[...] = Sol.X + order_two * Ampls.X Rights.Y[...] = 1.0 / (1.0 / Sol.Y + order_two * Ampls.Y) - vel = [Sol.u,Sol.v,Sol.w] + vel = [Sol.u, Sol.v, Sol.w] # Lefts.rhoY[lefts_idx] = Rights.rhoY[rights_idx] = 0.5 * (Sol.rhoY[lefts_idx] + Sol.rhoY[rights_idx]) \ # - order_two * 0.5 * lmbda * (Sol.u[rights_idx] * Sol.rhoY[rights_idx] - Sol.u[lefts_idx] * Sol.rhoY[lefts_idx]) - Lefts.rhoY[lefts_idx] = Rights.rhoY[rights_idx] = 0.5 * (Sol.rhoY[lefts_idx] + Sol.rhoY[rights_idx]) \ - - order_two * 0.5 * lmbda * (vel[split_step][rights_idx] * Sol.rhoY[rights_idx] - vel[split_step][lefts_idx] * Sol.rhoY[lefts_idx]) + Lefts.rhoY[lefts_idx] = Rights.rhoY[rights_idx] = 0.5 * ( + Sol.rhoY[lefts_idx] + Sol.rhoY[rights_idx] + ) - order_two * 0.5 * lmbda * ( + vel[split_step][rights_idx] * Sol.rhoY[rights_idx] + - vel[split_step][lefts_idx] * Sol.rhoY[lefts_idx] + ) - Lefts.p0[lefts_idx] = Rights.p0[rights_idx] = Lefts.rhoY[lefts_idx]**gamm + Lefts.p0[lefts_idx] = Rights.p0[rights_idx] = Lefts.rhoY[lefts_idx] ** gamm get_conservatives(Rights, ud, th) get_conservatives(Lefts, ud, th) @@ -104,6 +131,7 @@ def do(Sol, flux, lmbda, ud, th, elem, split_step, tag): # return Lefts, Rights, u, Diffs, Ampls, Slopes return Lefts, Rights + def slopes(Sol, Diffs, ud, elem): """ Reconstruct the piecewise linear slopes in the cells from the piecewise constants in the cell and its neighbours. @@ -123,14 +151,22 @@ def slopes(Sol, Diffs, ud, elem): ------- :py:class:`management.variable.Characters` Reconstructed piecewise linear slopes in the cell. - """ + """ limiter_type_velocity = ud.limiter_type_velocity limiter_type_scalar = ud.limiter_type_scalars ndim = elem.ndim - lefts_idx, rights_idx = [slice(None,)] * ndim, [slice(None,)] * ndim - lefts_idx[-1] = slice(0,-1) - rights_idx[-1] = slice(1,None) + lefts_idx, rights_idx = [ + slice( + None, + ) + ] * ndim, [ + slice( + None, + ) + ] * ndim + lefts_idx[-1] = slice(0, -1) + rights_idx[-1] = slice(1, None) lefts_idx, rights_idx = tuple(lefts_idx), tuple(rights_idx) # amplitudes of the state differences: @@ -151,14 +187,15 @@ def slopes(Sol, Diffs, ud, elem): Slopes = var.Characters(Diffs.u.shape) - Slopes.u[...,1:-1] = limiters(limiter_type_velocity, aul, aur) - Slopes.v[...,1:-1] = limiters(limiter_type_velocity, avl, avr) - Slopes.w[...,1:-1] = limiters(limiter_type_velocity, awl, awr) - Slopes.X[...,1:-1] = limiters(limiter_type_scalar, aXl, aXr) - Slopes.Y[...,1:-1] = limiters(limiter_type_scalar, aYl, aYr) + Slopes.u[..., 1:-1] = limiters(limiter_type_velocity, aul, aur) + Slopes.v[..., 1:-1] = limiters(limiter_type_velocity, avl, avr) + Slopes.w[..., 1:-1] = limiters(limiter_type_velocity, awl, awr) + Slopes.X[..., 1:-1] = limiters(limiter_type_scalar, aXl, aXr) + Slopes.Y[..., 1:-1] = limiters(limiter_type_scalar, aYl, aYr) return Slopes + def limiters(limiter_type, al, ar): """ Applies the limiter type specified in the initial conditions to recovery the slope. @@ -186,6 +223,7 @@ def limiters(limiter_type, al, ar): if limiter_type == opts.LimiterType.NONE: return 0.5 * (al + ar) + def get_conservatives(U, ud, th): """ Get advected (conservative) quantities at the left and right of the cell interfaces. @@ -205,6 +243,6 @@ def get_conservatives(U, ud, th): U.rhow = U.w * U.rho U.rhoY = U.Y * U.rho U.rhoX = U.X * U.rho - + sgn = np.sign(U.rhoY) - p = sgn*np.abs(U.rhoY)**th.gamminv \ No newline at end of file + p = sgn * np.abs(U.rhoY) ** th.gamminv diff --git a/src/flow_solver/physics/gas_dynamics/thermodynamics.py b/src/flow_solver/physics/gas_dynamics/thermodynamics.py index c958f230..bdf06637 100644 --- a/src/flow_solver/physics/gas_dynamics/thermodynamics.py +++ b/src/flow_solver/physics/gas_dynamics/thermodynamics.py @@ -3,6 +3,7 @@ class ThermodynamicalQuantities(object): Data container for thermodynamical quantities. """ + def __init__(self, ud): """ Parameters @@ -10,7 +11,7 @@ def __init__(self, ud): ud : :class:`inputs.user_data.UserDataInit` Data container for the initial conditions """ - + g = ud.gamm self.gamm = g self.gamminv = 1.0 / g @@ -18,4 +19,3 @@ def __init__(self, ud): self.gm1inv = 1.0 / (g - 1.0) self.Gamma = (g - 1.0) / g self.Gammainv = g / (g - 1.0) - diff --git a/src/flow_solver/physics/hydrostatics.py b/src/flow_solver/physics/hydrostatics.py index 48fe95d8..b106e9e0 100644 --- a/src/flow_solver/physics/hydrostatics.py +++ b/src/flow_solver/physics/hydrostatics.py @@ -3,6 +3,7 @@ from ..utils import boundary as bdry + def column(HydroState, HydroState_n, Y, Y_n, elem, node, th, ud): Gamma = th.gm1 / th.gamm gamm = th.gamm @@ -13,10 +14,10 @@ def column(HydroState, HydroState_n, Y, Y_n, elem, node, th, ud): icy = elem.icy igy = elem.igy - xc_idx = slice(0,-1) - yc_idx = slice(0,-1) + xc_idx = slice(0, -1) + yc_idx = slice(0, -1) - c_idx = (xc_idx,yc_idx) + c_idx = (xc_idx, yc_idx) rhoY0 = 1.0 @@ -24,23 +25,25 @@ def column(HydroState, HydroState_n, Y, Y_n, elem, node, th, ud): p0 = rhoY0**gamm pi0 = rhoY0**gm1 - HydroState_n.rho0[xc_idx,igy] = rhoY0 / Y_n[:,igy] - HydroState_n.rhoY0[xc_idx,igy] = rhoY0 - HydroState_n.Y0[xc_idx,igy] = Y_n[:,igy] - HydroState_n.S0[xc_idx,igy] = 1.0 / Y_n[:,igy] - HydroState_n.p0[xc_idx,igy] = p0 - HydroState_n.p20[xc_idx,igy] = pi0 / ud.Msq - - dys = np.array([-elem.dy] + [-elem.dy/2] + [elem.dy/2] + list(np.ones((icy-3)) * elem.dy)) - S_p = 1.0 / Y[:,:] + HydroState_n.rho0[xc_idx, igy] = rhoY0 / Y_n[:, igy] + HydroState_n.rhoY0[xc_idx, igy] = rhoY0 + HydroState_n.Y0[xc_idx, igy] = Y_n[:, igy] + HydroState_n.S0[xc_idx, igy] = 1.0 / Y_n[:, igy] + HydroState_n.p0[xc_idx, igy] = p0 + HydroState_n.p20[xc_idx, igy] = pi0 / ud.Msq + + dys = np.array( + [-elem.dy] + [-elem.dy / 2] + [elem.dy / 2] + list(np.ones((icy - 3)) * elem.dy) + ) + S_p = 1.0 / Y[:, :] S_m = np.zeros_like(S_p) - S_m[:,igy-1:igy+1] = 1.0 / Y_n[:,igy].reshape(-1,1) - S_m[:,0] = 1.0 / Y[:,igy-1] - S_m[:,igy+1:] = 1.0 / Y[:,igy:-1] + S_m[:, igy - 1 : igy + 1] = 1.0 / Y_n[:, igy].reshape(-1, 1) + S_m[:, 0] = 1.0 / Y[:, igy - 1] + S_m[:, igy + 1 :] = 1.0 / Y[:, igy:-1] S_integral_p = dys * 0.5 * (S_p + S_m) - S_integral_p[:,:igy] = np.cumsum(S_integral_p[:,:igy][:,::-1],axis=1)[:,::-1] - S_integral_p[:,igy:] = np.cumsum(S_integral_p[:,igy:],axis=1) + S_integral_p[:, :igy] = np.cumsum(S_integral_p[:, :igy][:, ::-1], axis=1)[:, ::-1] + S_integral_p[:, igy:] = np.cumsum(S_integral_p[:, igy:], axis=1) pi_hydro = pi0 - Gamma * g * S_integral_p p_hydro = pi_hydro**Gamma_inv @@ -54,27 +57,27 @@ def column(HydroState, HydroState_n, Y, Y_n, elem, node, th, ud): HydroState.Y0[c_idx] = 1.0 / S_p HydroState.rhoY0[c_idx] = rhoY_hydro - Sn_p = 1.0 / Y[:,:] + Sn_p = 1.0 / Y[:, :] dys = np.ones((icy)) * elem.dy dys[:igy] *= -1 Sn_integral_p = dys * Sn_p - Sn_integral_p[:,:igy] = np.cumsum(Sn_integral_p[:,:igy][:,::-1],axis=1)[:,::-1] - Sn_integral_p[:,igy:] = np.cumsum(Sn_integral_p[:,igy:],axis=1) + Sn_integral_p[:, :igy] = np.cumsum(Sn_integral_p[:, :igy][:, ::-1], axis=1)[:, ::-1] + Sn_integral_p[:, igy:] = np.cumsum(Sn_integral_p[:, igy:], axis=1) pi_hydro_n = pi0 - Gamma * g * Sn_integral_p rhoY_hydro_n = pi_hydro_n**gm1_inv - - HydroState_n.rhoY0[xc_idx,:igy] = rhoY_hydro_n[:,:igy] - HydroState_n.Y0[xc_idx,:igy] = Y_n[0,:igy] - HydroState_n.S0[xc_idx,:igy] = 1.0 / Y_n[:,:igy] - HydroState_n.p0[xc_idx,:igy] = rhoY_hydro_n[:,:igy]**th.gamm - HydroState_n.p20[xc_idx,:igy] = pi_hydro_n[:,:igy] / ud.Msq - HydroState_n.rhoY0[xc_idx,igy+1:] = rhoY_hydro_n[:,igy:] - HydroState_n.Y0[xc_idx,igy+1:] = Y_n[0,igy:] - HydroState_n.S0[xc_idx,igy+1:] = 1.0 / Y_n[:,igy:] - HydroState_n.p0[xc_idx,igy+1:] = rhoY_hydro_n[:,igy:]**th.gamm - HydroState_n.p20[xc_idx,igy+1:] = pi_hydro_n[:,igy:] / ud.Msq + HydroState_n.rhoY0[xc_idx, :igy] = rhoY_hydro_n[:, :igy] + HydroState_n.Y0[xc_idx, :igy] = Y_n[0, :igy] + HydroState_n.S0[xc_idx, :igy] = 1.0 / Y_n[:, :igy] + HydroState_n.p0[xc_idx, :igy] = rhoY_hydro_n[:, :igy] ** th.gamm + HydroState_n.p20[xc_idx, :igy] = pi_hydro_n[:, :igy] / ud.Msq + + HydroState_n.rhoY0[xc_idx, igy + 1 :] = rhoY_hydro_n[:, igy:] + HydroState_n.Y0[xc_idx, igy + 1 :] = Y_n[0, igy:] + HydroState_n.S0[xc_idx, igy + 1 :] = 1.0 / Y_n[:, igy:] + HydroState_n.p0[xc_idx, igy + 1 :] = rhoY_hydro_n[:, igy:] ** th.gamm + HydroState_n.p20[xc_idx, igy + 1 :] = pi_hydro_n[:, igy:] / ud.Msq def state(mpv, elem, node, th, ud): @@ -89,7 +92,7 @@ def state(mpv, elem, node, th, ud): pi_nm = np.exp(-(node.y - 0.5 * dy) / Hex) pi_n = np.exp(-(node.y) / Hex) - Y_n = - Gamma * g * dy / (pi_np - pi_nm) + Y_n = -Gamma * g * dy / (pi_np - pi_nm) P_n = pi_n**th.gm1inv p_n = pi_n**th.Gammainv rho_n = P_n / Y_n @@ -103,9 +106,9 @@ def state(mpv, elem, node, th, ud): pi_cp = np.exp(-(elem.y + 0.5 * dy) / Hex) pi_cm = np.exp(-(elem.y - 0.5 * dy) / Hex) - pi_c = np.exp(-(elem.y) / Hex) + pi_c = np.exp(-(elem.y) / Hex) - Y_c = - Gamma * g * dy / (pi_cp - pi_cm) + Y_c = -Gamma * g * dy / (pi_cp - pi_cm) P_c = pi_c**th.gm1inv p_c = pi_c**th.Gammainv rho_c = P_c / Y_c @@ -133,99 +136,118 @@ def state(mpv, elem, node, th, ud): mpv.HydroState_n.S0[...] = 1.0 -def initial_pressure(Sol,mpv,elem,node,ud,th): +def initial_pressure(Sol, mpv, elem, node, ud, th): Gammainv = th.Gammainv igy = node.igy igx = node.igx - icx= elem.icx + icx = elem.icx dx = node.dx dy = node.dy beta = np.zeros((node.icx)) bdpdx = np.zeros((node.icx)) - x_idx_m = slice(0,-1) - x_idx_c = slice(1,None) - y_idx = slice(igy,-igy) - xn_idx = slice(1,-1) - height = node.y[-igy-1] + x_idx_m = slice(0, -1) + x_idx_c = slice(1, None) + y_idx = slice(igy, -igy) + xn_idx = slice(1, -1) + height = node.y[-igy - 1] - Pc = Sol.rhoY[x_idx_c,y_idx] - Pm = Sol.rhoY[x_idx_m,y_idx] - thc = Pc / Sol.rho[x_idx_c,y_idx] - thm = Pm / Sol.rho[x_idx_m,y_idx] + Pc = Sol.rhoY[x_idx_c, y_idx] + Pm = Sol.rhoY[x_idx_m, y_idx] + thc = Pc / Sol.rho[x_idx_c, y_idx] + thm = Pm / Sol.rho[x_idx_m, y_idx] beta[xn_idx] = np.sum(0.5 * (Pm * thm + Pc * thc) * dy, axis=1) - bdpdx[xn_idx] = np.sum(0.5 * (Pm * thm + Pc * thc) * (mpv.p2_cells[x_idx_c,y_idx] - mpv.p2_cells[x_idx_m,y_idx]) * dy, axis=1) + bdpdx[xn_idx] = np.sum( + 0.5 + * (Pm * thm + Pc * thc) + * (mpv.p2_cells[x_idx_c, y_idx] - mpv.p2_cells[x_idx_m, y_idx]) + * dy, + axis=1, + ) beta *= Gammainv / height bdpdx *= Gammainv / height / dx coeff = np.zeros((elem.icx)) pibot = np.zeros((elem.icx)) - coeff[igx+1:-igx+1] = np.cumsum(coeff[igx:-igx] + dx / beta[igx+1:-igx]) - pibot[igx+1:-igx+1] = np.cumsum(pibot[igx:-igx] - dx * bdpdx[igx+1:-igx] / beta[igx+1:-igx]) - - dotPU = pibot[icx-igx] / coeff[icx-igx] + coeff[igx + 1 : -igx + 1] = np.cumsum(coeff[igx:-igx] + dx / beta[igx + 1 : -igx]) + pibot[igx + 1 : -igx + 1] = np.cumsum( + pibot[igx:-igx] - dx * bdpdx[igx + 1 : -igx] / beta[igx + 1 : -igx] + ) + + dotPU = pibot[icx - igx] / coeff[icx - igx] pibot[igx:-igx] -= dotPU * coeff[igx:-igx] - x_idx = slice(igx,-igx+1) - y_idx = slice(igy,-igy+1) + x_idx = slice(igx, -igx + 1) + y_idx = slice(igy, -igy + 1) - mpv.p2_cells[x_idx,y_idx] += pibot[x_idx].reshape(-1,1) - 1.0 * mpv.HydroState.p20[y_idx].reshape(1,-1) + mpv.p2_cells[x_idx, y_idx] += pibot[x_idx].reshape( + -1, 1 + ) - 1.0 * mpv.HydroState.p20[y_idx].reshape(1, -1) bdry.set_ghostcells_p2(mpv.p2_cells, elem, ud) icxn = node.icx icyn = node.icy - x_idx = slice(1,icxn-1) - y_idx = slice(igy,-igy+1) + x_idx = slice(1, icxn - 1) + y_idx = slice(igy, -igy + 1) height = node.y[-igy] - Pc = Sol.rhoY[1:,y_idx] - thc = Pc / Sol.rho[1:,y_idx] + Pc = Sol.rhoY[1:, y_idx] + thc = Pc / Sol.rho[1:, y_idx] beta = np.zeros((elem.icx,)) bdpdx = np.zeros((elem.icx)) - - beta[1:] = np.sum(Pc*thc*dy, axis=1) + + beta[1:] = np.sum(Pc * thc * dy, axis=1) beta *= Gammainv / height - bdpdx[1:] = np.sum(Pc * thc * (mpv.p2_nodes[1:-1,igy:-igy] - mpv.p2_nodes[:-2,igy:-igy]) * dy, axis=1) + bdpdx[1:] = np.sum( + Pc * thc * (mpv.p2_nodes[1:-1, igy:-igy] - mpv.p2_nodes[:-2, igy:-igy]) * dy, + axis=1, + ) bdpdx *= Gammainv / height / dx coeff = np.zeros((node.icx)) pibot = np.zeros((node.icx)) - coeff[igx+1:-igx+1] = np.cumsum(coeff[igx:-igx] + dx / beta[igx+1:]) - pibot[igx+1:-igx+1] = np.cumsum(pibot[igx:-igx] - dx * bdpdx[igx+1:] / beta[igx+1:]) + coeff[igx + 1 : -igx + 1] = np.cumsum(coeff[igx:-igx] + dx / beta[igx + 1 :]) + pibot[igx + 1 : -igx + 1] = np.cumsum( + pibot[igx:-igx] - dx * bdpdx[igx + 1 :] / beta[igx + 1 :] + ) - dotPU = pibot[icx-igx] / coeff[icx-igx] + dotPU = pibot[icx - igx] / coeff[icx - igx] pibot[igx:-igx] -= dotPU * coeff[igx:-igx] - x_idx = slice(igx,-igx+1) - y_idx = slice(igy,-igy+1) - mpv.p2_nodes[x_idx,y_idx] += pibot[x_idx].reshape(-1,1) - 1.0 * mpv.HydroState_n.p20[y_idx].reshape(1,-1) + x_idx = slice(igx, -igx + 1) + y_idx = slice(igy, -igy + 1) + mpv.p2_nodes[x_idx, y_idx] += pibot[x_idx].reshape( + -1, 1 + ) - 1.0 * mpv.HydroState_n.p20[y_idx].reshape(1, -1) - mpv.dp2_nodes[:,:] = mpv.p2_nodes + mpv.dp2_nodes[:, :] = mpv.p2_nodes # guess initial node value (at left-most node) - mpv.p2_nodes[igx,igy:-igy] = mpv.dp2_nodes[igx,igy:-igy] + mpv.p2_nodes[igx, igy:-igy] = mpv.dp2_nodes[igx, igy:-igy] - mpv.p2_nodes[:,:] = __loop_over_array(igx,igy,icxn,icyn,mpv.p2_nodes, mpv.dp2_nodes) + mpv.p2_nodes[:, :] = __loop_over_array( + igx, igy, icxn, icyn, mpv.p2_nodes, mpv.dp2_nodes + ) + + assert ((node.icx + 1) % 2) == 1 + delp2 = 0.5 * (mpv.p2_nodes[-igx - 1, igy:-igy] - mpv.p2_nodes[igx, igy:-igy]) + delp2 = delp2.reshape(1, -1) + sgn = np.ones_like(mpv.p2_nodes[:, 0][igy:-igy]).reshape(-1, 1) - assert ((node.icx+1)%2) == 1 - delp2 = 0.5 * (mpv.p2_nodes[-igx-1,igy:-igy] - mpv.p2_nodes[igx,igy:-igy]) - delp2 = delp2.reshape(1,-1) - sgn = np.ones_like(mpv.p2_nodes[:,0][igy:-igy]).reshape(-1,1) - sgn[1::2] *= -1 - mpv.p2_nodes[igx:-igx,igy:-igy] += sgn * delp2 + mpv.p2_nodes[igx:-igx, igy:-igy] += sgn * delp2 bdry.set_ghostnodes_p2(mpv.p2_nodes, node, ud) - mpv.dp2_nodes[:,:] = 0.0 + mpv.dp2_nodes[:, :] = 0.0 - inner_domain = (slice(igx,-igx), slice(igy,-igy)) + inner_domain = (slice(igx, -igx), slice(igy, -igy)) pi = ud.Msq * (mpv.p2_cells[inner_domain] + 1.0 * mpv.HydroState.p20[igy:-igy]) Y = Sol.rhoY[inner_domain] / Sol.rho[inner_domain] rhoold = np.copy(Sol.rho[inner_domain]) @@ -236,15 +258,13 @@ def initial_pressure(Sol,mpv,elem,node,ud,th): Sol.rhow[inner_domain] *= Sol.rho[inner_domain] / rhoold Sol.rhoX[inner_domain] *= Sol.rho[inner_domain] / rhoold + # need details: # populate the rest of the nodes recursively based on the left-most node. # recursive: use numba. @nb.jit(nopython=True) -def __loop_over_array(igx,igy,icxn,icyn,p,dp): - for j in range(igy,icyn-igy): - for i in range(igx+1,icxn-igx): - p[i,j] = 2.0 * dp[i-1,j] - p[i-1,j] +def __loop_over_array(igx, igy, icxn, icyn, p, dp): + for j in range(igy, icyn - igy): + for i in range(igx + 1, icxn - igx): + p[i, j] = 2.0 * dp[i - 1, j] - p[i - 1, j] return p - - - \ No newline at end of file diff --git a/src/flow_solver/physics/low_mach/laplacian.py b/src/flow_solver/physics/low_mach/laplacian.py index 4b940ab8..1dfc9035 100644 --- a/src/flow_solver/physics/low_mach/laplacian.py +++ b/src/flow_solver/physics/low_mach/laplacian.py @@ -4,7 +4,8 @@ from ...utils import options as opts -def stencil_9pt(elem,node,mpv,Sol,ud,diag_inv,dt,coriolis_params): + +def stencil_9pt(elem, node, mpv, Sol, ud, diag_inv, dt, coriolis_params): igx = elem.igx igy = elem.igy @@ -19,14 +20,22 @@ def stencil_9pt(elem,node,mpv,Sol,ud,diag_inv,dt,coriolis_params): dx = node.dy dy = node.dx - inner_domain = (slice(igx,-igx),slice(igy,-igy)) + inner_domain = (slice(igx, -igx), slice(igy, -igy)) i1 = node.i1 - hplusx = mpv.wplus[1][i1].reshape(-1,) - hplusy = mpv.wplus[0][i1].reshape(-1,) - hcenter = mpv.wcenter[i1].reshape(-1,) + hplusx = mpv.wplus[1][i1].reshape( + -1, + ) + hplusy = mpv.wplus[0][i1].reshape( + -1, + ) + hcenter = mpv.wcenter[i1].reshape( + -1, + ) - diag_inv = diag_inv[i1].reshape(-1,) + diag_inv = diag_inv[i1].reshape( + -1, + ) oodx = 1.0 / (dx) oody = 1.0 / (dy) @@ -34,9 +43,14 @@ def stencil_9pt(elem,node,mpv,Sol,ud,diag_inv,dt,coriolis_params): x_periodic = ud.bdry_type[1] == opts.BdryType.PERIODIC y_periodic = ud.bdry_type[0] == opts.BdryType.PERIODIC - x_wall = ud.bdry_type[1] == opts.BdryType.WALL or ud.bdry_type[1] == opts.BdryType.RAYLEIGH - y_wall = ud.bdry_type[0] == opts.BdryType.WALL or ud.bdry_type[0] == opts.BdryType.RAYLEIGH - + x_wall = ( + ud.bdry_type[1] == opts.BdryType.WALL + or ud.bdry_type[1] == opts.BdryType.RAYLEIGH + ) + y_wall = ( + ud.bdry_type[0] == opts.BdryType.WALL + or ud.bdry_type[0] == opts.BdryType.RAYLEIGH + ) #### Compute Coriolis parameters: # nonhydro = ud.nonhydrostasy @@ -67,7 +81,7 @@ def stencil_9pt(elem,node,mpv,Sol,ud,diag_inv,dt,coriolis_params): # y_idx1 = slice(igs[dim]-is_periodic+1, right_idx) # innerdim1[dim] = slice(igs[dim]-1, (-igs[dim]+1)) - + # strat = (mpv.HydroState_n.S0[y_idx1] - mpv.HydroState_n.S0[y_idx]) / dy # nindim = tuple(nindim) @@ -97,7 +111,24 @@ def stencil_9pt(elem,node,mpv,Sol,ud,diag_inv,dt,coriolis_params): # coriolis_params = (coeff_vv, coeff_vu, coeff_uv, coeff_uu) # coriolis_params = np.array(coriolis_params, dtype=np.float64) - return lambda p : lap2D_gather(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx, oody, x_periodic, y_periodic, x_wall, y_wall, diag_inv, coriolis_params) + return lambda p: lap2D_gather( + p, + igx, + igy, + iicxn, + iicyn, + hplusx, + hplusy, + hcenter, + oodx, + oody, + x_periodic, + y_periodic, + x_wall, + y_wall, + diag_inv, + coriolis_params, + ) # ndim = elem.ndim # periodicity = np.zeros(ndim, dtype='int') @@ -145,8 +176,26 @@ def stencil_9pt(elem,node,mpv,Sol,ud,diag_inv,dt,coriolis_params): # return lambda p : lap2Dc(p, hplusx, hplusy, hcenter, dxy, periodicity, diag_inv, coriolis_params) + @nb.jit(nopython=True, nogil=False, cache=True) -def lap2D_gather(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx, oody, x_periodic, y_periodic, x_wall, y_wall, diag_inv, coriolis): +def lap2D_gather( + p, + igx, + igy, + iicxn, + iicyn, + hplusx, + hplusy, + hcenter, + oodx, + oody, + x_periodic, + y_periodic, + x_wall, + y_wall, + diag_inv, + coriolis, +): ngnc = (iicxn) * (iicyn) lap = np.zeros((ngnc)) cnt_x = 0 @@ -159,7 +208,7 @@ def lap2D_gather(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx, oody, for idx in range(iicxn * iicyn): ne_topleft = idx - iicxn - 1 - ne_topright = idx - iicxn + ne_topright = idx - iicxn ne_botleft = idx - 1 ne_botright = idx @@ -193,20 +242,20 @@ def lap2D_gather(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx, oody, ne_botright -= iicxn - 1 if cnt_y == 0: - topleft_idx += ((iicxn) * (iicyn - 1)) - topmid_idx += ((iicxn) * (iicyn - 1)) - topright_idx += ((iicxn) * (iicyn - 1)) + topleft_idx += (iicxn) * (iicyn - 1) + topmid_idx += (iicxn) * (iicyn - 1) + topright_idx += (iicxn) * (iicyn - 1) - ne_topleft += ((iicxn) * (iicyn - 1)) - ne_topright += ((iicxn) * (iicyn - 1)) + ne_topleft += (iicxn) * (iicyn - 1) + ne_topright += (iicxn) * (iicyn - 1) if cnt_y == (iicyn - 1): - botleft_idx -= ((iicxn) * (iicyn - 1)) - botmid_idx -= ((iicxn) * (iicyn - 1)) - botright_idx -= ((iicxn) * (iicyn - 1)) + botleft_idx -= (iicxn) * (iicyn - 1) + botmid_idx -= (iicxn) * (iicyn - 1) + botright_idx -= (iicxn) * (iicyn - 1) - ne_botleft -= ((iicxn) * (iicyn - 1)) - ne_botright -= ((iicxn) * (iicyn - 1)) + ne_botleft -= (iicxn) * (iicyn - 1) + ne_botright -= (iicxn) * (iicyn - 1) topleft = p[topleft_idx] midleft = p[midleft_idx] @@ -230,51 +279,50 @@ def lap2D_gather(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx, oody, hplusy_topright = hplusy[ne_topright] hplusy_botright = hplusy[ne_botright] - cxx_tl = cxx[ne_topleft] + cxx_tl = cxx[ne_topleft] cxx_tr = cxx[ne_topright] - cxx_bl = cxx[ne_botleft] + cxx_bl = cxx[ne_botleft] cxx_br = cxx[ne_botright] - cxy_tl = cxy[ne_topleft] - cxy_tr = cxy[ne_topright] - cxy_bl = cxy[ne_botleft] - cxy_br = cxy[ne_botright] + cxy_tl = cxy[ne_topleft] + cxy_tr = cxy[ne_topright] + cxy_bl = cxy[ne_botleft] + cxy_br = cxy[ne_botright] - cyx_tl = cyx[ne_topleft] - cyx_tr = cyx[ne_topright] - cyx_bl = cyx[ne_botleft] - cyx_br = cyx[ne_botright] + cyx_tl = cyx[ne_topleft] + cyx_tr = cyx[ne_topright] + cyx_bl = cyx[ne_botleft] + cyx_br = cyx[ne_botright] - cyy_tl = cyy[ne_topleft] - cyy_tr = cyy[ne_topright] - cyy_bl = cyy[ne_botleft] - cyy_br = cyy[ne_botright] - + cyy_tl = cyy[ne_topleft] + cyy_tr = cyy[ne_topright] + cyy_bl = cyy[ne_botleft] + cyy_br = cyy[ne_botright] if x_wall and (cnt_x == 0): - hplusx_topleft = 0. - hplusy_topleft = 0. - hplusx_botleft = 0. - hplusy_botleft = 0. + hplusx_topleft = 0.0 + hplusy_topleft = 0.0 + hplusx_botleft = 0.0 + hplusy_botleft = 0.0 if x_wall and (cnt_x == (iicxn - 1)): - hplusx_topright = 0. - hplusy_topright = 0. - hplusx_botright = 0. - hplusy_botright = 0. + hplusx_topright = 0.0 + hplusy_topright = 0.0 + hplusx_botright = 0.0 + hplusy_botright = 0.0 if y_wall and (cnt_y == 0): - hplusx_topleft = 0. - hplusy_topleft = 0. - hplusx_topright = 0. - hplusy_topright = 0. - + hplusx_topleft = 0.0 + hplusy_topleft = 0.0 + hplusx_topright = 0.0 + hplusy_topright = 0.0 + if y_wall and (cnt_y == (iicyn - 1)): - hplusx_botleft = 0. - hplusy_botleft = 0. - hplusx_botright = 0. - hplusy_botright = 0. - + hplusx_botleft = 0.0 + hplusy_botleft = 0.0 + hplusx_botright = 0.0 + hplusy_botright = 0.0 + # dp2dxdy1 = ((midmid - midleft) - (topmid - topleft)) * nine_pt # dp2dxdy2 = ((midright - midmid) - (topright - topmid)) * nine_pt # dp2dxdy3 = ((botmid - botleft) - (midmid - midleft)) * nine_pt @@ -290,26 +338,48 @@ def lap2D_gather(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx, oody, # + hplusy_botright * oody2 * ((botmid - midmid) + dp2dxdy4) \ # + hcenter[idx] * p[idx] - Dx_tl = 0.5 * (topmid - topleft + midmid - midleft) * hplusx_topleft - Dx_tr = 0.5 * (topright - topmid + midright - midmid ) * hplusx_topright - Dx_bl = 0.5 * (botmid - botleft + midmid - midleft) * hplusx_botleft - Dx_br = 0.5 * (botright - botmid + midright - midmid ) * hplusx_botright + Dx_tl = 0.5 * (topmid - topleft + midmid - midleft) * hplusx_topleft + Dx_tr = 0.5 * (topright - topmid + midright - midmid) * hplusx_topright + Dx_bl = 0.5 * (botmid - botleft + midmid - midleft) * hplusx_botleft + Dx_br = 0.5 * (botright - botmid + midright - midmid) * hplusx_botright - Dy_tl = 0.5 * (midmid - topmid + midleft - topleft) * hplusy_topleft - Dy_tr = 0.5 * (midright - topright + midmid - topmid ) * hplusy_topright - Dy_bl = 0.5 * (botmid - midmid + botleft - midleft) * hplusy_botleft - Dy_br = 0.5 * (botright - midright + botmid - midmid ) * hplusy_botright + Dy_tl = 0.5 * (midmid - topmid + midleft - topleft) * hplusy_topleft + Dy_tr = 0.5 * (midright - topright + midmid - topmid) * hplusy_topright + Dy_bl = 0.5 * (botmid - midmid + botleft - midleft) * hplusy_botleft + Dy_br = 0.5 * (botright - midright + botmid - midmid) * hplusy_botright fac = 1.0 - Dxx = 0.5 * (cxx_tr * Dx_tr - cxx_tl * Dx_tl + cxx_br * Dx_br - cxx_bl * Dx_bl) * oodx * oodx * fac - Dyy = 0.5 * (cyy_br * Dy_br - cyy_tr * Dy_tr + cyy_bl * Dy_bl - cyy_tl * Dy_tl) * oody * oody * fac - Dyx = 0.5 * (cyx_br * Dy_br - cyx_bl * Dy_bl + cyx_tr * Dy_tr - cyx_tl * Dy_tl) * oody * oodx * fac - Dxy = 0.5 * (cxy_br * Dx_br - cxy_tr * Dx_tr + cxy_bl * Dy_bl - cxy_tl * Dx_tl) * oodx * oody * fac - + Dxx = ( + 0.5 + * (cxx_tr * Dx_tr - cxx_tl * Dx_tl + cxx_br * Dx_br - cxx_bl * Dx_bl) + * oodx + * oodx + * fac + ) + Dyy = ( + 0.5 + * (cyy_br * Dy_br - cyy_tr * Dy_tr + cyy_bl * Dy_bl - cyy_tl * Dy_tl) + * oody + * oody + * fac + ) + Dyx = ( + 0.5 + * (cyx_br * Dy_br - cyx_bl * Dy_bl + cyx_tr * Dy_tr - cyx_tl * Dy_tl) + * oody + * oodx + * fac + ) + Dxy = ( + 0.5 + * (cxy_br * Dx_br - cxy_tr * Dx_tr + cxy_bl * Dy_bl - cxy_tl * Dx_tl) + * oodx + * oody + * fac + ) lap[idx] = Dxx + Dyy + Dyx + Dxy + hcenter[idx] * p[idx] - # fac = 1.0 # lap[idx] = - fac * hplusx_topleft * oodx2 * ((midmid - midleft)) \ # - fac * hplusy_topleft * oody2 * ((midmid - topmid)) \ @@ -327,12 +397,28 @@ def lap2D_gather(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx, oody, if cnt_x % iicxn == 0: cnt_y += 1 cnt_x = 0 - + return lap @nb.jit(nopython=True, nogil=False, cache=True) -def lap2D(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx2, oody2, x_periodic, y_periodic, x_wall, y_wall, diag_inv): +def lap2D( + p, + igx, + igy, + iicxn, + iicyn, + hplusx, + hplusy, + hcenter, + oodx2, + oody2, + x_periodic, + y_periodic, + x_wall, + y_wall, + diag_inv, +): ngnc = (iicxn) * (iicyn) lap = np.zeros((ngnc)) cnt_x = 0 @@ -340,10 +426,9 @@ def lap2D(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx2, oody2, x_per nine_pt = 0.25 * (2.0) * 1.0 - for idx in range(iicxn * iicyn): ne_topleft = idx - iicxn - 1 - ne_topright = idx - iicxn + ne_topright = idx - iicxn ne_botleft = idx - 1 ne_botright = idx @@ -387,30 +472,30 @@ def lap2D(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx2, oody2, x_per ne_botright -= iicxn - 1 if cnt_y == 0: - topleft_idx += ((iicxn) * (iicyn - 1)) - topmid_idx += ((iicxn) * (iicyn - 1)) - topright_idx += ((iicxn) * (iicyn - 1)) + topleft_idx += (iicxn) * (iicyn - 1) + topmid_idx += (iicxn) * (iicyn - 1) + topright_idx += (iicxn) * (iicyn - 1) # if y_periodic: # midleft_idx += ((iicxn) * (iicyn - 1)) # midmid_idx += ((iicxn) * (iicyn - 1)) # midright_idx += ((iicxn) * (iicyn - 1)) - ne_topleft += ((iicxn) * (iicyn - 1)) - ne_topright += ((iicxn) * (iicyn - 1)) + ne_topleft += (iicxn) * (iicyn - 1) + ne_topright += (iicxn) * (iicyn - 1) if cnt_y == (iicyn - 1): - botleft_idx -= ((iicxn) * (iicyn - 1)) - botmid_idx -= ((iicxn) * (iicyn - 1)) - botright_idx -= ((iicxn) * (iicyn - 1)) + botleft_idx -= (iicxn) * (iicyn - 1) + botmid_idx -= (iicxn) * (iicyn - 1) + botright_idx -= (iicxn) * (iicyn - 1) # if y_periodic: # midleft_idx -= ((iicxn) * (iicyn - 1)) # midmid_idx -= ((iicxn) * (iicyn - 1)) # midright_idx -= ((iicxn) * (iicyn - 1)) - ne_botleft -= ((iicxn) * (iicyn - 1)) - ne_botright -= ((iicxn) * (iicyn - 1)) + ne_botleft -= (iicxn) * (iicyn - 1) + ne_botright -= (iicxn) * (iicyn - 1) topleft = p[topleft_idx] midleft = p[midleft_idx] @@ -435,43 +520,45 @@ def lap2D(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx2, oody2, x_per hplusy_botright = hplusy[ne_botright] if x_wall and (cnt_x == 0): - hplusx_topleft = 0. - hplusy_topleft = 0. - hplusx_botleft = 0. - hplusy_botleft = 0. + hplusx_topleft = 0.0 + hplusy_topleft = 0.0 + hplusx_botleft = 0.0 + hplusy_botleft = 0.0 if x_wall and (cnt_x == (iicxn - 1)): - hplusx_topright = 0. - hplusy_topright = 0. - hplusx_botright = 0. - hplusy_botright = 0. + hplusx_topright = 0.0 + hplusy_topright = 0.0 + hplusx_botright = 0.0 + hplusy_botright = 0.0 if y_wall and (cnt_y == 0): - hplusx_topleft = 0. - hplusy_topleft = 0. - hplusx_topright = 0. - hplusy_topright = 0. - + hplusx_topleft = 0.0 + hplusy_topleft = 0.0 + hplusx_topright = 0.0 + hplusy_topright = 0.0 + if y_wall and (cnt_y == (iicyn - 1)): - hplusx_botleft = 0. - hplusy_botleft = 0. - hplusx_botright = 0. - hplusy_botright = 0. - + hplusx_botleft = 0.0 + hplusy_botleft = 0.0 + hplusx_botright = 0.0 + hplusy_botright = 0.0 + dp2dxdy1 = ((midmid - midleft) - (topmid - topleft)) * nine_pt dp2dxdy2 = ((midright - midmid) - (topright - topmid)) * nine_pt dp2dxdy3 = ((botmid - botleft) - (midmid - midleft)) * nine_pt dp2dxdy4 = ((botright - botmid) - (midright - midmid)) * nine_pt - lap[idx] = - hplusx_topleft * oodx2 * ((midmid - midleft) - dp2dxdy1) \ - - hplusy_topleft * oody2 * ((midmid - topmid) - dp2dxdy1) \ - + hplusx_topright * oodx2 * ((midright - midmid) - dp2dxdy2) \ - - hplusy_topright * oody2 * ((midmid - topmid) + dp2dxdy2) \ - - hplusx_botleft * oodx2 * ((midmid - midleft) + dp2dxdy3) \ - + hplusy_botleft * oody2 * ((botmid - midmid) - dp2dxdy3) \ - + hplusx_botright * oodx2 * ((midright - midmid) + dp2dxdy4) \ - + hplusy_botright * oody2 * ((botmid - midmid) + dp2dxdy4) \ - + hcenter[idx] * p[idx] + lap[idx] = ( + -hplusx_topleft * oodx2 * ((midmid - midleft) - dp2dxdy1) + - hplusy_topleft * oody2 * ((midmid - topmid) - dp2dxdy1) + + hplusx_topright * oodx2 * ((midright - midmid) - dp2dxdy2) + - hplusy_topright * oody2 * ((midmid - topmid) + dp2dxdy2) + - hplusx_botleft * oodx2 * ((midmid - midleft) + dp2dxdy3) + + hplusy_botleft * oody2 * ((botmid - midmid) - dp2dxdy3) + + hplusx_botright * oodx2 * ((midright - midmid) + dp2dxdy4) + + hplusy_botright * oody2 * ((botmid - midmid) + dp2dxdy4) + + hcenter[idx] * p[idx] + ) # if cnt_x == 0 and x_wall: # lap[idx] *= 2. @@ -489,11 +576,11 @@ def lap2D(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx2, oody2, x_per if cnt_x % iicxn == 0: cnt_y += 1 cnt_x = 0 - + return lap -def stencil_9pt_numba_test(mpv,node,coriolis,diag_inv, ud): +def stencil_9pt_numba_test(mpv, node, coriolis, diag_inv, ud): dx = node.dx dy = node.dy @@ -505,46 +592,105 @@ def stencil_9pt_numba_test(mpv,node,coriolis,diag_inv, ud): shp = node.iisc - dummy_p = np.zeros((node.isc[1],node.isc[0])) + dummy_p = np.zeros((node.isc[1], node.isc[0])) ### Need to clean this up, but the Numba stencil is used in the Helmholtz solve for radiative BC! - if hasattr(ud, 'LAMB_BDRY'): - return lambda p : lap2D_numba_test(p, dummy_p, dx, dy, coeffs, diag_inv.T, coriolis, shp) + if hasattr(ud, "LAMB_BDRY"): + return lambda p: lap2D_numba_test( + p, dummy_p, dx, dy, coeffs, diag_inv.T, coriolis, shp + ) ################### else: - x_wall = ud.bdry_type[0] == opts.BdryType.WALL or ud.bdry_type[0] == opts.BdryType.RAYLEIGH - y_wall = ud.bdry_type[1] == opts.BdryType.WALL or ud.bdry_type[1] == opts.BdryType.RAYLEIGH + x_wall = ( + ud.bdry_type[0] == opts.BdryType.WALL + or ud.bdry_type[0] == opts.BdryType.RAYLEIGH + ) + y_wall = ( + ud.bdry_type[1] == opts.BdryType.WALL + or ud.bdry_type[1] == opts.BdryType.RAYLEIGH + ) y_rayleigh = ud.bdry_type[1] == opts.BdryType.RAYLEIGH - cor_slc = (slice(1,-1), slice(1,-1)) - coeff_slc = (slice(1,-1), slice(1,-1)) - - coeffs = (hplusx[coeff_slc].T.reshape(-1,), hplusy[coeff_slc].T.reshape(-1,), hcenter[node.i1].T.reshape(-1,)) - - coriolis = (coriolis[0][cor_slc].reshape(-1,),coriolis[1][cor_slc].reshape(-1,),coriolis[2][cor_slc].reshape(-1,),coriolis[3][cor_slc].reshape(-1,)) + cor_slc = (slice(1, -1), slice(1, -1)) + coeff_slc = (slice(1, -1), slice(1, -1)) + + coeffs = ( + hplusx[coeff_slc].T.reshape( + -1, + ), + hplusy[coeff_slc].T.reshape( + -1, + ), + hcenter[node.i1].T.reshape( + -1, + ), + ) + + coriolis = ( + coriolis[0][cor_slc].reshape( + -1, + ), + coriolis[1][cor_slc].reshape( + -1, + ), + coriolis[2][cor_slc].reshape( + -1, + ), + coriolis[3][cor_slc].reshape( + -1, + ), + ) + + return lambda p: lap2D_gather_new( + p, + node.iicx, + node.iicy, + coeffs, + dx, + dy, + y_rayleigh, + x_wall, + y_wall, + diag_inv[node.i1].T.reshape( + -1, + ), + coriolis, + ) - return lambda p : lap2D_gather_new(p, node.iicx, node.iicy, coeffs, dx, dy, y_rayleigh, x_wall, y_wall, diag_inv[node.i1].T.reshape(-1,), coriolis) - @nb.jit(nopython=True, cache=False) def lap2D_numba_test(p, dp, dx, dy, coeffs, diag_inv, coriolis, shp): - p = p.reshape(shp[1],shp[0]) - dp[1:-1,1:-1] = p + p = p.reshape(shp[1], shp[0]) + dp[1:-1, 1:-1] = p # dp = p dp = periodic(dp) - dp = kernel_9pt(dp, dx, dy, coeffs[0], coeffs[1], coeffs[2], diag_inv, coriolis[0], coriolis[1], coriolis[2], coriolis[3]) + dp = kernel_9pt( + dp, + dx, + dy, + coeffs[0], + coeffs[1], + coeffs[2], + diag_inv, + coriolis[0], + coriolis[1], + coriolis[2], + coriolis[3], + ) # p = dp # dp = periodic(dp) - p = dp[1:-1,1:-1] + p = dp[1:-1, 1:-1] return p.ravel() @nb.njit(cache=True) -def lap2D_gather_new(p, iicxn, iicyn, coeffs, dx, dy, y_rayleigh, x_wall, y_wall, diag_inv, coriolis): +def lap2D_gather_new( + p, iicxn, iicyn, coeffs, dx, dy, y_rayleigh, x_wall, y_wall, diag_inv, coriolis +): ngnc = (iicxn) * (iicyn) lap = np.zeros((ngnc)) cnt_x = 0 @@ -615,9 +761,9 @@ def lap2D_gather_new(p, iicxn, iicyn, coeffs, dx, dy, y_rayleigh, x_wall, y_wall # ne_botright -= iicxn + 1 if cnt_y == 0: - topleft_idx += ((iicxn) * (iicyn - 1)) - topmid_idx += ((iicxn) * (iicyn - 1)) - topright_idx += ((iicxn) * (iicyn - 1)) + topleft_idx += (iicxn) * (iicyn - 1) + topmid_idx += (iicxn) * (iicyn - 1) + topright_idx += (iicxn) * (iicyn - 1) # ne_topleft += ((iicxn + 1) * (iicyn)) # ne_topright += ((iicxn + 1) * (iicyn)) @@ -627,9 +773,9 @@ def lap2D_gather_new(p, iicxn, iicyn, coeffs, dx, dy, y_rayleigh, x_wall, y_wall # if cnt_y == (iicyn - 1) and not y_rayleigh: if cnt_y == (iicyn - 1): - botleft_idx -= ((iicxn) * (iicyn - 1)) - botmid_idx -= ((iicxn) * (iicyn - 1)) - botright_idx -= ((iicxn) * (iicyn - 1)) + botleft_idx -= (iicxn) * (iicyn - 1) + botmid_idx -= (iicxn) * (iicyn - 1) + botright_idx -= (iicxn) * (iicyn - 1) # ne_botleft -= ((iicxn + 1) * (iicyn)) # ne_botright -= ((iicxn + 1) * (iicyn)) @@ -667,72 +813,95 @@ def lap2D_gather_new(p, iicxn, iicyn, coeffs, dx, dy, y_rayleigh, x_wall, y_wall hplusy_topright = hplusy[ne_topright] hplusy_botright = hplusy[ne_botright] - cxx_tl = cxx[ne_topleft] + cxx_tl = cxx[ne_topleft] cxx_tr = cxx[ne_topright] - cxx_bl = cxx[ne_botleft] + cxx_bl = cxx[ne_botleft] cxx_br = cxx[ne_botright] - cxy_tl = cxy[ne_topleft] - cxy_tr = cxy[ne_topright] - cxy_bl = cxy[ne_botleft] - cxy_br = cxy[ne_botright] + cxy_tl = cxy[ne_topleft] + cxy_tr = cxy[ne_topright] + cxy_bl = cxy[ne_botleft] + cxy_br = cxy[ne_botright] - cyx_tl = cyx[ne_topleft] - cyx_tr = cyx[ne_topright] - cyx_bl = cyx[ne_botleft] - cyx_br = cyx[ne_botright] + cyx_tl = cyx[ne_topleft] + cyx_tr = cyx[ne_topright] + cyx_bl = cyx[ne_botleft] + cyx_br = cyx[ne_botright] - cyy_tl = cyy[ne_topleft] - cyy_tr = cyy[ne_topright] - cyy_bl = cyy[ne_botleft] - cyy_br = cyy[ne_botright] - + cyy_tl = cyy[ne_topleft] + cyy_tr = cyy[ne_topright] + cyy_bl = cyy[ne_botleft] + cyy_br = cyy[ne_botright] if x_wall and (cnt_x == 0): - hplusx_topleft = 0. - hplusy_topleft = 0. - hplusx_botleft = 0. - hplusy_botleft = 0. + hplusx_topleft = 0.0 + hplusy_topleft = 0.0 + hplusx_botleft = 0.0 + hplusy_botleft = 0.0 if x_wall and (cnt_x == (iicxn - 1)): - hplusx_topright = 0. - hplusy_topright = 0. - hplusx_botright = 0. - hplusy_botright = 0. + hplusx_topright = 0.0 + hplusy_topright = 0.0 + hplusx_botright = 0.0 + hplusy_botright = 0.0 if y_wall and (cnt_y == 0): - hplusx_topleft = 0. - hplusy_topleft = 0. - hplusx_topright = 0. - hplusy_topright = 0. - + hplusx_topleft = 0.0 + hplusy_topleft = 0.0 + hplusx_topright = 0.0 + hplusy_topright = 0.0 + if y_wall and (cnt_y == (iicyn - 1)): - hplusx_botleft = 0. - hplusy_botleft = 0. - hplusx_botright = 0. - hplusy_botright = 0. + hplusx_botleft = 0.0 + hplusy_botleft = 0.0 + hplusx_botright = 0.0 + hplusy_botright = 0.0 # if y_rayleigh and (cnt_y == 0): # hplusx_topleft = 0. - # hplusy_topleft = 0. + # hplusy_topleft = 0. # hplusx_topright = 0. # hplusy_topright = 0. - Dx_tl = 0.5 * (topmid - topleft + midmid - midleft) * hplusx_topleft - Dx_tr = 0.5 * (topright - topmid + midright - midmid ) * hplusx_topright - Dx_bl = 0.5 * (botmid - botleft + midmid - midleft) * hplusx_botleft - Dx_br = 0.5 * (botright - botmid + midright - midmid ) * hplusx_botright + Dx_tl = 0.5 * (topmid - topleft + midmid - midleft) * hplusx_topleft + Dx_tr = 0.5 * (topright - topmid + midright - midmid) * hplusx_topright + Dx_bl = 0.5 * (botmid - botleft + midmid - midleft) * hplusx_botleft + Dx_br = 0.5 * (botright - botmid + midright - midmid) * hplusx_botright - Dy_tl = 0.5 * (midmid - topmid + midleft - topleft) * hplusy_topleft - Dy_tr = 0.5 * (midright - topright + midmid - topmid ) * hplusy_topright - Dy_bl = 0.5 * (botmid - midmid + botleft - midleft) * hplusy_botleft - Dy_br = 0.5 * (botright - midright + botmid - midmid ) * hplusy_botright + Dy_tl = 0.5 * (midmid - topmid + midleft - topleft) * hplusy_topleft + Dy_tr = 0.5 * (midright - topright + midmid - topmid) * hplusy_topright + Dy_bl = 0.5 * (botmid - midmid + botleft - midleft) * hplusy_botleft + Dy_br = 0.5 * (botright - midright + botmid - midmid) * hplusy_botright fac = 1.0 - Dxx = 0.5 * (cxx_tr * Dx_tr - cxx_tl * Dx_tl + cxx_br * Dx_br - cxx_bl * Dx_bl) * oodx * oodx * fac - Dyy = 0.5 * (cyy_br * Dy_br - cyy_tr * Dy_tr + cyy_bl * Dy_bl - cyy_tl * Dy_tl) * oody * oody * fac - Dyx = 0.5 * (cxy_br * Dy_br - cxy_bl * Dy_bl + cxy_tr * Dy_tr - cxy_tl * Dy_tl) * oody * oodx * fac - Dxy = 0.5 * (cyx_br * Dx_br - cyx_tr * Dx_tr + cyx_bl * Dx_bl - cyx_tl * Dx_tl) * oodx * oody * fac + Dxx = ( + 0.5 + * (cxx_tr * Dx_tr - cxx_tl * Dx_tl + cxx_br * Dx_br - cxx_bl * Dx_bl) + * oodx + * oodx + * fac + ) + Dyy = ( + 0.5 + * (cyy_br * Dy_br - cyy_tr * Dy_tr + cyy_bl * Dy_bl - cyy_tl * Dy_tl) + * oody + * oody + * fac + ) + Dyx = ( + 0.5 + * (cxy_br * Dy_br - cxy_bl * Dy_bl + cxy_tr * Dy_tr - cxy_tl * Dy_tl) + * oody + * oodx + * fac + ) + Dxy = ( + 0.5 + * (cyx_br * Dx_br - cyx_tr * Dx_tr + cyx_bl * Dx_bl - cyx_tl * Dx_tl) + * oodx + * oody + * fac + ) lap[idx] = Dxx + Dyy + Dyx + Dxy + hcenter[idx] * p[idx] @@ -742,7 +911,7 @@ def lap2D_gather_new(p, iicxn, iicyn, coeffs, dx, dy, y_rayleigh, x_wall, y_wall if cnt_x % iicxn == 0: cnt_y += 1 cnt_x = 0 - + return lap @@ -751,17 +920,17 @@ def kernel_9pt(a, dx, dy, hpx, hpy, hpc, diag_inv, cxx, cyy, cxy, cyx): oodx = 1.0 / dx oody = 1.0 / dy - topleft = a[1,-1] - topmid = a[1,0] - topright = a[1,1] - - midleft = a[0,-1] - midmid = a[0,0] - midright = a[0,1] - - botleft = a[-1,-1] - botmid = a[-1,0] - botright = a[-1,1] + topleft = a[1, -1] + topmid = a[1, 0] + topright = a[1, 1] + + midleft = a[0, -1] + midmid = a[0, 0] + midright = a[0, 1] + + botleft = a[-1, -1] + botmid = a[-1, 0] + botright = a[-1, 1] # shftr = 1 # shftc = 0 @@ -804,83 +973,103 @@ def kernel_9pt(a, dx, dy, hpx, hpy, hpc, diag_inv, cxx, cyy, cxy, cyx): # cyx_tl = cyx[tlr,tlc] # cyx_tr = cyx[trr,trc] - hpx_bl = hpx[0,0] - hpx_br = hpx[0,1] - hpx_tl = hpx[1,0] - hpx_tr = hpx[1,1] - - hpy_bl = hpy[0,0] - hpy_br = hpy[0,1] - hpy_tl = hpy[1,0] - hpy_tr = hpy[1,1] - - cxx_bl = cxx[0,0] - cxx_br = cxx[0,1] - cxx_tl = cxx[1,0] - cxx_tr = cxx[1,1] - - cyy_bl = cyy[0,0] - cyy_br = cyy[0,1] - cyy_tl = cyy[1,0] - cyy_tr = cyy[1,1] - - cxy_bl = cxy[0,0] - cxy_br = cxy[0,1] - cxy_tl = cxy[1,0] - cxy_tr = cxy[1,1] - - cyx_bl = cyx[0,0] - cyx_br = cyx[0,1] - cyx_tl = cyx[1,0] - cyx_tr = cyx[1,1] - - Dx_tl = 0.5 * (topmid - topleft + midmid - midleft) * hpx_tl - Dx_tr = 0.5 * (topright - topmid + midright - midmid ) * hpx_tr - Dx_bl = 0.5 * (botmid - botleft + midmid - midleft) * hpx_bl - Dx_br = 0.5 * (botright - botmid + midright - midmid ) * hpx_br - - Dy_tl = 0.5 * (topmid - midmid + topleft - midleft) * hpy_tl - Dy_tr = 0.5 * (topright - midright + topmid - midmid ) * hpy_tr - Dy_bl = 0.5 * (midmid - botmid + midleft - botleft) * hpy_bl - Dy_br = 0.5 * (midright - botright + midmid - botmid ) * hpy_br + hpx_bl = hpx[0, 0] + hpx_br = hpx[0, 1] + hpx_tl = hpx[1, 0] + hpx_tr = hpx[1, 1] + + hpy_bl = hpy[0, 0] + hpy_br = hpy[0, 1] + hpy_tl = hpy[1, 0] + hpy_tr = hpy[1, 1] + + cxx_bl = cxx[0, 0] + cxx_br = cxx[0, 1] + cxx_tl = cxx[1, 0] + cxx_tr = cxx[1, 1] + + cyy_bl = cyy[0, 0] + cyy_br = cyy[0, 1] + cyy_tl = cyy[1, 0] + cyy_tr = cyy[1, 1] + + cxy_bl = cxy[0, 0] + cxy_br = cxy[0, 1] + cxy_tl = cxy[1, 0] + cxy_tr = cxy[1, 1] + + cyx_bl = cyx[0, 0] + cyx_br = cyx[0, 1] + cyx_tl = cyx[1, 0] + cyx_tr = cyx[1, 1] + + Dx_tl = 0.5 * (topmid - topleft + midmid - midleft) * hpx_tl + Dx_tr = 0.5 * (topright - topmid + midright - midmid) * hpx_tr + Dx_bl = 0.5 * (botmid - botleft + midmid - midleft) * hpx_bl + Dx_br = 0.5 * (botright - botmid + midright - midmid) * hpx_br + + Dy_tl = 0.5 * (topmid - midmid + topleft - midleft) * hpy_tl + Dy_tr = 0.5 * (topright - midright + topmid - midmid) * hpy_tr + Dy_bl = 0.5 * (midmid - botmid + midleft - botleft) * hpy_bl + Dy_br = 0.5 * (midright - botright + midmid - botmid) * hpy_br # print(hpx_tl, hpx_tr, hpx_bl, hpx_br) # print(hpy_tl, hpy_tr, hpy_bl, hpy_br) # print("") - - Dxx = 0.5 * (cxx_tr * Dx_tr - cxx_tl * Dx_tl + cxx_br * Dx_br - cxx_bl * Dx_bl) * oodx * oodx - Dyy = 0.5 * (cyy_tr * Dy_tr - cyy_br * Dy_br + cyy_tl * Dy_tl - cyy_bl * Dy_bl) * oody * oody - Dyx = 0.5 * (cxy_br * Dy_br - cxy_bl * Dy_bl + cxy_tr * Dy_tr - cxy_tl * Dy_tl) * oody * oodx - Dxy = 0.5 * (cyx_tr * Dx_tr - cyx_br * Dx_br + cyx_tl * Dx_tl - cyx_bl * Dx_bl) * oodx * oody - - return ((Dxx + Dyy + Dyx + Dxy) + hpc[0,0] * a[0,0]) * diag_inv[0,0] + + Dxx = ( + 0.5 + * (cxx_tr * Dx_tr - cxx_tl * Dx_tl + cxx_br * Dx_br - cxx_bl * Dx_bl) + * oodx + * oodx + ) + Dyy = ( + 0.5 + * (cyy_tr * Dy_tr - cyy_br * Dy_br + cyy_tl * Dy_tl - cyy_bl * Dy_bl) + * oody + * oody + ) + Dyx = ( + 0.5 + * (cxy_br * Dy_br - cxy_bl * Dy_bl + cxy_tr * Dy_tr - cxy_tl * Dy_tl) + * oody + * oodx + ) + Dxy = ( + 0.5 + * (cyx_tr * Dx_tr - cyx_br * Dx_br + cyx_tl * Dx_tl - cyx_bl * Dx_bl) + * oodx + * oody + ) + + return ((Dxx + Dyy + Dyx + Dxy) + hpc[0, 0] * a[0, 0]) * diag_inv[0, 0] + @nb.njit(cache=True) def periodic(arr): # periodic padding - arr[:,0] = arr[:,-3] - arr[:,-1] = arr[:,2] + arr[:, 0] = arr[:, -3] + arr[:, -1] = arr[:, 2] # wall padding - arr[0,:] = arr[2,:] - arr[-1,:] = arr[-3,:] - - return arr + arr[0, :] = arr[2, :] + arr[-1, :] = arr[-3, :] + return arr -def stencil_27pt(elem,node,mpv,ud,diag_inv,dt): +def stencil_27pt(elem, node, mpv, ud, diag_inv, dt): oodxyz = node.dxyz - oodxyz = 1./(oodxyz**2) + oodxyz = 1.0 / (oodxyz**2) oodx2, oody2, oodz2 = oodxyz[0], oodxyz[1], oodxyz[2] - odx, odz = 1./node.dx, 1./node.dz + odx, odz = 1.0 / node.dx, 1.0 / node.dz - i0 = (slice(0,-1),slice(0,-1),slice(0,-1)) - i1 = (slice(1,-1),slice(1,-1),slice(1,-1)) - i2 = (slice(2,-2),slice(2,-2),slice(2,-2)) + i0 = (slice(0, -1), slice(0, -1), slice(0, -1)) + i1 = (slice(1, -1), slice(1, -1), slice(1, -1)) + i2 = (slice(2, -2), slice(2, -2), slice(2, -2)) ndim = elem.ndim - periodicity = np.empty(ndim, dtype='int') + periodicity = np.empty(ndim, dtype="int") for dim in range(ndim): periodicity[dim] = ud.bdry_type[dim] == opts.BdryType.PERIODIC @@ -893,154 +1082,261 @@ def stencil_27pt(elem,node,mpv,ud,diag_inv,dt): corrf = dt * ud.coriolis_strength[0] - return lambda p : lap3D(p, hplusx, hplusy, hplusz, hcenter, oodx2, oody2, oodz2, periodicity, diag_inv, corrf, odx, odz) + return lambda p: lap3D( + p, + hplusx, + hplusy, + hplusz, + hcenter, + oodx2, + oody2, + oodz2, + periodicity, + diag_inv, + corrf, + odx, + odz, + ) + @nb.jit(nopython=True, cache=True, nogil=False) -def lap3D(p0, hplusx, hplusy, hplusz, hcenter, oodx2, oody2, oodz2, periodicity, diag_inv, corrf, odx, odz): +def lap3D( + p0, + hplusx, + hplusy, + hplusz, + hcenter, + oodx2, + oody2, + oodz2, + periodicity, + diag_inv, + corrf, + odx, + odz, +): shx, shy, shz = hcenter.shape - p = p0.reshape(shz+2,shy+2,shx+2) + p = p0.reshape(shz + 2, shy + 2, shx + 2) - coeff = 1./16 + coeff = 1.0 / 16 lap = np.zeros_like(p) - + # cut out four cubes from the 3d array corresponding to the nodes... in each axial direction. - toplefts = [(slice(0,None),slice(0,-1),slice(0,-1)), - (slice(0,-1),slice(0,None),slice(0,-1)), - (slice(0,-1),slice(0,-1),slice(0,None)) - ] - toprights = [(slice(0,None),slice(0,-1),slice(1,None)), - (slice(1,None),slice(0,None),slice(0,-1)), - (slice(0,-1),slice(1,None),slice(0,None)) - ] - - botlefts = [(slice(0,None),slice(1,None),slice(0,-1)), - (slice(0,-1),slice(0,None),slice(1,None)), - (slice(1,None),slice(0,-1),slice(0,None)) - ] - botrights = [(slice(0,None),slice(1,None),slice(1,None)), - (slice(1,None),slice(0,None),slice(1,None)), - (slice(1,None),slice(1,None),slice(0,None)) - ] + toplefts = [ + (slice(0, None), slice(0, -1), slice(0, -1)), + (slice(0, -1), slice(0, None), slice(0, -1)), + (slice(0, -1), slice(0, -1), slice(0, None)), + ] + toprights = [ + (slice(0, None), slice(0, -1), slice(1, None)), + (slice(1, None), slice(0, None), slice(0, -1)), + (slice(0, -1), slice(1, None), slice(0, None)), + ] + + botlefts = [ + (slice(0, None), slice(1, None), slice(0, -1)), + (slice(0, -1), slice(0, None), slice(1, None)), + (slice(1, None), slice(0, -1), slice(0, None)), + ] + botrights = [ + (slice(0, None), slice(1, None), slice(1, None)), + (slice(1, None), slice(0, None), slice(1, None)), + (slice(1, None), slice(1, None), slice(0, None)), + ] cnt = 0 for bc in periodicity: if bc == True and cnt == 0: - tmp = p[1,:,:] - p[0,:,:] = p[-3,:,:] - p[-1,:,:] = p[2,:,:] - p[1,:,:] = p[-2,:,:] - p[-2,:,:] = tmp + tmp = p[1, :, :] + p[0, :, :] = p[-3, :, :] + p[-1, :, :] = p[2, :, :] + p[1, :, :] = p[-2, :, :] + p[-2, :, :] = tmp elif bc == False and cnt == 0: - hplusx[0,:,:] = 0.0 - hplusx[-1,:,:] = 0.0 - hplusy[0,:,:] = 0.0 - hplusy[-1,:,:] = 0.0 - hplusz[0,:,:] = 0.0 - hplusz[-1,:,:] = 0.0 + hplusx[0, :, :] = 0.0 + hplusx[-1, :, :] = 0.0 + hplusy[0, :, :] = 0.0 + hplusy[-1, :, :] = 0.0 + hplusz[0, :, :] = 0.0 + hplusz[-1, :, :] = 0.0 if bc == True and cnt == 1: - tmp = p[:,1,:] - p[:,0,:] = p[:,-3,:] - p[:,-1,:] = p[:,2,:] - p[:,1,:] = p[:,-2,:] - p[:,-2,:] = tmp + tmp = p[:, 1, :] + p[:, 0, :] = p[:, -3, :] + p[:, -1, :] = p[:, 2, :] + p[:, 1, :] = p[:, -2, :] + p[:, -2, :] = tmp elif bc == False and cnt == 1: - hplusx[:,0,:] = 0.0 - hplusx[:,-1,:] = 0.0 - hplusy[:,0,:] = 0.0 - hplusy[:,-1,:] = 0.0 - hplusz[:,0,:] = 0.0 - hplusz[:,-1,:] = 0.0 + hplusx[:, 0, :] = 0.0 + hplusx[:, -1, :] = 0.0 + hplusy[:, 0, :] = 0.0 + hplusy[:, -1, :] = 0.0 + hplusz[:, 0, :] = 0.0 + hplusz[:, -1, :] = 0.0 if bc == True and cnt == 2: - tmp = p[:,:,1] - p[:,:,0] = p[:,:,-3] - p[:,:,-1] = p[:,:,2] - p[:,:,1] = p[:,:,-2] - p[:,:,-2] = tmp - elif bc == False and cnt ==2: - hplusx[:,:,0] = 0.0 - hplusx[:,:,-1] = 0.0 - hplusy[:,:,0] = 0.0 - hplusy[:,:,-1] = 0.0 - hplusz[:,:,0] = 0.0 - hplusz[:,:,-1] = 0.0 + tmp = p[:, :, 1] + p[:, :, 0] = p[:, :, -3] + p[:, :, -1] = p[:, :, 2] + p[:, :, 1] = p[:, :, -2] + p[:, :, -2] = tmp + elif bc == False and cnt == 2: + hplusx[:, :, 0] = 0.0 + hplusx[:, :, -1] = 0.0 + hplusy[:, :, 0] = 0.0 + hplusy[:, :, -1] = 0.0 + hplusz[:, :, 0] = 0.0 + hplusz[:, :, -1] = 0.0 cnt += 1 - leftz = p[:,:,:-1] - rightz = p[:,:,1:] - - z_fluxes = (rightz - leftz) + leftz = p[:, :, :-1] + rightz = p[:, :, 1:] + + z_fluxes = rightz - leftz - lefty = p[:,:-1,:] - righty = p[:,1:,:] + lefty = p[:, :-1, :] + righty = p[:, 1:, :] - y_fluxes = (righty - lefty) + y_fluxes = righty - lefty - leftx = p[:-1,:,:] - rightx = p[1:,:,:] + leftx = p[:-1, :, :] + rightx = p[1:, :, :] - x_fluxes = (rightx - leftx) + x_fluxes = rightx - leftx - x_flx = x_fluxes[toplefts[0]] + x_fluxes[toprights[0]] + x_fluxes[botlefts[0]] + x_fluxes[botrights[0]] - y_flx = y_fluxes[toplefts[1]] + y_fluxes[toprights[1]] + y_fluxes[botlefts[1]] + y_fluxes[botrights[1]] - z_flx = z_fluxes[toplefts[2]] + z_fluxes[toprights[2]] + z_fluxes[botlefts[2]] + z_fluxes[botrights[2]] + x_flx = ( + x_fluxes[toplefts[0]] + + x_fluxes[toprights[0]] + + x_fluxes[botlefts[0]] + + x_fluxes[botrights[0]] + ) + y_flx = ( + y_fluxes[toplefts[1]] + + y_fluxes[toprights[1]] + + y_fluxes[botlefts[1]] + + y_fluxes[botrights[1]] + ) + z_flx = ( + z_fluxes[toplefts[2]] + + z_fluxes[toprights[2]] + + z_fluxes[botlefts[2]] + + z_fluxes[botrights[2]] + ) hxzp = hplusx * z_flx - hxzpm = hxzp[:-1,:,:] - hxzpm = hxzpm[toplefts[0]] + hxzpm[toprights[0]] + hxzpm[botlefts[0]] + hxzpm[botrights[0]] - hxzpp = hxzp[1:,:,:] - hxzpp = hxzpp[toplefts[0]] + hxzpp[toprights[0]] + hxzpp[botlefts[0]] + hxzpp[botrights[0]] + hxzpm = hxzp[:-1, :, :] + hxzpm = ( + hxzpm[toplefts[0]] + + hxzpm[toprights[0]] + + hxzpm[botlefts[0]] + + hxzpm[botrights[0]] + ) + hxzpp = hxzp[1:, :, :] + hxzpp = ( + hxzpp[toplefts[0]] + + hxzpp[toprights[0]] + + hxzpp[botlefts[0]] + + hxzpp[botrights[0]] + ) hzxp = hplusz * x_flx - hzxpm = hzxp[:,:,:-1] - hzxpm = hzxpm[toplefts[2]] + hzxpm[toprights[2]] + hzxpm[botlefts[2]] + hzxpm[botrights[2]] - hzxpp = hzxp[:,:,1:] - hzxpp = hzxpp[toplefts[2]] + hzxpp[toprights[2]] + hzxpp[botlefts[2]] + hzxpp[botrights[2]] + hzxpm = hzxp[:, :, :-1] + hzxpm = ( + hzxpm[toplefts[2]] + + hzxpm[toprights[2]] + + hzxpm[botlefts[2]] + + hzxpm[botrights[2]] + ) + hzxpp = hzxp[:, :, 1:] + hzxpp = ( + hzxpp[toplefts[2]] + + hzxpp[toprights[2]] + + hzxpp[botlefts[2]] + + hzxpp[botrights[2]] + ) x_flx = hplusx * x_flx - x_flxm = x_flx[:-1,:,:] - x_flxm = x_flxm[toplefts[0]] + x_flxm[toprights[0]] + x_flxm[botlefts[0]] + x_flxm[botrights[0]] - x_flxp = x_flx[1:,:,:] - x_flxp = x_flxp[toplefts[0]] + x_flxp[toprights[0]] + x_flxp[botlefts[0]] + x_flxp[botrights[0]] + x_flxm = x_flx[:-1, :, :] + x_flxm = ( + x_flxm[toplefts[0]] + + x_flxm[toprights[0]] + + x_flxm[botlefts[0]] + + x_flxm[botrights[0]] + ) + x_flxp = x_flx[1:, :, :] + x_flxp = ( + x_flxp[toplefts[0]] + + x_flxp[toprights[0]] + + x_flxp[botlefts[0]] + + x_flxp[botrights[0]] + ) y_flx = hplusy * y_flx - y_flxm = y_flx[:,:-1,:] - y_flxm = y_flxm[toplefts[1]] + y_flxm[toprights[1]] + y_flxm[botlefts[1]] + y_flxm[botrights[1]] - y_flxp = y_flx[:,1:,:] - y_flxp = y_flxp[toplefts[1]] + y_flxp[toprights[1]] + y_flxp[botlefts[1]] + y_flxp[botrights[1]] + y_flxm = y_flx[:, :-1, :] + y_flxm = ( + y_flxm[toplefts[1]] + + y_flxm[toprights[1]] + + y_flxm[botlefts[1]] + + y_flxm[botrights[1]] + ) + y_flxp = y_flx[:, 1:, :] + y_flxp = ( + y_flxp[toplefts[1]] + + y_flxp[toprights[1]] + + y_flxp[botlefts[1]] + + y_flxp[botrights[1]] + ) z_flx = hplusz * z_flx - z_flxm = z_flx[:,:,:-1] - z_flxm = z_flxm[toplefts[2]] + z_flxm[toprights[2]] + z_flxm[botlefts[2]] + z_flxm[botrights[2]] - z_flxp = z_flx[:,:,1:] - z_flxp = z_flxp[toplefts[2]] + z_flxp[toprights[2]] + z_flxp[botlefts[2]] + z_flxp[botrights[2]] - - lap[1:-1,1:-1,1:-1] = oodx2 * coeff * (-x_flxm + x_flxp) + \ - oody2 * coeff * (-y_flxm + y_flxp) + \ - oodz2 * coeff * (-z_flxm + z_flxp) + \ - +1.0 * odx * odz * coeff * corrf * (hxzpp - hxzpm) + \ - -1.0 * odx * odz * coeff * corrf * (hzxpp - hzxpm) + \ - hcenter * p[1:-1,1:-1,1:-1] + z_flxm = z_flx[:, :, :-1] + z_flxm = ( + z_flxm[toplefts[2]] + + z_flxm[toprights[2]] + + z_flxm[botlefts[2]] + + z_flxm[botrights[2]] + ) + z_flxp = z_flx[:, :, 1:] + z_flxp = ( + z_flxp[toplefts[2]] + + z_flxp[toprights[2]] + + z_flxp[botlefts[2]] + + z_flxp[botrights[2]] + ) + + lap[1:-1, 1:-1, 1:-1] = ( + oodx2 * coeff * (-x_flxm + x_flxp) + + oody2 * coeff * (-y_flxm + y_flxp) + + oodz2 * coeff * (-z_flxm + z_flxp) + + +1.0 * odx * odz * coeff * corrf * (hxzpp - hxzpm) + + -1.0 * odx * odz * coeff * corrf * (hzxpp - hzxpm) + + hcenter * p[1:-1, 1:-1, 1:-1] + ) lap = lap * diag_inv return lap - -def stencil_hs(elem,node,mpv,ud,diag_inv,dt): - oodx2 = 1./node.dx**2 - oodz2 = 1./node.dz**2 - odx, odz = 1./node.dx, 1./node.dz +def stencil_hs(elem, node, mpv, ud, diag_inv, dt): + oodx2 = 1.0 / node.dx**2 + oodz2 = 1.0 / node.dz**2 + odx, odz = 1.0 / node.dx, 1.0 / node.dz igy = elem.igs[1] - proj = (slice(None,),igy,slice(None,)) - i0 = (slice(0,-1),slice(0,-1)) - i1 = (slice(1,-1),slice(1,-1)) - i2 = (slice(2,-2),slice(2,-2)) + proj = ( + slice( + None, + ), + igy, + slice( + None, + ), + ) + i0 = (slice(0, -1), slice(0, -1)) + i1 = (slice(1, -1), slice(1, -1)) + i2 = (slice(2, -2), slice(2, -2)) ndim = elem.ndim - periodicity = np.empty(ndim, dtype='int') - for dim in range(0,ndim,2): + periodicity = np.empty(ndim, dtype="int") + for dim in range(0, ndim, 2): periodicity[dim] = ud.bdry_type[dim] == opts.BdryType.PERIODIC hplusx = mpv.wplus[0][proj][i0][i1] @@ -1050,106 +1346,111 @@ def stencil_hs(elem,node,mpv,ud,diag_inv,dt): corrf = dt * ud.coriolis_strength[1] - return lambda p : lapHS(p, hplusx, hplusz, hcenter, oodx2, oodz2, periodicity, diag_inv, corrf, odx, odz) + return lambda p: lapHS( + p, hplusx, hplusz, hcenter, oodx2, oodz2, periodicity, diag_inv, corrf, odx, odz + ) @nb.jit(nopython=True, cache=True, nogil=True) -def lapHS(p0, hplusx, hplusz, hcenter, oodx2, oodz2, periodicity, diag_inv, corrf, odx, odz): +def lapHS( + p0, hplusx, hplusz, hcenter, oodx2, oodz2, periodicity, diag_inv, corrf, odx, odz +): shx, shz = hcenter.shape - p = p0.reshape(shx+2,shz+2) + p = p0.reshape(shx + 2, shz + 2) - coeff = 1./4 + coeff = 1.0 / 4 lap = np.zeros_like(p) - + cnt = 0 for bc in periodicity: if bc == True and cnt == 0: - tmp = p[1,:] - p[0,:] = p[-3,:] - p[-1,:] = p[2,:] - p[1,:] = p[-2,:] - p[-2,:] = tmp + tmp = p[1, :] + p[0, :] = p[-3, :] + p[-1, :] = p[2, :] + p[1, :] = p[-2, :] + p[-2, :] = tmp # p[0,:] = p[-4,:] # p[-1,:] = p[3,:] # p[1,:] = p[-3,:] # p[-2,:] = p[2,:] elif bc == False and cnt == 0: - hplusx[0,:] = 0.0 - hplusx[-1,:] = 0.0 - hplusz[0,:] = 0.0 - hplusz[-1,:] = 0.0 + hplusx[0, :] = 0.0 + hplusx[-1, :] = 0.0 + hplusz[0, :] = 0.0 + hplusz[-1, :] = 0.0 if bc == True and cnt == 2: - tmp = p[:,1] - p[:,0] = p[:,-3] - p[:,-1] = p[:,2] - p[:,1] = p[:,-2] - p[:,-2] = tmp + tmp = p[:, 1] + p[:, 0] = p[:, -3] + p[:, -1] = p[:, 2] + p[:, 1] = p[:, -2] + p[:, -2] = tmp # p[:,0] = p[:,-4] # p[:,-1] = p[:,3] # p[:,1] = p[:,-3] # p[:,-2] = p[:,2] elif bc == False and cnt == 2: - hplusx[:,0] = 0.0 - hplusx[:,-1] = 0.0 - hplusz[:,0] = 0.0 - hplusz[:,-1] = 0.0 + hplusx[:, 0] = 0.0 + hplusx[:, -1] = 0.0 + hplusz[:, 0] = 0.0 + hplusz[:, -1] = 0.0 cnt += 1 - - leftz = p[:,:-1] - rightz = p[:,1:] - - z_fluxes = (rightz - leftz) - leftx = p[:-1,:] - rightx = p[1:,:] + leftz = p[:, :-1] + rightz = p[:, 1:] + + z_fluxes = rightz - leftz - x_fluxes = (rightx - leftx) + leftx = p[:-1, :] + rightx = p[1:, :] - x_flx = x_fluxes[:,:-1] + x_fluxes[:,1:] - z_flx = z_fluxes[:-1,:] + z_fluxes[1:,:] + x_fluxes = rightx - leftx + + x_flx = x_fluxes[:, :-1] + x_fluxes[:, 1:] + z_flx = z_fluxes[:-1, :] + z_fluxes[1:, :] hxzp = hplusx * z_flx - hxzpm = hxzp[:-1,:] - hxzpm = hxzpm[:,:-1] + hxzpm[:,1:] + hxzpm = hxzp[:-1, :] + hxzpm = hxzpm[:, :-1] + hxzpm[:, 1:] # hxzpm = hxzpm[:-1,:] + hxzpm[1:,:] - hxzpp = hxzp[1:,:] - hxzpp = hxzpp[:,:-1] + hxzpp[:,1:] + hxzpp = hxzp[1:, :] + hxzpp = hxzpp[:, :-1] + hxzpp[:, 1:] # hxzpp = hxzpp[:-1,:] + hxzpp[1:,:] hzxp = hplusz * x_flx - hzxpm = hzxp[:,:-1] - hzxpm = hzxpm[:-1,:] + hzxpm[1:,:] + hzxpm = hzxp[:, :-1] + hzxpm = hzxpm[:-1, :] + hzxpm[1:, :] # hzxpm = hzxpm[:,:-1] + hzxpm[:,1:] - hzxpp = hzxp[:,1:] - hzxpp = hzxpp[:-1,:] + hzxpp[1:,:] + hzxpp = hzxp[:, 1:] + hzxpp = hzxpp[:-1, :] + hzxpp[1:, :] # hzxpp = hzxpp[:,:-1] + hzxpp[:,1:] x_flx = hplusx * x_flx - x_flxm = x_flx[:-1,:] - x_flxm = x_flxm[:,:-1] + x_flxm[:,1:] - x_flxp = x_flx[1:,:] - x_flxp = x_flxp[:,:-1] + x_flxp[:,1:] + x_flxm = x_flx[:-1, :] + x_flxm = x_flxm[:, :-1] + x_flxm[:, 1:] + x_flxp = x_flx[1:, :] + x_flxp = x_flxp[:, :-1] + x_flxp[:, 1:] z_flx = hplusz * z_flx - z_flxm = z_flx[:,:-1] - z_flxm = z_flxm[:-1,:] + z_flxm[1:,:] - z_flxp = z_flx[:,1:] - z_flxp = z_flxp[:-1,:] + z_flxp[1:,:] - - lap[1:-1,1:-1] = oodx2 * coeff * (-x_flxm + x_flxp) + \ - oodz2 * coeff * (-z_flxm + z_flxp) + \ - +1.0 * odx * odz * coeff * corrf * (hxzpp - hxzpm) + \ - -1.0 * odx * odz * coeff * corrf * (hzxpp - hzxpm) + \ - hcenter * p[1:-1,1:-1] + z_flxm = z_flx[:, :-1] + z_flxm = z_flxm[:-1, :] + z_flxm[1:, :] + z_flxp = z_flx[:, 1:] + z_flxp = z_flxp[:-1, :] + z_flxp[1:, :] + + lap[1:-1, 1:-1] = ( + oodx2 * coeff * (-x_flxm + x_flxp) + + oodz2 * coeff * (-z_flxm + z_flxp) + + +1.0 * odx * odz * coeff * corrf * (hxzpp - hxzpm) + + -1.0 * odx * odz * coeff * corrf * (hzxpp - hzxpm) + + hcenter * p[1:-1, 1:-1] + ) lap = lap * diag_inv return lap - -def stencil_vs(elem,node,mpv,ud,diag_inv,dt): +def stencil_vs(elem, node, mpv, ud, diag_inv, dt): igx = elem.igx igy = elem.igy igz = elem.igz @@ -1170,10 +1471,18 @@ def stencil_vs(elem,node,mpv,ud,diag_inv,dt): xx, yy = 1, 0 - proj = (slice(None,),slice(None,),igz) - i0 = (slice(0,-1),slice(0,-1)) - i1 = (slice(1,-1),slice(1,-1)) - i2 = (slice(igx,-igx),slice(igy,-igy)) + proj = ( + slice( + None, + ), + slice( + None, + ), + igz, + ) + i0 = (slice(0, -1), slice(0, -1)) + i1 = (slice(1, -1), slice(1, -1)) + i2 = (slice(igx, -igx), slice(igy, -igy)) VS = True @@ -1184,20 +1493,44 @@ def stencil_vs(elem,node,mpv,ud,diag_inv,dt): x_wall = ud.bdry_type[xx] == opts.BdryType.WALL y_wall = ud.bdry_type[yy] == opts.BdryType.WALL - hplusx = mpv.wplus[xx][proj][i2].reshape(-1,) - hplusy = mpv.wplus[yy][proj][i2].reshape(-1,) - hcenter = mpv.wcenter[proj][i2].reshape(-1,) - diag_inv = diag_inv[proj][i2].reshape(-1,) - - return lambda p : lap2D(p, igx,igy, iicxn, iicyn, hplusx, hplusy, hcenter, oodx2, oody2, x_periodic, y_periodic, x_wall, y_wall, diag_inv) + hplusx = mpv.wplus[xx][proj][i2].reshape( + -1, + ) + hplusy = mpv.wplus[yy][proj][i2].reshape( + -1, + ) + hcenter = mpv.wcenter[proj][i2].reshape( + -1, + ) + diag_inv = diag_inv[proj][i2].reshape( + -1, + ) + + return lambda p: lap2D( + p, + igx, + igy, + iicxn, + iicyn, + hplusx, + hplusy, + hcenter, + oodx2, + oody2, + x_periodic, + y_periodic, + x_wall, + y_wall, + diag_inv, + ) if VS: - oodx2 = 1./node.dx**2 - oody2 = 1./node.dy**2 + oodx2 = 1.0 / node.dx**2 + oody2 = 1.0 / node.dy**2 ndim = elem.ndim - periodicity = np.zeros(ndim, dtype='int') - for dim in range(0,ndim,2): + periodicity = np.zeros(ndim, dtype="int") + for dim in range(0, ndim, 2): periodicity[dim] = ud.bdry_type[dim] == opts.BdryType.PERIODIC hplusx = mpv.wplus[0][proj][i0][i1] @@ -1205,82 +1538,85 @@ def stencil_vs(elem,node,mpv,ud,diag_inv,dt): hcenter = mpv.wcenter[proj][i2] diag_inv = diag_inv[proj][i1] - return lambda p : lapVS(p, hplusx, hplusy, hcenter, oodx2, oody2, periodicity, diag_inv) + return lambda p: lapVS( + p, hplusx, hplusy, hcenter, oodx2, oody2, periodicity, diag_inv + ) @nb.jit(nopython=True, cache=True, nogil=False) def lapVS(p0, hplusx, hplusy, hcenter, oodx2, oody2, periodicity, diag_inv): shx, shy = hcenter.shape - p = p0.reshape(shx+2,shy+2) + p = p0.reshape(shx + 2, shy + 2) - coeff = 1./4 + coeff = 1.0 / 4 lap = np.zeros_like(p) - + cnt = 0 for bc in periodicity: if bc == True and cnt == 0: - p[0,:] = p[-3,:] - p[-1,:] = p[2,:] + p[0, :] = p[-3, :] + p[-1, :] = p[2, :] elif bc == False and cnt == 0: - hplusx[0,:] = 0.0 - hplusx[-1,:] = 0.0 - hplusy[0,:] = 0.0 - hplusy[-1,:] = 0.0 + hplusx[0, :] = 0.0 + hplusx[-1, :] = 0.0 + hplusy[0, :] = 0.0 + hplusy[-1, :] = 0.0 # p[0,:] = p[2,:] # p[-1,:] = p[-3,:] if bc == True and cnt == 1: - p[:,0] = p[:,-3] - p[:,-1] = p[:,2] + p[:, 0] = p[:, -3] + p[:, -1] = p[:, 2] elif bc == False and cnt == 1: - hplusx[:,0] = 0.0 - hplusx[:,-1] = 0.0 - hplusy[:,0] = 0.0 - hplusy[:,-1] = 0.0 + hplusx[:, 0] = 0.0 + hplusx[:, -1] = 0.0 + hplusy[:, 0] = 0.0 + hplusy[:, -1] = 0.0 # p[:,0] = p[:,2] # p[:,-1] = p[:,-3] - + cnt += 1 - - lefty = p[:,:-1] - righty = p[:,1:] - - y_fluxes = (righty - lefty) - leftx = p[:-1,:] - rightx = p[1:,:] + lefty = p[:, :-1] + righty = p[:, 1:] + + y_fluxes = righty - lefty + + leftx = p[:-1, :] + rightx = p[1:, :] - x_fluxes = (rightx - leftx) + x_fluxes = rightx - leftx - x_flx = x_fluxes[:,:-1] + x_fluxes[:,1:] - y_flx = y_fluxes[:-1,:] + y_fluxes[1:,:] + x_flx = x_fluxes[:, :-1] + x_fluxes[:, 1:] + y_flx = y_fluxes[:-1, :] + y_fluxes[1:, :] x_flx = hplusx * x_flx - x_flxm = x_flx[:-1,:] - x_flxm = x_flxm[:,:-1] + x_flxm[:,1:] - x_flxp = x_flx[1:,:] - x_flxp = x_flxp[:,:-1] + x_flxp[:,1:] + x_flxm = x_flx[:-1, :] + x_flxm = x_flxm[:, :-1] + x_flxm[:, 1:] + x_flxp = x_flx[1:, :] + x_flxp = x_flxp[:, :-1] + x_flxp[:, 1:] y_flx = hplusy * y_flx - y_flxm = y_flx[:,:-1] - y_flxm = y_flxm[:-1,:] + y_flxm[1:,:] - y_flxp = y_flx[:,1:] - y_flxp = y_flxp[:-1,:] + y_flxp[1:,:] - - lap[1:-1,1:-1] = oodx2 * coeff * (-x_flxm + x_flxp) + \ - oody2 * coeff * (-y_flxm + y_flxp) + \ - hcenter * p[1:-1,1:-1] - + y_flxm = y_flx[:, :-1] + y_flxm = y_flxm[:-1, :] + y_flxm[1:, :] + y_flxp = y_flx[:, 1:] + y_flxp = y_flxp[:-1, :] + y_flxp[1:, :] + + lap[1:-1, 1:-1] = ( + oodx2 * coeff * (-x_flxm + x_flxp) + + oody2 * coeff * (-y_flxm + y_flxp) + + hcenter * p[1:-1, 1:-1] + ) + lap = lap * diag_inv return lap - def precon_diag_prepare(mpv, elem, node, ud, coriolis): dx, dy, dz = node.dx, node.dy, node.dz @@ -1299,24 +1635,27 @@ def precon_diag_prepare(mpv, elem, node, ud, coriolis): for dim in range(ndim): if ud.bdry_type[dim] == opts.BdryType.PERIODIC: - idx_periodic[dim] = slice(1,-1) + idx_periodic[dim] = slice(1, -1) - idx_e[dim] = slice(igs[dim] - periodicity[dim], -igs[dim] + periodicity[dim] - 1) + idx_e[dim] = slice( + igs[dim] - periodicity[dim], -igs[dim] + periodicity[dim] - 1 + ) idx_n[dim] = slice(igs[dim], -igs[dim]) idx_periodic, idx_e, idx_n = tuple(idx_periodic), tuple(idx_e), tuple(idx_n) # idx_n = (slice(igx,-igx), slice(igy,-igy)) - hplusxx = mpv.wplus[0] #* (coriolis[0].T) - hplusyy = mpv.wplus[1] #* (coriolis[1].T) - hplusxy = mpv.wplus[0] #* (coriolis[3].T) - hplusyx = mpv.wplus[1] #* (coriolis[2].T) + hplusxx = mpv.wplus[0] # * (coriolis[0].T) + hplusyy = mpv.wplus[1] # * (coriolis[1].T) + hplusxy = mpv.wplus[0] # * (coriolis[3].T) + hplusyx = mpv.wplus[1] # * (coriolis[2].T) - if ndim == 3: hplusz = mpv.wplus[2] + if ndim == 3: + hplusz = mpv.wplus[2] nine_pt = 0.25 * (2.0) * 1.0 - nine_pt = 0.5 * 0.5 + nine_pt = 0.5 * 0.5 if ndim == 2: coeff = 1.0 - nine_pt elif ndim == 3: @@ -1334,7 +1673,7 @@ def precon_diag_prepare(mpv, elem, node, ud, coriolis): diag_kernel = np.array(np.ones([2] * ndim)) # diag = np.zeros((node.sc)).squeeze() - # diag[idx_n] = -wx * signal.fftconvolve(hplusx[idx_e],diag_kernel,mode='full')[idx_periodic] + # diag[idx_n] = -wx * signal.fftconvolve(hplusx[idx_e],diag_kernel,mode='full')[idx_periodic] # diag[idx_n] -= wy * signal.fftconvolve(hplusy[idx_e],diag_kernel,mode='full')[idx_periodic] # if ndim == 3: # diag[idx_n] -= wz * signal.fftconvolve(hplusz[idx_e],diag_kernel,mode='full')[idx_periodic] @@ -1343,12 +1682,12 @@ def precon_diag_prepare(mpv, elem, node, ud, coriolis): # diag[idx_n] = 1.0 / diag[idx_n] diag = np.zeros_like(mpv.wcenter) - diag[...] = -wxx * sp.signal.fftconvolve(hplusxx,diag_kernel,mode='valid') - diag[...] -= wyy * sp.signal.fftconvolve(hplusyy,diag_kernel,mode='valid') - diag[...] -= wxy * sp.signal.fftconvolve(hplusxy,diag_kernel,mode='valid') - diag[...] -= wyx * sp.signal.fftconvolve(hplusyx,diag_kernel,mode='valid') + diag[...] = -wxx * sp.signal.fftconvolve(hplusxx, diag_kernel, mode="valid") + diag[...] -= wyy * sp.signal.fftconvolve(hplusyy, diag_kernel, mode="valid") + diag[...] -= wxy * sp.signal.fftconvolve(hplusxy, diag_kernel, mode="valid") + diag[...] -= wyx * sp.signal.fftconvolve(hplusyx, diag_kernel, mode="valid") if ndim == 3: - diag[...] -= wzz * sp.signal.fftconvolve(hplusz,diag_kernel,mode='valid') + diag[...] -= wzz * sp.signal.fftconvolve(hplusz, diag_kernel, mode="valid") diag[...] += mpv.wcenter diag[...] = 1.0 / diag @@ -1356,10 +1695,7 @@ def precon_diag_prepare(mpv, elem, node, ud, coriolis): return diag - - - -def stencil_3pt(elem,node,ud): +def stencil_3pt(elem, node, ud): # 1d stencil for exner pressure perturbation constraint in 2d igx = elem.igx igy = elem.igy @@ -1375,13 +1711,14 @@ def stencil_3pt(elem,node,ud): dx = node.dx # print(node.dx) - oodx2 = 1. / (dx**2) + oodx2 = 1.0 / (dx**2) # x_periodic = ud.bdry_type[1] == BdryType.PERIODIC x_periodic = ud.bdry_type[0] == opts.BdryType.PERIODIC x_wall = ud.bdry_type[0] == opts.BdryType.WALL - return lambda p : lap2D_exner(p,iicxn, iicyn, oodx2, x_periodic, x_wall) + return lambda p: lap2D_exner(p, iicxn, iicyn, oodx2, x_periodic, x_wall) + @nb.jit(nopython=True, nogil=True, cache=True) def lap2D_exner(p, iicxn, iicyn, oodx2, x_periodic, x_wall): @@ -1413,29 +1750,29 @@ def lap2D_exner(p, iicxn, iicyn, oodx2, x_periodic, x_wall): if cnt_y == 0: if x_periodic: - right_idx += ((iicxn) * (iicyn - 1)) - mid_idx += ((iicxn) * (iicyn - 1)) + right_idx += (iicxn) * (iicyn - 1) + mid_idx += (iicxn) * (iicyn - 1) if cnt_y == (iicyn - 1): if x_periodic: - left_idx -= ((iicxn) * (iicyn - 1)) - mid_idx -= ((iicxn) * (iicyn - 1)) + left_idx -= (iicxn) * (iicyn - 1) + mid_idx -= (iicxn) * (iicyn - 1) left = p[left_idx] mid = p[mid_idx] right = p[right_idx] - lap[idx] = oodx2 * (left - 2. * mid + right) + lap[idx] = oodx2 * (left - 2.0 * mid + right) cnt_x += 1 if cnt_x % iicxn == 0: cnt_y += 1 cnt_x = 0 - + return lap -def stencil_5pt(elem,node,ud): +def stencil_5pt(elem, node, ud): igx = elem.igx igy = elem.igy @@ -1462,7 +1799,10 @@ def stencil_5pt(elem,node,ud): x_wall = ud.bdry_type[1] == opts.BdryType.WALL y_wall = ud.bdry_type[0] == opts.BdryType.WALL - return lambda p : lap2D_5pt(p, iicxn, iicyn, oodx2, oody2, x_periodic, y_periodic, x_wall, y_wall) + return lambda p: lap2D_5pt( + p, iicxn, iicyn, oodx2, oody2, x_periodic, y_periodic, x_wall, y_wall + ) + @nb.jit(nopython=True, nogil=True, cache=True) def lap2D_5pt(p, iicxn, iicyn, oodx2, oody2, x_periodic, y_periodic, x_wall, y_wall): @@ -1472,7 +1812,6 @@ def lap2D_5pt(p, iicxn, iicyn, oodx2, oody2, x_periodic, y_periodic, x_wall, y_w cnt_y = 0 for idx in range(iicxn * iicyn): - # get indices of the 9pt stencil midleft_idx = idx - 1 topmid_idx = idx - iicxn @@ -1496,20 +1835,20 @@ def lap2D_5pt(p, iicxn, iicyn, oodx2, oody2, x_periodic, y_periodic, x_wall, y_w botmid_idx -= iicxn - 1 if cnt_y == 0: - topmid_idx += ((iicxn) * (iicyn - 1)) + topmid_idx += (iicxn) * (iicyn - 1) if y_periodic: - midleft_idx += ((iicxn) * (iicyn - 1)) - midmid_idx += ((iicxn) * (iicyn - 1)) - midright_idx += ((iicxn) * (iicyn - 1)) + midleft_idx += (iicxn) * (iicyn - 1) + midmid_idx += (iicxn) * (iicyn - 1) + midright_idx += (iicxn) * (iicyn - 1) if cnt_y == (iicyn - 1): - botmid_idx -= ((iicxn) * (iicyn - 1)) + botmid_idx -= (iicxn) * (iicyn - 1) if y_periodic: - midleft_idx -= ((iicxn) * (iicyn - 1)) - midmid_idx -= ((iicxn) * (iicyn - 1)) - midright_idx -= ((iicxn) * (iicyn - 1)) + midleft_idx -= (iicxn) * (iicyn - 1) + midmid_idx -= (iicxn) * (iicyn - 1) + midright_idx -= (iicxn) * (iicyn - 1) midleft = p[midleft_idx] topmid = p[topmid_idx] @@ -1518,22 +1857,24 @@ def lap2D_5pt(p, iicxn, iicyn, oodx2, oody2, x_periodic, y_periodic, x_wall, y_w midright = p[midright_idx] if x_wall and (cnt_x == 0): - midleft = 0. + midleft = 0.0 if x_wall and (cnt_x == (iicxn - 1)): - midright = 0. + midright = 0.0 if y_wall and (cnt_y == 0): - topmid = 0. - + topmid = 0.0 + if y_wall and (cnt_y == (iicyn - 1)): - botmid = 0. - - lap[idx] = oodx2 * (midleft - 2.0 * midmid + midright) + oody2 * (topmid - 2.0 * midmid + botmid) + botmid = 0.0 + + lap[idx] = oodx2 * (midleft - 2.0 * midmid + midright) + oody2 * ( + topmid - 2.0 * midmid + botmid + ) cnt_x += 1 if cnt_x % iicxn == 0: cnt_y += 1 cnt_x = 0 - - return lap \ No newline at end of file + + return lap diff --git a/src/flow_solver/physics/low_mach/mpv.py b/src/flow_solver/physics/low_mach/mpv.py index a45a8ae1..4e08a7af 100644 --- a/src/flow_solver/physics/low_mach/mpv.py +++ b/src/flow_solver/physics/low_mach/mpv.py @@ -2,11 +2,12 @@ from ...utils import variable as var + class MPV(object): - def __init__(self,elem,node,ud): + def __init__(self, elem, node, ud): sc = elem.sc sn = node.sc - + self.p0 = 1.0 self.p00 = 1.0 @@ -22,14 +23,14 @@ def __init__(self,elem,node,ud): self.rhs = np.zeros((node.isc)) self.wcenter = np.zeros((node.isc)) - self.wplus = np.zeros(([elem.ndim]+list(sc))) + self.wplus = np.zeros(([elem.ndim] + list(sc))) - self.HydroState = var.States([sc[1]],ud) - self.HydroState_n = var.States([sn[1]],ud) + self.HydroState = var.States([sc[1]], ud) + self.HydroState_n = var.States([sn[1]], ud) self.squeezer() def squeezer(self): for key, value in vars(self).items(): if type(value) == np.ndarray: - setattr(self,key,value.squeeze()) + setattr(self, key, value.squeeze()) diff --git a/src/flow_solver/physics/low_mach/second_projection.py b/src/flow_solver/physics/low_mach/second_projection.py index 6a7f5958..23461a17 100644 --- a/src/flow_solver/physics/low_mach/second_projection.py +++ b/src/flow_solver/physics/low_mach/second_projection.py @@ -4,27 +4,33 @@ import numpy as np import scipy as sp -from ...utils import options as opts, boundary as bdry +from ...utils import options as opts, boundary as bdry from . import laplacian as lm_lp + class solver_counter(object): """ taken from https://stackoverflow.com/questions/33512081/getting-the-number-of-iterations-of-scipys-gmres-iterative-method """ + def __init__(self, disp=True): self.niter = 0 + def __call__(self, rk=None): self.niter += 1 self.rk = rk -def euler_forward_non_advective(Sol, mpv, elem, node, dt, ud, th, writer = None, label = None, debug = False): + +def euler_forward_non_advective( + Sol, mpv, elem, node, dt, ud, th, writer=None, label=None, debug=False +): nonhydro = ud.nonhydrostasy g = ud.gravity_strength[1] Msq = ud.Msq Ginv = th.Gammainv corr_h1 = ud.coriolis_strength[0] - corr_v = ud.coriolis_strength[1] + corr_v = ud.coriolis_strength[1] corr_h2 = ud.coriolis_strength[2] u0 = ud.u_wind_speed v0 = ud.v_wind_speed @@ -35,17 +41,23 @@ def euler_forward_non_advective(Sol, mpv, elem, node, dt, ud, th, writer = None, ndim = elem.ndim S0c = mpv.HydroState.get_S0c(elem) - dSdy = mpv.HydroState_n.get_dSdy(elem,node) + dSdy = mpv.HydroState_n.get_dSdy(elem, node) - mpv.rhs[...] = divergence_nodes(mpv.rhs,elem,node,Sol,ud) - if not hasattr(ud, 'LAMB_BDRY'): scale_wall_node_values(mpv.rhs, node, ud, 2.0) + mpv.rhs[...] = divergence_nodes(mpv.rhs, elem, node, Sol, ud) + if not hasattr(ud, "LAMB_BDRY"): + scale_wall_node_values(mpv.rhs, node, ud, 2.0) div = mpv.rhs - if debug: writer.populate(str(label), 'rhs', div) + if debug: + writer.populate(str(label), "rhs", div) - rhoY = Sol.rhoY**(th.gamm - 2.0) - dpidP_kernel = np.ones([2]*ndim) - dpidP = (th.gm1 / ud.Msq) * sp.signal.fftconvolve(rhoY, dpidP_kernel, mode='valid') / dpidP_kernel.sum() + rhoY = Sol.rhoY ** (th.gamm - 2.0) + dpidP_kernel = np.ones([2] * ndim) + dpidP = ( + (th.gm1 / ud.Msq) + * sp.signal.fftconvolve(rhoY, dpidP_kernel, mode="valid") + / dpidP_kernel.sum() + ) rhoYovG = Ginv * Sol.rhoY dbuoy = Sol.rhoY * (Sol.rhoX / Sol.rho) @@ -55,21 +67,28 @@ def euler_forward_non_advective(Sol, mpv, elem, node, dt, ud, th, writer = None, drhov = Sol.rhov - v0 * Sol.rho drhow = Sol.rhow - w0 * Sol.rho v = Sol.rhov / Sol.rho - - Sol.rhou = Sol.rhou - dt * ( rhoYovG * dpdx - corr_h2 * drhov + corr_v * drhow) - Sol.rhov = Sol.rhov - dt * ( rhoYovG * dpdy + (g/Msq) * dbuoy * nonhydro - corr_h1 * drhow + corr_h2 * drhou) * (1 - ud.is_ArakawaKonor) + Sol.rhou = Sol.rhou - dt * (rhoYovG * dpdx - corr_h2 * drhov + corr_v * drhow) + + Sol.rhov = Sol.rhov - dt * ( + rhoYovG * dpdy + + (g / Msq) * dbuoy * nonhydro + - corr_h1 * drhow + + corr_h2 * drhou + ) * (1 - ud.is_ArakawaKonor) - Sol.rhow = Sol.rhow - dt * ( rhoYovG * dpdz - corr_v * drhou + corr_h1 * drhov) * (ndim == 3) + Sol.rhow = Sol.rhow - dt * (rhoYovG * dpdz - corr_v * drhou + corr_h1 * drhov) * ( + ndim == 3 + ) Sol.rhoX = (Sol.rho * (Sol.rho / Sol.rhoY - S0c)) - dt * (v * dSdy) * Sol.rho - dp2n[node.i1] -= dt * dpidP * div#[node.i1] + dp2n[node.i1] -= dt * dpidP * div # [node.i1] weight = ud.compressibility mpv.p2_nodes += weight * dp2n - bdry.set_ghostnodes_p2(mpv.p2_nodes,node, ud) + bdry.set_ghostnodes_p2(mpv.p2_nodes, node, ud) bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) @@ -79,7 +98,7 @@ def euler_backward_non_advective_expl_part(Sol, mpv, elem, dt, ud, th): Msq = ud.Msq dbuoy = Sol.rhoY * (Sol.rhoX / Sol.rho) - Sol.rhov = (nonhydro * Sol.rhov) - dt * (g/Msq) * dbuoy + Sol.rhov = (nonhydro * Sol.rhov) - dt * (g / Msq) * dbuoy # Sol.rhov[np.where(Sol.rhov < 1e-15)] = 0.0 Sol.mod_bg_wind(ud, -1.0) @@ -93,7 +112,23 @@ def euler_backward_non_advective_expl_part(Sol, mpv, elem, dt, ud, th): total_iter = 0 total_calls = 0 -def euler_backward_non_advective_impl_part(Sol, mpv, elem, node, ud, th, t, dt, alpha_diff, Sol0 = None, writer = None, label=None, debug=False): + + +def euler_backward_non_advective_impl_part( + Sol, + mpv, + elem, + node, + ud, + th, + t, + dt, + alpha_diff, + Sol0=None, + writer=None, + label=None, + debug=False, +): if not debug: writer = None nc = node.sc @@ -105,9 +140,9 @@ def euler_backward_non_advective_impl_part(Sol, mpv, elem, node, ud, th, t, dt, # p2 = mpv.p2_nodes[node.p_isc] # elif elem.ndim == 3: # p2 = np.copy(mpv.p2_nodes[1:-1,1:-1,1:-1]) - + if writer != None: - writer.populate(str(label),'p2_initial',mpv.p2_nodes) + writer.populate(str(label), "p2_initial", mpv.p2_nodes) if Sol0 is not None: bdry.set_explicit_boundary_data(Sol0, elem, ud, th, mpv) @@ -115,44 +150,47 @@ def euler_backward_non_advective_impl_part(Sol, mpv, elem, node, ud, th, t, dt, else: bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt) - - i0 = node.ndim * [(slice(0,-1))] + i0 = node.ndim * [(slice(0, -1))] i0 = tuple(i0) if writer != None: - writer.populate(str(label),'hcenter',mpv.wcenter) - writer.populate(str(label),'wplusx',mpv.wplus[0]) - writer.populate(str(label),'wplusy',mpv.wplus[1]) - writer.populate(str(label),'wplusz',mpv.wplus[2]) if elem.ndim == 3 else writer.populate(str(label),'wplusz',np.zeros_like(mpv.wplus[0])) - - bdry.set_ghostnodes_p2(mpv.p2_nodes,node,ud) - correction_nodes(Sol,elem,node,mpv,mpv.p2_nodes,dt,ud,th,0) + writer.populate(str(label), "hcenter", mpv.wcenter) + writer.populate(str(label), "wplusx", mpv.wplus[0]) + writer.populate(str(label), "wplusy", mpv.wplus[1]) + writer.populate( + str(label), "wplusz", mpv.wplus[2] + ) if elem.ndim == 3 else writer.populate( + str(label), "wplusz", np.zeros_like(mpv.wplus[0]) + ) + + bdry.set_ghostnodes_p2(mpv.p2_nodes, node, ud) + correction_nodes(Sol, elem, node, mpv, mpv.p2_nodes, dt, ud, th, 0) bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - rhs[...] = divergence_nodes(rhs,elem,node,Sol,ud) + rhs[...] = divergence_nodes(rhs, elem, node, Sol, ud) if writer != None: - writer.populate(str(label),'rhs',rhs) + writer.populate(str(label), "rhs", rhs) rhs /= dt if ud.is_compressible == 1: - rhs = rhs_from_p_old(rhs,node,mpv) - # if + rhs = rhs_from_p_old(rhs, node, mpv) + # if elif ud.is_compressible == 0: if ud.is_ArakawaKonor: rhs -= mpv.wcenter * mpv.dp2_nodes mpv.wcenter[...] = 0.0 else: - rhs_new = rhs_from_p_old(rhs,node,mpv) + rhs_new = rhs_from_p_old(rhs, node, mpv) rhs = ud.compressibility * rhs_new + (1.0 - ud.compressibility) * rhs mpv.wcenter[...] *= ud.compressibility else: mpv.wcenter *= ud.compressibility if writer != None: - writer.populate(str(label),'rhs_nodes',rhs) + writer.populate(str(label), "rhs_nodes", rhs) mpv.rhs[...] = rhs @@ -161,7 +199,9 @@ def euler_backward_non_advective_impl_part(Sol, mpv, elem, node, ud, th, t, dt, # prepare initial left-hand side and the laplacian stencil if elem.ndim == 2: Vec = mpv - coriolis_params = multiply_inverse_coriolis(Vec, Sol, mpv, ud, elem, node, dt, attrs=('u', 'v', 'w'), get_coeffs = True) + coriolis_params = multiply_inverse_coriolis( + Vec, Sol, mpv, ud, elem, node, dt, attrs=("u", "v", "w"), get_coeffs=True + ) # lap = stencil_9pt(elem,node,mpv,Sol,ud,diag_inv,dt,coriolis_params) # sh = (ud.inx)*(ud.iny) @@ -171,62 +211,65 @@ def euler_backward_non_advective_impl_part(Sol, mpv, elem, node, ud, th, t, dt, # diag_inv = np.ones_like(mpv.rhs) p2 = mpv.p2_nodes[node.i2].T - lap = lm_lp.stencil_9pt_numba_test(mpv,node,coriolis_params,diag_inv, ud) + lap = lm_lp.stencil_9pt_numba_test(mpv, node, coriolis_params, diag_inv, ud) sh = p2.shape[0] * p2.shape[1] # p2 = np.copy(mpv.p2_nodes[1:-1,1:-1]) # sh = p2.reshape(-1).shape[0] - - - elif elem.ndim == 3 and elem.icy - 2*elem.igs[1] <= 2: + elif elem.ndim == 3 and elem.icy - 2 * elem.igs[1] <= 2: # horizontal slice hack - p2 = np.copy(mpv.p2_nodes[1:-1,elem.igs[1],1:-1]) - lap = lm_lp.stencil_hs(elem,node,mpv,ud,diag_inv,dt) + p2 = np.copy(mpv.p2_nodes[1:-1, elem.igs[1], 1:-1]) + lap = lm_lp.stencil_hs(elem, node, mpv, ud, diag_inv, dt) sh = p2.reshape(-1).shape[0] elif elem.ndim == 3 and elem.iicy > 1 and elem.iicz == 1: # vertical slice hack if not VS: - p2 = np.copy(mpv.p2_nodes[...,elem.igz][node.igx:-node.igx,node.igy:-node.igy]) - lap = lm_lp.stencil_vs(elem,node,mpv,ud,diag_inv,dt) - sh = (node.iicx)*(node.iicy) + p2 = np.copy( + mpv.p2_nodes[..., elem.igz][node.igx : -node.igx, node.igy : -node.igy] + ) + lap = lm_lp.stencil_vs(elem, node, mpv, ud, diag_inv, dt) + sh = (node.iicx) * (node.iicy) if VS: - p2 = np.copy(mpv.p2_nodes[1:-1,1:-1,elem.igs[2]]) - lap = lm_lp.stencil_vs(elem,node,mpv,ud,diag_inv,dt) + p2 = np.copy(mpv.p2_nodes[1:-1, 1:-1, elem.igs[2]]) + lap = lm_lp.stencil_vs(elem, node, mpv, ud, diag_inv, dt) sh = p2.reshape(-1).shape[0] - elif elem.ndim == 3 and elem.icy - 2*elem.igs[1] > 2: - lap = lm_lp.stencil_27pt(elem,node,mpv,ud,diag_inv,dt) + elif elem.ndim == 3 and elem.icy - 2 * elem.igs[1] > 2: + lap = lm_lp.stencil_27pt(elem, node, mpv, ud, diag_inv, dt) sh = p2.reshape(-1).shape[0] - lap = sp.sparse.linalg.LinearOperator((sh,sh),lap) + lap = sp.sparse.linalg.LinearOperator((sh, sh), lap) # lap = LinearOperator(sh,lap) - + counter = solver_counter() # prepare right-hand side if elem.ndim == 2: # rhs_inner = rhs[node.igx:-node.igx,node.igy:-node.igy].ravel() # rhs_inner = rhs[1:-1,1:-1].ravel() - rhs_inner = rhs[1:-1,1:-1].T.ravel() + rhs_inner = rhs[1:-1, 1:-1].T.ravel() # rhs_inner = rhs.T.ravel() elif elem.ndim == 3 and elem.iicy > 1 and elem.iicz == 1: - if not VS: - rhs_inner = rhs[...,elem.igs[2]][node.igx:-node.igx,node.igy:-node.igy].ravel() + rhs_inner = rhs[..., elem.igs[2]][ + node.igx : -node.igx, node.igy : -node.igy + ].ravel() if VS: - rhs_inner = rhs[1:-1,1:-1,elem.igs[2]].ravel() + rhs_inner = rhs[1:-1, 1:-1, elem.igs[2]].ravel() - elif elem.ndim == 3 and elem.icy - 2*elem.igs[1] > 2: - rhs_inner = rhs[1:-1,1:-1,1:-1].ravel() + elif elem.ndim == 3 and elem.icy - 2 * elem.igs[1] > 2: + rhs_inner = rhs[1:-1, 1:-1, 1:-1].ravel() else: - rhs_inner = rhs[1:-1,elem.igs[1],1:-1].ravel() + rhs_inner = rhs[1:-1, elem.igs[1], 1:-1].ravel() # p2, _ = bicgstab(lap,rhs_inner,tol=ud.tol,maxiter=ud.max_iterations,callback=counter) - p2, _ = sp.sparse.linalg.bicgstab(lap,rhs_inner,tol=ud.tol,maxiter=ud.max_iterations,callback=counter) + p2, _ = sp.sparse.linalg.bicgstab( + lap, rhs_inner, tol=ud.tol, maxiter=ud.max_iterations, callback=counter + ) # p2, _ = gmres(lap,rhs_inner,tol=ud.tol,maxiter=ud.max_iterations) # p2,info = bicgstab(lap,rhs.ravel(),x0=p2.ravel(),tol=1e-16,maxiter=6000,callback=counter) # print("Convergence info = %i, no. of iterations = %i" %(info,counter.niter)) @@ -235,48 +278,50 @@ def euler_backward_non_advective_impl_part(Sol, mpv, elem, node, ud, th, t, dt, total_iter += counter.niter total_calls += 1 logging.info(counter.niter) - logging.info("Total calls to BiCGStab routine = %i, total iterations = %i" %(total_calls, total_iter)) + logging.info( + "Total calls to BiCGStab routine = %i, total iterations = %i" + % (total_calls, total_iter) + ) p2_full = np.zeros(nc).squeeze() if elem.ndim == 2: # p2_full[node.igx:-node.igx,node.igy:-node.igy] = p2.reshape(ud.inx,ud.iny) # p2_full[node.i2] = p2.reshape(rhs[node.i1].shape[0],rhs[node.i1].shape[1]) - p2_full[node.i2] = p2.reshape(rhs[node.i1].shape[1],rhs[node.i1].shape[0]).T + p2_full[node.i2] = p2.reshape(rhs[node.i1].shape[1], rhs[node.i1].shape[0]).T # p2_full[node.i1] = p2.reshape(rhs.shape[1],rhs.shape[0]).T # p2 = p2.reshape(ud.inx+2, ud.iny+2) # p2_full[1:-1,1:-1] = p2 - elif elem.ndim == 3 and elem.icy - 2*elem.igs[1] <= 2: + elif elem.ndim == 3 and elem.icy - 2 * elem.igs[1] <= 2: # horizontal slice hack - p2 = p2.reshape(ud.inx+2, ud.inz+2) - p2 = np.expand_dims(p2,1) + p2 = p2.reshape(ud.inx + 2, ud.inz + 2) + p2 = np.expand_dims(p2, 1) p2 = np.repeat(p2, node.icy, axis=1) - p2_full[1:-1,:,1:-1] = p2 + p2_full[1:-1, :, 1:-1] = p2 elif elem.ndim == 3 and elem.iicy > 1 and elem.iicz == 1: if not VS: - p2 = p2.reshape(node.iicx,node.iicy) - p2 = np.repeat(p2[...,np.newaxis], node.icz, axis=2) - p2_full[node.igx:-node.igx,node.igy:-node.igy] = p2 + p2 = p2.reshape(node.iicx, node.iicy) + p2 = np.repeat(p2[..., np.newaxis], node.icz, axis=2) + p2_full[node.igx : -node.igx, node.igy : -node.igy] = p2 if VS: - p2 = p2.reshape(ud.inx+2, ud.iny+2) - p2 = np.expand_dims(p2,2) + p2 = p2.reshape(ud.inx + 2, ud.iny + 2) + p2 = np.expand_dims(p2, 2) p2 = np.repeat(p2, node.icz, axis=2) - p2_full[1:-1,1:-1,:] = p2 - + p2_full[1:-1, 1:-1, :] = p2 - elif elem.ndim == 3 and elem.icy - 2*elem.igs[1] > 2: - p2_full[1:-1,1:-1,1:-1] = p2.reshape(ud.inx+2,ud.iny+2,ud.inz+2) + elif elem.ndim == 3 and elem.icy - 2 * elem.igs[1] > 2: + p2_full[1:-1, 1:-1, 1:-1] = p2.reshape(ud.inx + 2, ud.iny + 2, ud.inz + 2) if writer != None: - writer.populate(str(label),'p2_full',p2_full) + writer.populate(str(label), "p2_full", p2_full) - bdry.set_ghostnodes_p2(p2_full,node,ud) - correction_nodes(Sol,elem,node,mpv,p2_full,dt,ud,th,1) + bdry.set_ghostnodes_p2(p2_full, node, ud) + correction_nodes(Sol, elem, node, mpv, p2_full, dt, ud, th, 1) mpv.p2_nodes[...] += p2_full - bdry.set_ghostnodes_p2(mpv.p2_nodes,node,ud) + bdry.set_ghostnodes_p2(mpv.p2_nodes, node, ud) bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) -def correction_nodes(Sol,elem,node,mpv,p,dt,ud,th,updt_chi): +def correction_nodes(Sol, elem, node, mpv, p, dt, ud, th, updt_chi): ndim = node.ndim Gammainv = th.Gammainv @@ -284,26 +329,27 @@ def correction_nodes(Sol,elem,node,mpv,p,dt,ud,th,updt_chi): Dpx, Dpy, Dpz = grad_nodes(p, elem.ndim, node.dxyz) - thinv = (Sol.rho / Sol.rhoY) + thinv = Sol.rho / Sol.rhoY Y = Sol.rhoY / Sol.rho - coeff = (Gammainv * Sol.rhoY * Y) + coeff = Gammainv * Sol.rhoY * Y mpv.u = -dt * coeff * Dpx mpv.v = -dt * coeff * Dpy mpv.w = -dt * coeff * Dpz - multiply_inverse_coriolis(mpv, Sol, mpv, ud, elem, elem, dt, attrs=['u', 'v', 'w']) + multiply_inverse_coriolis(mpv, Sol, mpv, ud, elem, elem, dt, attrs=["u", "v", "w"]) Sol.rhou += thinv * mpv.u Sol.rhov += thinv * mpv.v Sol.rhow += thinv * mpv.w if ndim == 3 else 0.0 - Sol.rhoX += - updt_chi * dt * dSdy * Sol.rhov + Sol.rhoX += -updt_chi * dt * dSdy * Sol.rhov # set_explicit_boundary_data(Sol, elem, ud, th, mpv) assert True + def operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt): g = ud.gravity_strength[1] Msq = ud.Msq @@ -315,7 +361,7 @@ def operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt): wh1, wv, wh2 = dt * ud.coriolis_strength - ccenter = - ud.Msq * th.gm1inv / (dt**2) + ccenter = -ud.Msq * th.gm1inv / (dt**2) cexp = 2.0 - th.gamm igs = elem.igs @@ -326,24 +372,27 @@ def operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt): coeff = Gammainv * Sol.rhoY * Y nu = np.zeros_like(mpv.wcenter) - nu = -dt**2 * (g / Msq) * strat * Y + nu = -(dt**2) * (g / Msq) * strat * Y - setattr(mpv, 'nu_c', nu) + setattr(mpv, "nu_c", nu) nu = nu - for dim in range(ndim): ## Assuming 2D vertical slice! if dim == 1: - mpv.wplus[dim][...] = coeff #* gimp #* (wv**2 + 1.0) + mpv.wplus[dim][...] = coeff # * gimp #* (wv**2 + 1.0) else: - mpv.wplus[dim][...] = coeff #* fimp #* (wh1**2 + nu + nonhydro) + mpv.wplus[dim][...] = coeff # * fimp #* (wh1**2 + nu + nonhydro) kernel = np.ones([2] * ndim) - mpv.wcenter = (ccenter * sp.signal.fftconvolve(Sol.rhoY**cexp,kernel,mode='valid') / kernel.sum()) + mpv.wcenter = ( + ccenter + * sp.signal.fftconvolve(Sol.rhoY**cexp, kernel, mode="valid") + / kernel.sum() + ) - tmp_wplus = sp.signal.fftconvolve(mpv.wplus[0],kernel,mode='valid') / kernel.sum() + tmp_wplus = sp.signal.fftconvolve(mpv.wplus[0], kernel, mode="valid") / kernel.sum() # set_ghostcells_p2(mpv.wplus[0], elem, ud) # set_ghostcells_p2(mpv.wplus[1], elem, ud) @@ -352,7 +401,8 @@ def operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt): # mpv.wcenter[:,-1] = mpv.wcenter[:,-2] assert True - if not hasattr(ud, 'LAMB_BDRY'): scale_wall_node_values(mpv.wcenter, node, ud) + if not hasattr(ud, "LAMB_BDRY"): + scale_wall_node_values(mpv.wcenter, node, ud) # def operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt): @@ -388,7 +438,7 @@ def operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt): # y_idx1 = slice(igs[dim]-is_periodic+1, right_idx) # innerdim1[dim] = slice(igs[dim]-1, (-igs[dim]+1)) - + # strat = (mpv.HydroState_n.S0[y_idx1] - mpv.HydroState_n.S0[y_idx]) / dy # nindim = tuple(nindim) @@ -429,7 +479,7 @@ def operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt): # scale_wall_node_values(mpv.wcenter, node, ud) -def scale_wall_node_values(rhs, node, ud, factor=.5): +def scale_wall_node_values(rhs, node, ud, factor=0.5): # if factor < 1.0: # if factor < 1.0: # factor = 1.0 @@ -450,13 +500,16 @@ def scale_wall_node_values(rhs, node, ud, factor=.5): wall_idx = np.empty((ndim), dtype=object) for dim in range(ndim): - wall_idx[dim] = slice(igs[dim],-igs[dim]) + wall_idx[dim] = slice(igs[dim], -igs[dim]) for dim in range(ndim): - is_wall = ud.bdry_type[dim] == opts.BdryType.WALL or ud.bdry_type[dim] == opts.BdryType.RAYLEIGH + is_wall = ( + ud.bdry_type[dim] == opts.BdryType.WALL + or ud.bdry_type[dim] == opts.BdryType.RAYLEIGH + ) if is_wall: - for direction in [-1,1]: - wall_idx[dim] = (igs[dim]-1) * direction + for direction in [-1, 1]: + wall_idx[dim] = (igs[dim] - 1) * direction if direction == -1: wall_idx[dim] -= 1 wall_idx_tuple = tuple(wall_idx) @@ -472,40 +525,54 @@ def scale_wall_node_values(rhs, node, ud, factor=.5): # rhs[wall_idx_tuple] *= factor - def grad_nodes_fft(p2n, elem, node): ndim = node.ndim dx, dy, dz = node.dx, node.dy, node.dz kernels = [] for dim in range(ndim): - kernel = np.ones([2]*ndim) - slc = [slice(None,)]*ndim - slc[dim] = slice(0,1) + kernel = np.ones([2] * ndim) + slc = [ + slice( + None, + ) + ] * ndim + slc[dim] = slice(0, 1) kernel[tuple(slc)] *= -1.0 kernels.append(kernel) - dpdx = -0.5**(ndim-1) * sp.signal.fftconvolve(p2n, kernels[0], mode='valid') / dx - dpdy = -0.5**(ndim-1) * sp.signal.fftconvolve(p2n, kernels[1], mode='valid') / dy if elem.iicy > 1 else 0.0 - dpdz = -0.5**(ndim-1) * sp.signal.fftconvolve(p2n, kernels[2], mode='valid') / dz if (ndim == 3) else 0.0 + dpdx = ( + -(0.5 ** (ndim - 1)) * sp.signal.fftconvolve(p2n, kernels[0], mode="valid") / dx + ) + dpdy = ( + -(0.5 ** (ndim - 1)) * sp.signal.fftconvolve(p2n, kernels[1], mode="valid") / dy + if elem.iicy > 1 + else 0.0 + ) + dpdz = ( + -(0.5 ** (ndim - 1)) * sp.signal.fftconvolve(p2n, kernels[2], mode="valid") / dz + if (ndim == 3) + else 0.0 + ) return dpdx, dpdy, dpdz + # @jit(nopython=True, nogil=False, cache=True) def grad_nodes(p, ndim, dxy): dx, dy, dz = dxy - indices = [idx for idx in it.product([slice(0,-1),slice(1,None)], repeat=ndim)] + indices = [idx for idx in it.product([slice(0, -1), slice(1, None)], repeat=ndim)] if ndim == 2: - signs_x = (-1., -1., +1., +1.) - signs_y = (-1., +1., -1., +1.) - signs_z = ( 0., 0., 0., 0.) + signs_x = (-1.0, -1.0, +1.0, +1.0) + signs_y = (-1.0, +1.0, -1.0, +1.0) + signs_z = (0.0, 0.0, 0.0, 0.0) elif ndim == 3: - signs_x = (-1., -1., -1., -1., +1., +1., +1., +1.) - signs_y = (-1., -1., +1., +1., -1., -1., +1., +1.) - signs_z = (-1., +1., -1., +1., -1., +1., -1., +1.) + signs_x = (-1.0, -1.0, -1.0, -1.0, +1.0, +1.0, +1.0, +1.0) + signs_y = (-1.0, -1.0, +1.0, +1.0, -1.0, -1.0, +1.0, +1.0) + signs_z = (-1.0, +1.0, -1.0, +1.0, -1.0, +1.0, -1.0, +1.0) - Dpx, Dpy, Dpz = 0., 0., 0. + Dpx, Dpy, Dpz = 0.0, 0.0, 0.0 cnt = 0 for index in indices: Dpx += signs_x[cnt] * p[index] @@ -513,15 +580,14 @@ def grad_nodes(p, ndim, dxy): Dpz += signs_z[cnt] * p[index] cnt += 1 - Dpx *= 0.5**(ndim-1) / dx - Dpy *= 0.5**(ndim-1) / dy - Dpz *= 0.5**(ndim-1) / dz + Dpx *= 0.5 ** (ndim - 1) / dx + Dpy *= 0.5 ** (ndim - 1) / dy + Dpz *= 0.5 ** (ndim - 1) / dz return Dpx, Dpy, Dpz - -def divergence_nodes(rhs,elem,node,Sol,ud): +def divergence_nodes(rhs, elem, node, Sol, ud): ndim = elem.ndim igs = elem.igs dxyz = node.dxyz @@ -529,61 +595,63 @@ def divergence_nodes(rhs,elem,node,Sol,ud): for dim in range(ndim): is_periodic = ud.bdry_type[dim] == opts.BdryType.PERIODIC - inner_idx[dim] = slice(igs[dim]-is_periodic,-igs[dim]+is_periodic) + inner_idx[dim] = slice(igs[dim] - is_periodic, -igs[dim] + is_periodic) inner_idx_p1y = np.copy(inner_idx) - inner_idx_p1y[1] = slice(1,-1) - - indices = [idx for idx in it.product([slice(0,-1),slice(1,None)], repeat = ndim)] - signs = [sgn for sgn in it.product([1,-1], repeat = ndim)] + inner_idx_p1y[1] = slice(1, -1) + + indices = [idx for idx in it.product([slice(0, -1), slice(1, None)], repeat=ndim)] + signs = [sgn for sgn in it.product([1, -1], repeat=ndim)] inner_idx = tuple(inner_idx) inner_idx_p1y = tuple(inner_idx_p1y) - if not hasattr(ud, 'LAMB_BDRY'): - if ud.bdry_type[1] == opts.BdryType.WALL or ud.bdry_type[1] == opts.BdryType.RAYLEIGH: - Sol.rhou[:,:2,...] = 0.0 - Sol.rhov[:,:2,...] = 0.0 - Sol.rhow[:,:2,...] = 0.0 - - # if ud.bdry_type[1] == BdryType.WALL: - Sol.rhou[:,-2:,...] = 0.0 - Sol.rhov[:,-2:,...] = 0.0 - Sol.rhow[:,-2:,...] = 0.0 + if not hasattr(ud, "LAMB_BDRY"): + if ( + ud.bdry_type[1] == opts.BdryType.WALL + or ud.bdry_type[1] == opts.BdryType.RAYLEIGH + ): + Sol.rhou[:, :2, ...] = 0.0 + Sol.rhov[:, :2, ...] = 0.0 + Sol.rhow[:, :2, ...] = 0.0 + # if ud.bdry_type[1] == BdryType.WALL: + Sol.rhou[:, -2:, ...] = 0.0 + Sol.rhov[:, -2:, ...] = 0.0 + Sol.rhow[:, -2:, ...] = 0.0 Y = Sol.rhoY / Sol.rho - Ux = np.diff(Sol.rhou * Y,axis=0) / elem.dx - Ux = 0.5 * (Ux[:,:-1,...] + Ux[:,1:,...]) + Ux = np.diff(Sol.rhou * Y, axis=0) / elem.dx + Ux = 0.5 * (Ux[:, :-1, ...] + Ux[:, 1:, ...]) - Vy = np.diff(Sol.rhov * Y,axis=1) / elem.dy - Vy = 0.5 * (Vy[:-1,...] + Vy[1:,...]) + Vy = np.diff(Sol.rhov * Y, axis=1) / elem.dy + Vy = 0.5 * (Vy[:-1, ...] + Vy[1:, ...]) if ndim == 3: - Ux = -0.5 * (Ux[...,:-1] + Ux[...,1:]) - Vy = 0.5 * (Vy[...,:-1] + Vy[...,1:]) + Ux = -0.5 * (Ux[..., :-1] + Ux[..., 1:]) + Vy = 0.5 * (Vy[..., :-1] + Vy[..., 1:]) - Wz = np.diff(Sol.rhow * Y,axis=2) / elem.dz - Wz = 0.5 * (Wz[:-1,...] + Wz[1:,...]) - Wz = 0.5 * (Wz[:,:-1,...] + Wz[:,1:,...]) + Wz = np.diff(Sol.rhow * Y, axis=2) / elem.dz + Wz = 0.5 * (Wz[:-1, ...] + Wz[1:, ...]) + Wz = 0.5 * (Wz[:, :-1, ...] + Wz[:, 1:, ...]) - rhs[1:-1,1:-1,1:-1] = (Ux + Vy + Wz) + rhs[1:-1, 1:-1, 1:-1] = Ux + Vy + Wz else: - rhs = (Ux + Vy) + rhs = Ux + Vy rhs_max = np.max(rhs[inner_idx]) if np.max(rhs[inner_idx]) > 0 else 0 return rhs -def rhs_from_p_old(rhs,node,mpv): +def rhs_from_p_old(rhs, node, mpv): igs = node.igs ndim = node.ndim assert ndim != 1, "Not implemented for 1D" - + # inner_idx = np.empty((ndim), dtype=object) # for dim in range(ndim): # inner_idx[dim] = slice(igs[dim],-igs[dim]) - + # inner_idx = tuple(inner_idx) # rhs_n = np.zeros_like(rhs) # rhs_hh = mpv.wcenter[inner_idx] * mpv.p2_nodes[inner_idx] @@ -591,8 +659,8 @@ def rhs_from_p_old(rhs,node,mpv): inner_idx = np.empty((ndim), dtype=object) for dim in range(ndim): - inner_idx[dim] = slice(igs[dim],-igs[dim]) - + inner_idx[dim] = slice(igs[dim], -igs[dim]) + inner_idx = tuple(inner_idx) rhs_n = np.zeros_like(rhs) rhs_hh = mpv.wcenter * mpv.p2_nodes[node.i1] @@ -600,7 +668,9 @@ def rhs_from_p_old(rhs,node,mpv): return rhs_n -def multiply_inverse_coriolis(Vec, Sol, mpv, ud, elem, node, dt, attrs=('rhou', 'rhov', 'rhow'), get_coeffs = False): +def multiply_inverse_coriolis( + Vec, Sol, mpv, ud, elem, node, dt, attrs=("rhou", "rhov", "rhow"), get_coeffs=False +): nonhydro = ud.nonhydrostasy g = ud.gravity_strength[1] Msq = ud.Msq @@ -610,26 +680,26 @@ def multiply_inverse_coriolis(Vec, Sol, mpv, ud, elem, node, dt, attrs=('rhou', strat = mpv.HydroState_n.get_dSdy(elem, node) Y = Sol.rhoY / Sol.rho - nu = -dt**2 * (g / Msq) * strat * Y + nu = -(dt**2) * (g / Msq) * strat * Y # get coefficients of the explicit terms # common denominator denom = 1.0 / (wh1**2 + wh2**2 + (nu + nonhydro) * (wv**2 + 1.0)) # U update - coeff_uu = (wh1**2 + nu + nonhydro) + coeff_uu = wh1**2 + nu + nonhydro coeff_uv = nonhydro * (wh1 * wv + wh2) - coeff_uw = (wh1 * wh2 - (nu + nonhydro) * wv) + coeff_uw = wh1 * wh2 - (nu + nonhydro) * wv # V update - coeff_vu = (wh1 * wv - wh2) + coeff_vu = wh1 * wv - wh2 coeff_vv = nonhydro * (1 + wv**2) - coeff_vw = (wh2 * wv + wh1) + coeff_vw = wh2 * wv + wh1 # W update - coeff_wu = (wh1 * wh2 + (nu + nonhydro) * wv) + coeff_wu = wh1 * wh2 + (nu + nonhydro) * wv coeff_wv = nonhydro * (wh2 * wv - wh1) - coeff_ww = (nu + nonhydro + wh2**2) + coeff_ww = nu + nonhydro + wh2**2 VecU = getattr(Vec, attrs[0]) VecV = getattr(Vec, attrs[1]) @@ -647,5 +717,10 @@ def multiply_inverse_coriolis(Vec, Sol, mpv, ud, elem, node, dt, attrs=('rhou', i1 = node.i1 if get_coeffs: # coriolis_parameters = ((coeff_uu * denom)[i1].reshape(-1,), (coeff_vv * denom)[i1].reshape(-1,), (coeff_uv * denom)[i1].reshape(-1,), (coeff_vu * denom)[i1].reshape(-1,)) - coriolis_parameters = ((coeff_uu * denom).T, (coeff_vv * denom).T, (coeff_uv * denom).T, (coeff_vu * denom).T) - return coriolis_parameters \ No newline at end of file + coriolis_parameters = ( + (coeff_uu * denom).T, + (coeff_vv * denom).T, + (coeff_uv * denom).T, + (coeff_vu * denom).T, + ) + return coriolis_parameters diff --git a/src/flow_solver/utils/boundary.py b/src/flow_solver/utils/boundary.py index 7586f59f..c45f6030 100644 --- a/src/flow_solver/utils/boundary.py +++ b/src/flow_solver/utils/boundary.py @@ -4,6 +4,7 @@ import numpy as np from . import options as opts + def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): """ In-place update of the ghost cells in :class:`management.variable.Vars` given the boundary conditions specified by :class:`inputs.user_data.UserDataInit`. @@ -31,23 +32,23 @@ def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): if step == None: dims = np.arange(ndim) else: - dims = [ndim-1] + dims = [ndim - 1] for dim in dims: if step is not None: current_step = step else: current_step = dim - ghost_padding, idx = get_ghost_padding(ndim,dim,igs) + ghost_padding, idx = get_ghost_padding(ndim, dim, igs) if ud.gravity_strength[current_step] == 0.0: # Do this for the axes that do not have gravity. # Periodic BC. if ud.bdry_type[current_step] == opts.BdryType.PERIODIC: - set_boundary(Sol,ghost_padding,'wrap',idx,step=None) + set_boundary(Sol, ghost_padding, "wrap", idx, step=None) # Wall BC. elif ud.bdry_type[current_step] == opts.BdryType.WALL: - set_boundary(Sol,ghost_padding,'symmetric',idx,step=None) + set_boundary(Sol, ghost_padding, "symmetric", idx, step=None) elif ud.bdry_type[current_step] == opts.BdryType.RAYLEIGH: assert 0, "Rayleigh boundary not defined on x-direction." # set_boundary(Sol,((0,0),(0,2)),'constant',(slice(None,),slice(0,-2)),step=None) @@ -56,8 +57,8 @@ def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): else: # get current axis that has gravity. gravity_axis = dim - - direction = -1. + + direction = -1.0 offset = 0 # get gravity strength specified in the user data file. @@ -69,34 +70,51 @@ def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): # loop through each of these ghost cells. for current_idx in np.arange(side)[::-1]: if step != None: - y_axs = (ndim - 1) + y_axs = ndim - 1 else: y_axs = 1 - nlast, nsource, nimage = get_gravity_padding(ndim,current_idx,direction,offset,elem,y_axs=y_axs) + nlast, nsource, nimage = get_gravity_padding( + ndim, current_idx, direction, offset, elem, y_axs=y_axs + ) Y_last = Sol.rhoY[nlast] / Sol.rho[nlast] - rhoYv_image = -Sol.rhov[nsource] * Sol.rhoY[nsource] / Sol.rho[nsource] + rhoYv_image = ( + -Sol.rhov[nsource] * Sol.rhoY[nsource] / Sol.rho[nsource] + ) - S = 1. / ud.stratification(elem.y[nimage[y_axs]]) + S = 1.0 / ud.stratification(elem.y[nimage[y_axs]]) - if hasattr(ud, 'LAMB_BDRY'): - dpi = (mpv.HydroState.p20[nimage[y_axs]] - mpv.HydroState.p20[nlast[y_axs]]) * ud.Msq + if hasattr(ud, "LAMB_BDRY"): + dpi = ( + mpv.HydroState.p20[nimage[y_axs]] + - mpv.HydroState.p20[nlast[y_axs]] + ) * ud.Msq else: - dpi = direction * (th.Gamma*g) * 0.5 * elem.dy * (1.0 / Y_last + S) - - rhoY = ((Sol.rhoY[nlast]**th.gm1) + dpi)**th.gm1inv if ud.is_compressible == 1 else mpv.HydroState.rhoY0[nimage[y_axs]] + dpi = ( + direction + * (th.Gamma * g) + * 0.5 + * elem.dy + * (1.0 / Y_last + S) + ) + + rhoY = ( + ((Sol.rhoY[nlast] ** th.gm1) + dpi) ** th.gm1inv + if ud.is_compressible == 1 + else mpv.HydroState.rhoY0[nimage[y_axs]] + ) rho = rhoY * S Y_source = Sol.rhoY[nsource] / Sol.rho[nsource] Y_image = rhoY / rho - if hasattr(ud, 'LAMB_BDRY'): - if direction > 0: # if bottom boundary + if hasattr(ud, "LAMB_BDRY"): + if direction > 0: # if bottom boundary v = Sol.rhov[nsource] * Y_source / Sol.rho[nsource] * rho - else: # if top boundary - v = Sol.rhov[nsource] * Y_source + else: # if top boundary + v = Sol.rhov[nsource] * Y_source Th_slc = rhoY / rho / Y_last @@ -119,20 +137,20 @@ def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): # v = -Sol.rhov[nsource] / Sol.rho[nsource] Sol.rho[nimage] = rho - Sol.rhou[nimage] = rho*u * Th_slc + Sol.rhou[nimage] = rho * u * Th_slc # Sol.rhov[nimage] = 0.0#rho*v - if hasattr(ud, 'LAMB_BDRY'): + if hasattr(ud, "LAMB_BDRY"): Sol.rhov[nimage] = -v / Y_image else: - Sol.rhov[nimage] = rho*v - Sol.rhow[nimage] = rho*w * Th_slc + Sol.rhov[nimage] = rho * v + Sol.rhow[nimage] = rho * w * Th_slc Sol.rhoY[nimage] = rhoY Sol.rhoX[nimage] = rho * X offset += 1 -def set_boundary(Sol,pads,btype,idx,step=None): +def set_boundary(Sol, pads, btype, idx, step=None): """ Called by the function :func:`inputs.boundary.set_explicit_boundary_data`. Pads in-place the ghost cells for a given boundary type. @@ -153,27 +171,27 @@ def set_boundary(Sol,pads,btype,idx,step=None): If we are in the advection routine with the flipped arrays according to the directional Strang-splitting, we want to pad the correct direction. `step=0`, pads the x-direction while `step=1` pads the y-direction. """ - Sol.rho[...] = np.pad(Sol.rho[idx],pads,btype) + Sol.rho[...] = np.pad(Sol.rho[idx], pads, btype) # Sol.rhou[...] = np.pad(Sol.rhou[idx],pads,btype) # Sol.rhov[...] = np.pad(Sol.rhov[idx],pads,btype) # Sol.rhow[...] = np.pad(Sol.rhow[idx],pads,btype) - if btype == 'symmetric': + if btype == "symmetric": # Sol.rhou[...] = np.pad(Sol.rhou[idx],pads,negative_symmetric) - Sol.rhov[...] = np.pad(Sol.rhov[idx],pads,negative_symmetric) + Sol.rhov[...] = np.pad(Sol.rhov[idx], pads, negative_symmetric) # Sol.rhow[...] = np.pad(Sol.rhow[idx],pads,negative_symmetric) - Sol.rho[...] = np.pad(Sol.rho[idx],pads,'symmetric') - Sol.rhou[...] = np.pad(Sol.rhou[idx],pads,'symmetric') - elif btype == 'constant': - Sol.rho[...] = np.pad(Sol.rho[idx],pads,'symmetric') - Sol.rhou[...] = np.pad(Sol.rhou[idx],pads,'symmetric') - Sol.rhov[...] = np.pad(Sol.rhov[idx],pads,btype) - Sol.rhow[...] = np.pad(Sol.rhow[idx],pads,'symmetric') - btype = 'symmetric' + Sol.rho[...] = np.pad(Sol.rho[idx], pads, "symmetric") + Sol.rhou[...] = np.pad(Sol.rhou[idx], pads, "symmetric") + elif btype == "constant": + Sol.rho[...] = np.pad(Sol.rho[idx], pads, "symmetric") + Sol.rhou[...] = np.pad(Sol.rhou[idx], pads, "symmetric") + Sol.rhov[...] = np.pad(Sol.rhov[idx], pads, btype) + Sol.rhow[...] = np.pad(Sol.rhow[idx], pads, "symmetric") + btype = "symmetric" else: - Sol.rhou[...] = np.pad(Sol.rhou[idx],pads,btype) - Sol.rhov[...] = np.pad(Sol.rhov[idx],pads,btype) - Sol.rhow[...] = np.pad(Sol.rhow[idx],pads,btype) + Sol.rhou[...] = np.pad(Sol.rhou[idx], pads, btype) + Sol.rhov[...] = np.pad(Sol.rhov[idx], pads, btype) + Sol.rhow[...] = np.pad(Sol.rhow[idx], pads, btype) # if step == 0: # Sol.rhov[...] = np.pad(Sol.rhov[idx],pads,btype) @@ -212,11 +230,11 @@ def set_boundary(Sol,pads,btype,idx,step=None): # Sol.rhov[...] = np.pad(Sol.rhov[idx],pads,btype) # Sol.rhow[...] = np.pad(Sol.rhow[idx],pads,btype) - Sol.rhoY[...] = np.pad(Sol.rhoY[idx],pads,btype) - Sol.rhoX[...] = np.pad(Sol.rhoX[idx],pads,btype) + Sol.rhoY[...] = np.pad(Sol.rhoY[idx], pads, btype) + Sol.rhoX[...] = np.pad(Sol.rhoX[idx], pads, btype) -def negative_symmetric(vector,pad_width,iaxis,kwargs=None): +def negative_symmetric(vector, pad_width, iaxis, kwargs=None): """ Taken from the reference: @@ -238,14 +256,14 @@ def negative_symmetric(vector,pad_width,iaxis,kwargs=None): """ if pad_width[1] > 0: sign = -1 - vector[:pad_width[0]] = sign * vector[pad_width[0]:2*pad_width[0]][::-1] - vector[-pad_width[1]:] = sign * vector[-2*pad_width[1]:-pad_width[1]][::-1] + vector[: pad_width[0]] = sign * vector[pad_width[0] : 2 * pad_width[0]][::-1] + vector[-pad_width[1] :] = sign * vector[-2 * pad_width[1] : -pad_width[1]][::-1] return vector - else: # axis must have length > 0 for padding + else: # axis must have length > 0 for padding return vector -def get_gravity_padding(ndim,cur_idx,direction,offset,elem,y_axs=None): +def get_gravity_padding(ndim, cur_idx, direction, offset, elem, y_axs=None): """ Parameters ---------- @@ -264,7 +282,7 @@ def get_gravity_padding(ndim,cur_idx,direction,offset,elem,y_axs=None): """ cur_i = np.copy(cur_idx) - cur_idx += offset * ((elem.icy - 1) - 2*cur_idx) + cur_idx += offset * ((elem.icy - 1) - 2 * cur_idx) gravity_padding = [(slice(None))] * ndim if y_axs == None: # y_axs = ndim - 1 @@ -274,43 +292,46 @@ def get_gravity_padding(ndim,cur_idx,direction,offset,elem,y_axs=None): nlast[y_axs] = int(cur_idx + direction) nsource = np.copy(gravity_padding) - nsource[y_axs] = int(offset*(elem.icy) + direction * (2 * elem.igy - (1 - offset) - cur_i)) + nsource[y_axs] = int( + offset * (elem.icy) + direction * (2 * elem.igy - (1 - offset) - cur_i) + ) nimage = np.copy(gravity_padding) nimage[y_axs] = int(cur_idx) return tuple(nlast), tuple(nsource), tuple(nimage) -def set_ghostcells_p2(p,elem,ud): +def set_ghostcells_p2(p, elem, ud): igs = elem.igs - + for dim in range(elem.ndim): - ghost_padding, idx = get_ghost_padding(elem.ndim,dim,igs) + ghost_padding, idx = get_ghost_padding(elem.ndim, dim, igs) if ud.bdry_type[dim] == opts.BdryType.PERIODIC: - p[...] = np.pad(p[idx],ghost_padding,'wrap') - else: # WALL - p[...] = np.pad(p[idx],ghost_padding,'symmetric') + p[...] = np.pad(p[idx], ghost_padding, "wrap") + else: # WALL + p[...] = np.pad(p[idx], ghost_padding, "symmetric") -def set_ghostnodes_p2(p,node,ud, igs=None): - if igs is None: igs = node.igs +def set_ghostnodes_p2(p, node, ud, igs=None): + if igs is None: + igs = node.igs for dim in range(node.ndim): - ghost_padding, idx = get_ghost_padding(node.ndim,dim,igs) + ghost_padding, idx = get_ghost_padding(node.ndim, dim, igs) if ud.bdry_type[dim] == opts.BdryType.PERIODIC: p[...] = np.pad(p[idx], ghost_padding, periodic_plus_one) - else: # ud.bdry_type[dim] == opts.BdryType.WALL: - p[...] = np.pad(p[idx], ghost_padding, 'reflect') + else: # ud.bdry_type[dim] == opts.BdryType.WALL: + p[...] = np.pad(p[idx], ghost_padding, "reflect") - # if periodic_plus_one - if node.iicy == 2: # implying horizontal slices - pn = p[:,2,:] + # if periodic_plus_one + if node.iicy == 2: # implying horizontal slices + pn = p[:, 2, :] pn = np.expand_dims(pn, axis=1) p[...] = np.repeat(pn, node.icy, axis=1) -def get_ghost_padding(ndim,dim,igs): +def get_ghost_padding(ndim, dim, igs): """ For a given direction, return the number of ghost cells to pad the current direction, and the index slice of the inner array without the ghost cells. @@ -331,18 +352,18 @@ def get_ghost_padding(ndim,dim,igs): Index slice of the inner domain of the array. """ - ghost_padding = [(0,0)] * ndim - ghost_padding[dim] = (igs[dim],igs[dim]) + ghost_padding = [(0, 0)] * ndim + ghost_padding[dim] = (igs[dim], igs[dim]) padded_idx = np.empty((ndim), dtype=object) for idim in range(ndim): - padded_idx[idim] = slice(igs[idim],-igs[idim]) + padded_idx[idim] = slice(igs[idim], -igs[idim]) padded_idx[dim] = slice(None) inner_domain = [slice(None)] * ndim - inner_domain[dim] = slice(igs[dim],-igs[dim]) + inner_domain[dim] = slice(igs[dim], -igs[dim]) - return tuple(ghost_padding), tuple(inner_domain) + return tuple(ghost_padding), tuple(inner_domain) def periodic_plus_one(vector, pad_width, iaxis, kwargs=None): @@ -365,7 +386,10 @@ def periodic_plus_one(vector, pad_width, iaxis, kwargs=None): """ if all(pad_width) > 0: - vector[:pad_width[0]+1], vector[-pad_width[1]-1:] = vector[-pad_width[1]-pad_width[1]-1:-pad_width[1]] , vector[pad_width[0]:pad_width[0]+pad_width[0]+1].copy() + vector[: pad_width[0] + 1], vector[-pad_width[1] - 1 :] = ( + vector[-pad_width[1] - pad_width[1] - 1 : -pad_width[1]], + vector[pad_width[0] : pad_width[0] + pad_width[0] + 1].copy(), + ) return vector @@ -374,7 +398,7 @@ def get_tau_y(ud, elem, node, alpha): taun_y = np.zeros_like(node.y) # ud.bcy = elem.y[-ud.inbcy-2] - ud.bny = node.y[-ud.inbcy-3] + ud.bny = node.y[-ud.inbcy - 3] # ud.bny = ud.bcy # c1c = elem.y <= ud.bcy @@ -394,8 +418,22 @@ def get_tau_y(ud, elem, node, alpha): # tauc_y[np.where(c3c)] = - alpha / 2.0 * (1.0 + ((elem.y[np.where(c3c)] - ud.bcy) / (elem.y[-1] - ud.bcy) - 0.5) * np.pi) taun_y[np.where(c1n)] = 0.0 - taun_y[np.where(c2n)] = - alpha / 2.0 * (1.0 - np.cos( (node.y[np.where(c2n)] - ud.bny) / (node.y[-1] - ud.bny) * np.pi )) - taun_y[np.where(c3n)] = - alpha / 2.0 * (1.0 + ((node.y[np.where(c3n)] - ud.bny) / (node.y[-1] - ud.bny) - 0.5) * np.pi) + taun_y[np.where(c2n)] = ( + -alpha + / 2.0 + * ( + 1.0 + - np.cos((node.y[np.where(c2n)] - ud.bny) / (node.y[-1] - ud.bny) * np.pi) + ) + ) + taun_y[np.where(c3n)] = ( + -alpha + / 2.0 + * ( + 1.0 + + ((node.y[np.where(c3n)] - ud.bny) / (node.y[-1] - ud.bny) - 0.5) * np.pi + ) + ) taun_y[-2:] = -np.abs(taun_y).max() tauc_y[...] = np.interp(elem.y, node.y, taun_y) @@ -420,8 +458,30 @@ def get_bottom_tau_y(ud, elem, node, alpha, cutoff=0.5): c3n = np.logical_and(ccn > 0.5, ccn <= 1.0) taun_y[np.where(c1n)] = 0.0 - taun_y[np.where(c2n)] = - alpha / 2.0 * (1.0 - np.cos( (node.y[np.where(c2n)] - ud.forcing_bny) / (node.y[-1] - ud.forcing_bny) * np.pi )) - taun_y[np.where(c3n)] = - alpha / 2.0 * (1.0 + ((node.y[np.where(c3n)] - ud.forcing_bny) / (node.y[-1] - ud.forcing_bny) - 0.5) * np.pi) + taun_y[np.where(c2n)] = ( + -alpha + / 2.0 + * ( + 1.0 + - np.cos( + (node.y[np.where(c2n)] - ud.forcing_bny) + / (node.y[-1] - ud.forcing_bny) + * np.pi + ) + ) + ) + taun_y[np.where(c3n)] = ( + -alpha + / 2.0 + * ( + 1.0 + + ( + (node.y[np.where(c3n)] - ud.forcing_bny) / (node.y[-1] - ud.forcing_bny) + - 0.5 + ) + * np.pi + ) + ) taun_y[-3:] = -np.abs(taun_y).max() taun_y[...] = taun_y[::-1] @@ -437,27 +497,26 @@ def get_bottom_tau_y(ud, elem, node, alpha, cutoff=0.5): return tauc_y, taun_y - def rayleigh_damping(Sol, mpv, ud, elem, node, forcing=None): - u = (Sol.rhou / Sol.rho)#[elem.i2] - v = (Sol.rhov / Sol.rho)#[elem.i2] - Y = (Sol.rhoY / Sol.rho)#[elem.i2] - rho = Sol.rho#[elem.i2] + u = Sol.rhou / Sol.rho # [elem.i2] + v = Sol.rhov / Sol.rho # [elem.i2] + Y = Sol.rhoY / Sol.rho # [elem.i2] + rho = Sol.rho # [elem.i2] if ud.bdry_type[1] == opts.BdryType.RAYLEIGH: tcy, tny = ud.tcy, ud.tny else: tcy, tny = 0.0, 0.0 - if (forcing is not None): + if forcing is not None: tcy_f, tny_f = ud.forcing_tcy, ud.forcing_tny tcy, tny = 0.0, 0.0 u_f, v_f, Y_f, pi_f, t = forcing - if ud.rayleigh_forcing_type == 'file': - G = np.sqrt( 9.0 / 40.0 ) - N = np.sqrt(ud.Nsq_ref) + if ud.rayleigh_forcing_type == "file": + G = np.sqrt(9.0 / 40.0) + N = np.sqrt(ud.Nsq_ref) C = ud.Cs * ud.u_ref Gam = N * G / C Om = ud.coriolis_strength[2] / 2.0 / ud.t_ref @@ -467,7 +526,7 @@ def rayleigh_damping(Sol, mpv, ud, elem, node, forcing=None): # if np.all(ud.coriolis_strength) == 0.0: # if ud.trad_forcing: - # mfac = 1.0 + # mfac = 1.0 else: mfac = 1.0 @@ -481,10 +540,14 @@ def rayleigh_damping(Sol, mpv, ud, elem, node, forcing=None): mfac = 0.0 # assuming 2D vertical slice - not dimension agnostic - u += tcy * (u - ud.u_wind_speed) + c_f * (tcy_f * (u - ud.u_wind_speed) + np.abs(tcy_f) * mfac * u_f) - v += tcy * (v - ud.v_wind_speed) + c_f * (tcy_f * (v - ud.v_wind_speed) + np.abs(tcy_f) * mfac * v_f) - - Ybar = mpv.HydroState.Y0.reshape(1,-1) + u += tcy * (u - ud.u_wind_speed) + c_f * ( + tcy_f * (u - ud.u_wind_speed) + np.abs(tcy_f) * mfac * u_f + ) + v += tcy * (v - ud.v_wind_speed) + c_f * ( + tcy_f * (v - ud.v_wind_speed) + np.abs(tcy_f) * mfac * v_f + ) + + Ybar = mpv.HydroState.Y0.reshape(1, -1) Y += tcy * (Y - Ybar) + c_f * (tcy_f * (Y - Ybar) + np.abs(tcy_f) * mfac * Y_f) Sol.rhou[...] = rho * u @@ -492,23 +555,23 @@ def rayleigh_damping(Sol, mpv, ud, elem, node, forcing=None): Sol.rhoY[...] = rho * Y - def check_flux_bcs(Lefts, Rights, elem, split_step, ud): igx = elem.igx igy = elem.igy if split_step == 1: if ud.bdry_type[split_step] == opts.BdryType.WALL: + left_inner = (slice(None), slice(igy, igy + 1)) + left_ghost = (slice(None), slice(igy - 1, igy)) - left_inner = (slice(None),slice(igy,igy+1)) - left_ghost = (slice(None),slice(igy-1,igy)) + right_inner = (slice(None), slice(-igy - 1, -igy)) + right_ghost = (slice(None), slice(-igy, -igy + 1)) - right_inner = (slice(None),slice(-igy-1,-igy)) - right_ghost = (slice(None),slice(-igy,-igy+1)) - - rhou_wall = 0. + rhou_wall = 0.0 # Lefts.rhou[left_ghost] = Rights.rhou[left_inner] = rhou_wall - Lefts.rhoY[left_ghost] = Rights.rhoY[left_inner] = Rights.rho[left_inner] * ud.stratification(0.0) + Lefts.rhoY[left_ghost] = Rights.rhoY[left_inner] = Rights.rho[ + left_inner + ] * ud.stratification(0.0) Lefts.rho[left_ghost] = Rights.rho[left_inner] Lefts.rhov[left_ghost] = Rights.rhov[left_inner] @@ -516,25 +579,24 @@ def check_flux_bcs(Lefts, Rights, elem, split_step, ud): Lefts.rhoX[left_ghost] = Rights.rhoX[left_inner] Rights.rho[right_ghost] = Lefts.rho[right_inner] - Rights.rhou[right_ghost] = -1. * Lefts.rhou[right_inner] + Rights.rhou[right_ghost] = -1.0 * Lefts.rhou[right_inner] Rights.rhov[right_ghost] = Lefts.rhov[right_inner] Rights.rhow[right_ghost] = Lefts.rhow[right_inner] Rights.rhoY[right_ghost] = Lefts.rhoY[right_inner] else: if ud.bdry_type[split_step] == opts.BdryType.WALL: - - assert(0) # INCOMPLETE!!! - Lefts.rho[left_inner] = Rights.rho[:,igx-2] - Lefts.rhou[left_inner] = -1. * Rights.rhou[:,igx-2] - Lefts.rhov[left_inner] = Rights.rhov[:,igx-2] - Lefts.rhow[left_inner] = Rights.rhow[:,igx-2] - Lefts.rhoY[left_inner] = Rights.rhoY[:,igx-2] + assert 0 # INCOMPLETE!!! + Lefts.rho[left_inner] = Rights.rho[:, igx - 2] + Lefts.rhou[left_inner] = -1.0 * Rights.rhou[:, igx - 2] + Lefts.rhov[left_inner] = Rights.rhov[:, igx - 2] + Lefts.rhow[left_inner] = Rights.rhow[:, igx - 2] + Lefts.rhoY[left_inner] = Rights.rhoY[:, igx - 2] # print("#################### TRUE ########################") - Rights.rho[right_ghost] = Lefts.rho[:,-igx-2] - Rights.rhou[right_ghost] = -1. * Lefts.rhou[:,-igx-2] - Rights.rhov[right_ghost] = Lefts.rhov[:,-igx-2] - Rights.rhow[right_ghost] = Lefts.rhow[:,-igx-2] - Rights.rhoY[right_ghost] = Lefts.rhoY[:,-igx-2] - # print(Rights.rhoY[right_ghost]) \ No newline at end of file + Rights.rho[right_ghost] = Lefts.rho[:, -igx - 2] + Rights.rhou[right_ghost] = -1.0 * Lefts.rhou[:, -igx - 2] + Rights.rhov[right_ghost] = Lefts.rhov[:, -igx - 2] + Rights.rhow[right_ghost] = Lefts.rhow[:, -igx - 2] + Rights.rhoY[right_ghost] = Lefts.rhoY[:, -igx - 2] + # print(Rights.rhoY[right_ghost]) diff --git a/src/flow_solver/utils/options.py b/src/flow_solver/utils/options.py index 3c56a361..621bea7a 100644 --- a/src/flow_solver/utils/options.py +++ b/src/flow_solver/utils/options.py @@ -1,4 +1,4 @@ -from enum import Enum # ! Version > Python 3.4 +from enum import Enum # ! Version > Python 3.4 # class RecoveryOrder(Enum): # FIRST = 0 @@ -27,6 +27,7 @@ # ZERO_ORDER_EXTRAPOL = 0 # BOTTOM_BC_DEFAULT = 1 + class LimiterType(Enum): NONE = 0 # MINMOD = 1 @@ -39,11 +40,12 @@ class LimiterType(Enum): # NO_SLOPE = 8 # NUMBER_OF_LIMITER = 9 + class BdryType(Enum): """ An enumeration class that defines the accepted boundary condition types. """ - - WALL = 'symmetric' - PERIODIC = 'wrap' - RAYLEIGH = 'radiation' \ No newline at end of file + + WALL = "symmetric" + PERIODIC = "wrap" + RAYLEIGH = "radiation" diff --git a/src/flow_solver/utils/solver_diagnostics.py b/src/flow_solver/utils/solver_diagnostics.py index 79927d18..3feb31cf 100644 --- a/src/flow_solver/utils/solver_diagnostics.py +++ b/src/flow_solver/utils/solver_diagnostics.py @@ -1,6 +1,7 @@ import numpy as np import scipy as sp + def get_p_from_pressure_related_fields(mem, ud, psinc=False): p2n = mem.mpv.p2_nodes rhoY = mem.sol.rhoY @@ -8,15 +9,15 @@ def get_p_from_pressure_related_fields(mem, ud, psinc=False): th = mem.th - kernel = np.ones((2,2)) - dp2c = sp.signal.fftconvolve(dp2n, kernel, mode='valid') / kernel.sum() + kernel = np.ones((2, 2)) + dp2c = sp.signal.fftconvolve(dp2n, kernel, mode="valid") / kernel.sum() if psinc: - P0 = (rhoY**(th.gamm-1.0) + dp2c)**(1.0/(th.gamm-1.0)) - p = P0**(th.gamm) + P0 = (rhoY ** (th.gamm - 1.0) + dp2c) ** (1.0 / (th.gamm - 1.0)) + p = P0 ** (th.gamm) else: - P0 = (rhoY**(th.gamm-1.0) - dp2c)**(1.0/(th.gamm-1.0)) - p = rhoY**(th.gamm) - P0**(th.gamm) + P0 = (rhoY ** (th.gamm - 1.0) - dp2c) ** (1.0 / (th.gamm - 1.0)) + p = rhoY ** (th.gamm) - P0 ** (th.gamm) # non-dimensionalised p/p_ref - return p \ No newline at end of file + return p diff --git a/src/flow_solver/utils/variable.py b/src/flow_solver/utils/variable.py index b14674ec..e45eab43 100644 --- a/src/flow_solver/utils/variable.py +++ b/src/flow_solver/utils/variable.py @@ -7,7 +7,8 @@ class Vars(object): The data container for the solution state variables, i.e. `Sol`. """ - def __init__(self,size,ud): + + def __init__(self, size, ud): """ Parameters ---------- @@ -28,7 +29,7 @@ def __init__(self,size,ud): Notes ----- 2. `rhoX` has to be extended by `ud.nspec` for moist process. - + """ self.rho = np.zeros((size)) self.rhou = np.zeros((size)) @@ -45,10 +46,11 @@ def squeezer(self): """ for key, value in vars(self).items(): - setattr(self,key,value.squeeze()) + setattr(self, key, value.squeeze()) + # method written for 2D - def primitives(self,th): + def primitives(self, th): """ Calculate the primitive quantities from the state variables and extend the data container to include these quantities. @@ -65,7 +67,7 @@ def primitives(self,th): Y : ndarray(size_of_rhoY) X : ndarray(size_of_rhoX) p : ndarray(size_of_rhoY) - + """ nonzero_idx = np.nonzero(self.rho) @@ -83,44 +85,45 @@ def primitives(self,th): self.w[nonzero_idx] = self.rhow[nonzero_idx] / self.rho[nonzero_idx] self.Y[nonzero_idx] = self.rhoY[nonzero_idx] / self.rho[nonzero_idx] self.X[nonzero_idx] = self.rhoX[nonzero_idx] / self.rho[nonzero_idx] - self.p[nonzero_idx] = self.rhoY[nonzero_idx]**th.gamm + self.p[nonzero_idx] = self.rhoY[nonzero_idx] ** th.gamm def flip(self): """ Flips the solution variables arrays for the advection routine. `rhou` and `rhov` are also flipped, i.e.:: - self.rhou, self.rhov = self.rhov, self.rhou + self.rhou, self.rhov = self.rhov, self.rhou """ for key, value in vars(self).items(): - setattr(self,key,value.T) + setattr(self, key, value.T) self.rhou, self.rhov = self.rhov, self.rhou def flip_forward(self): for key, value in vars(self).items(): - setattr(self,key,np.moveaxis(value,0,-1)) + setattr(self, key, np.moveaxis(value, 0, -1)) def flip_backward(self): for key, value in vars(self).items(): - setattr(self,key,np.moveaxis(value,-1,0)) - + setattr(self, key, np.moveaxis(value, -1, 0)) def mod_bg_wind(self, ud, fac): u0 = ud.u_wind_speed v0 = ud.v_wind_speed w0 = ud.w_wind_speed - + self.rhou = self.rhou + fac * u0 * self.rho self.rhov = self.rhov + fac * v0 * self.rho self.rhow = self.rhow + fac * w0 * self.rho - + + class States(Vars): """ Data container for `Lefts` and `Rights` for the Riemann solver. Inherits the solution class :class:`management.variable.Vars`. """ - def __init__(self,size,ud): + + def __init__(self, size, ud): """ Parameters ---------- @@ -134,7 +137,7 @@ def __init__(self,size,ud): Many variables in this data container are no longer used and can be removed. """ - super().__init__(size,ud) + super().__init__(size, ud) self.u = np.zeros((size)) self.v = np.zeros((size)) self.w = np.zeros((size)) @@ -159,19 +162,17 @@ def __init__(self,size,ud): self.get_dSdy = self.get_dSdy self.get_S0c = self.get_S0c - - def get_dSdy(self, elem, node): - if hasattr(self, 'dSdy'): + if hasattr(self, "dSdy"): return self.dSdy else: ndim = node.ndim dy = node.dy dSdy = self.S0 - dSdy = sp.signal.convolve(dSdy,[1.,-1.],mode='valid') / dy + dSdy = sp.signal.convolve(dSdy, [1.0, -1.0], mode="valid") / dy - for dim in range(0,ndim,2): + for dim in range(0, ndim, 2): dSdy = np.expand_dims(dSdy, dim) dSdy = np.repeat(dSdy, elem.sc[dim], axis=dim) @@ -179,13 +180,13 @@ def get_dSdy(self, elem, node): return dSdy def get_S0c(self, elem): - if hasattr(self, 'S0c'): + if hasattr(self, "S0c"): return self.S0c else: ndim = elem.ndim S0c = self.S0 - for dim in range(0,ndim,2): + for dim in range(0, ndim, 2): S0c = np.expand_dims(S0c, dim) S0c = np.repeat(S0c, elem.sc[dim], axis=dim) @@ -198,6 +199,7 @@ class Characters(object): Data container for the slope and amplitude of the interpolation to the faces for the Riemann solver. """ + def __init__(self, size): """ Parameters diff --git a/src/inputs/rising_bubble.py b/src/inputs/rising_bubble.py index d16f2c4d..30e86cec 100644 --- a/src/inputs/rising_bubble.py +++ b/src/inputs/rising_bubble.py @@ -2,25 +2,26 @@ from ..flow_solver.physics import hydrostatics from ..flow_solver.utils import boundary as bdry + class UserData(object): # Nsq_ref = grav * 1.3e-05 def __init__(self): - self.grav = 10.0 # [m/s^2] - self.t_ref = 1000.0 # [s] + self.grav = 10.0 # [m/s^2] + self.t_ref = 1000.0 # [s] ########################################## # NUMERICS ########################################## - self.CFL = 0.5 + self.CFL = 0.5 self.dtfixed0 = 100.0 self.dtfixed = 100.0 - self.inx = 160+1 - self.iny = 80+1 + self.inx = 160 + 1 + self.iny = 80 + 1 self.inz = 1 - self.tout = np.arange(0.0,1.01,0.01)[10:] + self.tout = np.arange(0.0, 1.01, 0.01)[10:] self.stepmax = 10000 self.output_base_name = "_rising_bubble" @@ -30,8 +31,8 @@ def __init__(self): # self.output_suffix = "_%i_%i_%.1f_psinc" %(self.inx-1,self.iny-1,self.tout[-1]) # if self.continuous_blending == True: # self.output_suffix = "_%i_%i_%.1f" %(self.inx-1,self.iny-1,self.tout[-1]) - - aux = 'debug_imbal_CFLfixed' + + aux = "debug_imbal_CFLfixed" self.aux = aux # self.output_suffix = "_%i_%i_%.1f_%s" %(self.inx-1,self.iny-1,self.tout[-1],aux) # self.output_suffix += '_w=%i-%i' %(self.blending_weight*16.0,16.0-(self.blending_weight*16.0)) @@ -41,8 +42,8 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): u0 = ud.u_wind_speed v0 = ud.v_wind_speed w0 = ud.w_wind_speed - delth = 2.0 # [K] - + delth = 2.0 # [K] + y0 = 0.2 r0 = 0.2 @@ -54,26 +55,26 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): x = elem.x y = elem.y - x, y = np.meshgrid(x,y) + x, y = np.meshgrid(x, y) if seed != None: np.random.seed(seed) # y0 += (np.random.random()-.5)/2.0 # delth += 10.0*(np.random.random()-.5) - delth += 10.0*(np.random.random()) - - if 'truth' in ud.aux: + delth += 10.0 * (np.random.random()) + + if "truth" in ud.aux: np.random.seed(1234) # delth += 10.0*(np.random.random()-.5) - delth += 10.0*(np.random.random()) + delth += 10.0 * (np.random.random()) print(delth) - - r = np.sqrt((x)**2 + (y-y0)**2) / r0 - p = np.repeat(mpv.HydroState.p0.reshape(1,-1),elem.icx,axis=0) - rhoY = np.repeat(mpv.HydroState.rhoY0.reshape(1,-1),elem.icx,axis=0) + r = np.sqrt((x) ** 2 + (y - y0) ** 2) / r0 + + p = np.repeat(mpv.HydroState.p0.reshape(1, -1), elem.icx, axis=0) + rhoY = np.repeat(mpv.HydroState.rhoY0.reshape(1, -1), elem.icx, axis=0) - perturbation = (delth/300.0) * (np.cos(0.5 * np.pi * r)**2) + perturbation = (delth / 300.0) * (np.cos(0.5 * np.pi * r) ** 2) perturbation[np.where(r > 1.0)] = 0.0 rho = rhoY / (ud.stratification(y) + perturbation.T) @@ -82,16 +83,16 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): u, v, w = u0, v0, w0 - Sol.rho[x_idx,y_idx] = rho - Sol.rhou[x_idx,y_idx] = rho * u - Sol.rhov[x_idx,y_idx] = rho * v - Sol.rhow[x_idx,y_idx] = rho * w - Sol.rhoY[x_idx,y_idx] = rhoY + Sol.rho[x_idx, y_idx] = rho + Sol.rhou[x_idx, y_idx] = rho * u + Sol.rhov[x_idx, y_idx] = rho * v + Sol.rhow[x_idx, y_idx] = rho * w + Sol.rhoY[x_idx, y_idx] = rhoY p = mpv.HydroState_n.p0[0] rhoY = mpv.HydroState_n.rhoY0[0] mpv.p2_nodes[...] = (p - mpv.HydroState_n.p0[0]) / rhoY / ud.Msq - bdry.set_explicit_boundary_data(Sol,elem,ud,th,mpv) + bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - return Sol \ No newline at end of file + return Sol diff --git a/src/interfaces/dynamics_blending/prepare.py b/src/interfaces/dynamics_blending/prepare.py index 0bc913d7..65e4dc36 100644 --- a/src/interfaces/dynamics_blending/prepare.py +++ b/src/interfaces/dynamics_blending/prepare.py @@ -1,5 +1,6 @@ from . import schemes + def initialise(sst): bld = schemes.Blend(sst.ud) @@ -9,7 +10,9 @@ def initialise(sst): def init_da_window(sst, tout_old, outer_step): # In ensemble case, do blending for each DA window if sst.N > 1: - blend = sst.interface_params.bld if tout_old in sst.da_params.dap.da_times else None + blend = ( + sst.interface_params.bld if tout_old in sst.da_params.dap.da_times else None + ) else: blend = sst.interface_params.bld @@ -17,4 +20,4 @@ def init_da_window(sst, tout_old, outer_step): if sst.ud.initial_blending == True and (outer_step == 0 or outer_step == 1): blend = sst.interface_params.bld - return blend \ No newline at end of file + return blend diff --git a/src/interfaces/dynamics_blending/schemes.py b/src/interfaces/dynamics_blending/schemes.py index b0071348..c06d61b8 100644 --- a/src/interfaces/dynamics_blending/schemes.py +++ b/src/interfaces/dynamics_blending/schemes.py @@ -6,6 +6,7 @@ from ...flow_solver.physics.gas_dynamics import eos as gd_eos + class Blend(object): """ Class that takes care of the blending interface. @@ -55,7 +56,7 @@ def update_sol(self, mem, ud, sgn, label=None, writer=None): Sol = mem.sol mpv = mem.mpv - th = mem.th + th = mem.th if sgn == "bef": sign = -1.0 @@ -118,7 +119,13 @@ def do_comp_to_psinc_conv(mem, bld, ud, label, writer): def do_psinc_to_comp_conv( - sst, mem, bld, label, writer, step, tout, + sst, + mem, + bld, + label, + writer, + step, + tout, ): from ...flow_solver.discretisation import time_update @@ -296,7 +303,6 @@ def do_lake_to_swe_conv( def do_nonhydro_to_hydro_conv( Sol, flux, mpv, bld, elem, node, th, ud, label, writer, step, window_step, t, dt ): - logging.info("nonhydrostatic to hydrostatic conversion...") # bld.convert_p2n(mpv.p2_nodes) # bld.update_Sol(Sol,elem,node,th,ud,mpv,'bef',label=label,writer=writer) @@ -326,7 +332,6 @@ def do_nonhydro_to_hydro_conv( def do_hydro_to_nonhydro_conv( Sol, flux, mpv, bld, elem, node, th, ud, label, writer, step, window_step, t, dt ): - logging.info("hydrostatic to nonhydrostatic conversion...") logging.info(f"Blending... step = {step}") @@ -414,9 +419,7 @@ def blending_before_timestep( do_swe_to_lake_conv(Sol, mpv, elem, node, ud, th, writer, label, debug) swe_to_lake = True else: - mem = do_comp_to_psinc_conv( - mem, bld, ud, label, writer - ) + mem = do_comp_to_psinc_conv(mem, bld, ud, label, writer) ###################################################### # Blending : Do full steps or transition steps? @@ -454,9 +457,7 @@ def blending_before_timestep( if bld.psinc_init > 0: ud.is_compressible = 0 ud.compressibility = 0.0 - mem = do_comp_to_psinc_conv( - mem, bld, ud, label, writer - ) + mem = do_comp_to_psinc_conv(mem, bld, ud, label, writer) elif bld.hydro_init > 0: Sol, mpv, t = do_nonhydro_to_hydro_conv( Sol, diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index aa778761..e3d41451 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -7,10 +7,7 @@ from ..utils.data_structures import DiagnosticState from ..flow_solver.utils.solver_diagnostics import get_p_from_pressure_related_fields -from ..vis import ( - utils as vis_utils, - plotting_tools as vis_pt -) +from ..vis import utils as vis_utils, plotting_tools as vis_pt class CompareSol(object): @@ -57,30 +54,30 @@ def test_do(self, mem, ud, plot=False): else: test = mpv.p2_nodes.astype("float32").sum() - try: - assert ( - np.isclose(ref, test) - ), "sum for attribute %s of %s changed with discrepancy:\n%.16f\n%.16f" % ( - key, - self.current_run, - ref, - test, + assert np.isclose(ref, test), ( + "sum for attribute %s of %s changed with discrepancy:\n%.16f\n%.16f" + % ( + key, + self.current_run, + ref, + test, + ) ) logging.info(f"test passed for {key}") except AssertionError as e: logging.info(str(e)) raise - logging.info(f""" + logging.info( + f""" {'#' * 10} Test passed for {self.current_run} {'#' * 10} - """.strip()) - - def __init(self, ds: DiagnosticState - ): + """.strip() + ) + def __init(self, ds: DiagnosticState): tp = test_params(ds) self.tps = { @@ -92,7 +89,9 @@ def __get_tc(self): self.tcs = {} for test_name, test_param in self.tps.items(): fn = test_param.fn + ".h5" - tc = vis_utils.test_case(fn, test_param.dir, test_param.Nx, test_param.Ny, "") + tc = vis_utils.test_case( + fn, test_param.dir, test_param.Nx, test_param.Ny, "" + ) self.tcs[test_name] = tc @@ -106,11 +105,18 @@ def __plot_comparison(self, mem, ud): ref_mem = copy.deepcopy(mem) for attribute in tp.attributes: - if attribute != "p2_nodes": - setattr(ref_mem.sol, attribute, self.__get_ens(tc, tp, attribute, summed=False)) + setattr( + ref_mem.sol, + attribute, + self.__get_ens(tc, tp, attribute, summed=False), + ) else: - setattr(ref_mem.mpv, attribute, self.__get_ens(tc, tp, attribute, summed=False)) + setattr( + ref_mem.mpv, + attribute, + self.__get_ens(tc, tp, attribute, summed=False), + ) for attribute in tp.attributes: arr_plots = [] @@ -133,18 +139,18 @@ def __get_sol_for_comparison(mem, ud, attribute): Sol = mem.sol mpv = mem.mpv if attribute != "p2_nodes": - test_sol = getattr(Sol, attribute).T - if attribute != 'rho': - rho = getattr(Sol, 'rho').T + test_sol = np.copy(getattr(Sol, attribute).T) + if attribute != "rho": + rho = getattr(Sol, "rho").T test_sol /= rho # if attribute == 'rhoY': # test_sol -= mpv.HydroState.Y0[:,np.newaxis] else: - test_sol = mpv.p2_nodes.T * ud.Msq - test_sol -= mpv.HydroState_n.pi0[:,np.newaxis] - # test_sol = get_p_from_pressure_related_fields(mem, ud).T + # test_sol = mpv.p2_nodes.T * ud.Msq + # test_sol -= mpv.HydroState_n.pi0[:,np.newaxis] + test_sol = get_p_from_pressure_related_fields(mem, ud).T return test_sol @@ -180,10 +186,9 @@ def __get_ens(tc, params, attribute, summed=True, normed=False): class test_params(object): def __init__(self, ds: DiagnosticState): - self.name = ds.test_name self.dir = ds.path + ds.file_name + "/" - self.fn = f"{ds.file_name}_{ds.Nx}_{ds.Ny}" + self.fn = f"{ds.file_name}_{ds.Nx}_{ds.Ny}" self.Nx = ds.Nx self.Ny = ds.Ny diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 6be36e01..b6d365d3 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -4,25 +4,26 @@ from ..utils.data_structures import DiagnosticState + class UserData(object): # Nsq_ref = grav * 1.3e-05 def __init__(self): - self.grav = 10.0 # [m/s^2] - self.t_ref = 1000.0 # [s] + self.grav = 10.0 # [m/s^2] + self.t_ref = 1000.0 # [s] ########################################## # NUMERICS ########################################## - self.CFL = 0.9 - self.dtfixed0 = 1.0 - self.dtfixed = 1.0 + self.CFL = 0.9 + self.dtfixed0 = 100.0 + self.dtfixed = 100.0 - self.inx = 64+1 - self.iny = 48+1 + self.inx = 64 + 1 + self.iny = 48 + 1 self.inz = 1 - self.tout = [100.0] + self.tout = [1000.0] self.stepmax = 31 self.is_compressible = 1 @@ -41,10 +42,10 @@ def __init__(self): self.no_of_hy_transition = 0 self.initial_blending = False - + self.output_base_name = "_blending_warm_bubble" self.output_type = "test" - self.aux = '' + self.aux = "CFLfixed" self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) @@ -56,20 +57,21 @@ def __init__(self): self.diag_state = DiagnosticState( test_name="test_blending_warm_bubble", file_name="target_blending_warm_bubble", - Nx=self.inx-1, - Ny=self.iny-1, - steps=[self.stepmax-1], - plot_compare=True + Nx=self.inx - 1, + Ny=self.iny - 1, + steps=[self.stepmax - 1], + plot_compare=True, ) self.autogen_fn = False + def sol_init(Sol, mpv, elem, node, th, ud, seed=None): u0 = ud.u_wind_speed v0 = ud.v_wind_speed w0 = ud.w_wind_speed - delth = 2.0 # [K] - + delth = 2.0 # [K] + y0 = 0.2 r0 = 0.2 @@ -78,14 +80,16 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): x = elem.x y = elem.y - x, y = np.meshgrid(x,y) - - r = np.sqrt((x)**2 + (y-y0)**2) / r0 + x, y = np.meshgrid(x, y) + + r = np.sqrt((x) ** 2 + (y - y0) ** 2) / r0 - p = np.repeat(mpv.HydroState.p0.reshape(1,-1),elem.icx,axis=0) - rhoY = np.repeat(mpv.HydroState.rhoY0.reshape(1,-1),elem.icx,axis=0) + p = np.repeat(mpv.HydroState.p0.reshape(1, -1), elem.icx, axis=0) + rhoY = mpv.HydroState.rhoY0[ + np.newaxis, : + ] # np.repeat(mpv.HydroState.rhoY0.reshape(1,-1),elem.icx,axis=0) - perturbation = (delth/300.0) * (np.cos(0.5 * np.pi * r)**2) + perturbation = (delth / 300.0) * (np.cos(0.5 * np.pi * r) ** 2) perturbation[np.where(r > 1.0)] = 0.0 rho = rhoY / (ud.stratification(y) + perturbation.T) @@ -94,16 +98,16 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): u, v, w = u0, v0, w0 - Sol.rho[x_idx,y_idx] = rho - Sol.rhou[x_idx,y_idx] = rho * u - Sol.rhov[x_idx,y_idx] = rho * v - Sol.rhow[x_idx,y_idx] = rho * w - Sol.rhoY[x_idx,y_idx] = rhoY + Sol.rho[x_idx, y_idx] = rho + Sol.rhou[x_idx, y_idx] = rho * u + Sol.rhov[x_idx, y_idx] = rho * v + Sol.rhow[x_idx, y_idx] = rho * w + Sol.rhoY[x_idx, y_idx] = rhoY - p = mpv.HydroState_n.p0[0] - rhoY = mpv.HydroState_n.rhoY0[0] - mpv.p2_nodes[...] = 1.0 # (p - mpv.HydroState_n.p0[0]) / rhoY / ud.Msq + p = mpv.HydroState_n.p0 + rhoY = mpv.HydroState_n.rhoY0 + mpv.p2_nodes[...] = (p - mpv.HydroState_n.p0) / rhoY / ud.Msq - bdry.set_explicit_boundary_data(Sol,elem,ud,th,mpv) + bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - return Sol \ No newline at end of file + return Sol diff --git a/src/tests/test_internal_long_wave.py b/src/tests/test_internal_long_wave.py index ebd1dcd2..c4d609b0 100644 --- a/src/tests/test_internal_long_wave.py +++ b/src/tests/test_internal_long_wave.py @@ -1,14 +1,11 @@ import numpy as np -from ..flow_solver.utils import( - options as opts, - boundary as bdry, - variable as var -) +from ..flow_solver.utils import options as opts, boundary as bdry, variable as var from ..flow_solver.physics import hydrostatics from ..utils.data_structures import DiagnosticState + class UserData(object): NSPEC = 1 BUOY = 0 @@ -163,9 +160,9 @@ def __init__(self): self.diag_state = DiagnosticState( test_name="test_internal_long_wave", file_name="test_internal_long_wave", - Nx=self.inx-1, - Ny=self.iny-1, - steps=[self.stepmax-1], + Nx=self.inx - 1, + Ny=self.iny - 1, + steps=[self.stepmax - 1], ) def stratification_function(self, y): diff --git a/src/tests/test_lamb_wave.py b/src/tests/test_lamb_wave.py index ae71b1fa..ed7f24f6 100644 --- a/src/tests/test_lamb_wave.py +++ b/src/tests/test_lamb_wave.py @@ -1,33 +1,31 @@ import numpy as np -from ..flow_solver.utils import ( - options as opts, - boundary as bdry -) +from ..flow_solver.utils import options as opts, boundary as bdry from ..flow_solver.physics import hydrostatics -from .. utils.data_structures import DiagnosticState +from ..utils.data_structures import DiagnosticState + class UserData(object): NSPEC = 1 - grav = 9.81 # [m s^{-2}] - omega = 7.292 * 1e-5 # [s^{-1}] + grav = 9.81 # [m s^{-2}] + omega = 7.292 * 1e-5 # [s^{-1}] - R_gas = 287.4 # [J kg^{-1} K^{-1}] + R_gas = 287.4 # [J kg^{-1} K^{-1}] R_vap = 461.0 - Q_vap = 2.53e+06 + Q_vap = 2.53e06 gamma = 1.4 - cp_gas = gamma * R_gas / (gamma-1.0) + cp_gas = gamma * R_gas / (gamma - 1.0) - p_ref = 1e+5 - T_ref = 300.00 # [K] + p_ref = 1e5 + T_ref = 300.00 # [K] rho_ref = p_ref / (R_gas * T_ref) N_ref = grav / np.sqrt(cp_gas * T_ref) Cs = np.sqrt(gamma * R_gas * T_ref) - h_ref = 10.0e3 # [m] - t_ref = 100.0 # [s] + h_ref = 10.0e3 # [m] + t_ref = 100.0 # [s] u_ref = h_ref / t_ref i_gravity = np.zeros((3)) @@ -70,17 +68,17 @@ def __init__(self): self.i_gravity[i] = 1 self.gravity_direction = 1 - if (self.coriolis_strength[i] > np.finfo(np.float).eps): + if self.coriolis_strength[i] > np.finfo(np.float).eps: self.i_coriolis[i] = 1 j = 4.0 Lx = 1.0 * np.pi * self.Cs / self.N_ref * j - self.xmin = - Lx / self.h_ref - self.xmax = Lx / self.h_ref - self.ymin = - 0.0 - self.ymax = 2.0 - self.zmin = - 1.0 - self.zmax = 1.0 + self.xmin = -Lx / self.h_ref + self.xmax = Lx / self.h_ref + self.ymin = -0.0 + self.ymax = 2.0 + self.zmin = -1.0 + self.zmax = 1.0 self.u_wind_speed = 0.0 * self.u_ref self.v_wind_speed = 0.0 @@ -97,25 +95,25 @@ def __init__(self): ########################################## self.CFL = 0.9 - self.inx = 151+1 - self.iny = 15+1 + self.inx = 151 + 1 + self.iny = 15 + 1 self.inz = 1 self.dtfixed0 = 100.0 / self.t_ref self.dtfixed = self.dtfixed0 - + self.do_advection = False self.limiter_type_scalars = opts.LimiterType.NONE self.limiter_type_velocity = opts.LimiterType.NONE - self.tol = 1.e-30 + self.tol = 1.0e-30 self.max_iterations = 10000 # blending parameters - self.perturb_type = 'pos_perturb' - self.blending_mean = 'rhoY' # 1.0, rhoY - self.blending_conv = 'rho' #theta, rho - self.blending_type = 'half' # half, full + self.perturb_type = "pos_perturb" + self.blending_mean = "rhoY" # 1.0, rhoY + self.blending_conv = "rho" # theta, rho + self.blending_type = "half" # half, full self.continuous_blending = False self.no_of_pi_initial = 1 @@ -123,11 +121,10 @@ def __init__(self): self.no_of_hy_initial = 0 self.no_of_hy_transition = 0 - self.blending_weight = 0./16 + self.blending_weight = 0.0 / 16 self.initial_blending = False self.initial_projection = True - self.tout = [36.0] # self.tout = np.arange(0,361,1.0) # self.tout = np.append(self.tout, [720.0]) @@ -137,9 +134,9 @@ def __init__(self): self.autogen_fn = False self.output_base_name = "_lamb_wave" - self.output_type = 'test' - self.aux = '' - self.output_suffix = "_%i_%i" %(self.inx-1,self.iny-1) + self.output_type = "test" + self.aux = "" + self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) self.diag = True self.diag_updt_targets = False @@ -147,24 +144,24 @@ def __init__(self): self.diag_state = DiagnosticState( test_name="test_lamb_wave", file_name="test_lamb_wave", - Nx=self.inx-1, - Ny=self.iny-1, - steps=[self.stepmax-1], + Nx=self.inx - 1, + Ny=self.iny - 1, + steps=[self.stepmax - 1], ) - self.stratification = self.stratification_wrapper self.rayleigh_bc = self.rayleigh_bc_function self.init_forcing = self.forcing self.rayleigh_forcing = True - self.rayleigh_forcing_type = 'func' # func or file - self.rayleigh_forcing_fn = 'output_mark_wave_ensemble=1_601_240_bottom_forcing_S16.h5' - self.rayleigh_forcing_path = './output_mark_wave' - + self.rayleigh_forcing_type = "func" # func or file + self.rayleigh_forcing_fn = ( + "output_mark_wave_ensemble=1_601_240_bottom_forcing_S16.h5" + ) + self.rayleigh_forcing_path = "./output_mark_wave" def stratification_wrapper(self, dy): - return lambda y : self.stratification_function(y, dy) + return lambda y: self.stratification_function(y, dy) def stratification_function(self, y, dy): g = self.gravity_strength[1] @@ -173,8 +170,8 @@ def stratification_function(self, y, dy): Hex = 1.0 / (Gamma * g) pi_m = np.exp(-(y - 0.5 * dy) / Hex) pi_p = np.exp(-(y + 0.5 * dy) / Hex) - - Theta = - (Gamma * g * dy) / (pi_p - pi_m) + + Theta = -(Gamma * g * dy) / (pi_p - pi_m) return Theta @@ -188,15 +185,32 @@ def rayleigh_bc_function(ud): if ud.bdry_type[1] == opts.BdryType.RAYLEIGH or ud.rayleigh_forcing == True: ud.inbcy = ud.iny - 1 ud.iny0 = np.copy(ud.iny) - ud.iny = ud.iny0 + int(3*ud.inbcy) + ud.iny = ud.iny0 + int(3 * ud.inbcy) # tentative workaround ud.bcy = ud.ymax ud.ymax += 3.0 * ud.bcy - class forcing(object): - def __init__(self, k, mu, Cs, F, N, Gamma, ampl, g, rhobar, Ybar, rhobar_n, Ybar_n, X, Y, Xn, Yn): + def __init__( + self, + k, + mu, + Cs, + F, + N, + Gamma, + ampl, + g, + rhobar, + Ybar, + rhobar_n, + Ybar_n, + X, + Y, + Xn, + Yn, + ): self.k = k self.mu = mu self.Cs = Cs @@ -219,43 +233,53 @@ def __init__(self, k, mu, Cs, F, N, Gamma, ampl, g, rhobar, Ybar, rhobar_n, Ybar self.Yn = Yn def get_T_matrix(self): - # system matrix of linearized equations - matrix = -np.array([[0, self.F, 0, 1j*self.Cs*self.k], - [-self.F, 0, -self.N, self.Cs*(self.mu+self.Gamma)], - [0, self.N, 0, 0], - [1j*self.Cs*self.k, self.Cs*(self.mu-self.Gamma), 0, 0]]) - + matrix = -np.array( + [ + [0, self.F, 0, 1j * self.Cs * self.k], + [-self.F, 0, -self.N, self.Cs * (self.mu + self.Gamma)], + [0, self.N, 0, 0], + [1j * self.Cs * self.k, self.Cs * (self.mu - self.Gamma), 0, 0], + ] + ) + self.T_matrix = matrix - def eigenfunction(self, t, s, grid='c'): - if grid == 'c': + def eigenfunction(self, t, s, grid="c"): + if grid == "c": x, z = self.X, self.Y - elif grid == 'n': - x, z, = self.Xn, self.Yn - + elif grid == "n": + ( + x, + z, + ) = ( + self.Xn, + self.Yn, + ) + # Compute eigenvalues and eigenvectors - eigval, eigvec = np.linalg.eig( self.T_matrix ) + eigval, eigvec = np.linalg.eig(self.T_matrix) - # Find index of eigenvalue + # Find index of eigenvalue # with greatest real part aka the instability growth rate - ind = np.argmax( np.real( eigval ) ) + ind = np.argmax(np.real(eigval)) # construct solution according to eq. 2.27 and 2.19 - exponentials = np.exp( 1j * self.k * x + self.mu * z - + ( eigval[ind] ) * (t) + 1j * s * t ) - chi_u = self.ampl * np.real( eigvec[0,ind] * exponentials ) - chi_w = self.ampl * np.real( eigvec[1,ind] * exponentials ) - chi_th = self.ampl * np.real( eigvec[2,ind] * exponentials ) - chi_pi = self.ampl * np.real( eigvec[3,ind] * exponentials ) - - self.arrs = ( chi_u, chi_w, chi_th, chi_pi ) - - def dehatter(self, th, grid='c'): - if grid == 'n': + exponentials = np.exp( + 1j * self.k * x + self.mu * z + (eigval[ind]) * (t) + 1j * s * t + ) + chi_u = self.ampl * np.real(eigvec[0, ind] * exponentials) + chi_w = self.ampl * np.real(eigvec[1, ind] * exponentials) + chi_th = self.ampl * np.real(eigvec[2, ind] * exponentials) + chi_pi = self.ampl * np.real(eigvec[3, ind] * exponentials) + + self.arrs = (chi_u, chi_w, chi_th, chi_pi) + + def dehatter(self, th, grid="c"): + if grid == "n": Ybar = self.Ybar_n oorhobarsqrt = self.oorhobarsqrt_n - elif grid == 'c': + elif grid == "c": Ybar = self.Ybar oorhobarsqrt = self.oorhobarsqrt @@ -265,13 +289,12 @@ def dehatter(self, th, grid='c'): vp = oorhobarsqrt * chi_v Yp = oorhobarsqrt * self.N / self.g * Ybar * chi_Y pi_p = oorhobarsqrt * self.Cs / Ybar / th.Gammainv * chi_pi - + return up.T, vp.T, Yp.T, pi_p.T def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): - - if hasattr(ud, 'rayleigh_bdry_switch'): + if hasattr(ud, "rayleigh_bdry_switch"): if ud.rayleigh_bdry_switch: ud.bdry_type[1] = opts.BdryType.RAYLEIGH @@ -280,19 +303,21 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): if ud.rayleigh_forcing: # ud.tcy, ud.tny = get_tau_y(ud, elem, node, 0.005) - - ud.forcing_tcy, ud.forcing_tny = bdry.get_bottom_tau_y(ud, elem, node, 0.2, cutoff=0.3) + + ud.forcing_tcy, ud.forcing_tny = bdry.get_bottom_tau_y( + ud, elem, node, 0.2, cutoff=0.3 + ) A0 = 1.0e-1 / ud.u_ref Msq = ud.Msq g = ud.gravity_strength[1] * ud.Rg - x = elem.x.reshape(-1,1) - y = elem.y.reshape(1,-1) + x = elem.x.reshape(-1, 1) + y = elem.y.reshape(1, -1) X, Y = np.meshgrid(x, y) - xn = node.x.reshape(-1,1) - yn = node.y.reshape(1,-1) + xn = node.x.reshape(-1, 1) + yn = node.y.reshape(1, -1) dy = np.diff(node.y)[0] @@ -305,18 +330,18 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): # Use hydrostatically balanced background hydrostatics.state(mpv, elem, node, th, ud) - rhobar = mpv.HydroState.rho0.reshape(1,-1) - Ybar = mpv.HydroState.Y0.reshape(1,-1) - pibar = mpv.HydroState.p20.reshape(1,-1) * ud.Msq + rhobar = mpv.HydroState.rho0.reshape(1, -1) + Ybar = mpv.HydroState.Y0.reshape(1, -1) + pibar = mpv.HydroState.p20.reshape(1, -1) * ud.Msq - rhobar_n = mpv.HydroState_n.rho0.reshape(1,-1) - Ybar_n = mpv.HydroState_n.Y0.reshape(1,-1) + rhobar_n = mpv.HydroState_n.rho0.reshape(1, -1) + Ybar_n = mpv.HydroState_n.Y0.reshape(1, -1) ################################################## # dimensionless Brunt-Väisälä frequency - N = ud.t_ref * np.sqrt(ud.Nsq_ref) + N = ud.t_ref * np.sqrt(ud.Nsq_ref) # dimensionless speed of sound - Cs = np.sqrt(th.gamm / Msq) + Cs = np.sqrt(th.gamm / Msq) ud.Cs = Cs ud.Ns = N # dimensionless Coriolis strength @@ -326,11 +351,13 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): # if F == 0.0: # F += 1e-15 - G = np.sqrt( 9. / 40. ) + G = np.sqrt(9.0 / 40.0) Gamma = G * N / Cs - k = N / Cs + k = N / Cs - ud.rf_bot = ud.init_forcing(k, -Gamma, Cs, F, N, Gamma, A0, g, rhobar, Ybar, rhobar_n, Ybar_n, X, Y, Xn, Yn) + ud.rf_bot = ud.init_forcing( + k, -Gamma, Cs, F, N, Gamma, A0, g, rhobar, Ybar, rhobar_n, Ybar_n, X, Y, Xn, Yn + ) ud.rf_bot.get_T_matrix() ud.u_wind_speed = 0.0 @@ -356,23 +383,23 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): ################################################### # initialise nodal pi - ud.rf_bot.eigenfunction(0, 1, grid='n') - _, _, _, pi_n = ud.rf_bot.dehatter(th, grid='n') + ud.rf_bot.eigenfunction(0, 1, grid="n") + _, _, _, pi_n = ud.rf_bot.dehatter(th, grid="n") mpv.p2_nodes[...] = pi_n # if ud.bdry_type[1] == 'RAYLEIGH': # rayleigh_damping(Sol, mpv, ud, ud.tcy, elem, th) - bdry.set_explicit_boundary_data(Sol,elem,ud,th,mpv) + bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - if hasattr(ud, 'mixed_run'): + if hasattr(ud, "mixed_run"): if ud.mixed_run: ud.coriolis_strength[2] = 2.0 * 7.292 * 1e-5 * ud.t_ref - if hasattr(ud, 'trad_forcing'): + if hasattr(ud, "trad_forcing"): if ud.trad_forcing: ud.rf_bot.F = 0.0 ud.rf_bot.get_T_matrix() - return Sol \ No newline at end of file + return Sol diff --git a/src/tests/test_targets.yml b/src/tests/test_targets.yml index 4676cc09..3e412133 100644 --- a/src/tests/test_targets.yml +++ b/src/tests/test_targets.yml @@ -30,3 +30,19 @@ test_blending_warm_bubble: rhou: -9.5367431640625e-07 rhov: 554.5759887695312 rhow: 0.0 +test_blending_warm_bubble: + p2_nodes: -12329.044921875 + rho: 2415.03955078125 + rhoX: 304.032958984375 + rhoY: 2415.36279296875 + rhou: 0.0 + rhov: -1.432103157043457 + rhow: 0.0 +test_blending_warm_bubble: + p2_nodes: -16146.2158203125 + rho: 2415.7255859375 + rhoX: 289.7033386230469 + rhoY: 2416.049072265625 + rhou: -9.5367431640625e-07 + rhov: 554.5759887695312 + rhow: 0.0 diff --git a/src/tests/test_travelling_vortex.py b/src/tests/test_travelling_vortex.py index 18094e4d..d3bfeae4 100644 --- a/src/tests/test_travelling_vortex.py +++ b/src/tests/test_travelling_vortex.py @@ -1,12 +1,9 @@ import numpy as np -from ..flow_solver.utils import ( - options as opts, - boundary as bdry -) +from ..flow_solver.utils import options as opts, boundary as bdry from ..flow_solver.physics import hydrostatics from ..flow_solver.physics.low_mach import second_projection as lm_sp -from .. utils.data_structures import DiagnosticState +from ..utils.data_structures import DiagnosticState import logging @@ -131,7 +128,7 @@ def __init__(self): self.initial_projection = True self.initial_impl_Euler = False - self.tout = [1.0]#np.arange(0.0,10.1,0.1)[1:] + self.tout = [1.0] # np.arange(0.0,10.1,0.1)[1:] self.stepmax = 101 self.output_base_name = "_travelling_vortex" @@ -151,9 +148,9 @@ def __init__(self): self.diag_state = DiagnosticState( test_name="test_travelling_vortex", file_name="test_travelling_vortex", - Nx=self.inx-1, - Ny=self.iny-1, - steps=[self.stepmax-1], + Nx=self.inx - 1, + Ny=self.iny - 1, + steps=[self.stepmax - 1], ) self.autogen_fn = False diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index 29973de3..ae338f9b 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -6,11 +6,13 @@ from ..flow_solver.physics.low_mach.mpv import MPV from ..flow_solver.physics.gas_dynamics.thermodynamics import ThermodynamicalQuantities + @dataclass class IntegrationTime: - step : int = 0 - t : float = 0.0 - window_step : int = 0 + step: int = 0 + t: float = 0.0 + window_step: int = 0 + @dataclass class ModelState: @@ -28,24 +30,27 @@ def __post_init__(self): def __iter__(self): return iter(getattr(self, field.name) for field in fields(self)) + @dataclass class InterfaceParameters: bld: Optional[Any] = None + @dataclass class DataAssimilationParameters: # DA user-input parameters - dap : Any + dap: Any # r-localisation function - rloc : Any + rloc: Any # solution ensemble # sol_ens : Any # observation related attributes - obs : Any - obs_noisy : Any - obs_mask : Any - obs_covar : Any + obs: Any + obs_noisy: Any + obs_mask: Any + obs_covar: Any + @dataclass class RestartParameters: @@ -53,15 +58,24 @@ class RestartParameters: dap_rewrite: Optional[object] = None r_params: Optional[object] = None + @dataclass class EnsembleState: members: List[ModelState] = field(default_factory=list) - def update_member(self, elem: Grid, node: Grid, sol: Vars, mpv: MPV, flux: List[Vars], th: ThermodynamicalQuantities): + def update_member( + self, + elem: Grid, + node: Grid, + sol: Vars, + mpv: MPV, + flux: List[Vars], + th: ThermodynamicalQuantities, + ): new_state = ModelState(elem, node, sol, flux, mpv, th) self.members.append(new_state) - def set_members(self, members : List[ModelState]): + def set_members(self, members: List[ModelState]): assert len(self.set_members == members) self.members = members @@ -70,16 +84,16 @@ def get_member(self, index: int) -> ModelState: def get_all_members(self) -> List[ModelState]: return self.members - + def get_grid(self) -> tuple[Grid, Grid]: # Assuming identical underlying grid for all ensemble memebers elem = self.memebers[0].elem node = self.memebers[0].node return elem, node - + def __getitem__(self, index): return self.members[index] - + @dataclass class DiagnosticState: @@ -88,6 +102,7 @@ class DiagnosticState: Consider removing run-specific parameters, e.g., (Nx, Ny), in future. """ + # the name to look up in test_targets.yml test_name: str # filename of the reference (if updt_target = True or plot_compare = True) @@ -99,7 +114,7 @@ class DiagnosticState: path: str = "./outputs/" # plot the comparison? - plot_compare: bool = False + plot_compare: bool = True @dataclass @@ -112,8 +127,7 @@ class SimulationState: ensemble_state: EnsembleState restart_params: RestartParameters - interface_params : Optional[InterfaceParameters] = None + interface_params: Optional[InterfaceParameters] = None da_params: Optional[DataAssimilationParameters] = None diag_comparison: Optional[object] = None - diff --git a/src/utils/io.py b/src/utils/io.py index d1bf9173..119d7eea 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -49,7 +49,6 @@ def initialise(sst): return writer, wrtr - class hdf5(object): """ HDF5 writer class. Contains methods to create HDF5 file, create data sets and populate them with output variables. @@ -488,7 +487,6 @@ def jar(self, content=None): class read_input(object): - def __init__(self, fn, path): self.fn = fn self.path = path @@ -727,7 +725,6 @@ def sim_restart(path, name, elem, node, ud, Sol, mpv, restart_touts): def fn_gen(ud, dap, N): - suffix = "" suffix += "_%i" % (ud.inx - 1) suffix += "_%i" % (ud.iny - 1) @@ -765,22 +762,24 @@ def mkdir_p(path): try: os.makedirs(path, exist_ok=True) # Python>3.2 except OSError as exc: - if exc.errno == errno.EEXIST and os.path.isdir(path): - pass - else: raise + if exc.errno == errno.EEXIST and os.path.isdir(path): + pass + else: + raise ########################################################## # Initialise logger ########################################################## - + + def init_logger(ud): now = datetime.now() date = now.strftime("%d%m%y") time = now.strftime("%H%M%S") - input_filename = "%s%s" %(ud.output_type, ud.output_base_name) - logger_filename = "./logs/%s_%s_%s.log" %(input_filename, date, time) + input_filename = "%s%s" % (ud.output_type, ud.output_base_name) + logger_filename = "./logs/%s_%s_%s.log" % (input_filename, date, time) mkdir_p(os.path.dirname(logger_filename)) @@ -802,4 +801,4 @@ def init_logger(ud): # add the handler to the root logger logging.getLogger().addHandler(console) - logging.info("Input file is %s" %input_filename) \ No newline at end of file + logging.info("Input file is %s" % input_filename) diff --git a/src/utils/prepare.py b/src/utils/prepare.py index 3189acde..5d776d59 100644 --- a/src/utils/prepare.py +++ b/src/utils/prepare.py @@ -1,28 +1,25 @@ import numpy as np -from . import ( - user_data, - io, - data_structures -) - -from ..flow_solver.discretisation import grid as dis_grid -from ..flow_solver.utils import variable as var +from . import user_data, io, data_structures + +from ..flow_solver.discretisation import grid as dis_grid +from ..flow_solver.utils import variable as var from ..flow_solver.utils import boundary as bdry from ..flow_solver.physics import hydrostatics -from ..flow_solver.physics.low_mach import mpv as lm_var +from ..flow_solver.physics.low_mach import mpv as lm_var from ..flow_solver.physics.gas_dynamics import thermodynamics as gd_thermodynamics # test module from ..tests import diagnostics as diag + def initialise(): #### # Initialise simulation state #### from . import sim_params as params - np.set_printoptions(precision = params.print_precision) + np.set_printoptions(precision=params.print_precision) ########################################################## # Initialisation of data containers and helper classes @@ -55,7 +52,6 @@ def initialise(): th = gd_thermodynamics.ThermodynamicalQuantities(ud) mpv = lm_var.MPV(elem, node, ud) - io.init_logger(ud) @@ -71,7 +67,6 @@ def initialise(): else: diag_comparison = None - ########################################################## # Populate data structures ########################################################## @@ -90,13 +85,13 @@ def initialise(): sol = sol_init(sol, mpv, elem, node, th, ud) ensemble_state.update_member( - elem=elem, - node=node, - sol=sol, - flux=flux, - mpv=mpv, - th=th, - ) + elem=elem, + node=node, + sol=sol, + flux=flux, + mpv=mpv, + th=th, + ) restart_params = data_structures.RestartParameters( ud_rewrite=ud_rewrite, @@ -109,16 +104,12 @@ def initialise(): sim_st = data_structures.SimulationState( N=N, restart=restart, - ud=ud, sol_init=sol_init, - ensemble_state=ensemble_state, - diag_comparison=diag_comparison, - restart_params=restart_params, - interface_params=interface_params + interface_params=interface_params, ) return sim_st @@ -132,11 +123,18 @@ def overwrite_init_with_restart(sst): sst.ud.old_suffix = np.copy(sst.ud.output_suffix) sst.ud.old_suffix = "_ensemble=%i%s" % (sst.N, sst.ud.old_suffix) Sol0, mpv0, touts = io.sim_restart( - rp.r_params[0], rp.r_params[1], es.elem, es.node, es.ud, es.Sol, es.mpv, rp.r_params[2] + rp.r_params[0], + rp.r_params[1], + es.elem, + es.node, + es.ud, + es.Sol, + es.mpv, + rp.r_params[2], ) sol_ens = [[Sol0, es.flux, mpv0, [-np.inf, sst.step]]] # ud.tout = touts[1:] sst.ud.tout = [touts[-1]] sst.t = touts[0] - sst.ensemble_state = sol_ens \ No newline at end of file + sst.ensemble_state = sol_ens diff --git a/src/utils/sim_params.py b/src/utils/sim_params.py index 395c2e69..8bef8077 100644 --- a/src/utils/sim_params.py +++ b/src/utils/sim_params.py @@ -9,7 +9,7 @@ random_seed = 888 print_precision = 18 -output_path = './outputs' +output_path = "./outputs" # global constants @@ -18,16 +18,16 @@ def __init__(self): self.nspec = 1 self.buoy = 0 - self.grav = 9.81 # [m s^{-2}] - self.omega = 0.0 # [s^{-1}] + self.grav = 9.81 # [m s^{-2}] + self.omega = 0.0 # [s^{-1}] - self.R_gas = 287.4 # [J kg^{-1} K^{-1}] + self.R_gas = 287.4 # [J kg^{-1} K^{-1}] self.R_vap = 461.0 - self.Q_vap = 2.53e+06 + self.Q_vap = 2.53e06 self.gamm = 1.4 - self.p_ref = 8.61 * 1e4 # [N/m^2] - self.T_ref = 300.00 # [K] + self.p_ref = 8.61 * 1e4 # [N/m^2] + self.T_ref = 300.00 # [K] - self.h_ref = 10000.0 # [m] - self.t_ref = 100.0 # [s] \ No newline at end of file + self.h_ref = 10000.0 # [m] + self.t_ref = 100.0 # [s] diff --git a/src/utils/user_data.py b/src/utils/user_data.py index ffc0b70d..f9f8915c 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -3,6 +3,7 @@ from ..flow_solver.utils import options as opts from . import sim_params as params + class UserDataInit(object): """ Loads user defined initial conditions. Specifically, all attributes of the class object defined in the initial condition is overwritten. @@ -13,26 +14,25 @@ class UserDataInit(object): """ - def __init__(self,**kwargs): + def __init__(self, **kwargs): gconsts = params.global_constants() for key, value in vars(gconsts).items(): setattr(self, key, value) - # else: + # else: ########################################## # SPATIAL GRID ########################################## - self.inx = 64+1 - self.iny = 64+1 + self.inx = 64 + 1 + self.iny = 64 + 1 self.inz = 1 - self.xmin = - 1.0 - self.xmax = 1.0 - self.ymin = 0.0 - self.ymax = 1.0 - self.zmin = - 1.0 - self.zmax = 1.0 - + self.xmin = -1.0 + self.xmax = 1.0 + self.ymin = 0.0 + self.ymax = 1.0 + self.zmin = -1.0 + self.zmax = 1.0 ########################################## # BOUNDARY CONDITIONS @@ -42,20 +42,18 @@ def __init__(self,**kwargs): self.bdry_type[1] = opts.BdryType.WALL self.bdry_type[2] = opts.BdryType.WALL - ########################################## # TEMPORAL ########################################## - self.CFL = 0.5 + self.CFL = 0.5 self.dtfixed0 = 100.0 self.dtfixed = 100.0 self.acoustic_timestep = 0 - self.tout = np.arange(0.0,1.01,0.01)[10:] + self.tout = np.arange(0.0, 1.01, 0.01)[10:] self.stepmax = 10000 - ########################################## # MODEL REGIMES ########################################## @@ -65,7 +63,6 @@ def __init__(self,**kwargs): self.compressibility = 1.0 - ########################################## # PHYSICS AND BACKGROUND WIND ########################################## @@ -75,29 +72,27 @@ def __init__(self,**kwargs): self.stratification = self.stratification_function - ########################################## # NUMERICS - ########################################## + ########################################## # Do we solve the left-hand side? self.do_advection = True - # Advection limiter types - self.limiter_type_scalars = opts.LimiterType.NONE + # Advection limiter types + self.limiter_type_scalars = opts.LimiterType.NONE self.limiter_type_velocity = opts.LimiterType.NONE # Iterative solver - self.tol = 1.e-8 + self.tol = 1.0e-8 self.max_iterations = 6000 - ########################################## # BLENDING ########################################## - self.blending_weight = 0./16 - self.blending_mean = 'rhoY' # 1.0, rhoY - self.blending_conv = 'rho' # theta, rho - self.blending_type = 'half' + self.blending_weight = 0.0 / 16 + self.blending_mean = "rhoY" # 1.0, rhoY + self.blending_conv = "rho" # theta, rho + self.blending_type = "half" self.continuous_blending = False self.no_of_pi_initial = 1 @@ -107,22 +102,19 @@ def __init__(self,**kwargs): self.initial_blending = False - ########################################## # DIAGNOSTICS ########################################## self.diag = False self.diag_state = None - ########################################## # OUTPUTS ########################################## self.autogen_fn = False self.output_timesteps = False - self.output_type = 'output' - self.output_suffix = "_%i_%i" %(self.inx-1,self.iny-1) - + self.output_type = "output" + self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) if len(kwargs) > 0: for key, value in kwargs.items(): @@ -132,11 +124,9 @@ def compute_u_ref(self): self.u_ref = self.h_ref / self.t_ref self.compute_Msq() - def compute_Msq(self): self.Msq = self.u_ref * self.u_ref / (self.R_gas * self.T_ref) - def compute_gravity(self): self.i_gravity = np.zeros((3)) self.gravity_strength = np.zeros((3)) @@ -148,7 +138,6 @@ def compute_gravity(self): self.i_gravity[i] = 1 self.gravity_direction = i - def compute_coriolis(self): self.i_coriolis = np.zeros((3)) self.coriolis_strength = np.zeros((3)) @@ -156,32 +145,26 @@ def compute_coriolis(self): self.coriolis_strength[0] = self.omega * self.t_ref self.coriolis_strength[2] = self.omega * self.t_ref - def compute_cp_gas(self): - self.cp_gas = self.gamm * self.R_gas / (self.gamm-1.0) + self.cp_gas = self.gamm * self.R_gas / (self.gamm - 1.0) if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): self.compute_N_ref() - def compute_rho_ref(self): self.rho_ref = self.p_ref / (self.R_gas * self.T_ref) - def compute_N_ref(self): self.N_ref = self.grav / np.sqrt(self.cp_gas * self.T_ref) self.Nsq_ref = self.N_ref * self.N_ref - def compute_Cs(self): self.Cs = np.sqrt(self.gamm * self.R_gas * self.T_ref) - @staticmethod def stratification_function(y): return 1.0 - def update_ud(self, obj): for key, value in obj.items(): setattr(self, key, value) @@ -194,7 +177,7 @@ def update_ud(self, obj): @property def R_gas(self): return self._R_gas - + @R_gas.setter def R_gas(self, val): self._R_gas = val @@ -217,7 +200,7 @@ def R_gas(self, val): @property def T_ref(self): return self._T_ref - + @T_ref.setter def T_ref(self, val): self._T_ref = val @@ -233,7 +216,7 @@ def T_ref(self, val): if all(hasattr(self, attr) for attr in ["grav", "cp_gas", "T_ref"]): self.compute_N_ref() - + if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): self.compute_Cs() @@ -241,7 +224,7 @@ def T_ref(self, val): @property def grav(self): return self._grav - + @grav.setter def grav(self, val): self._grav = val @@ -255,14 +238,14 @@ def grav(self, val): @property def h_ref(self): return self._h_ref - + @h_ref.setter def h_ref(self, val): self._h_ref = val if all(hasattr(self, attr) for attr in ["h_ref", "t_ref"]): self.compute_u_ref() - + if all(hasattr(self, attr) for attr in ["grav", "h_ref", "R_gas", "T_ref"]): self.compute_gravity() @@ -270,7 +253,7 @@ def h_ref(self, val): @property def t_ref(self): return self._t_ref - + @t_ref.setter def t_ref(self, val): self._t_ref = val @@ -284,7 +267,7 @@ def t_ref(self, val): @property def omega(self): return self._omega - + @omega.setter def omega(self, val): self._omega = val @@ -292,19 +275,18 @@ def omega(self, val): if all(hasattr(self, attr) for attr in ["omega", "t_ref"]): self.compute_coriolis() - # Cs and cp_gas argument @property def gamm(self): return self._gamm - + @gamm.setter def gamm(self, val): self._gamm = val if all(hasattr(self, attr) for attr in ["gamm", "R_gas"]): self.compute_cp_gas() - + if all(hasattr(self, attr) for attr in ["gamm", "R_gas", "T_ref"]): self.compute_Cs() @@ -312,10 +294,10 @@ def gamm(self, val): @property def p_ref(self): return self._p_ref - + @p_ref.setter def p_ref(self, val): self._p_ref = val if all(hasattr(self, attr) for attr in ["p_ref, R_gas", "T_ref"]): - self.compute_rho_ref() \ No newline at end of file + self.compute_rho_ref() diff --git a/src/vis/plotting_tools.py b/src/vis/plotting_tools.py index baa4b328..17bb771d 100644 --- a/src/vis/plotting_tools.py +++ b/src/vis/plotting_tools.py @@ -6,19 +6,29 @@ class plotter(object): - def __init__(self,arr_lst, ncols=4, figsize=(12,8), fontsize=14, sharexlabel=False, shareylabel=False, sharex=False, sharey=False): - plt.rcParams.update({'font.size': fontsize}) - self.arr_lst = np.array(arr_lst, dtype='object') + def __init__( + self, + arr_lst, + ncols=4, + figsize=(12, 8), + fontsize=14, + sharexlabel=False, + shareylabel=False, + sharex=False, + sharey=False, + ): + plt.rcParams.update({"font.size": fontsize}) + self.arr_lst = np.array(arr_lst, dtype="object") N = self.arr_lst.shape[0] - + if N > ncols: - self.nrows = int(np.ceil(N/ncols)) + self.nrows = int(np.ceil(N / ncols)) self.ncols = ncols if N <= ncols: self.nrows = 1 self.ncols = N self.N = N - + ridx = np.arange(self.nrows) cidx = np.arange(self.ncols) @@ -28,201 +38,251 @@ def __init__(self,arr_lst, ncols=4, figsize=(12,8), fontsize=14, sharexlabel=Fal self.idx.append(pair) else: self.idx = cidx - + self.visualise = self.visualise - self.fig, self.ax = plt.subplots(ncols=self.ncols,nrows=self.nrows,figsize=figsize,sharex=sharex,sharey=sharey) - + self.fig, self.ax = plt.subplots( + ncols=self.ncols, + nrows=self.nrows, + figsize=figsize, + sharex=sharex, + sharey=sharey, + ) + self.sharexlabel = sharexlabel self.shareylabel = shareylabel - + self.img = plt - - def set_axes(self,**kwargs): + + def set_axes(self, **kwargs): for key, value in kwargs.items(): - setattr(self,key,value) - - def set_cax_axes(self,cax,n): - if hasattr(self, 'x_locs') : cax.set_xticks(self.x_locs) - if hasattr(self, 'x_axs') : cax.set_xticklabels(self.x_axs) - if hasattr(self, 'y_locs') : cax.set_yticks(self.y_locs) - if hasattr(self, 'y_axs') : cax.set_yticklabels(self.y_axs) - cax.tick_params(axis='x', pad=15) + setattr(self, key, value) + + def set_cax_axes(self, cax, n): + if hasattr(self, "x_locs"): + cax.set_xticks(self.x_locs) + if hasattr(self, "x_axs"): + cax.set_xticklabels(self.x_axs) + if hasattr(self, "y_locs"): + cax.set_yticks(self.y_locs) + if hasattr(self, "y_axs"): + cax.set_yticklabels(self.y_axs) + cax.tick_params(axis="x", pad=15) if self.sharexlabel: if int(n // self.ncols) == self.nrows - 1: - if hasattr(self, 'x_label') : cax.set_xlabel(self.x_label) + if hasattr(self, "x_label"): + cax.set_xlabel(self.x_label) else: - if hasattr(self, 'x_label') : cax.set_xlabel(self.x_label) + if hasattr(self, "x_label"): + cax.set_xlabel(self.x_label) if self.shareylabel: if n % self.ncols == 0: - if hasattr(self, 'y_label') : cax.set_ylabel(self.y_label) + if hasattr(self, "y_label"): + cax.set_ylabel(self.y_label) else: - if hasattr(self, 'y_label') : cax.set_ylabel(self.y_label) - if hasattr(self, 'axhline'): cax.axhline(self.axhline,c='k',lw=0.5) - if hasattr(self, 'axvline'): cax.axvline(self.axvline,c='k',lw=0.5) - if hasattr(self, 'marker'): + if hasattr(self, "y_label"): + cax.set_ylabel(self.y_label) + if hasattr(self, "axhline"): + cax.axhline(self.axhline, c="k", lw=0.5) + if hasattr(self, "axvline"): + cax.axvline(self.axvline, c="k", lw=0.5) + if hasattr(self, "marker"): for marker in self.marker: - cax.plot(marker[0],marker[1],marker='x',c=marker[2], ms=18, mew=4) - if hasattr(self, 'rects'): + cax.plot(marker[0], marker[1], marker="x", c=marker[2], ms=18, mew=4) + if hasattr(self, "rects"): for rect in self.rects: cax.add_patch(rect) - - - def plot(self,method='imshow',inner=False,suptitle="",rect=[0, 0.03, 1, 0.95],aspect='auto',lvls=None,cmaps=None): - if method != 'imshow' and method != 'contour': + + def plot( + self, + method="imshow", + inner=False, + suptitle="", + rect=[0, 0.03, 1, 0.95], + aspect="auto", + lvls=None, + cmaps=None, + ): + if method != "imshow" and method != "contour": assert 0, "Visualisation method not implemented!" - + if self.N > 1: ims, caxs, baxs = [], [], [] for n, arr in enumerate(self.arr_lst): arr, title = arr[0], arr[1] if inner == True: - arr = arr[2:-2,2:-2] + arr = arr[2:-2, 2:-2] cax = self.ax[self.idx[n]] - + lvl = lvls[n] if lvls is not None else None - cmap = cmaps[n] if cmaps is not None else 'viridis' - - im = self.visualise(method,cax,arr,aspect,lvl,cmap) + cmap = cmaps[n] if cmaps is not None else "viridis" + + im = self.visualise(method, cax, arr, aspect, lvl, cmap) if type(title) == str: cax.set_title(title) elif type(title) == np.ndarray or type(title) == list: cax.set_title(title[0], fontsize=title[1], fontweight=title[2]) loc = cax.get_xticklabels() - self.set_cax_axes(cax,n) + self.set_cax_axes(cax, n) caxs.append(cax) divider = axes_grid.make_axes_locatable(cax) bax = divider.append_axes("right", size="5%", pad=0.05) - if method == 'imshow' and lvl is not None: -# plt.colorbar(im, cax=bax, ticks=lvl)#, format='%.3f') - plt.colorbar(im, cax=bax, ticks=lvl, extend='both')#, format='%.3f') + if method == "imshow" and lvl is not None: + # plt.colorbar(im, cax=bax, ticks=lvl)#, format='%.3f') + plt.colorbar( + im, cax=bax, ticks=lvl, extend="both" + ) # , format='%.3f') else: # plt.colorbar(im, cax=bax, extend='both')#, format='%.3f') plt.colorbar(im, cax=bax, extendrect=True) -# plt.colorbar(im, cax=bax, ticks=lvl) + # plt.colorbar(im, cax=bax, ticks=lvl) baxs.append(bax) - if hasattr(self, 'cbar_label'): + if hasattr(self, "cbar_label"): bax.set_xlabel(self.cbar_label) - bax.xaxis.set_label_position('top') - if hasattr(self, 'cbar_label_coords'): - bax.xaxis.set_label_coords(self.cbar_label_coords[0],self.cbar_label_coords[1]) + bax.xaxis.set_label_position("top") + if hasattr(self, "cbar_label_coords"): + bax.xaxis.set_label_coords( + self.cbar_label_coords[0], self.cbar_label_coords[1] + ) ims.append(im) - - for i in range(n+1,self.nrows*self.ncols): + + for i in range(n + 1, self.nrows * self.ncols): self.fig.delaxes(self.ax[self.idx[i]]) - + else: arr, title = self.arr_lst[0][0], self.arr_lst[0][1] if inner == True: - arr = arr[2:-2,2:-2] -# cax = self.fig.gca() - cmap = cmaps if cmaps is not None else 'viridis' + arr = arr[2:-2, 2:-2] + # cax = self.fig.gca() + cmap = cmaps if cmaps is not None else "viridis" cax = self.ax - im = self.visualise(method,cax,arr,aspect,lvls,cmap) + im = self.visualise(method, cax, arr, aspect, lvls, cmap) cax.set_title(title) - self.set_cax_axes(cax,0) + self.set_cax_axes(cax, 0) caxs = [cax] divider = axes_grid.make_axes_locatable(cax) bax = divider.append_axes("right", size="5%", pad=0.05) - if hasattr(self, 'cbar_label'): + if hasattr(self, "cbar_label"): bax.set_xlabel(self.cbar_label) - bax.xaxis.set_label_position('top') - if method == 'imshow' and lvls is not None: -# plt.colorbar(im, cax=bax, ticks=lvls)#, format='%.3f') + bax.xaxis.set_label_position("top") + if method == "imshow" and lvls is not None: + # plt.colorbar(im, cax=bax, ticks=lvls)#, format='%.3f') plt.colorbar(im, cax=bax, ticks=lvls) else: plt.colorbar(im, cax=bax, extendrect=True) -# plt.colorbar(im, cax=bax) - if aspect != 'auto' and aspect != 'equal': - bax.set_aspect(float(aspect)*10.0) + # plt.colorbar(im, cax=bax) + if aspect != "auto" and aspect != "equal": + bax.set_aspect(float(aspect) * 10.0) ims = [im] baxs = [bax] - + plt.suptitle(suptitle) plt.tight_layout(rect=rect) # plt.subplots_adjust(hspace = .000005) - + if self.N > 1: return ims, caxs, baxs else: return ims, caxs, baxs - - def save_fig(self, fn, format='.pdf'): + + def save_fig(self, fn, format=".pdf"): self.fig.tight_layout() - self.fig.savefig(fn + format, bbox_inches = 'tight', pad_inches = 0.1) - - + self.fig.savefig(fn + format, bbox_inches="tight", pad_inches=0.1) + @staticmethod - def visualise(method,cax,arr,aspect,lvls,cmap): + def visualise(method, cax, arr, aspect, lvls, cmap): if cmap is None: norm = None - cmap = 'viridis' + cmap = "viridis" elif len(cmap) == 2: norm = cmap[1] cmap = cmap[0] else: norm = None cmap = cmap - - if method == 'imshow': + + if method == "imshow": if lvls is None: - im = cax.imshow(arr,aspect=aspect,origin='lower',cmap=cmap, norm=norm) + im = cax.imshow( + arr, aspect=aspect, origin="lower", cmap=cmap, norm=norm + ) else: - im = cax.imshow(arr,aspect=aspect,origin='lower',interpolation='none',cmap=cmap, norm=norm) - elif method == 'contour': + im = cax.imshow( + arr, + aspect=aspect, + origin="lower", + interpolation="none", + cmap=cmap, + norm=norm, + ) + elif method == "contour": if lvls is None: - im = cax.contour(arr,colors='k') - im = cax.contourf(arr,cmap=cmap,norm=norm) + im = cax.contour(arr, colors="k") + im = cax.contourf(arr, cmap=cmap, norm=norm) cax.set_aspect(aspect) else: cax.set_aspect(aspect) -# im = cax.contour(arr,linewidths=0.5,levels=lvls,colors='k',) -# lvls = lvls[1:-1] -# print(lvls) - im = cax.contour(arr,linewidths=1.0,colors='k',levels=lvls) -# im = cax.contourf(arr,levels=lvls,extend='both') -# lvls = lvls[1:-1] - im = cax.contourf(arr,levels=lvls,extend='both',cmap=cmap,norm=norm) + # im = cax.contour(arr,linewidths=0.5,levels=lvls,colors='k',) + # lvls = lvls[1:-1] + # print(lvls) + im = cax.contour(arr, linewidths=1.0, colors="k", levels=lvls) + # im = cax.contourf(arr,levels=lvls,extend='both') + # lvls = lvls[1:-1] + im = cax.contourf(arr, levels=lvls, extend="both", cmap=cmap, norm=norm) # im = cax.contour(arr,linewidths=0.5,levels=lvls[1:-1],colors='k',vmin=lvls[0],vmax=lvls[-1]) # im = cax.contourf(arr,levels=lvls[1:-1],extend='both',vmin=lvls[0],vmax=lvls[-1]) cax.set_aspect(aspect) return im - + class animator_2D(plotter): - def __init__(self,time_series,ncols,figsize=(16,8)): + def __init__(self, time_series, ncols, figsize=(16, 8)): self.time_series = time_series self.frns = time_series.shape[0] super().__init__(self.time_series[0], ncols, figsize) - + self.update_plot = self.update_plot self.fig.tight_layout() self.suptitle = None - self.method = None - + self.method = None + def animate(self, interval=100, **kwargs): self.ims, self.caxs, self.baxs = self.plot(**kwargs) - anim = animation.FuncAnimation(self.fig, self.update_plot, self.frns, fargs=(self.time_series, self.ims, self.caxs, self.baxs, self.fig, self.suptitle, self.method), interval=interval) + anim = animation.FuncAnimation( + self.fig, + self.update_plot, + self.frns, + fargs=( + self.time_series, + self.ims, + self.caxs, + self.baxs, + self.fig, + self.suptitle, + self.method, + ), + interval=interval, + ) return anim @staticmethod def update_plot(frame_number, time_series, ims, caxs, baxs, img, title, method): - if method == 'imshow': - for ii,im in enumerate(ims): + if method == "imshow": + for ii, im in enumerate(ims): arr = time_series[frame_number][ii][0] im.set_array(arr) - im.set_clim(arr.min(),arr.max()) - elif method == 'contour': + im.set_clim(arr.min(), arr.max()) + elif method == "contour": for ii, cax in enumerate(caxs): arr = time_series[frame_number][ii][0] im = ims[ii] bax = baxs[ii] for c in cax.collections: cax.collections.remove(c) -# for c in cax.collections: -# cax.collections.remove(c) -# for c in cax.collections: -# cax.collections.remove(c) - im = cax.contour(arr,colors='k') + # for c in cax.collections: + # cax.collections.remove(c) + # for c in cax.collections: + # cax.collections.remove(c) + im = cax.contour(arr, colors="k") im = cax.contourf(arr) plt.colorbar(im, cax=bax) if title is not None: @@ -230,102 +290,108 @@ def update_plot(frame_number, time_series, ims, caxs, baxs, img, title, method): img.suptitle(stt) else: img.suptitle(frame_number) - - + + class plotter_1d(object): - def __init__(self,ncols=3,nrows=2,figsize=(12,12),fontsize=16): - plt.rcParams.update({'font.size': fontsize}) - self.fig, self.ax = plt.subplots(ncols=ncols,nrows=nrows, sharex=False, sharey=False, figsize=figsize) + def __init__(self, ncols=3, nrows=2, figsize=(12, 12), fontsize=16): + plt.rcParams.update({"font.size": fontsize}) + self.fig, self.ax = plt.subplots( + ncols=ncols, nrows=nrows, sharex=False, sharey=False, figsize=figsize + ) self.nrows = nrows self.ncols = ncols - + self.img = plt - - def set_suptitle(self,suptitle): + + def set_suptitle(self, suptitle): self.img.suptitle(suptitle) - - def set_x(self,x_axs): + + def set_x(self, x_axs): self.x = x_axs - - def get_ax(self,i): - - #if not hasattr(self,'x'): - #assert 0, "x-axis has not been set, use set_x(x_axs)." + + def get_ax(self, i): + # if not hasattr(self,'x'): + # assert 0, "x-axis has not been set, use set_x(x_axs)." if self.ncols == 1 and self.nrows == 1: return self.ax elif self.nrows == 1 or self.ncols == 1: return self.ax[i] else: - row = int(np.floor(i/self.ncols)) - col = int(i%self.ncols) - - return self.ax[row,col] + row = int(np.floor(i / self.ncols)) + col = int(i % self.ncols) + + return self.ax[row, col] + + def save_fig(self, fn, format=".pdf"): + self.img.savefig(fn + format, bbox_inches="tight", pad_inches=0) - def save_fig(self, fn, format='.pdf'): - self.img.savefig(fn + format, bbox_inches = 'tight', pad_inches = 0) - def labels(): labels_dict = { - 'rho' : r'$\rho$, density', - 'rhou' : r'$\rho u$, horizontal momentum', - 'rhov' : r'$\rho w$, vertical momentum', - 'rhow' : r'$\rho v$, horizontal momentum', - 'buoy' : r'buoyancy', - 'rhoX' : r'$\rho / \Theta$, mass-weighted inverse pot. temp.', - 'rhoY' : r'$P$, mass-weighted potential temperature', - 'p2_nodes' : r'$\pi^\prime$, Exner pressure perturbation' - } + "rho": r"$\rho$, density", + "rhou": r"$\rho u$, horizontal momentum", + "rhov": r"$\rho w$, vertical momentum", + "rhow": r"$\rho v$, horizontal momentum", + "buoy": r"buoyancy", + "rhoX": r"$\rho / \Theta$, mass-weighted inverse pot. temp.", + "rhoY": r"$P$, mass-weighted potential temperature", + "p2_nodes": r"$\pi^\prime$, Exner pressure perturbation", + } return labels_dict + def labels_increment(): labels_dict = labels() - labels_dict['p2_nodes'] = r'$\delta \pi$, nodal Exner pressure increment' + labels_dict["p2_nodes"] = r"$\delta \pi$, nodal Exner pressure increment" return labels_dict + def swe_labels(): labels_dict = { - 'rho' : r'$h$, water depth', - 'rhou' : r'$h u$, horizontal momentum', - 'rhov' : r'$h w$, vertical momentum', - 'rhow' : r'$h v$, horizontal momentum', - 'buoy' : r'buoyancy', - 'vorty' : r'vorticity', - 'rhoX' : r'$h / \Theta$', - 'rhoY' : r'$h (\rho \Theta)$, water depth', - 'p2_nodes' : r'$h^\prime$, water depth perturbation' + "rho": r"$h$, water depth", + "rhou": r"$h u$, horizontal momentum", + "rhov": r"$h w$, vertical momentum", + "rhow": r"$h v$, horizontal momentum", + "buoy": r"buoyancy", + "vorty": r"vorticity", + "rhoX": r"$h / \Theta$", + "rhoY": r"$h (\rho \Theta)$, water depth", + "p2_nodes": r"$h^\prime$, water depth perturbation", } return labels_dict + def lake_labels(): labels_dict = { - 'rho' : r'$h^{(0)}$, leading-order' + '\n water depth', - 'rhou' : r'$h^{(0)} u^{(0)}$, leading-order horizontal momentum', - 'rhov' : r'$h^{(0)} w^{(0)}$, leading-order vertical momentum', - 'rhow' : r'$h^{(0)} v^{(0)}$, leading-order horizontal momentum', - 'buoy' : r'buoyancy', - 'vorty' : r'vorticity', - 'rhoX' : r'$h / \Theta$', - 'rhoY' : r'$h^{(0)} (\rho \Theta)$, leading-order' + '\n water depth', - 'p2_nodes' : r'$h^{(1)}$, next-to-leading' + '\n order water depth' + "rho": r"$h^{(0)}$, leading-order" + "\n water depth", + "rhou": r"$h^{(0)} u^{(0)}$, leading-order horizontal momentum", + "rhov": r"$h^{(0)} w^{(0)}$, leading-order vertical momentum", + "rhow": r"$h^{(0)} v^{(0)}$, leading-order horizontal momentum", + "buoy": r"buoyancy", + "vorty": r"vorticity", + "rhoX": r"$h / \Theta$", + "rhoY": r"$h^{(0)} (\rho \Theta)$, leading-order" + "\n water depth", + "p2_nodes": r"$h^{(1)}$, next-to-leading" + "\n order water depth", } return labels_dict + def swe_labels_increment(): labels_dict = swe_labels() - labels_dict['p2_nodes'] = r'$\delta h^\prime$, water depth increment' + labels_dict["p2_nodes"] = r"$\delta h^\prime$, water depth increment" return labels_dict + def short_labels(): labels_dict = { - 'rho' : r'$\rho$', - 'rhou' : r'$\rho u$', - 'rhov' : r'$\rho v$', - 'rhow' : r'$\rho w$', - 'buoy' : r'buoyancy', - 'rhoX' : r'$\rho / \Theta$', - 'rhoY' : r'$\rho \Theta$', - 'p2_nodes' : r'$\pi$' - } + "rho": r"$\rho$", + "rhou": r"$\rho u$", + "rhov": r"$\rho v$", + "rhow": r"$\rho w$", + "buoy": r"buoyancy", + "rhoX": r"$\rho / \Theta$", + "rhoY": r"$\rho \Theta$", + "p2_nodes": r"$\pi$", + } return labels_dict diff --git a/src/vis/utils.py b/src/vis/utils.py index e152a04e..b22ee596 100644 --- a/src/vis/utils.py +++ b/src/vis/utils.py @@ -2,8 +2,9 @@ import h5py import time + class test_case(object): - def __init__(self,base_fn,py_dir,Nx,Ny,end_time,Nz=None): + def __init__(self, base_fn, py_dir, Nx, Ny, end_time, Nz=None): self.base_fn = base_fn self.py_dir = py_dir self.grid_x = Nx @@ -14,102 +15,136 @@ def __init__(self,base_fn,py_dir,Nx,Ny,end_time,Nz=None): self.ndim = 3 else: self.ndim = 2 - + self.cb_suffix = self.cb_suffix self.get_tag_dict = self.get_tag_dict self.py_out = self.py_out - + self.get_filename = self.get_filename self.get_path = self.get_path self.get_arr = self.get_arr - - self.i0 = tuple([slice(None,)]*self.ndim) + + self.i0 = tuple( + [ + slice( + None, + ) + ] + * self.ndim + ) if self.grid_z is not None and Ny == 1: - self.i2 = tuple([slice(2,-2)]*(self.ndim+1)) + self.i2 = tuple([slice(2, -2)] * (self.ndim + 1)) else: - self.i2 = tuple([slice(2,-2)]*self.ndim) - - def cb_suffix(self,fs,ts,suffix=""): + self.i2 = tuple([slice(2, -2)] * self.ndim) + + def cb_suffix(self, fs, ts, suffix=""): if suffix != "": - return "%s_cont_blend_fs=%i_ts=%i" %(suffix,fs,ts) + return "%s_cont_blend_fs=%i_ts=%i" % (suffix, fs, ts) else: - return "cont_blend_fs=%i_ts=%i" %(fs,ts) - + return "cont_blend_fs=%i_ts=%i" % (fs, ts) @staticmethod def get_tag_dict(): td = { - 0 : 'before_flux', - 1 : 'before_advect', - 2 : 'after_advect', - 3 : 'after_ebnaexp', - 4 : 'after_ebnaimp', - 5 : 'after_half_step', - 6 : 'after_efna', - 7 : 'after_full_advect', - 8 : 'after_full_ebnaexp', - 9 : 'after_full_step', + 0: "before_flux", + 1: "before_advect", + 2: "after_advect", + 3: "after_ebnaexp", + 4: "after_ebnaimp", + 5: "after_half_step", + 6: "after_efna", + 7: "after_full_advect", + 8: "after_full_ebnaexp", + 9: "after_full_step", } return td @staticmethod def get_debug_attrs(): dd = { - 'p2_initial' : 'p2_initial', - 'hcenter' : 'hcenter', - 'wplusx' : 'wplusx', - 'wplusy' : 'wplusy', - 'wplusz' : 'wplusz', - 'rhs' : 'rhs', - 'rhs_nodes' : 'rhs_nodes', - 'p2_full' : 'p2_full' + "p2_initial": "p2_initial", + "hcenter": "hcenter", + "wplusx": "wplusx", + "wplusy": "wplusy", + "wplusz": "wplusz", + "rhs": "rhs", + "rhs_nodes": "rhs_nodes", + "p2_full": "p2_full", } return dd - def get_filename(self,N,suffix,format='h5'): + def get_filename(self, N, suffix, format="h5"): if self.ndim == 2: - fn = "%s_ensemble=%i_%i_%i_%.6f_%s.%s" %(self.base_fn,N,self.grid_x,self.grid_y,self.end_time,suffix,format) + fn = "%s_ensemble=%i_%i_%i_%.6f_%s.%s" % ( + self.base_fn, + N, + self.grid_x, + self.grid_y, + self.end_time, + suffix, + format, + ) if self.ndim == 3 or self.grid_z is not None: - fn = "%s_ensemble=%i_%i_%i_%i_%.6f_%s.%s" %(self.base_fn,N,self.grid_x,self.grid_y,self.grid_z,self.end_time,suffix,format) + fn = "%s_ensemble=%i_%i_%i_%i_%.6f_%s.%s" % ( + self.base_fn, + N, + self.grid_x, + self.grid_y, + self.grid_z, + self.end_time, + suffix, + format, + ) return fn - - def get_path(self,fn): + def get_path(self, fn): path = self.py_dir + fn return path - @staticmethod - def py_out(pyfile,py_dataset,time): - return pyfile[str(py_dataset)][str(py_dataset)+time][:], pyfile[str(py_dataset)][str(py_dataset)+time].attrs.get('t') - + def py_out(pyfile, py_dataset, time): + return pyfile[str(py_dataset)][str(py_dataset) + time][:], pyfile[ + str(py_dataset) + ][str(py_dataset) + time].attrs.get("t") - def get_arr(self, path, time, N, attribute, label_type='TIME', tag='after_full_step', inner=False, avg=False, file=None): + def get_arr( + self, + path, + time, + N, + attribute, + label_type="TIME", + tag="after_full_step", + inner=False, + avg=False, + file=None, + ): if inner == False: inner = self.i0 else: inner = self.i2 - + if file is None: - file = h5py.File(path,'r') - + file = h5py.File(path, "r") + array = [] - - if not hasattr(self,'t_arr'): self.t_arr = [] + + if not hasattr(self, "t_arr"): + self.t_arr = [] t_arr = self.t_arr for n in range(N): - if label_type == 'TIME': - t_label = '_ensemble_mem=%i_%.3f_%s' %(n,time, tag) - elif label_type == 'WINDOW_STEP': - if N==1: - t_label = '_%.3d_%s' %(time, tag) - elif label_type == 'STEP': - if N==1: - t_label = '_ensemble_mem=0_%.3d_%s' %(time, tag) + if label_type == "TIME": + t_label = "_ensemble_mem=%i_%.3f_%s" % (n, time, tag) + elif label_type == "WINDOW_STEP": + if N == 1: + t_label = "_%.3d_%s" % (time, tag) + elif label_type == "STEP": + if N == 1: + t_label = "_ensemble_mem=0_%.3d_%s" % (time, tag) else: - t_label = '_ensemble_mem=%i_%.3d_%s' %(n,time, tag) - - arr, t = self.py_out(file,attribute,time=t_label) + t_label = "_ensemble_mem=%i_%.3d_%s" % (n, time, tag) + + arr, t = self.py_out(file, attribute, time=t_label) array.append(arr[inner]) t_arr.append(t) @@ -121,211 +156,269 @@ def get_arr(self, path, time, N, attribute, label_type='TIME', tag='after_full_s file.close() self.t_arr = t_arr return np.array(array) - - def spatially_averaged_rmse(self, arrs,refs,avg=False, grid_type='c'): + + def spatially_averaged_rmse(self, arrs, refs, avg=False, grid_type="c"): diff = [] - refs = refs[:,np.newaxis,...] + refs = refs[:, np.newaxis, ...] refs = np.repeat(refs, arrs.shape[1], axis=1) -# print(arrs.shape, refs.shape) - for arr, ref in zip(arrs,refs): - #arr = (arr[self.i2]) - #ref = (ref[self.i2]) - if grid_type == 'n': -# print("arr before ie1 shape", arr.shape) + # print(arrs.shape, refs.shape) + for arr, ref in zip(arrs, refs): + # arr = (arr[self.i2]) + # ref = (ref[self.i2]) + if grid_type == "n": + # print("arr before ie1 shape", arr.shape) arr = self.get_ie1(arr) ref = self.get_ie1(ref) -# print(arr.shape) - if avg==True: + # print(arr.shape) + if avg == True: for ens_mem in arr: - ens_mem -= ens_mem.mean() -# arr -= arr.mean() + ens_mem -= ens_mem.mean() + # arr -= arr.mean() ref -= ref.mean() - + ref_ampl = ref.max() - ref.min() factor = ref_ampl factor = 1.0 - diff.append( np.sqrt(((arr - ref)**2).mean()) ) -# diff.append(np.sqrt( ((arr - ref)**2).mean() / (ref[0]**2).mean() ) ) -# diff.append(np.sqrt((((arr - ref) / ref)**2).mean()) ) - # Method A - # err = [np.linalg.norm(mem - ref[0]) / np.linalg.norm(ref[0]) for mem in arr] - #err = np.array(err).mean() - # diff.append(err) - # Method B - # diff.append(np.linalg.norm(arr-ref) / np.linalg.norm(ref)) - # Method C -# diff.append(np.linalg.norm((arr-ref).mean(axis=0)) / np.linalg.norm(ref[0])) - + diff.append(np.sqrt(((arr - ref) ** 2).mean())) + # diff.append(np.sqrt( ((arr - ref)**2).mean() / (ref[0]**2).mean() ) ) + # diff.append(np.sqrt((((arr - ref) / ref)**2).mean()) ) + # Method A + # err = [np.linalg.norm(mem - ref[0]) / np.linalg.norm(ref[0]) for mem in arr] + # err = np.array(err).mean() + # diff.append(err) + # Method B + # diff.append(np.linalg.norm(arr-ref) / np.linalg.norm(ref)) + # Method C + # diff.append(np.linalg.norm((arr-ref).mean(axis=0)) / np.linalg.norm(ref[0])) + return np.array(diff) - def ensemble_spread(self, arrs,avg=False, grid_type='c'): + def ensemble_spread(self, arrs, avg=False, grid_type="c"): diff = [] - + refs = arrs.mean(axis=1) - refs = refs[:,np.newaxis,...] - refs = np.repeat(refs,arrs.shape[1],axis=1) -# print(arrs.shape, refs.shape) + refs = refs[:, np.newaxis, ...] + refs = np.repeat(refs, arrs.shape[1], axis=1) + # print(arrs.shape, refs.shape) - for arr, ref in zip(arrs,refs): - if grid_type == 'n': + for arr, ref in zip(arrs, refs): + if grid_type == "n": arr = self.get_ie1(arr) ref = self.get_ie1(ref) - if avg==True: + if avg == True: for ens_mem in arr: - ens_mem -= ens_mem.mean() -# arr -= arr.mean() + ens_mem -= ens_mem.mean() + # arr -= arr.mean() ref -= ref.mean() - - diff.append(np.sqrt(((arr - ref)**2).mean())) + + diff.append(np.sqrt(((arr - ref) ** 2).mean())) return np.array(diff) - - + def probe_rmse(self, arrs, refs, probe_loc, avg=False, inner=False): diff = [] - - for arr, ref in zip(arrs,refs): + + for arr, ref in zip(arrs, refs): if avg == True: arr = arr.mean(axis=0) ref = ref.mean(axis=0) if arr.ndim == 3: - arr = arr[:,0,:] - ref = ref[:,0,:] - + arr = arr[:, 0, :] + ref = ref[:, 0, :] + if inner == True: - arr = arr[probe_loc[0],probe_loc[1]] - ref = ref[probe_loc[0],probe_loc[1]] + arr = arr[probe_loc[0], probe_loc[1]] + ref = ref[probe_loc[0], probe_loc[1]] else: - arr = arr[probe_loc[0],probe_loc[1]] - ref = ref[probe_loc[0],probe_loc[1]] - - #diff.append(np.sqrt(((arr - ref)**2).mean())) - diff.append(np.linalg.norm(arr-ref)) + arr = arr[probe_loc[0], probe_loc[1]] + ref = ref[probe_loc[0], probe_loc[1]] + + # diff.append(np.sqrt(((arr - ref)**2).mean())) + diff.append(np.linalg.norm(arr - ref)) return np.array(diff) - + # the first and last node rows / columns are repeated in periodic bcs, when we take mean we want to avoid this. @staticmethod def get_ie1(arr): arr = arr.squeeze() ndim = arr.ndim - ie1 = tuple([slice(0,-1)]*ndim) + ie1 = tuple([slice(0, -1)] * ndim) arr = arr[ie1] return arr - - def get_mean(self, arrs, grid_type='c'): + + def get_mean(self, arrs, grid_type="c"): arr_mean = [] - + for arr in arrs: - if grid_type == 'n': + if grid_type == "n": arr = self.get_ie1(arr) arr_mean.append(arr.mean()) - + return arr_mean - @staticmethod def get_probe_loc(arrs, probe_loc): time_series = [] for arr in arrs: - time_series.append(arr[probe_loc[0],probe_loc[1]]) + time_series.append(arr[probe_loc[0], probe_loc[1]]) return time_series - - - def get_ensemble(self, times, N, attribute, suffix, cont_blend=False, ts=0, fs=0, label_type='TIME', tag='after_full_step', avg=False, diff=False, inner=True, load_ic=True, get_fn=True, fn=""): + + def get_ensemble( + self, + times, + N, + attribute, + suffix, + cont_blend=False, + ts=0, + fs=0, + label_type="TIME", + tag="after_full_step", + avg=False, + diff=False, + inner=True, + load_ic=True, + get_fn=True, + fn="", + ): self.t_arr = [] if cont_blend == True: - suffix += cb_suffix(fs,ts) - + suffix += cb_suffix(fs, ts) + if get_fn: - fn = self.get_filename(N,suffix) + fn = self.get_filename(N, suffix) else: fn = fn path = self.get_path(fn) - - file = h5py.File(path,'r') - -# arr_lst = np.zeros((times.size+1),dtype=np.ndarray) + + file = h5py.File(path, "r") + + # arr_lst = np.zeros((times.size+1),dtype=np.ndarray) arr_lst = [] if load_ic: - arr = self.get_arr(path, 0, N, attribute, tag='ic', label_type=label_type, avg=avg, inner=inner, file=file) + arr = self.get_arr( + path, + 0, + N, + attribute, + tag="ic", + label_type=label_type, + avg=avg, + inner=inner, + file=file, + ) arr_lst.append(arr) for tt, time in enumerate(times): - arr = self.get_arr(path, time, N, attribute, tag=tag, label_type=label_type, avg=avg, inner=inner, file=file) -# arr_lst[tt] = arr + arr = self.get_arr( + path, + time, + N, + attribute, + tag=tag, + label_type=label_type, + avg=avg, + inner=inner, + file=file, + ) + # arr_lst[tt] = arr arr_lst.append(arr) - - - if diff == True: + + if diff == True: arr_lst = get_diff(arr_lst) - - file.close() + + file.close() if load_ic: self.t_arr[0] = 0.0 return np.array(arr_lst) - - - def get_time_series(self, times, N, attribute, suffix, probe_loc, tag='after_full_step', cont_blend=False, ts=0, fs=0, label_type='TIME', diff=False, slc=[None], avg=False): + + def get_time_series( + self, + times, + N, + attribute, + suffix, + probe_loc, + tag="after_full_step", + cont_blend=False, + ts=0, + fs=0, + label_type="TIME", + diff=False, + slc=[None], + avg=False, + ): if self.ndim == 3 and slc[0] == None: - assert 0, "3D array has no 2D slice, define argument slc=(slice(...),slice(...),slice(...))" - + assert ( + 0 + ), "3D array has no 2D slice, define argument slc=(slice(...),slice(...),slice(...))" + probe_row = probe_loc[0] probe_col = probe_loc[1] - + if cont_blend == True: - suffix += '_' + self.cb_suffix(fs,ts) - - fn = self.get_filename(N,suffix) + suffix += "_" + self.cb_suffix(fs, ts) + + fn = self.get_filename(N, suffix) path = self.get_path(fn) - + probe = [] for time in times: - arr = self.get_arr(path, time, N, attribute, tag=tag, label_type=label_type, inner=True) - + arr = self.get_arr( + path, time, N, attribute, tag=tag, label_type=label_type, inner=True + ) + if avg == True: arr -= arr.mean() - + if self.ndim == 3: arr = arr[slc].squeeze() - probe.append(arr[probe_row,probe_col]) - + probe.append(arr[probe_row, probe_col]) + probe = np.array(probe) - if diff==True: + if diff == True: return get_diff(probe) - elif diff==False: + elif diff == False: return probe +def bin_func(obs, ens_mem_shape): + obs = obs.reshape( + ens_mem_shape[0], + obs.shape[0] // ens_mem_shape[0], + ens_mem_shape[1], + obs.shape[1] // ens_mem_shape[1], + ) + return obs.mean(axis=(1, 3)) -def bin_func(obs,ens_mem_shape): - obs = obs.reshape(ens_mem_shape[0],obs.shape[0]//ens_mem_shape[0], - ens_mem_shape[1],obs.shape[1]//ens_mem_shape[1]) - return obs.mean(axis=(1,3)) def rmse(diff): return np.sqrt((diff**2).mean()) + def get_diff(probe): probe = np.array(probe) return probe[1:] - probe[:-1] -def spatially_averaged_rmse(arr,ref): - #arr = arr[2:-2,2:-2] - #ref = ref[2:-2,2:-2] - - #arr -= arr.mean() - #ref -= ref.mean() - return np.sqrt(((arr - ref)**2).mean()) +def spatially_averaged_rmse(arr, ref): + # arr = arr[2:-2,2:-2] + # ref = ref[2:-2,2:-2] + + # arr -= arr.mean() + # ref -= ref.mean() + + return np.sqrt(((arr - ref) ** 2).mean()) + class prt_time(object): # simple profiler for utils and plottting_tools def __init__(self, debug=True): self.tic = time.time() self.debug = debug - + def prtt(self, label=""): curr_time = time.time() - if self.debug==True: + if self.debug == True: print(label, curr_time - self.tic) self.tic = curr_time From ca350c6eff7d10b9a2d4b53fe60a2f3a0d126718 Mon Sep 17 00:00:00 2001 From: raychew Date: Sat, 31 May 2025 15:35:41 -0700 Subject: [PATCH 36/76] updated test diagnostics to compute L2 and max norms as errors, tolerances for each attribute type, and to output time increment of pressure fields for blending tests --- run_scripts/test_blending.py | 7 - run_scripts/test_flow_solver.py | 25 ++-- run_scripts/test_suite.py | 59 ++++----- src/__main__.py | 2 +- src/flow_solver/utils/solver_diagnostics.py | 1 - src/tests/diagnostics.py | 137 ++++++++++++-------- src/utils/data_structures.py | 11 ++ 7 files changed, 134 insertions(+), 108 deletions(-) diff --git a/run_scripts/test_blending.py b/run_scripts/test_blending.py index 6734a944..ad20cd26 100644 --- a/run_scripts/test_blending.py +++ b/run_scripts/test_blending.py @@ -1,7 +1,6 @@ import pytest import subprocess - @pytest.mark.parametrize( "ic", [ @@ -12,10 +11,4 @@ def test_single_run(ic): result = subprocess.run( ["pybella", "-ic", ic, "-N", "1"], capture_output=True, text=True ) - - # result = subprocess.run( - # ["python3", "-m", "pdb", "pybella", "-ic", ic, "-N", "1"], - # capture_output=False, - # text=True - # ) assert result.returncode == 0, result.stderr.splitlines()[-3:] diff --git a/run_scripts/test_flow_solver.py b/run_scripts/test_flow_solver.py index 2059ad06..20699d11 100644 --- a/run_scripts/test_flow_solver.py +++ b/run_scripts/test_flow_solver.py @@ -1,24 +1,15 @@ import pytest -import sys import subprocess - -@pytest.mark.parametrize( - "ic", ["test_travelling_vortex", "test_internal_long_wave", "test_lamb_wave"] -) -# def test_single_run(ic): -# run = subprocess.Popen( -# [sys.executable, "src", "-ic", ic, "-N", "1"], -# stdout=subprocess.PIPE, -# stderr=subprocess.PIPE, -# ) -# _, stderr = run.communicate() -# assert run.returncode == 0, stderr.splitlines()[-3:] - - +@pytest.mark.parametrize("ic", + ["test_travelling_vortex", + "test_internal_long_wave", + "test_lamb_wave"]) def test_single_run(ic): result = subprocess.run( - ["pybella", "-ic", ic, "-N", "1"], capture_output=True, text=True + ["pybella", "-ic", ic, "-N", "1"], + capture_output=True, + text=True ) - assert result.returncode == 0, result.stderr.splitlines()[-3:] + assert result.returncode == 0, result.stderr.splitlines()[-3:] \ No newline at end of file diff --git a/run_scripts/test_suite.py b/run_scripts/test_suite.py index eabe324a..4cd596a5 100644 --- a/run_scripts/test_suite.py +++ b/run_scripts/test_suite.py @@ -17,46 +17,47 @@ rp.N = 1 ud = {} -if gen_targets: - # set target user data parameters - ud["output_type"] = "target" - ud["diag"] = False +if __name__ == "__main__": + if gen_targets: + # set target user data parameters + ud["output_type"] = "target" + ud["diag"] = False + + # generate target + # define horizontal slice test case + rp.tc = "test_travelling_vortex" + rp.ud = json.dumps(ud) + rp.queue_run() + + # define vertical slice test case + rp.tc = "test_internal_long_wave" + rp.ud = json.dumps(ud) + rp.queue_run() + + # define test case + rp.tc = "test_lamb_wave" + rp.ud = json.dumps(ud) + rp.queue_run() + + if updt_targets: + diag = td.compare_sol("gen_target") + diag.update_targets() + + + ud["output_type"] = "test" + # Do diagnostics + ud["diag"] = True - # generate target - # define horizontal slice test case rp.tc = "test_travelling_vortex" rp.ud = json.dumps(ud) rp.queue_run() - # define vertical slice test case rp.tc = "test_internal_long_wave" rp.ud = json.dumps(ud) rp.queue_run() - # define test case rp.tc = "test_lamb_wave" rp.ud = json.dumps(ud) rp.queue_run() -if updt_targets: - diag = td.compare_sol("gen_target") - diag.update_targets() - - -ud["output_type"] = "test" -# Do diagnostics -ud["diag"] = True - -rp.tc = "test_travelling_vortex" -rp.ud = json.dumps(ud) -rp.queue_run() - -rp.tc = "test_internal_long_wave" -rp.ud = json.dumps(ud) -rp.queue_run() - -rp.tc = "test_lamb_wave" -rp.ud = json.dumps(ud) -rp.queue_run() - # %% diff --git a/src/__main__.py b/src/__main__.py index 67bebed4..5b996fda 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -77,7 +77,7 @@ def main(): sst.diag_comparison.update_targets() else: sst.diag_comparison.test_do( - mem, sst.ud, plot=sst.ud.diag_state.plot_compare + mem, sst.ud ) futures.append(mem) diff --git a/src/flow_solver/utils/solver_diagnostics.py b/src/flow_solver/utils/solver_diagnostics.py index 3feb31cf..22983dcd 100644 --- a/src/flow_solver/utils/solver_diagnostics.py +++ b/src/flow_solver/utils/solver_diagnostics.py @@ -19,5 +19,4 @@ def get_p_from_pressure_related_fields(mem, ud, psinc=False): P0 = (rhoY ** (th.gamm - 1.0) - dp2c) ** (1.0 / (th.gamm - 1.0)) p = rhoY ** (th.gamm) - P0 ** (th.gamm) - # non-dimensionalised p/p_ref return p diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index e3d41451..f22c8e2c 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -14,6 +14,9 @@ class CompareSol(object): def __init__(self, diag_state: DiagnosticState): self.diag_state = diag_state self.current_run = diag_state.test_name + self.plot = diag_state.plot_compare + self.tolerances = diag_state.tolerances + self.time_increment = diag_state.time_increment self.__init(diag_state) self.__get_tc() @@ -22,60 +25,94 @@ def update_targets(self): for tc_name, tc in self.tcs.items(): tp = self.tps[tc_name] - self.arr_dump[tp.name] = {} + dump_name = tp.name.replace("target","test") + self.arr_dump[dump_name] = {} for attribute in tp.attributes: - self.arr_dump[tp.name][attribute] = float( - self.__get_ens(tc, tp, attribute, summed=True) + arr = self.__get_ens(tc, tp, attribute, time_increment=self.time_increment, summed=False) + self.arr_dump[dump_name][attribute] = float( + arr.sum() ) + if self.plot: + # vis_pt.plotter accepts a list of tuples with plot and panel title. + pl = vis_pt.plotter([(arr.T, "ref"), ], ncols=1, figsize=(4, 3), sharey=False) + _ = pl.plot(method="contour", lvls=None, suptitle=attribute) + pl.img.savefig(tp.dir + attribute + ".png") + with open("./src/tests/test_targets.yml", "a") as outfile: yaml.dump(self.arr_dump, outfile, default_flow_style=False) - def test_do(self, mem, ud, plot=False): - Sol = mem.sol - mpv = mem.mpv - - self.__read_yaml() + def test_do(self, mem, ud): + tc = self.tcs[self.current_run] + tp = self.tps[self.current_run] - try: - target_values = self.target[self.current_run] - except: - assert 0, "test %s has no target for comparison" % (self.current_run) + # populate reference arrays + ref_mem = copy.deepcopy(mem) + for attribute in tp.attributes: + try: + ref_data = self.__get_ens(tc, tp, attribute, time_increment=False, summed=False) + if attribute != "p2_nodes": + setattr(ref_mem.sol, attribute, ref_data) + else: + if self.time_increment: + # in the case where we are interested in the time increment + # of the pressure-related fields, we need to load the previous + # time step from the output file. + tc_test = copy.deepcopy(tc) + tc_test.base_fn = tc_test.base_fn.replace("target", "test") + tc_test.py_dir = tc_test.py_dir.replace("target", "test") + data = self.__get_ens(tc_test, tp, attribute, time_increment=self.time_increment, summed=False) + setattr(mem.mpv, attribute, data) + ref_data = self.__get_ens(tc, tp, attribute, time_increment=self.time_increment, summed=False) + setattr(ref_mem.mpv, attribute, ref_data) + except Exception as e: + raise AssertionError(f"test {self.current_run} has no target for comparison: {e}") + + if self.plot: + self.__plot_comparison(mem, ref_mem, ud) - if plot: - self.__plot_comparison(mem, ud) + for attribute in tp.attributes: + test = self.__get_sol_for_comparison(mem, ud, attribute) + ref = self.__get_sol_for_comparison(ref_mem, ud, attribute) - for key, value in target_values.items(): - ref = value + l2_error = np.linalg.norm(test - ref) + ref_norm = np.linalg.norm(ref) - if key != "p2_nodes": - test = getattr(Sol, key).astype("float32").sum() + if ref_norm > 0.0: + rel_l2_error = l2_error / ref_norm else: - test = mpv.p2_nodes.astype("float32").sum() + rel_l2_error = np.inf if l2_error > self.tolerances[attribute] else 0.0 + max_abs_error = np.max(np.abs(test - ref)) try: - assert np.isclose(ref, test), ( - "sum for attribute %s of %s changed with discrepancy:\n%.16f\n%.16f" + assert rel_l2_error < self.tolerances[attribute], ( + "Relative L2 error for attribute %s of %s exceeds tolerance:\n" + "L2 error: %.6e\nRelative L2 error: %.6e\nMax abs error: %.6e\nTolerance: %.6e" % ( - key, + attribute, self.current_run, - ref, - test, + l2_error, + rel_l2_error, + max_abs_error, + self.tolerances[attribute], ) ) - logging.info(f"test passed for {key}") + logging.info( + f"Test passed for {attribute} | " + f"L2: {l2_error:.2e}, Rel L2: {rel_l2_error:.2e}, Max Abs: {max_abs_error:.2e}" + ) except AssertionError as e: logging.info(str(e)) raise logging.info( f""" - {'#' * 10} - Test passed for {self.current_run} - {'#' * 10} - """.strip() - ) + {'#' * 10} + Test passed for {self.current_run} + {'#' * 10} + """.strip() + ) def __init(self, ds: DiagnosticState): tp = test_params(ds) @@ -99,25 +136,9 @@ def __read_yaml(self): with open("./src/tests/test_targets.yml", "r") as infile: self.target = yaml.safe_load(infile) - def __plot_comparison(self, mem, ud): - tc = self.tcs[self.current_run] + def __plot_comparison(self, mem, ref_mem, ud): tp = self.tps[self.current_run] - ref_mem = copy.deepcopy(mem) - for attribute in tp.attributes: - if attribute != "p2_nodes": - setattr( - ref_mem.sol, - attribute, - self.__get_ens(tc, tp, attribute, summed=False), - ) - else: - setattr( - ref_mem.mpv, - attribute, - self.__get_ens(tc, tp, attribute, summed=False), - ) - for attribute in tp.attributes: arr_plots = [] @@ -150,13 +171,17 @@ def __get_sol_for_comparison(mem, ud, attribute): else: # test_sol = mpv.p2_nodes.T * ud.Msq # test_sol -= mpv.HydroState_n.pi0[:,np.newaxis] - test_sol = get_p_from_pressure_related_fields(mem, ud).T + test_sol = get_p_from_pressure_related_fields(mem, ud, perturbation=True).T + # pass return test_sol @staticmethod - def __get_ens(tc, params, attribute, summed=True, normed=False): - times = params.times + def __get_ens(tc, params, attribute, time_increment=False, summed=True, normed=False): + if time_increment and attribute == "p2_nodes": + times = [params.times[0]-1, params.times[0]] + else: + times = params.times l_typ = params.l_typ tags = tc.get_tag_dict() @@ -171,10 +196,16 @@ def __get_ens(tc, params, attribute, summed=True, normed=False): tag=tag, inner=False, get_fn=False, - fn=params.fn + ".h5", + fn=tc.base_fn, load_ic=False, - avg=True, - )[0] + avg=False, + ) + + if time_increment and attribute == "p2_nodes": + ens = ens[1] - ens[0] + else: + ens = ens[0] # removes time axis + ens = ens[0] # removes ensemble axis if summed: return ens.sum() diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index ae338f9b..8fc17c5a 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -116,6 +116,17 @@ class DiagnosticState: # plot the comparison? plot_compare: bool = True + tolerances: dict[str, float] = field(default_factory=lambda: { + "rhou": 1e-5, + "rhov": 1e-5, + "rhow": 1e-5, + "rhoY": 1e-5, + "rhoX": 1e-5, + "rho": 1e-5, + "p2_nodes": 1e-5 + }) + time_increment: bool = False + @dataclass class SimulationState: From df7bf1c3e0fed4d62cb705d9669c6e2c807c9f7c Mon Sep 17 00:00:00 2001 From: raychew Date: Sat, 31 May 2025 15:36:17 -0700 Subject: [PATCH 37/76] fixed pressure imprint bug #34 --- src/flow_solver/physics/hydrostatics.py | 180 +++++++++++++++++------- src/flow_solver/utils/variable.py | 9 +- src/tests/test_blending_warm_bubble.py | 25 +++- 3 files changed, 155 insertions(+), 59 deletions(-) diff --git a/src/flow_solver/physics/hydrostatics.py b/src/flow_solver/physics/hydrostatics.py index b106e9e0..d83ee32e 100644 --- a/src/flow_solver/physics/hydrostatics.py +++ b/src/flow_solver/physics/hydrostatics.py @@ -79,61 +79,139 @@ def column(HydroState, HydroState_n, Y, Y_n, elem, node, th, ud): HydroState_n.p0[xc_idx, igy + 1 :] = rhoY_hydro_n[:, igy:] ** th.gamm HydroState_n.p20[xc_idx, igy + 1 :] = pi_hydro_n[:, igy:] / ud.Msq - def state(mpv, elem, node, th, ud): + """ + Compute hydrostatic background state for atmospheric model. + Handles arbitrary stratification profiles and proper numerical integration. + """ + # Thermodynamic constants + Gamma = th.gm1 / th.gamm + gamm = th.gamm + gm1 = th.gm1 + Gamma_inv = 1.0 / Gamma + gm1_inv = 1.0 / gm1 + + # Grid parameters + icy = elem.icy + igy = elem.igy + + # Reference state at y=0 + rhoY0 = 1.0 g = ud.gravity_strength[1] - + p0 = rhoY0**gamm + pi0 = rhoY0**gm1 + if g != 0.0: - Gamma = th.Gamma - Hex = 1.0 / (th.Gamma * g) - dy = elem.dy - - pi_np = np.exp(-(node.y + 0.5 * dy) / Hex) - pi_nm = np.exp(-(node.y - 0.5 * dy) / Hex) - pi_n = np.exp(-(node.y) / Hex) - - Y_n = -Gamma * g * dy / (pi_np - pi_nm) - P_n = pi_n**th.gm1inv - p_n = pi_n**th.Gammainv - rho_n = P_n / Y_n - - mpv.HydroState_n.p20[...] = pi_n / ud.Msq - mpv.HydroState_n.p0[...] = p_n - mpv.HydroState_n.rho0[...] = rho_n - mpv.HydroState_n.rhoY0[...] = P_n - mpv.HydroState_n.Y0[...] = Y_n - mpv.HydroState_n.S0[...] = 1.0 / Y_n - - pi_cp = np.exp(-(elem.y + 0.5 * dy) / Hex) - pi_cm = np.exp(-(elem.y - 0.5 * dy) / Hex) - pi_c = np.exp(-(elem.y) / Hex) - - Y_c = -Gamma * g * dy / (pi_cp - pi_cm) - P_c = pi_c**th.gm1inv - p_c = pi_c**th.Gammainv - rho_c = P_c / Y_c - - mpv.HydroState.p20[...] = pi_c / ud.Msq - mpv.HydroState.p0[...] = p_c - mpv.HydroState.rho0[...] = rho_c - mpv.HydroState.rhoY0[...] = P_c - mpv.HydroState.Y0[...] = Y_c - mpv.HydroState.S0[...] = 1.0 / Y_c - + ########################### + # Update cell hydrostates + ########################### + + # Define midpoint quadrature along vertical (y-axis) + dys = np.hstack(( + np.ones(igy-1) * -elem.dy, + [-elem.dy/2], + [elem.dy/2], + np.ones(icy-3) * elem.dy + )) + + # Cell centers and midpoints for integration + y_ps = elem.y + y_ms = np.hstack(( + elem.y[1:igy], + node.y[igy], + node.y[igy], + elem.y[igy:-1] + )) + + # Get inverse stratification at each point + S_ps = 1.0 / ud.stratification(y_ps) + S_ms = 1.0 / ud.stratification(y_ms) + + # Trapezoidal integration over inverse stratification + S_integral_p = 0.5 * dys * (S_ms + S_ps) + + # Cumulative integration (split at boundary igy) + S_integral_p[:igy] = np.cumsum(S_integral_p[:igy][::-1])[::-1] + S_integral_p[igy:] = np.cumsum(S_integral_p[igy:]) + + # Calculate hydrostatic fields + pi_hydro = pi0 - Gamma * g * S_integral_p + p_hydro = pi_hydro**Gamma_inv + rhoY_hydro = pi_hydro**gm1_inv + + # Update cell solutions + mpv.HydroState.rhoY0[:] = rhoY_hydro + mpv.HydroState.rho0[:] = rhoY_hydro * S_ps + mpv.HydroState.p0[:] = p_hydro + mpv.HydroState.p20[:] = pi_hydro / ud.Msq + mpv.HydroState.S0[:] = S_ps + mpv.HydroState.S10[:] = 0.0 + mpv.HydroState.Y0[:] = 1.0 / S_ps + + ############################ + # Update node hydrostates + ############################ + + # Bottom reference node (y=0) + mpv.HydroState_n.Y0[igy] = ud.stratification(0.0) + mpv.HydroState_n.rhoY0[igy] = rhoY0 + mpv.HydroState_n.rho0[igy] = rhoY0 / ud.stratification(0.0) + mpv.HydroState_n.S0[igy] = 1.0 / mpv.HydroState_n.Y0[igy] + mpv.HydroState_n.p0[igy] = p0 + mpv.HydroState_n.p20[igy] = pi0 / ud.Msq + + # Ghost cells below bottom (negative heights) + Sn_integral_p = np.zeros(igy) + yn_p = node.y[:igy] - node.dy + yn_m = node.y[1:igy+1] - node.dy + + Sn_integral_p[:] = -node.dy * 1.0 / ud.stratification(0.5*(yn_p + yn_m)) + Sn_integral_p = np.cumsum(Sn_integral_p[:igy][::-1])[::-1] + + # Bulk domain above reference level + yn_p = node.y[igy+1:] + yn_m = np.zeros_like(yn_p) + yn_m[1:] = yn_p[:-1] + + Sn_p = 1.0 / ud.stratification(0.5 * (yn_p + yn_m)) + Sn_integral_p = np.hstack((Sn_integral_p, np.cumsum(elem.dy * Sn_p))) + + # Calculate nodal hydrostatic fields + pi_hydro_n = pi0 - Gamma * g * Sn_integral_p + rhoY_hydro_n = pi_hydro_n**gm1_inv + + # Update node solutions - below reference + mpv.HydroState_n.rhoY0[:igy] = rhoY_hydro_n[:igy] + mpv.HydroState_n.Y0[:igy+1] = ud.stratification(0.5 * (y_ps[:igy+1] + y_ps[:igy+1] - elem.dy)) + mpv.HydroState_n.rho0[:igy] = rhoY_hydro_n[:igy] / mpv.HydroState_n.Y0[:igy] + mpv.HydroState_n.S0[:igy] = 1.0 / mpv.HydroState_n.Y0[:igy] + mpv.HydroState_n.p0[:igy] = rhoY_hydro_n[:igy]**th.gamm + mpv.HydroState_n.p20[:igy] = pi_hydro_n[:igy] / ud.Msq + + # Update node solutions - above reference + mpv.HydroState_n.rhoY0[igy+1:] = rhoY_hydro_n[igy:] + mpv.HydroState_n.Y0[igy+1:] = ud.stratification(0.5 * (y_ps[igy:] + y_ps[igy:] + elem.dy)) + mpv.HydroState_n.rho0[igy+1:] = rhoY_hydro_n[igy:] / mpv.HydroState_n.Y0[igy+1:] + mpv.HydroState_n.S0[igy+1:] = 1.0 / mpv.HydroState_n.Y0[igy+1:] + mpv.HydroState_n.p0[igy+1:] = rhoY_hydro_n[igy:]**th.gamm + mpv.HydroState_n.p20[igy+1:] = pi_hydro_n[igy:] / ud.Msq + else: - mpv.HydroState.p20[...] = 1.0 - mpv.HydroState.p0[...] = 1.0 - mpv.HydroState.rho0[...] = 1.0 - mpv.HydroState.rhoY0[...] = 1.0 - mpv.HydroState.Y0[...] = 1.0 - mpv.HydroState.S0[...] = 1.0 - - mpv.HydroState_n.p20[...] = 1.0 - mpv.HydroState_n.p0[...] = 1.0 - mpv.HydroState_n.rho0[...] = 1.0 - mpv.HydroState_n.rhoY0[...] = 1.0 - mpv.HydroState_n.Y0[...] = 1.0 - mpv.HydroState_n.S0[...] = 1.0 + # No gravity case - uniform atmosphere + mpv.HydroState.p20[:] = 1.0 + mpv.HydroState.p0[:] = 1.0 + mpv.HydroState.rho0[:] = 1.0 + mpv.HydroState.rhoY0[:] = 1.0 + mpv.HydroState.Y0[:] = 1.0 + mpv.HydroState.S0[:] = 1.0 + mpv.HydroState.S10[:] = 0.0 + + mpv.HydroState_n.p20[:] = 1.0 + mpv.HydroState_n.p0[:] = 1.0 + mpv.HydroState_n.rho0[:] = 1.0 + mpv.HydroState_n.rhoY0[:] = 1.0 + mpv.HydroState_n.Y0[:] = 1.0 + mpv.HydroState_n.S0[:] = 1.0 def initial_pressure(Sol, mpv, elem, node, ud, th): diff --git a/src/flow_solver/utils/variable.py b/src/flow_solver/utils/variable.py index e45eab43..48811fb0 100644 --- a/src/flow_solver/utils/variable.py +++ b/src/flow_solver/utils/variable.py @@ -162,8 +162,11 @@ def __init__(self, size, ud): self.get_dSdy = self.get_dSdy self.get_S0c = self.get_S0c + self.init_dSdy = False + self.init_S0c = False + def get_dSdy(self, elem, node): - if hasattr(self, "dSdy"): + if self.init_dSdy: return self.dSdy else: ndim = node.ndim @@ -177,10 +180,11 @@ def get_dSdy(self, elem, node): dSdy = np.repeat(dSdy, elem.sc[dim], axis=dim) self.dSdy = dSdy + self.init_dSdy = True return dSdy def get_S0c(self, elem): - if hasattr(self, "S0c"): + if self.init_S0c: return self.S0c else: ndim = elem.ndim @@ -191,6 +195,7 @@ def get_S0c(self, elem): S0c = np.repeat(S0c, elem.sc[dim], axis=dim) self.S0c = S0c + self.init_S0c = True return S0c diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index b6d365d3..5098cd24 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -36,31 +36,43 @@ def __init__(self): # self.output_suffix = "_%i_%i_%.1f" %(self.inx-1,self.iny-1,self.tout[-1]) self.continuous_blending = False - self.no_of_pi_initial = 0 + self.no_of_pi_initial = 1 self.no_of_pi_transition = 0 self.no_of_hy_initial = 0 self.no_of_hy_transition = 0 self.initial_blending = False + self.diag = True + self.diag_updt_targets = False + self.output_base_name = "_blending_warm_bubble" - self.output_type = "test" + self.output_type = "test" if not self.diag_updt_targets else "target" self.aux = "CFLfixed" self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) self.output_timesteps = True - self.diag = True - self.diag_updt_targets = False - self.diag_state = DiagnosticState( - test_name="test_blending_warm_bubble", + test_name=f"{self.output_type}_blending_warm_bubble", file_name="target_blending_warm_bubble", Nx=self.inx - 1, Ny=self.iny - 1, steps=[self.stepmax - 1], plot_compare=True, + time_increment=True, + # The only thing that matters here is that + # p2_nodes remains of the order of magnitude + tolerances={ + "rho": 1.0e-0, + "rhou": 1.0e-0, + "rhov": 1.0e-0, + "rhow": 1.0e-0, + "rhoY": 1.0e-0, + "rhoX": 1.0e-0, + "p2_nodes": 1.0e-0, + } ) self.autogen_fn = False @@ -107,6 +119,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): p = mpv.HydroState_n.p0 rhoY = mpv.HydroState_n.rhoY0 mpv.p2_nodes[...] = (p - mpv.HydroState_n.p0) / rhoY / ud.Msq + # mpv.p2_nodes[...] = 1.0 bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) From efe180f5edefb6000d9257b311eba54524bd5f02 Mon Sep 17 00:00:00 2001 From: raychew Date: Sat, 31 May 2025 15:37:42 -0700 Subject: [PATCH 38/76] latest yml targets although this is now no longer used --- src/tests/test_targets.yml | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/tests/test_targets.yml b/src/tests/test_targets.yml index 3e412133..45f4a41c 100644 --- a/src/tests/test_targets.yml +++ b/src/tests/test_targets.yml @@ -23,26 +23,10 @@ test_travelling_vortex: rhov: 4408.03857421875 rhow: 0.0 test_blending_warm_bubble: - p2_nodes: -16146.2158203125 - rho: 2415.7255859375 - rhoX: 289.7033386230469 - rhoY: 2416.049072265625 - rhou: -9.5367431640625e-07 - rhov: 554.5759887695312 - rhow: 0.0 -test_blending_warm_bubble: - p2_nodes: -12329.044921875 - rho: 2415.03955078125 - rhoX: 304.032958984375 - rhoY: 2415.36279296875 - rhou: 0.0 - rhov: -1.432103157043457 - rhow: 0.0 -test_blending_warm_bubble: - p2_nodes: -16146.2158203125 - rho: 2415.7255859375 - rhoX: 289.7033386230469 - rhoY: 2416.049072265625 - rhou: -9.5367431640625e-07 - rhov: 554.5759887695312 + p2_nodes: 0.2735753059387207 + rho: 2312.83837890625 + rhoX: -0.32045888900756836 + rhoY: 2313.16015625 + rhou: -4.76837158203125e-07 + rhov: -4.810579299926758 rhow: 0.0 From e3666b37107e4aa50009afbb365ee347b1dc9c61 Mon Sep 17 00:00:00 2001 From: raychew Date: Sat, 31 May 2025 16:09:50 -0700 Subject: [PATCH 39/76] moved diagnostics tolerance check to the max abs error. all tests pass. --- src/tests/diagnostics.py | 4 ++-- src/tests/test_blending_warm_bubble.py | 6 +++--- src/utils/data_structures.py | 3 +++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tests/diagnostics.py b/src/tests/diagnostics.py index f22c8e2c..f2ffe5a5 100644 --- a/src/tests/diagnostics.py +++ b/src/tests/diagnostics.py @@ -86,7 +86,7 @@ def test_do(self, mem, ud): max_abs_error = np.max(np.abs(test - ref)) try: - assert rel_l2_error < self.tolerances[attribute], ( + assert max_abs_error < self.tolerances[attribute], ( "Relative L2 error for attribute %s of %s exceeds tolerance:\n" "L2 error: %.6e\nRelative L2 error: %.6e\nMax abs error: %.6e\nTolerance: %.6e" % ( @@ -171,7 +171,7 @@ def __get_sol_for_comparison(mem, ud, attribute): else: # test_sol = mpv.p2_nodes.T * ud.Msq # test_sol -= mpv.HydroState_n.pi0[:,np.newaxis] - test_sol = get_p_from_pressure_related_fields(mem, ud, perturbation=True).T + test_sol = get_p_from_pressure_related_fields(mem, ud).T # pass return test_sol diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 5098cd24..8ca8e539 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -41,7 +41,7 @@ def __init__(self): self.no_of_hy_initial = 0 self.no_of_hy_transition = 0 - self.initial_blending = False + self.initial_blending = True self.diag = True self.diag_updt_targets = False @@ -63,7 +63,7 @@ def __init__(self): plot_compare=True, time_increment=True, # The only thing that matters here is that - # p2_nodes remains of the order of magnitude + # p2_nodes remains small tolerances={ "rho": 1.0e-0, "rhou": 1.0e-0, @@ -71,7 +71,7 @@ def __init__(self): "rhow": 1.0e-0, "rhoY": 1.0e-0, "rhoX": 1.0e-0, - "p2_nodes": 1.0e-0, + "p2_nodes": 1.0e-4, } ) diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index 8fc17c5a..6748a675 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -117,6 +117,9 @@ class DiagnosticState: plot_compare: bool = True tolerances: dict[str, float] = field(default_factory=lambda: { + # for most tests, we want to ensure that the + # max absolute error is within singular precision + # limit. "rhou": 1e-5, "rhov": 1e-5, "rhow": 1e-5, From d374d8329d7fa8905b42e4a45260388a8a15b937 Mon Sep 17 00:00:00 2001 From: raychew Date: Sun, 1 Jun 2025 00:56:46 -0700 Subject: [PATCH 40/76] fully separated the blending module (#3) --- src/flow_solver/discretisation/time_update.py | 258 ++---------------- src/interfaces/dynamics_blending/schemes.py | 211 +++++++++++++- src/interfaces/time_stepper/__init__.py | 0 src/interfaces/time_stepper/prestep.py | 17 ++ 4 files changed, 247 insertions(+), 239 deletions(-) create mode 100644 src/interfaces/time_stepper/__init__.py create mode 100644 src/interfaces/time_stepper/prestep.py diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index bbf4acb6..1a0bf5de 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -2,7 +2,6 @@ import logging import numpy as np -import termcolor # dependencies of the pyBELLA package from ...utils import io @@ -20,6 +19,7 @@ # for blending module from ...interfaces.dynamics_blending import schemes +from ...interfaces.time_stepper import prestep def data_init(ud): @@ -63,7 +63,7 @@ def do( tout, bld=None, writer=None, - debug=False, + debug_writer=None, ): """ For more details, refer to the write-up :ref:`time-stepping`. @@ -129,34 +129,12 @@ def do( dt, cfl, cfl_ac = gd_cfl.dynamic_timestep(Sol, t, tout, elem, ud, th, step) - if "CFLfixed" in ud.aux: - if step < 2: - dt = 21.69 / ud.t_ref - - c1 = ( - step == 0 - and ud.is_nonhydrostatic == 0 - and bld is not None - and "imbal" in ud.aux - ) - c2 = ( - step == 0 - and ud.is_nonhydrostatic == 1 - and ud.initial_blending == True - and bld is not None - and "imbal" in ud.aux - ) - - if c1 or c2: - logging.info("nonhydrostatic to hydrostatic conversion...") - ud.is_nonhydrostatic = 0 - # if test_hydrob == False: - # dt *= 0.5 + dt = prestep.apply_modifcations(dt, ud, step) ###################################################### # Blending : Do blending before timestep ###################################################### - swe_to_lake, Sol, mpv, t = schemes.blending_before_timestep( + swe_to_lake, Sol, mpv, t = schemes.prepare_blending( sst, mem, bld, @@ -167,7 +145,7 @@ def do( t, dt, swe_to_lake, - debug, + debug_writer, ) ud.is_nonhydrostatic = gd_eos.is_nonhydrostatic(ud, window_step) @@ -183,23 +161,16 @@ def do( compressibility = {ud.compressibility:.3f}, nonhydrostasy = {ud.nonhydrostasy:.3f} ------- """ - ) + ) Sol0 = copy.deepcopy(Sol) - flux0 = copy.deepcopy(flux) - mpv0 = copy.deepcopy(mpv) - if debug == True: - writer.write_all(mem, str(label) + "_before_flux") + debug_writer.write(f"{label}_before_flux") gd_flux.recompute_advective_fluxes(flux, Sol) - if debug: - writer.populate(f"{label}_before_advect", "rhoYu", flux[0].rhoY) - writer.populate(f"{label}_before_advect", "rhoYv", flux[1].rhoY) - if elem.ndim == 3: - writer.populate(f"{label}_before_advect", "rhoYw", flux[2].rhoY) - writer.write_all(mem, f"{label}_before_advect") + debug_writer.populate_flux_components(f"{label}_before_advect", flux, elem) + debug_writer.write(f"{label}_before_advect") if ud.do_advection: gd_explicit.advect_rk( @@ -216,16 +187,14 @@ def do( writer, ) - if debug: - writer.write_all(mem, str(label) + "_after_advect") - writer.populate(str(label) + "_after_full_step", "p2_nodes0", mpv.p2_nodes) + debug_writer.write(f"{label}_after_advect") + debug_writer.populate(f"{label}_after_full_step", "p2_nodes", mpv.p2_nodes) mpv.p2_nodes0[...] = mpv.p2_nodes lm_sp.euler_backward_non_advective_expl_part(Sol, mpv, elem, 0.5 * dt, ud, th) - if debug == True: - writer.write_all(mem, str(label) + "_after_ebnaexp") + debug_writer.write(f"{label}_after_ebnaexp") Sol0_increment = Sol0 if ud.is_compressible == 0 else None @@ -291,30 +260,16 @@ def do( ) bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - if debug == True: - writer.write_all(mem, str(label) + "_after_ebnaimp") - - flux_half_new = copy.deepcopy(flux) + debug_writer.write(f"{label}_after_ebnaimp") gd_flux.recompute_advective_fluxes(flux, Sol) - if debug: - writer.populate(f"{label}_after_half_step", "rhoYu", flux[0].rhoY) - writer.populate(f"{label}_after_half_step", "rhoYv", flux[1].rhoY) - if elem.ndim == 3: - writer.populate(f"{label}_after_half_step", "rhoYw", flux[2].rhoY) - writer.write_all(mem, f"{label}_after_half_step") + debug_writer.populate_flux_components(f"{label}_after_half_step", flux, elem) + debug_writer.write(f"{label}_after_half_step") Sol_half_new = copy.deepcopy(Sol) mpv_half_new = copy.deepcopy(mpv) - rho_half = np.copy(Sol.rho) - rhou_half = np.copy(Sol.rhou) - rhov_half = np.copy(Sol.rhov) - rhow_half = np.copy(Sol.rhow) - rhoX_half = np.copy(Sol.rhoX) - rhoY_half = np.copy(Sol.rhoY) - # pwchi = np.copy(Sol.pwchi) - p2_nodes_half = np.copy(mpv.p2_nodes) + mpv.p2_nodes_half = np.copy(mpv.p2_nodes) if ud.is_nonhydrostatic == 0 or ( ud.is_compressible == 1 and ud.is_nonhydrostatic == 1 @@ -323,29 +278,6 @@ def do( Sol = copy.deepcopy(Sol0) - # Sol.rhov0 = np.copy(Sol.rhov) - Sol.rho_half = rho_half - Sol.rhou_half = rhou_half - Sol.rhov_half = rhov_half - Sol.rhow_half = rhow_half - Sol.rhoX_half = rhoX_half - Sol.rhoY_half = rhoY_half - mpv.p2_nodes_half = p2_nodes_half - # Sol.pwchi = pwchi - - # Sol.rho_half = Sol.rho - # Sol.rhou_half = Sol.rhou - # Sol.rhov_half = Sol.rhov - # Sol.rhow_half = Sol.rhow - # Sol.rhoX_half = Sol.rhoX - # Sol.rhoY_half = Sol.rhoY - # mpv.p2_nodes_half = mpv.p2_nodes - Sol_half_old = copy.deepcopy(Sol_half_new) - flux_half_old = copy.deepcopy(flux_half_new) - mpv_half_old = copy.deepcopy(mpv_half_new) - - # mpv.p2_nodes[...] = ud.compressibility * mpv.p2_nodes0 + (1.0-ud.compressibility) * mpv.p2_nodes - lm_sp.euler_forward_non_advective( Sol, mpv, @@ -358,8 +290,7 @@ def do( label=str(label) + "_after_efna", ) - if debug == True: - writer.write_all(mem, str(label) + "_after_efna") + debug_writer.write(f"{label}_after_efna") if ud.do_advection: gd_explicit.advect( @@ -376,13 +307,11 @@ def do( writer, ) - if debug == True: - writer.write_all(mem, str(label) + "_after_full_advect") + debug_writer.write(f"{label}_after_full_advect") lm_sp.euler_backward_non_advective_expl_part(Sol, mpv, elem, 0.5 * dt, ud, th) - if debug == True: - writer.write_all(mem, str(label) + "_after_full_ebnaexp") + debug_writer.write(f"{label}_after_full_ebnaexp") lm_sp.euler_backward_non_advective_impl_part( Sol, @@ -442,8 +371,6 @@ def do( ) bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - # if writer is not None: writer.populate(str(label)+'_after_full_step','p2_half',mpv.p2_nodes_half) - ###################################################### # Blending : Do blending after timestep ###################################################### @@ -463,152 +390,9 @@ def do( t, dt, swe_to_lake, - debug, + debug_writer, ) - if c1 or c2: - logging.info( - termcolor.colored("hydrostatic to nonhydrostatic conversion...", "blue") - ) - - # writer.write_all(mem, str(label) + "_half_full") - # writer.populate(str(label) + "_ic", "pwchi", Sol.pwchi) - - # if test_hydrob == False: - # Sol = copy.deepcopy(Sol_half_old) - # # mpv = copy.deepcopy(mpv_half_old) - - # logging.info(termcolor.colored("test_hydrob == False", "red")) - # writer.write_all(mem, str(label) + "_quarter") - - # writer.populate(str(label) + "_quarter", "pwchi", Sol.pwchi) - - # logging.info("quarter dt = %.8f" % (dt * 0.5)) - - # ret = do( - # Sol_half_old, - # flux_half_old, - # mpv_half_old, - # dt - 0.5 * dt, - # dt + 0.5 * dt, - # ud, - # elem, - # node, - # [0, 0], - # th, - # bld=None, - # writer=None, - # debug=False, - # ) - - # Sol_tu = copy.deepcopy(ret[0]) - # # mpv_tu = copy.deepcopy(ret[2]) - # Sol.rho[...] = Sol_tu.rho_half - # Sol.rhou[...] = Sol_tu.rhou_half - # Sol.rhov[...] = Sol_tu.rhov_half - # Sol.rhow[...] = Sol_tu.rhow_half - # Sol.rhoX[...] = Sol_tu.rhoX_half - # Sol.rhoY[...] = Sol_tu.rhoY_half - # Sol.pwchi[...] = Sol_tu.pwchi - - # # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half - - # writer.write_all(mem, str(label) + "_half") - - # writer.populate(str(label) + "_half", "pwchi", Sol.pwchi) - - # ret = do( - # Sol, - # flux, - # mpv, - # dt, - # 2.0 * dt, - # ud, - # elem, - # node, - # [0, 0], - # th, - # bld=None, - # writer=None, - # debug=False, - # ) - - # Sol = copy.deepcopy(ret[0]) - # flux = copy.deepcopy(ret[1]) - # mpv = copy.deepcopy(ret[2]) - - # if test_hydrob == True: - # Sol = copy.deepcopy(Sol_half_old) - # # mpv = copy.deepcopy(mpv_half_old) - - # logging.info(termcolor.colored("test_hydrob == False", "red")) - # writer.write_all(mem, str(label) + "_quarter") - - # # writer.populate(str(label)+'_quarter', 'pwchi', Sol.pwchi) - - # logging.info("quarter dt = %.8f" % (dt * 0.5)) - - # ret = do( - # Sol_half_old, - # flux_half_old, - # mpv_half_old, - # dt - 0.5 * dt, - # dt + 0.5 * dt, - # ud, - # elem, - # node, - # [0, 0], - # th, - # bld=None, - # writer=None, - # debug=False, - # ) - - # Sol_tu = copy.deepcopy(ret[0]) - # # mpv_tu = copy.deepcopy(ret[2]) - # Sol.rho[...] = Sol_tu.rho_half - # Sol.rhou[...] = Sol_tu.rhou_half - # Sol.rhov[...] = Sol_tu.rhov_half - # Sol.rhow[...] = Sol_tu.rhow_half - # Sol.rhoX[...] = Sol_tu.rhoX_half - # Sol.rhoY[...] = Sol_tu.rhoY_half - # Sol.pwchi[...] = Sol_tu.pwchi - - # # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half - - # # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') - - # # writer.populate(str(label)+'_half', 'pwchi', Sol.pwchi) - - # ret = do( - # Sol, - # flux, - # mpv, - # dt, - # 2.0 * dt, - # ud, - # elem, - # node, - # [0, 0], - # th, - # bld=None, - # writer=None, - # debug=False, - # ) - - # Sol = copy.deepcopy(ret[0]) - # flux = copy.deepcopy(ret[1]) - # mpv = copy.deepcopy(ret[2]) - # # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') - # # writer.populate(str(label)+'_half', 'pwchi', Sol.pwchi) - - # logging.info(termcolor.colored("test_hydrob == True", "red")) - - # if test_hydrob == False: - # dt *= 2.0 - if c2: - ud.is_nonhydrostatic = 1 - mem.sol = Sol mem.flux = flux mem.mpv = mpv @@ -616,7 +400,7 @@ def do( if writer != None: writer.time = t writer.write_all(mem, str(label) + "_after_full_step") - # writer.populate(str(label)+'_after_full_step', 'pwchi', Sol.pwchi) + logging.info( "###############################################################################################" ) diff --git a/src/interfaces/dynamics_blending/schemes.py b/src/interfaces/dynamics_blending/schemes.py index c06d61b8..bad652ce 100644 --- a/src/interfaces/dynamics_blending/schemes.py +++ b/src/interfaces/dynamics_blending/schemes.py @@ -5,7 +5,7 @@ from scipy import signal from ...flow_solver.physics.gas_dynamics import eos as gd_eos - +from ...utils import io class Blend(object): """ @@ -139,7 +139,7 @@ def do_psinc_to_comp_conv( tout, bld=None, writer=None, - debug=False, + debug_writer=io.NullDebugWriter(), ) ud = sst.ud @@ -384,6 +384,154 @@ def do_hydro_to_nonhydro_conv( # bld.update_Sol(Sol,elem,node,th,ud,mpv,'aft',label=label,writer=writer) # bld.update_p2n(Sol,mpv,node,th,ud) # + + ############################### + # alternative version + ############################### + + # if c1 or c2: + # logging.info( + # termcolor.colored("hydrostatic to nonhydrostatic conversion...", "blue") + # ) + + # writer.write_all(mem, str(label) + "_half_full") + # writer.populate(str(label) + "_ic", "pwchi", Sol.pwchi) + + # if test_hydrob == False: + # Sol = copy.deepcopy(Sol_half_old) + # # mpv = copy.deepcopy(mpv_half_old) + + # logging.info(termcolor.colored("test_hydrob == False", "red")) + # writer.write_all(mem, str(label) + "_quarter") + + # writer.populate(str(label) + "_quarter", "pwchi", Sol.pwchi) + + # logging.info("quarter dt = %.8f" % (dt * 0.5)) + + # ret = do( + # Sol_half_old, + # flux_half_old, + # mpv_half_old, + # dt - 0.5 * dt, + # dt + 0.5 * dt, + # ud, + # elem, + # node, + # [0, 0], + # th, + # bld=None, + # writer=None, + # debug=False, + # ) + + # Sol_tu = copy.deepcopy(ret[0]) + # # mpv_tu = copy.deepcopy(ret[2]) + # Sol.rho[...] = Sol_tu.rho_half + # Sol.rhou[...] = Sol_tu.rhou_half + # Sol.rhov[...] = Sol_tu.rhov_half + # Sol.rhow[...] = Sol_tu.rhow_half + # Sol.rhoX[...] = Sol_tu.rhoX_half + # Sol.rhoY[...] = Sol_tu.rhoY_half + # Sol.pwchi[...] = Sol_tu.pwchi + + # # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half + + # writer.write_all(mem, str(label) + "_half") + + # writer.populate(str(label) + "_half", "pwchi", Sol.pwchi) + + # ret = do( + # Sol, + # flux, + # mpv, + # dt, + # 2.0 * dt, + # ud, + # elem, + # node, + # [0, 0], + # th, + # bld=None, + # writer=None, + # debug=False, + # ) + + # Sol = copy.deepcopy(ret[0]) + # flux = copy.deepcopy(ret[1]) + # mpv = copy.deepcopy(ret[2]) + + # if test_hydrob == True: + # Sol = copy.deepcopy(Sol_half_old) + # # mpv = copy.deepcopy(mpv_half_old) + + # logging.info(termcolor.colored("test_hydrob == False", "red")) + # writer.write_all(mem, str(label) + "_quarter") + + # # writer.populate(str(label)+'_quarter', 'pwchi', Sol.pwchi) + + # logging.info("quarter dt = %.8f" % (dt * 0.5)) + + # ret = do( + # Sol_half_old, + # flux_half_old, + # mpv_half_old, + # dt - 0.5 * dt, + # dt + 0.5 * dt, + # ud, + # elem, + # node, + # [0, 0], + # th, + # bld=None, + # writer=None, + # debug=False, + # ) + + # Sol_tu = copy.deepcopy(ret[0]) + # # mpv_tu = copy.deepcopy(ret[2]) + # Sol.rho[...] = Sol_tu.rho_half + # Sol.rhou[...] = Sol_tu.rhou_half + # Sol.rhov[...] = Sol_tu.rhov_half + # Sol.rhow[...] = Sol_tu.rhow_half + # Sol.rhoX[...] = Sol_tu.rhoX_half + # Sol.rhoY[...] = Sol_tu.rhoY_half + # Sol.pwchi[...] = Sol_tu.pwchi + + # # mpv.p2_nodes[...] = mpv_tu.p2_nodes_half + + # # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') + + # # writer.populate(str(label)+'_half', 'pwchi', Sol.pwchi) + + # ret = do( + # Sol, + # flux, + # mpv, + # dt, + # 2.0 * dt, + # ud, + # elem, + # node, + # [0, 0], + # th, + # bld=None, + # writer=None, + # debug=False, + # ) + + # Sol = copy.deepcopy(ret[0]) + # flux = copy.deepcopy(ret[1]) + # mpv = copy.deepcopy(ret[2]) + # # writer.write_all(Sol,mpv,elem,node,th,str(label)+'_half') + # # writer.populate(str(label)+'_half', 'pwchi', Sol.pwchi) + + # logging.info(termcolor.colored("test_hydrob == True", "red")) + + # if test_hydrob == False: + # dt *= 2.0 + # if c2: + # ud.is_nonhydrostatic = 1 + return Sol, mpv @@ -591,3 +739,62 @@ def blending_after_timestep( ud.compressibility = 1.0 return Sol, mpv + + +def prepare_blending( + sst, + mem, + bld, + label, + writer, + step, + window_step, + t, + dt, + swe_to_lake, + debug, + ): + + ud = sst.ud + if check_and_apply_initial_hydrostatic_conversion(step, ud, bld): + ud.is_nonhydrostatic = 0 + + swe_to_lake, Sol, mpv, t = blending_before_timestep( + sst, + mem, + bld, + label, + writer, + step, + window_step, + t, + dt, + swe_to_lake, + debug, + ) + + return swe_to_lake, Sol, mpv, t + + +def check_and_apply_initial_hydrostatic_conversion(step, ud, bld): + """ + Check and apply initial blending conversion if needed. + + Returns: + bool: True if conversion was applied, False otherwise + """ + if step != 0 or bld is None or "imbal" not in ud.aux: + return False + + hydrostatic_case = ud.is_nonhydrostatic == 0 + nonhydrostatic_case = ( + ud.is_nonhydrostatic == 1 and ud.initial_blending == True + ) + + if hydrostatic_case or nonhydrostatic_case: + logging.info("nonhydrostatic to hydrostatic conversion...") + ud.is_nonhydrostatic = 0 + return True + + return False + diff --git a/src/interfaces/time_stepper/__init__.py b/src/interfaces/time_stepper/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/interfaces/time_stepper/prestep.py b/src/interfaces/time_stepper/prestep.py new file mode 100644 index 00000000..3206579a --- /dev/null +++ b/src/interfaces/time_stepper/prestep.py @@ -0,0 +1,17 @@ +""" +Pre-step modifications for the time stepper. +""" + +def apply_modifcations(dt, ud, step): + """Apply modifications to the timestep based on user-defined parameters.""" + + dt = _apply_cfl_override(dt, ud, step) + + return dt + + +def _apply_cfl_override(dt, ud, step): + """Apply CFL override for fixed timestep cases.""" + if "CFLfixed" in ud.aux and step < 2: + return 21.69 / ud.t_ref + return dt \ No newline at end of file From 097739806b4ea9a5d35b52d2ba8c70bdeb755942 Mon Sep 17 00:00:00 2001 From: raychew Date: Sun, 1 Jun 2025 00:57:35 -0700 Subject: [PATCH 41/76] created debug writer object --- src/__main__.py | 4 ++- src/utils/io.py | 79 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/src/__main__.py b/src/__main__.py index 5b996fda..27346e1b 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -62,6 +62,8 @@ def main(): if sst.N == 1: mem.time.window_step = mem.time.step + debug_writer = io.create_debug_writer(params.debug, writer, mem) + logging.info("For ensemble member = %i..." % cnt) mem = dis_time_update.do( sst, @@ -69,7 +71,7 @@ def main(): tout, blend, step_writer, - params.debug, + debug_writer ) if sst.ud.diag: diff --git a/src/utils/io.py b/src/utils/io.py index 119d7eea..75034656 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -195,22 +195,6 @@ def write_all(self, model_state, name): self.populate(name, "rhow", Sol.rhow) self.populate(name, "rhoX", Sol.rhoX) - # if hasattr(Sol,'rhov_half'): - # self.populate(name,'rhov_half',Sol.rhov_half) - # if hasattr(Sol,'rhou_half'): - # self.populate(name,'rhou_half',Sol.rhou_half) - # if hasattr(Sol,'rhow_half'): - # self.populate(name,'rhow_half',Sol.rhow_half) - # if hasattr(Sol,'rhoX_half'): - # self.populate(name,'rhoX_half',Sol.rhoX_half) - # if hasattr(Sol,'rhoY_half'): - # self.populate(name,'rhoY_half',Sol.rhoY_half) - # if hasattr(Sol,'rho_half'): - # self.populate(name,'rho_half',Sol.rho_half) - # if hasattr(mpv,'p2_nodes_half'): - # self.populate(name,'p2_nodes_half',mpv.p2_nodes_half) - # self.populate(name,'buoy',Sol.rhoX / Sol.rho) - self.populate(name, "p2_nodes", mpv.p2_nodes) # vorticity in (x,z) @@ -801,4 +785,67 @@ def init_logger(ud): # add the handler to the root logger logging.getLogger().addHandler(console) + # Suppress matplotlib debug output + logging.getLogger("matplotlib").setLevel(logging.WARNING) + logging.getLogger("matplotlib.font_manager").setLevel(logging.WARNING) + logging.info("Input file is %s" % input_filename) + + +class NullDebugWriter: + """Null object that does nothing but implements the DebugWriter interface.""" + + def populate(self, label, field_name, data): + """No-op populate method.""" + pass + + def write(self, label): + """No-op write method.""" + pass + + def populate_flux_components(self, label, flux, elem): + """No-op populate flux components method.""" + pass + +class DebugWriter: + """Enhanced debug writer with populate functionality.""" + + def __init__(self, debug, writer, mem): + self.debug = debug + self.writer = writer + self.mem = mem + self._pending_populations = {} + + def populate(self, label, field_name, data): + """Populate field data for a given label.""" + if self.debug and self.writer is not None: + if label not in self._pending_populations: + self._pending_populations[label] = [] + self._pending_populations[label].append((field_name, data)) + + def write(self, label): + """Write all data including any pending populations.""" + if self.debug and self.writer is not None: + # Apply any pending populations for this label + if label in self._pending_populations: + for field_name, data in self._pending_populations[label]: + self.writer.populate(label, field_name, data) + del self._pending_populations[label] + + # Write the data + self.writer.write_all(self.mem, label) + + def populate_flux_components(self, label, flux, elem): + """Helper method to populate flux components.""" + if self.debug and self.writer is not None: + self.populate(label, "rhoYu", flux[0].rhoY) + self.populate(label, "rhoYv", flux[1].rhoY) + if elem.ndim == 3: + self.populate(label, "rhoYw", flux[2].rhoY) + +def create_debug_writer(debug, writer, mem): + """Factory function to create appropriate debug writer.""" + if debug and writer is not None: + return DebugWriter(debug, writer, mem) + else: + return NullDebugWriter() \ No newline at end of file From 4afbf211a80aff2aaae21ff91419fd554d3472da Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 02:42:11 -0700 Subject: [PATCH 42/76] removed deprecated functions to run with modern Python see #33 for version of Python and dependencies --- .../physics/low_mach/second_projection.py | 2 +- src/tests/test_blending_warm_bubble.py | 10 +--------- src/tests/test_internal_long_wave.py | 12 ++++++------ src/tests/test_lamb_wave.py | 12 ++++++------ src/tests/test_travelling_vortex.py | 12 ++++++------ 5 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/flow_solver/physics/low_mach/second_projection.py b/src/flow_solver/physics/low_mach/second_projection.py index 23461a17..406bb777 100644 --- a/src/flow_solver/physics/low_mach/second_projection.py +++ b/src/flow_solver/physics/low_mach/second_projection.py @@ -268,7 +268,7 @@ def euler_backward_non_advective_impl_part( # p2, _ = bicgstab(lap,rhs_inner,tol=ud.tol,maxiter=ud.max_iterations,callback=counter) p2, _ = sp.sparse.linalg.bicgstab( - lap, rhs_inner, tol=ud.tol, maxiter=ud.max_iterations, callback=counter + lap, rhs_inner, atol=ud.tol, maxiter=ud.max_iterations, callback=counter ) # p2, _ = gmres(lap,rhs_inner,tol=ud.tol,maxiter=ud.max_iterations) # p2,info = bicgstab(lap,rhs.ravel(),x0=p2.ravel(),tol=1e-16,maxiter=6000,callback=counter) diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 8ca8e539..1ae1df55 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -28,13 +28,6 @@ def __init__(self): self.is_compressible = 1 - # if self.is_compressible == 1: - # self.output_suffix = "_%i_%i_%.1f_comp" %(self.inx-1,self.iny-1,self.tout[-1]) - # if self.is_compressible == 0: - # self.output_suffix = "_%i_%i_%.1f_psinc" %(self.inx-1,self.iny-1,self.tout[-1]) - # if self.continuous_blending == True: - # self.output_suffix = "_%i_%i_%.1f" %(self.inx-1,self.iny-1,self.tout[-1]) - self.continuous_blending = False self.no_of_pi_initial = 1 self.no_of_pi_transition = 0 @@ -99,7 +92,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): p = np.repeat(mpv.HydroState.p0.reshape(1, -1), elem.icx, axis=0) rhoY = mpv.HydroState.rhoY0[ np.newaxis, : - ] # np.repeat(mpv.HydroState.rhoY0.reshape(1,-1),elem.icx,axis=0) + ] perturbation = (delth / 300.0) * (np.cos(0.5 * np.pi * r) ** 2) perturbation[np.where(r > 1.0)] = 0.0 @@ -119,7 +112,6 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): p = mpv.HydroState_n.p0 rhoY = mpv.HydroState_n.rhoY0 mpv.p2_nodes[...] = (p - mpv.HydroState_n.p0) / rhoY / ud.Msq - # mpv.p2_nodes[...] = 1.0 bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) diff --git a/src/tests/test_internal_long_wave.py b/src/tests/test_internal_long_wave.py index c4d609b0..0777d45a 100644 --- a/src/tests/test_internal_long_wave.py +++ b/src/tests/test_internal_long_wave.py @@ -68,13 +68,13 @@ def __init__(self): # self.coriolis_strength[2] = self.omega * self.t_ref # self.coriolis_strength[1] = self.omega * self.t_ref - for i in range(3): - if (self.gravity_strength[i] > np.finfo(np.float).eps) or (i == 1): - self.i_gravity[i] = 1 - self.gravity_direction = i + gravity_mask = (self.gravity_strength > np.finfo(np.float64).eps) | (np.arange(3) == 1) + self.i_gravity = gravity_mask.astype(int) + if np.any(gravity_mask): + self.gravity_direction = np.where(gravity_mask)[0][-1] # Use last matching index - if self.coriolis_strength[i] > np.finfo(np.float).eps: - self.i_coriolis[i] = 1 + coriolis_mask = self.coriolis_strength > np.finfo(np.float64).eps + self.i_coriolis = coriolis_mask.astype(int) self.xmin = -15.0 * self.scale_factor self.xmax = 15.0 * self.scale_factor diff --git a/src/tests/test_lamb_wave.py b/src/tests/test_lamb_wave.py index ed7f24f6..ec3f055f 100644 --- a/src/tests/test_lamb_wave.py +++ b/src/tests/test_lamb_wave.py @@ -63,13 +63,13 @@ def __init__(self): self.gravity_strength[1] = self.grav * self.h_ref / (self.R_gas * self.T_ref) self.coriolis_strength[2] = 2.0 * self.omega * self.t_ref - for i in range(3): - if (self.gravity_strength[i] > np.finfo(np.float).eps) or (i == 1): - self.i_gravity[i] = 1 - self.gravity_direction = 1 + gravity_mask = (self.gravity_strength > np.finfo(np.float64).eps) | (np.arange(3) == 1) + self.i_gravity = gravity_mask.astype(int) + if np.any(gravity_mask): + self.gravity_direction = np.where(gravity_mask)[0][-1] # Use last matching index - if self.coriolis_strength[i] > np.finfo(np.float).eps: - self.i_coriolis[i] = 1 + coriolis_mask = self.coriolis_strength > np.finfo(np.float64).eps + self.i_coriolis = coriolis_mask.astype(int) j = 4.0 Lx = 1.0 * np.pi * self.Cs / self.N_ref * j diff --git a/src/tests/test_travelling_vortex.py b/src/tests/test_travelling_vortex.py index d3bfeae4..15a4ff6a 100644 --- a/src/tests/test_travelling_vortex.py +++ b/src/tests/test_travelling_vortex.py @@ -64,13 +64,13 @@ def __init__(self): self.coriolis_strength[0] = self.omega * self.t_ref self.coriolis_strength[2] = self.omega * self.t_ref - for i in range(3): - if (self.gravity_strength[i] > np.finfo(np.float).eps) or (i == 1): - self.i_gravity[i] = 1 - self.gravity_direction = 1 + gravity_mask = (self.gravity_strength > np.finfo(np.float64).eps) | (np.arange(3) == 1) + self.i_gravity = gravity_mask.astype(int) + if np.any(gravity_mask): + self.gravity_direction = np.where(gravity_mask)[0][-1] # Use last matching index - if self.coriolis_strength[i] > np.finfo(np.float).eps: - self.i_coriolis[i] = 1 + coriolis_mask = self.coriolis_strength > np.finfo(np.float64).eps + self.i_coriolis = coriolis_mask.astype(int) self.xmin = -0.5 self.xmax = 0.5 From 30c46ff0f9d6371f045499c22cbdbcca2e40174f Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 02:42:31 -0700 Subject: [PATCH 43/76] updated requirements.txt --- requirements.txt | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/requirements.txt b/requirements.txt index 26d29b2b..1aa3210d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,12 +1,9 @@ -dask==2022.7.0 -dask[distributed]==2022.7.0 -dill==0.3.6 -h5py==3.7.0 -matplotlib==3.5.1 -numba==0.56.4 -numpy==1.22.1 -pyemd==1.0.0 -pytest==8.1.1 -PyYAML==6.0 -scipy==1.7.3 -termcolor==2.4.0 +dill +h5py +matplotlib +numba +numpy +pytest +scipy +dask + From 3d951e3bb2b6a1a77e6e03f7943dfaf31ce19f16 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 15:06:23 -0700 Subject: [PATCH 44/76] first attempt at reinstating unstable lamb IC (#37) --- src/tests/test_unstable_lamb.py | 297 ++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 src/tests/test_unstable_lamb.py diff --git a/src/tests/test_unstable_lamb.py b/src/tests/test_unstable_lamb.py new file mode 100644 index 00000000..3402cded --- /dev/null +++ b/src/tests/test_unstable_lamb.py @@ -0,0 +1,297 @@ +""" +Unstable Lamb Wave integral test involving vertical Coriolis and Rayleigh BC. +""" + +import numpy as np +from ..flow_solver.physics import hydrostatics +from ..flow_solver.utils import boundary as bdry + +from ..utils.data_structures import DiagnosticState + + +class UserData(object): + def __init__(self): + self.grav = 9.81 # [m/s^2] + self.omega = 7.292 * 1e-5 # [s^{-1}] + self.t_ref = 100.0 # [s] + + self.h_ref = 10.0e3 # [m] + self.u_ref = self.h_ref / self.t_ref + + self.T_ref = 300.00 # [K] + self.R_gas = 287.4 # [J kg^{-1} K^{-1}] + self.gamma = 1.4 + self.cp_gas = self.gamma * self.R_gas / (self.gamma-1.0) + + self.Nsq = (self.grav / np.sqrt(self.cp_gas * self.T_ref))**2 + self.Msq = self.u_ref * self.u_ref / (self.R_gas * self.T_ref) + + ########################################## + # SPATIAL GRID + ########################################## + self.inx = 301 + 1 + self.iny = 30 + 1 + self.inz = 1 + + self._setup_domain() + + ########################################## + # BOUNDARY CONDITIONS + ########################################## + from ..flow_solver.utils import options as opts + + self.bdry_type = np.empty((3), dtype=object) + self.bdry_type[0] = opts.BdryType.PERIODIC + self.bdry_type[1] = opts.BdryType.WALL + self.bdry_type[2] = opts.BdryType.WALL + self.ATMOSPHERIC_EXTENSION = True + + ########################################## + # NUMERICS + ########################################## + self.CFL = 0.9 + self.dtfixed0 = 100.0 / self.t_ref + self.dtfixed = self.dtfixed0 + + self.tout = [36.0] + self.stepmax = 101 + + self.is_compressible = 1 + self.is_nonhydrostatic = 1 + self.is_ArakawaKonor = 0 + + self.compressibility = 1.0 + self.acoustic_timestep = 0 + + ########################################## + # PHYSICS AND BACKGROUND WIND + ########################################## + self.u_wind_speed = 0.0 + self.v_wind_speed = 0.0 + self.w_wind_speed = 0.0 + + ########################################## + # BLENDING + ########################################## + self.continuous_blending = False + self.no_of_pi_initial = 1 + self.no_of_pi_transition = 0 + self.no_of_hy_initial = 0 + self.no_of_hy_transition = 0 + + self.blending_weight = 0.0 / 16 + self.blending_mean = "rhoY" + self.blending_conv = "rho" + self.blending_type = "half" + self.initial_blending = False + + ########################################## + # STRATIFICATION + ########################################## + self.stratification = self.stratification_wrapper + + ########################################## + # DIAGNOSTICS + ########################################## + self.diag = True + self.diag_updt_targets = True + + ########################################## + # OUTPUTS + ########################################## + self.output_base_name = "_unstable_lamb" + self.output_type = "test" if not self.diag_updt_targets else "target" + self.aux = "" + self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) + + self.output_timesteps = True + + # Rayleigh forcing parameters + self.rayleigh_forcing = True + self.rayleigh_forcing_type = "func" + self.rayleigh_forcing_fn = None + self.rayleigh_forcing_path = None + + self.diag_state = DiagnosticState( + test_name="test_unstable_lamb", + file_name="target_unstable_lamb", + Nx=self.inx - 1, + Ny=self.iny - 1, + steps=[self.stepmax - 1], + plot_compare=True, + ) + + self.autogen_fn = False + + def _setup_domain(self): + """Setup domain dimensions based on wave parameters""" + # Reference values (from global constants) + R_gas = 287.4 # [J kg^{-1} K^{-1}] + gamma = 1.4 + T_ref = 300.0 # [K] + h_ref = 10.0e3 # [m] + + # Compute derived quantities + Cs = np.sqrt(gamma * R_gas * T_ref) + cp_gas = gamma * R_gas / (gamma - 1.0) + N_ref = self.grav / np.sqrt(cp_gas * T_ref) + + # Domain size calculation + j = 4.0 + Lx = 1.0 * np.pi * Cs / N_ref * j + + self.xmin = -Lx / h_ref + self.xmax = Lx / h_ref + self.ymin = 0.0 + self.ymax = 2.0 + self.zmin = -1.0 + self.zmax = 1.0 + + def stratification_wrapper(self, dy): + return lambda y : self.stratification_function(y, dy) + + def stratification_function(self, y, dy): + + Nsq = self.Nsq * self.t_ref**2 + g = self.grav / self.Msq + + return np.exp(Nsq * y / g) + + + +def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): + def bump(xi): + # eqn (11) + tmp = np.zeros_like(xi) + tmp[np.where(np.abs(xi) < 1.0)] = np.exp( + -1.0 / (1.0 - xi[np.where(np.abs(xi) < 1.0)] ** 2) + ) + # return tmp + return np.ones_like(xi) + + if ud.bdry_type[1].value == "radiation": + ud.tcy, ud.tny = bdry.get_tau_y(ud, elem, node, 0.5) + + if hasattr(ud, "rayleigh_forcing"): + if ud.rayleigh_forcing: + ud.forcing_tcy, ud.forcing_tny = bdry.get_bottom_tau_y( + ud, elem, node, 0.2, cutoff=0.1 + ) + + A0 = 1.0e-3 # eqn (12) + + Msq = ud.Msq + g = ud.gravity_strength[1] + kappa = th.Gamma + + x = elem.x.reshape(-1, 1) + y = elem.y.reshape(1, -1) + dy = np.diff(node.y)[0] + + Hrho = 1.0 / g + use_hydrostate = False + + ud.stratification = ud.stratification(dy) + hydrostatics.state(mpv, elem, node, th, ud) + + if use_hydrostate: + # Use hydrostatically balanaced background + rhobar = mpv.HydroState.rho0.reshape(1, -1) + Ybar = mpv.HydroState.Y0.reshape(1, -1) + pibar = mpv.HydroState.p20.reshape(1, -1) * ud.Msq + + else: + # Use hydrostatic balance in Mark's notes + Htheta = Hrho / kappa + rhobar = np.exp(-y / Hrho) + Ybar = np.exp(y / Htheta) + pibar = 1.0 / Ybar + mpv.HydroState.rho0[...] = rhobar + mpv.HydroState.Y0[...] = Ybar + mpv.HydroState.S0[...] = 1.0 / Ybar # 1.0 / ud.stratification(y) + mpv.HydroState.rhoY0[...] = rhobar * Ybar + + # dimensionless Brunt-Väisälä frequency + N = ud.t_ref * np.sqrt(ud.Nsq_ref) + # dimensionless speed of sound + Cs = np.sqrt(th.gamm / Msq) + waveno = N / Cs + + ud.u_wind_speed = 0.0 # -Cs + + Gamma = 1.0 / Hrho * (1.0 / th.gamm - 0.5) + + # time shift of the initial solution + ts = -0.5 / N * np.pi + ts = 0.0 + + # set up perturbation quantities + # exp(-kGam * y) / sqrt(rhobar) / Ybar = 1.0 + up = A0 * Ybar * np.cos(waveno * x + Cs * ts) + vp = 0.0 + wp = 0.0 + Yp = 0.0 + # th.Gamma * ud.Msq == 1 / dimensionless(c_p) + fac = th.Gamma + pi = A0 * Cs * fac * np.cos(waveno * x + Cs * ts) * Msq + + # up = A / rhobar**0.5 * np.exp(-Gamma * y) * np.cos(N / Cs * (waveno * x + Cs * ts)) + # pi = A * Cs * fac / rhobar**0.5 / Ybar * np.exp(-Gamma * y) * np.cos(N / Cs * (waveno * x + Cs * ts)) + + u = ud.u_wind_speed + up + v = ud.v_wind_speed + vp + w = ud.w_wind_speed + wp + Y = Ybar + Yp + dPdpi = th.gm1inv * pibar ** (th.gm1inv - 1.0) + Pbar = pibar**th.gm1inv + rhoY = Pbar # + dPdpi * pi + + # eqn (2.3) + # rho = (((pibar + pi))**th.gm1inv) / Y + # rho = Pbar / Y + rhobar = Pbar / Ybar + rho = rhobar # rhoY / Ybar + + Sol.rho[...] = Pbar / Y + Sol.rhou[...] = rho * u + Sol.rhov[...] = rho * v + Sol.rhow[...] = rho * w + Sol.rhoY[...] = rhoY + Sol.rhoX[...] = 0.0 + mpv.p2_cells[...] = pi / Msq + + ################################################### + # initialise nodal pi + xn = node.x.reshape(-1, 1) + yn = node.y.reshape(1, -1) + + # initialise nodal pressure + Hrho_n = Hrho + + if use_hydrostate: + # Use hydrostatically balanced background + Ybar_n = mpv.HydroState_n.Y0.reshape(1, -1) + rhobar_n = mpv.HydroState_n.rho0.reshape(1, -1) + else: + # Use hydrostatic balance from notes + Ybar_n = np.exp(yn / Htheta) + rhobar_n = np.exp(-yn / Hrho_n) + mpv.HydroState_n.Y0[...] = Ybar_n + mpv.HydroState_n.S0[...] = 1.0 / Ybar_n + + An = A0 + + pi_n = An * Cs * fac * np.cos(waveno * xn + Cs * ts) + # pi_n = An * Cs * fac / rhobar_n**0.5 / Ybar_n * np.exp(-Gamma * yn) * np.cos(N / Cs * (waveno * xn + Cs * ts)) + + mpv.p2_nodes[...] = pi_n + + # if ud.bdry_type[1] == 'RAYLEIGH': + # rayleigh_damping(Sol, mpv, ud, ud.tcy, elem, th) + + rhoY_tmp = np.copy(Sol.rhoY) + rho_tmp = np.copy(Sol.rho) + + bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) + + return Sol From 23c18fc2a0b6572435865ff94335e35ab8d27801 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 22:52:12 -0700 Subject: [PATCH 45/76] unstable lamb wave test (#37) is getting close to Chew et al. 2022 --- src/tests/test_unstable_lamb.py | 274 ++++++++++++++++++++------------ 1 file changed, 172 insertions(+), 102 deletions(-) diff --git a/src/tests/test_unstable_lamb.py b/src/tests/test_unstable_lamb.py index 3402cded..17b77dbb 100644 --- a/src/tests/test_unstable_lamb.py +++ b/src/tests/test_unstable_lamb.py @@ -5,6 +5,7 @@ import numpy as np from ..flow_solver.physics import hydrostatics from ..flow_solver.utils import boundary as bdry +from ..flow_solver.utils import options as opts from ..utils.data_structures import DiagnosticState @@ -20,12 +21,28 @@ def __init__(self): self.T_ref = 300.00 # [K] self.R_gas = 287.4 # [J kg^{-1} K^{-1}] + self.Rg = self.R_gas / (self.h_ref**2 / self.t_ref**2 / self.T_ref) self.gamma = 1.4 self.cp_gas = self.gamma * self.R_gas / (self.gamma-1.0) self.Nsq = (self.grav / np.sqrt(self.cp_gas * self.T_ref))**2 self.Msq = self.u_ref * self.u_ref / (self.R_gas * self.T_ref) + self.gravity_strength = np.zeros((3)) + self.coriolis_strength = np.zeros((3)) + + self.gravity_strength[1] = self.grav * self.h_ref / (self.R_gas * self.T_ref) + self.coriolis_strength[0] = self.omega * self.t_ref + self.coriolis_strength[2] = self.omega * self.t_ref + + gravity_mask = (self.gravity_strength > np.finfo(np.float64).eps) | (np.arange(3) == 1) + self.i_gravity = gravity_mask.astype(int) + if np.any(gravity_mask): + self.gravity_direction = np.where(gravity_mask)[0][-1] # Use last matching index + + coriolis_mask = self.coriolis_strength > np.finfo(np.float64).eps + self.i_coriolis = coriolis_mask.astype(int) + ########################################## # SPATIAL GRID ########################################## @@ -38,7 +55,6 @@ def __init__(self): ########################################## # BOUNDARY CONDITIONS ########################################## - from ..flow_solver.utils import options as opts self.bdry_type = np.empty((3), dtype=object) self.bdry_type[0] = opts.BdryType.PERIODIC @@ -54,7 +70,7 @@ def __init__(self): self.dtfixed = self.dtfixed0 self.tout = [36.0] - self.stepmax = 101 + self.stepmax = 51 self.is_compressible = 1 self.is_nonhydrostatic = 1 @@ -89,6 +105,7 @@ def __init__(self): # STRATIFICATION ########################################## self.stratification = self.stratification_wrapper + self.rayleigh_bc = self.rayleigh_bc_function ########################################## # DIAGNOSTICS @@ -112,6 +129,9 @@ def __init__(self): self.rayleigh_forcing_fn = None self.rayleigh_forcing_path = None + self.init_forcing = self.forcing + self.rayleigh_bdry_switch = True + self.diag_state = DiagnosticState( test_name="test_unstable_lamb", file_name="target_unstable_lamb", @@ -151,147 +171,197 @@ def stratification_wrapper(self, dy): return lambda y : self.stratification_function(y, dy) def stratification_function(self, y, dy): - - Nsq = self.Nsq * self.t_ref**2 - g = self.grav / self.Msq - - return np.exp(Nsq * y / g) - + g = self.gravity_strength[1] + Gamma = (self.gamma - 1.0) / self.gamma + Hex = 1.0 / (Gamma * g) + + pi_p = np.exp(-(y + 0.5 * dy) / Hex) + pi_m = np.exp(-(y - 0.5 * dy) / Hex) + + Theta = - (Gamma * g * dy) / (pi_p - pi_m) + return Theta + + @staticmethod + def rayleigh_bc_function(ud): + if ud.bdry_type[1] == opts.BdryType.RAYLEIGH or ud.rayleigh_forcing == True: + ud.inbcy = ud.iny - 1 + ud.iny0 = np.copy(ud.iny) + ud.iny = ud.iny0 + int(3*ud.inbcy) + + # tentative workaround + ud.bcy = ud.ymax + ud.ymax += 3.0 * ud.bcy + + class forcing(object): + def __init__(self, k, mu, Cs, F, N, Gamma, ampl, g, rhobar, Ybar, rhobar_n, Ybar_n, X, Y, Xn, Yn): + self.k = k + self.mu = mu + self.Cs = Cs + self.F = F + self.N = N + self.Gamma = Gamma + + self.oorhobarsqrt = 1.0 / np.sqrt(rhobar.T) + self.Ybar = Ybar.T + + self.oorhobarsqrt_n = 1.0 / np.sqrt(rhobar_n.T) + self.Ybar_n = Ybar_n.T + + self.g = g + self.ampl = ampl + + self.X = X + self.Y = Y + self.Xn = Xn + self.Yn = Yn + + def get_T_matrix(self): + # system matrix of linearized equations + matrix = -np.array([[0, self.F, 0, 1j*self.Cs*self.k], + [-self.F, 0, -self.N, self.Cs*(self.mu+self.Gamma)], + [0, self.N, 0, 0], + [1j*self.Cs*self.k, self.Cs*(self.mu-self.Gamma), 0, 0]]) + + self.T_matrix = matrix + + def eigenfunction(self, t, s, grid='c'): + if grid == 'c': + x, z = self.X, self.Y + elif grid == 'n': + x, z, = self.Xn, self.Yn + + # Compute eigenvalues and eigenvectors + eigval, eigvec = np.linalg.eig( self.T_matrix ) + + # Find index of eigenvalue + # with greatest real part aka the instability growth rate + ind = np.argmax( np.real( eigval ) ) + + # construct solution according to eq. 2.27 and 2.19 + exponentials = np.exp( 1j * self.k * x + self.mu * z + + ( eigval[ind] ) * (t) + 1j * s * t ) + chi_u = self.ampl * np.real( eigvec[0,ind] * exponentials ) + chi_w = self.ampl * np.real( eigvec[1,ind] * exponentials ) + chi_th = self.ampl * np.real( eigvec[2,ind] * exponentials ) + chi_pi = self.ampl * np.real( eigvec[3,ind] * exponentials ) + + self.arrs = ( chi_u, chi_w, chi_th, chi_pi ) + + def dehatter(self, th, grid='c'): + if grid == 'n': + Ybar = self.Ybar_n + oorhobarsqrt = self.oorhobarsqrt_n + elif grid == 'c': + Ybar = self.Ybar + oorhobarsqrt = self.oorhobarsqrt + + chi_u, chi_v, chi_Y, chi_pi = self.arrs + + up = oorhobarsqrt * chi_u + vp = oorhobarsqrt * chi_v + Yp = oorhobarsqrt * self.N / self.g * Ybar * chi_Y + pi_p = oorhobarsqrt * self.Cs / Ybar / th.Gammainv * chi_pi + + return up.T, vp.T, Yp.T, pi_p.T def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): - def bump(xi): - # eqn (11) - tmp = np.zeros_like(xi) - tmp[np.where(np.abs(xi) < 1.0)] = np.exp( - -1.0 / (1.0 - xi[np.where(np.abs(xi) < 1.0)] ** 2) - ) - # return tmp - return np.ones_like(xi) + if hasattr(ud, 'rayleigh_bdry_switch'): + if ud.rayleigh_bdry_switch: + ud.bdry_type[1] = opts.BdryType.RAYLEIGH - if ud.bdry_type[1].value == "radiation": + if ud.bdry_type[1] == opts.BdryType.RAYLEIGH: ud.tcy, ud.tny = bdry.get_tau_y(ud, elem, node, 0.5) - if hasattr(ud, "rayleigh_forcing"): - if ud.rayleigh_forcing: - ud.forcing_tcy, ud.forcing_tny = bdry.get_bottom_tau_y( - ud, elem, node, 0.2, cutoff=0.1 - ) + if ud.rayleigh_forcing: + ud.forcing_tcy, ud.forcing_tny = bdry.get_bottom_tau_y(ud, elem, node, 0.2, cutoff=0.3) - A0 = 1.0e-3 # eqn (12) + A0 = 1.0e-1 / ud.u_ref Msq = ud.Msq - g = ud.gravity_strength[1] - kappa = th.Gamma + g = ud.gravity_strength[1] * ud.Rg x = elem.x.reshape(-1, 1) y = elem.y.reshape(1, -1) + X, Y = np.meshgrid(x, y) + + xn = node.x.reshape(-1, 1) + yn = node.y.reshape(1, -1) + dy = np.diff(node.y)[0] - Hrho = 1.0 / g - use_hydrostate = False + Xn, Yn = np.meshgrid(xn, yn) + ################################################## + # Reinitialise all background quantities + # as derived from one quantity. ud.stratification = ud.stratification(dy) - hydrostatics.state(mpv, elem, node, th, ud) - - if use_hydrostate: - # Use hydrostatically balanaced background - rhobar = mpv.HydroState.rho0.reshape(1, -1) - Ybar = mpv.HydroState.Y0.reshape(1, -1) - pibar = mpv.HydroState.p20.reshape(1, -1) * ud.Msq - - else: - # Use hydrostatic balance in Mark's notes - Htheta = Hrho / kappa - rhobar = np.exp(-y / Hrho) - Ybar = np.exp(y / Htheta) - pibar = 1.0 / Ybar - mpv.HydroState.rho0[...] = rhobar - mpv.HydroState.Y0[...] = Ybar - mpv.HydroState.S0[...] = 1.0 / Ybar # 1.0 / ud.stratification(y) - mpv.HydroState.rhoY0[...] = rhobar * Ybar + # Use hydrostatically balanced background + hydrostatics.analytical_state(mpv, elem, node, th, ud) + rhobar = mpv.HydroState.rho0.reshape(1, -1) + Ybar = mpv.HydroState.Y0.reshape(1, -1) + pibar = mpv.HydroState.p20.reshape(1, -1) * ud.Msq + + rhobar_n = mpv.HydroState_n.rho0.reshape(1, -1) + Ybar_n = mpv.HydroState_n.Y0.reshape(1, -1) + + ################################################## # dimensionless Brunt-Väisälä frequency - N = ud.t_ref * np.sqrt(ud.Nsq_ref) + N = ud.t_ref * np.sqrt(ud.Nsq) # dimensionless speed of sound Cs = np.sqrt(th.gamm / Msq) - waveno = N / Cs + ud.Cs = Cs + ud.Ns = N + # dimensionless Coriolis strength + if ud.coriolis_strength[2] == 0.0: + ud.coriolis_strength[2] += 1e-15 + F = ud.coriolis_strength[2] - ud.u_wind_speed = 0.0 # -Cs + G = np.sqrt(9. / 40.) + Gamma = G * N / Cs + k = N / Cs - Gamma = 1.0 / Hrho * (1.0 / th.gamm - 0.5) + ud.rf_bot = ud.init_forcing(k, -Gamma, Cs, F, N, Gamma, A0, g, rhobar, Ybar, rhobar_n, Ybar_n, X, Y, Xn, Yn) + ud.rf_bot.get_T_matrix() - # time shift of the initial solution - ts = -0.5 / N * np.pi - ts = 0.0 + ud.u_wind_speed = 0.0 - # set up perturbation quantities - # exp(-kGam * y) / sqrt(rhobar) / Ybar = 1.0 - up = A0 * Ybar * np.cos(waveno * x + Cs * ts) - vp = 0.0 - wp = 0.0 - Yp = 0.0 - # th.Gamma * ud.Msq == 1 / dimensionless(c_p) - fac = th.Gamma - pi = A0 * Cs * fac * np.cos(waveno * x + Cs * ts) * Msq - - # up = A / rhobar**0.5 * np.exp(-Gamma * y) * np.cos(N / Cs * (waveno * x + Cs * ts)) - # pi = A * Cs * fac / rhobar**0.5 / Ybar * np.exp(-Gamma * y) * np.cos(N / Cs * (waveno * x + Cs * ts)) + ud.rf_bot.eigenfunction(0, 1) + up, vp, Yp, pi_p = ud.rf_bot.dehatter(th) u = ud.u_wind_speed + up v = ud.v_wind_speed + vp - w = ud.w_wind_speed + wp + w = ud.w_wind_speed Y = Ybar + Yp - dPdpi = th.gm1inv * pibar ** (th.gm1inv - 1.0) - Pbar = pibar**th.gm1inv - rhoY = Pbar # + dPdpi * pi - # eqn (2.3) - # rho = (((pibar + pi))**th.gm1inv) / Y - # rho = Pbar / Y - rhobar = Pbar / Ybar - rho = rhobar # rhoY / Ybar + # rho = (((pibar + Msq * pi_p))**th.gm1inv) / Y + rho = rhobar - Sol.rho[...] = Pbar / Y + Sol.rho[...] = rho Sol.rhou[...] = rho * u Sol.rhov[...] = rho * v Sol.rhow[...] = rho * w - Sol.rhoY[...] = rhoY + Sol.rhoY[...] = rho * Y Sol.rhoX[...] = 0.0 - mpv.p2_cells[...] = pi / Msq + mpv.p2_cells[...] = pi_p ################################################### # initialise nodal pi - xn = node.x.reshape(-1, 1) - yn = node.y.reshape(1, -1) - - # initialise nodal pressure - Hrho_n = Hrho - - if use_hydrostate: - # Use hydrostatically balanced background - Ybar_n = mpv.HydroState_n.Y0.reshape(1, -1) - rhobar_n = mpv.HydroState_n.rho0.reshape(1, -1) - else: - # Use hydrostatic balance from notes - Ybar_n = np.exp(yn / Htheta) - rhobar_n = np.exp(-yn / Hrho_n) - mpv.HydroState_n.Y0[...] = Ybar_n - mpv.HydroState_n.S0[...] = 1.0 / Ybar_n - - An = A0 - - pi_n = An * Cs * fac * np.cos(waveno * xn + Cs * ts) - # pi_n = An * Cs * fac / rhobar_n**0.5 / Ybar_n * np.exp(-Gamma * yn) * np.cos(N / Cs * (waveno * xn + Cs * ts)) + ud.rf_bot.eigenfunction(0, 1, grid='n') + _, _, _, pi_n = ud.rf_bot.dehatter(th, grid='n') mpv.p2_nodes[...] = pi_n - # if ud.bdry_type[1] == 'RAYLEIGH': - # rayleigh_damping(Sol, mpv, ud, ud.tcy, elem, th) + bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - rhoY_tmp = np.copy(Sol.rhoY) - rho_tmp = np.copy(Sol.rho) + if hasattr(ud, 'mixed_run'): + if ud.mixed_run: + ud.coriolis_strength[2] = 2.0 * 7.292 * 1e-5 * ud.t_ref - bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) + if hasattr(ud, 'trad_forcing'): + if ud.trad_forcing: + ud.rf_bot.F = 0.0 + ud.rf_bot.get_T_matrix() return Sol From a0229757ba155e1c003f73443e89c4b376758612 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 22:52:32 -0700 Subject: [PATCH 46/76] fixed non-fatal bug in UserDataInit --- src/utils/user_data.py | 192 ++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/src/utils/user_data.py b/src/utils/user_data.py index f9f8915c..a8d19953 100644 --- a/src/utils/user_data.py +++ b/src/utils/user_data.py @@ -19,102 +19,102 @@ def __init__(self, **kwargs): for key, value in vars(gconsts).items(): setattr(self, key, value) - # else: - ########################################## - # SPATIAL GRID - ########################################## - self.inx = 64 + 1 - self.iny = 64 + 1 - self.inz = 1 - - self.xmin = -1.0 - self.xmax = 1.0 - self.ymin = 0.0 - self.ymax = 1.0 - self.zmin = -1.0 - self.zmax = 1.0 - - ########################################## - # BOUNDARY CONDITIONS - ########################################## - self.bdry_type = np.empty((3), dtype=object) - self.bdry_type[0] = opts.BdryType.PERIODIC - self.bdry_type[1] = opts.BdryType.WALL - self.bdry_type[2] = opts.BdryType.WALL - - ########################################## - # TEMPORAL - ########################################## - self.CFL = 0.5 - self.dtfixed0 = 100.0 - self.dtfixed = 100.0 - - self.acoustic_timestep = 0 - - self.tout = np.arange(0.0, 1.01, 0.01)[10:] - self.stepmax = 10000 - - ########################################## - # MODEL REGIMES - ########################################## - self.is_ArakawaKonor = 0 - self.is_nonhydrostatic = 1 - self.is_compressible = 1 - - self.compressibility = 1.0 - - ########################################## - # PHYSICS AND BACKGROUND WIND - ########################################## - self.u_wind_speed = 0.0 - self.v_wind_speed = 0.0 - self.w_wind_speed = 0.0 - - self.stratification = self.stratification_function - - ########################################## - # NUMERICS - ########################################## - # Do we solve the left-hand side? - self.do_advection = True - - # Advection limiter types - self.limiter_type_scalars = opts.LimiterType.NONE - self.limiter_type_velocity = opts.LimiterType.NONE - - # Iterative solver - self.tol = 1.0e-8 - self.max_iterations = 6000 - - ########################################## - # BLENDING - ########################################## - self.blending_weight = 0.0 / 16 - self.blending_mean = "rhoY" # 1.0, rhoY - self.blending_conv = "rho" # theta, rho - self.blending_type = "half" - - self.continuous_blending = False - self.no_of_pi_initial = 1 - self.no_of_pi_transition = 0 - self.no_of_hy_initial = 0 - self.no_of_hy_transition = 0 - - self.initial_blending = False - - ########################################## - # DIAGNOSTICS - ########################################## - self.diag = False - self.diag_state = None - - ########################################## - # OUTPUTS - ########################################## - self.autogen_fn = False - self.output_timesteps = False - self.output_type = "output" - self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) + # else: + ########################################## + # SPATIAL GRID + ########################################## + self.inx = 64 + 1 + self.iny = 64 + 1 + self.inz = 1 + + self.xmin = -1.0 + self.xmax = 1.0 + self.ymin = 0.0 + self.ymax = 1.0 + self.zmin = -1.0 + self.zmax = 1.0 + + ########################################## + # BOUNDARY CONDITIONS + ########################################## + self.bdry_type = np.empty((3), dtype=object) + self.bdry_type[0] = opts.BdryType.PERIODIC + self.bdry_type[1] = opts.BdryType.WALL + self.bdry_type[2] = opts.BdryType.WALL + + ########################################## + # TEMPORAL + ########################################## + self.CFL = 0.5 + self.dtfixed0 = 100.0 + self.dtfixed = 100.0 + + self.acoustic_timestep = 0 + + self.tout = np.arange(0.0, 1.01, 0.01)[10:] + self.stepmax = 10000 + + ########################################## + # MODEL REGIMES + ########################################## + self.is_ArakawaKonor = 0 + self.is_nonhydrostatic = 1 + self.is_compressible = 1 + + self.compressibility = 1.0 + + ########################################## + # PHYSICS AND BACKGROUND WIND + ########################################## + self.u_wind_speed = 0.0 + self.v_wind_speed = 0.0 + self.w_wind_speed = 0.0 + + self.stratification = self.stratification_function + + ########################################## + # NUMERICS + ########################################## + # Do we solve the left-hand side? + self.do_advection = True + + # Advection limiter types + self.limiter_type_scalars = opts.LimiterType.NONE + self.limiter_type_velocity = opts.LimiterType.NONE + + # Iterative solver + self.tol = 1.0e-8 + self.max_iterations = 6000 + + ########################################## + # BLENDING + ########################################## + self.blending_weight = 0.0 / 16 + self.blending_mean = "rhoY" # 1.0, rhoY + self.blending_conv = "rho" # theta, rho + self.blending_type = "half" + + self.continuous_blending = False + self.no_of_pi_initial = 1 + self.no_of_pi_transition = 0 + self.no_of_hy_initial = 0 + self.no_of_hy_transition = 0 + + self.initial_blending = False + + ########################################## + # DIAGNOSTICS + ########################################## + self.diag = False + self.diag_state = None + + ########################################## + # OUTPUTS + ########################################## + self.autogen_fn = False + self.output_timesteps = False + self.output_type = "output" + self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) if len(kwargs) > 0: for key, value in kwargs.items(): From 9c7fe8d16b3d416ca4180ae3b12bec9e6fe73075 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 22:54:10 -0700 Subject: [PATCH 47/76] refactor io import run scripts --- src/interfaces/ic_config.py | 27 +++++++++++ src/utils/io.py | 89 +++++++------------------------------ 2 files changed, 44 insertions(+), 72 deletions(-) create mode 100644 src/interfaces/ic_config.py diff --git a/src/interfaces/ic_config.py b/src/interfaces/ic_config.py new file mode 100644 index 00000000..067e5af1 --- /dev/null +++ b/src/interfaces/ic_config.py @@ -0,0 +1,27 @@ +IC_MODULES = { + "bi": "inputs.baroclinic_instability_periodic", + "tv": "inputs.travelling_vortex_2D", + "tv_2d": "inputs.travelling_vortex_2D", + "tv_neg": "inputs.travelling_vortex_2D_neg", + "tv_3d": "inputs.travelling_vortex_3D", + "tv_corr": "inputs.travelling_vortex_3D_Coriolis", + "aw": "inputs.acoustic_wave_high", + "igw": "inputs.internal_long_wave", + "igw_3d": "inputs.internal_long_wave_3D", + "lbw": "inputs.lamb_waves", + "skl": "inputs.sk_lamb_wave", + "mark": "inputs.mark", + "lw_p": "inputs.lamb_wave_perturb", + "igw_bb": "inputs.igw_baldauf_brdar", + "rb": "inputs.rising_bubble", + "rbc": "inputs.rising_bubble_cold", + "swe_bal_vortex": "inputs.swe_bal_vortex", + "swe": "inputs.shallow_water_3D", + "swe_icshear": "inputs.shallow_water_3D_icshear", + "swe_dvortex": "inputs.shallow_water_3D_dvortex", + "test_travelling_vortex": "pybella.tests.test_travelling_vortex", + "test_internal_long_wave": "pybella.tests.test_internal_long_wave", + "test_lamb_wave": "pybella.tests.test_lamb_wave", + "test_blending_warm_bubble": "pybella.tests.test_blending_warm_bubble", + "test_unstable_lamb": "pybella.tests.test_unstable_lamb", +} \ No newline at end of file diff --git a/src/utils/io.py b/src/utils/io.py index 75034656..9bc50095 100644 --- a/src/utils/io.py +++ b/src/utils/io.py @@ -13,6 +13,7 @@ import argparse from . import sim_params as params +from ..interfaces.ic_config import IC_MODULES def initialise(sst): @@ -520,31 +521,7 @@ def get_args(): dest="ic", help=" Set initial conditions", required=True, - choices={ - "aw", - "tv", - "tv_neg", - "tv_2d", - "tv_3d", - "tv_corr", - "rb", - "rbc", - "igw", - "igw_3d", - "lbw", - "skl", - "mark", - "lw_p", - "igw_bb", - "swe", - "swe_bal_vortex", - "swe_icshear", - "swe_dvortex", - "test_travelling_vortex", - "test_internal_long_wave", - "test_lamb_wave", - "test_blending_warm_bubble", - }, + choices=set(IC_MODULES.keys()), # Use the keys from IC_MODULES ) subparsers = parser.add_subparsers(dest="subcommand") @@ -586,55 +563,21 @@ def get_args(): args = parser.parse_args() # collect cmd line args ic = args.ic - if ic == "bi": - from inputs.baroclinic_instability_periodic import UserData, sol_init - elif ic == "tv" or ic == "tv_2d": - from inputs.travelling_vortex_2D import UserData, sol_init - elif ic == "tv_neg": - from inputs.travelling_vortex_2D_neg import UserData, sol_init - elif ic == "tv_3d": - from inputs.travelling_vortex_3D import UserData, sol_init - elif ic == "tv_corr": - from inputs.travelling_vortex_3D_Coriolis import UserData, sol_init - elif ic == "aw": - from inputs.acoustic_wave_high import UserData, sol_init - elif ic == "igw": - from inputs.internal_long_wave import UserData, sol_init - elif ic == "igw_3d": - from inputs.internal_long_wave_3D import UserData, sol_init - elif ic == "lbw": - from inputs.lamb_waves import UserData, sol_init - elif ic == "skl": - from inputs.sk_lamb_wave import UserData, sol_init - elif ic == "mark": - from inputs.mark import UserData, sol_init - elif ic == "lw_p": - from inputs.lamb_wave_perturb import UserData, sol_init - elif ic == "igw_bb": - from inputs.igw_baldauf_brdar import UserData, sol_init - elif ic == "rb": - from ..inputs.rising_bubble import UserData, sol_init - elif ic == "rbc": - from inputs.rising_bubble_cold import UserData, sol_init - elif ic == "swe_bal_vortex": - from inputs.swe_bal_vortex import UserData, sol_init - elif ic == "swe": - from inputs.shallow_water_3D import UserData, sol_init - elif ic == "swe_icshear": - from inputs.shallow_water_3D_icshear import UserData, sol_init - elif ic == "swe_dvortex": - from inputs.shallow_water_3D_dvortex import UserData, sol_init - elif ic == "test_travelling_vortex": - from ..tests.test_travelling_vortex import UserData, sol_init - elif ic == "test_internal_long_wave": - from ..tests.test_internal_long_wave import UserData, sol_init - elif ic == "test_lamb_wave": - from ..tests.test_lamb_wave import UserData, sol_init - elif ic == "test_blending_warm_bubble": - from ..tests.test_blending_warm_bubble import UserData, sol_init + # Import the appropriate module + if ic in IC_MODULES: + module_name = IC_MODULES[ic] + try: + module = __import__(module_name, fromlist=['UserData', 'sol_init']) + UserData = getattr(module, 'UserData') + sol_init = getattr(module, 'sol_init') + except ImportError as e: + raise ImportError(f"Failed to import {module_name}: {e}") + else: + raise ValueError(f"Unknown initial condition: {ic}") if UserData is None or sol_init is None: assert 0, "Initial condition file is not well defined." + if args.N is None: N = 1 else: @@ -785,9 +728,11 @@ def init_logger(ud): # add the handler to the root logger logging.getLogger().addHandler(console) - # Suppress matplotlib debug output + # Suppress library specific debug outputs logging.getLogger("matplotlib").setLevel(logging.WARNING) logging.getLogger("matplotlib.font_manager").setLevel(logging.WARNING) + logging.getLogger("numba").setLevel(logging.WARNING) + logging.getLogger("numba.core").setLevel(logging.WARNING) logging.info("Input file is %s" % input_filename) From 6519911f0cda1af6f7c4f01e27cb37bf87d32f83 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 22:54:39 -0700 Subject: [PATCH 48/76] fixed typo in EnsembleState.get_grid --- src/utils/data_structures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/data_structures.py b/src/utils/data_structures.py index 6748a675..15b2aef5 100644 --- a/src/utils/data_structures.py +++ b/src/utils/data_structures.py @@ -87,8 +87,8 @@ def get_all_members(self) -> List[ModelState]: def get_grid(self) -> tuple[Grid, Grid]: # Assuming identical underlying grid for all ensemble memebers - elem = self.memebers[0].elem - node = self.memebers[0].node + elem = self.members[0].elem + node = self.members[0].node return elem, node def __getitem__(self, index): From 3303b48daf5bb5b86142dc408af2c4e145ac6894 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 22:55:41 -0700 Subject: [PATCH 49/76] renamed LAMB_BDRY with ATMOSPHERIC_EXTENSION --- src/flow_solver/physics/low_mach/laplacian.py | 2 +- src/flow_solver/physics/low_mach/second_projection.py | 6 +++--- src/flow_solver/utils/boundary.py | 6 +++--- src/tests/test_lamb_wave.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/flow_solver/physics/low_mach/laplacian.py b/src/flow_solver/physics/low_mach/laplacian.py index 1dfc9035..cdf982e9 100644 --- a/src/flow_solver/physics/low_mach/laplacian.py +++ b/src/flow_solver/physics/low_mach/laplacian.py @@ -595,7 +595,7 @@ def stencil_9pt_numba_test(mpv, node, coriolis, diag_inv, ud): dummy_p = np.zeros((node.isc[1], node.isc[0])) ### Need to clean this up, but the Numba stencil is used in the Helmholtz solve for radiative BC! - if hasattr(ud, "LAMB_BDRY"): + if hasattr(ud, "ATMOSPHERIC_EXTENSION"): return lambda p: lap2D_numba_test( p, dummy_p, dx, dy, coeffs, diag_inv.T, coriolis, shp ) diff --git a/src/flow_solver/physics/low_mach/second_projection.py b/src/flow_solver/physics/low_mach/second_projection.py index 406bb777..3f208c94 100644 --- a/src/flow_solver/physics/low_mach/second_projection.py +++ b/src/flow_solver/physics/low_mach/second_projection.py @@ -44,7 +44,7 @@ def euler_forward_non_advective( dSdy = mpv.HydroState_n.get_dSdy(elem, node) mpv.rhs[...] = divergence_nodes(mpv.rhs, elem, node, Sol, ud) - if not hasattr(ud, "LAMB_BDRY"): + if not hasattr(ud, "ATMOSPHERIC_EXTENSION"): scale_wall_node_values(mpv.rhs, node, ud, 2.0) div = mpv.rhs @@ -401,7 +401,7 @@ def operator_coefficients_nodes(elem, node, Sol, mpv, ud, th, dt): # mpv.wcenter[:,-1] = mpv.wcenter[:,-2] assert True - if not hasattr(ud, "LAMB_BDRY"): + if not hasattr(ud, "ATMOSPHERIC_EXTENSION"): scale_wall_node_values(mpv.wcenter, node, ud) @@ -604,7 +604,7 @@ def divergence_nodes(rhs, elem, node, Sol, ud): inner_idx = tuple(inner_idx) inner_idx_p1y = tuple(inner_idx_p1y) - if not hasattr(ud, "LAMB_BDRY"): + if not hasattr(ud, "ATMOSPHERIC_EXTENSION"): if ( ud.bdry_type[1] == opts.BdryType.WALL or ud.bdry_type[1] == opts.BdryType.RAYLEIGH diff --git a/src/flow_solver/utils/boundary.py b/src/flow_solver/utils/boundary.py index c45f6030..783c5e29 100644 --- a/src/flow_solver/utils/boundary.py +++ b/src/flow_solver/utils/boundary.py @@ -85,7 +85,7 @@ def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): S = 1.0 / ud.stratification(elem.y[nimage[y_axs]]) - if hasattr(ud, "LAMB_BDRY"): + if hasattr(ud, "ATMOSPHERIC_EXTENSION"): dpi = ( mpv.HydroState.p20[nimage[y_axs]] - mpv.HydroState.p20[nlast[y_axs]] @@ -110,7 +110,7 @@ def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): Y_source = Sol.rhoY[nsource] / Sol.rho[nsource] Y_image = rhoY / rho - if hasattr(ud, "LAMB_BDRY"): + if hasattr(ud, "ATMOSPHERIC_EXTENSION"): if direction > 0: # if bottom boundary v = Sol.rhov[nsource] * Y_source / Sol.rho[nsource] * rho else: # if top boundary @@ -139,7 +139,7 @@ def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): Sol.rho[nimage] = rho Sol.rhou[nimage] = rho * u * Th_slc # Sol.rhov[nimage] = 0.0#rho*v - if hasattr(ud, "LAMB_BDRY"): + if hasattr(ud, "ATMOSPHERIC_EXTENSION"): Sol.rhov[nimage] = -v / Y_image else: Sol.rhov[nimage] = rho * v diff --git a/src/tests/test_lamb_wave.py b/src/tests/test_lamb_wave.py index ec3f055f..6f6645d2 100644 --- a/src/tests/test_lamb_wave.py +++ b/src/tests/test_lamb_wave.py @@ -88,7 +88,7 @@ def __init__(self): self.bdry_type[0] = opts.BdryType.PERIODIC self.bdry_type[1] = opts.BdryType.WALL self.bdry_type[2] = opts.BdryType.WALL - self.LAMB_BDRY = False + self.ATMOSPHERIC_EXTENSION = False ########################################## # NUMERICS From 3fc6f1aac592f6139bf736213bbc239ee3a72fb9 Mon Sep 17 00:00:00 2001 From: raychew Date: Wed, 4 Jun 2025 23:32:44 -0700 Subject: [PATCH 50/76] fixed typo in the unstable lamb test so the initial 30 time steps or so are very close to the 0.4.0 release, but the solutions diverge after about 50 time steps due to build up in this difference and the sensitivity of the instabilities. However, the amplitudes are slightly larger in our current run and 0.4.0 slightly underestimated the instability growth rate. So we might actually be on the better side of things here. Nevertheless, may be worth looking into this in the future. --- src/tests/test_unstable_lamb.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tests/test_unstable_lamb.py b/src/tests/test_unstable_lamb.py index 17b77dbb..d4c6b08a 100644 --- a/src/tests/test_unstable_lamb.py +++ b/src/tests/test_unstable_lamb.py @@ -32,8 +32,7 @@ def __init__(self): self.coriolis_strength = np.zeros((3)) self.gravity_strength[1] = self.grav * self.h_ref / (self.R_gas * self.T_ref) - self.coriolis_strength[0] = self.omega * self.t_ref - self.coriolis_strength[2] = self.omega * self.t_ref + self.coriolis_strength[2] = 2.0 * self.omega * self.t_ref gravity_mask = (self.gravity_strength > np.finfo(np.float64).eps) | (np.arange(3) == 1) self.i_gravity = gravity_mask.astype(int) From 8cf995a9b3b29cdcab2f5c6cc799c2c3fadf7206 Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 5 Jun 2025 01:12:16 -0700 Subject: [PATCH 51/76] rethought the flow solver tests now that we have the unstable lamb wave, the actual lamb wave test is now a long 800-time-step run. The internal long wave and travelling vortex use the integrated hydrostatic module, and the rest of the test cases use the analytical hydrostatic state (exponentially decaying pressure). These four flow solver tests took me a minute to run on my laptop, and they produce pretty large output files, especially for the long lamb wave run. Possibly have to improve this in the future. --- run_scripts/test_flow_solver.py | 4 ++- src/tests/test_internal_long_wave.py | 12 +++---- src/tests/test_lamb_wave.py | 52 ++++++++++------------------ src/tests/test_travelling_vortex.py | 16 ++++----- src/tests/test_unstable_lamb.py | 4 +-- 5 files changed, 37 insertions(+), 51 deletions(-) diff --git a/run_scripts/test_flow_solver.py b/run_scripts/test_flow_solver.py index 20699d11..b7f03ab1 100644 --- a/run_scripts/test_flow_solver.py +++ b/run_scripts/test_flow_solver.py @@ -4,7 +4,9 @@ @pytest.mark.parametrize("ic", ["test_travelling_vortex", "test_internal_long_wave", - "test_lamb_wave"]) + "test_lamb_wave", + "test_unstable_lamb",] + ) def test_single_run(ic): result = subprocess.run( ["pybella", "-ic", ic, "-N", "1"], diff --git a/src/tests/test_internal_long_wave.py b/src/tests/test_internal_long_wave.py index 0777d45a..d9b824e2 100644 --- a/src/tests/test_internal_long_wave.py +++ b/src/tests/test_internal_long_wave.py @@ -143,11 +143,6 @@ def __init__(self): self.autogen_fn = False - self.output_base_name = "_internal_long_wave" - self.output_type = "test" - self.aux = "" - self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) - self.output_timesteps = True self.stratification = self.stratification_function @@ -157,6 +152,11 @@ def __init__(self): self.diag = True self.diag_updt_targets = False + self.output_base_name = "_internal_long_wave" + self.output_type = "test" if not self.diag_updt_targets else "target" + self.aux = "" + self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) + self.diag_state = DiagnosticState( test_name="test_internal_long_wave", file_name="test_internal_long_wave", @@ -196,7 +196,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): xc = 0.0 a = ud.scale_factor * 5.0e3 / ud.h_ref - hydrostatics.state(mpv, elem, node, th, ud) + hydrostatics.analytical_state(mpv, elem, node, th, ud) HySt = var.States(node.sc, ud) HyStn = var.States(node.sc, ud) diff --git a/src/tests/test_lamb_wave.py b/src/tests/test_lamb_wave.py index 6f6645d2..154e27c1 100644 --- a/src/tests/test_lamb_wave.py +++ b/src/tests/test_lamb_wave.py @@ -10,7 +10,7 @@ class UserData(object): NSPEC = 1 grav = 9.81 # [m s^{-2}] - omega = 7.292 * 1e-5 # [s^{-1}] + omega = 0.0 * 1e-5 # [s^{-1}] R_gas = 287.4 # [J kg^{-1} K^{-1}] R_vap = 461.0 @@ -76,7 +76,7 @@ def __init__(self): self.xmin = -Lx / self.h_ref self.xmax = Lx / self.h_ref self.ymin = -0.0 - self.ymax = 2.0 + self.ymax = 8.0 self.zmin = -1.0 self.zmax = 1.0 @@ -88,7 +88,8 @@ def __init__(self): self.bdry_type[0] = opts.BdryType.PERIODIC self.bdry_type[1] = opts.BdryType.WALL self.bdry_type[2] = opts.BdryType.WALL - self.ATMOSPHERIC_EXTENSION = False + self.ATMOSPHERIC_EXTENSION = True + self.rayleigh_bdry_switch = False ########################################## # NUMERICS @@ -96,13 +97,13 @@ def __init__(self): self.CFL = 0.9 self.inx = 151 + 1 - self.iny = 15 + 1 + self.iny = 60 + 1 self.inz = 1 - self.dtfixed0 = 100.0 / self.t_ref + self.dtfixed0 = 10.0 / self.t_ref self.dtfixed = self.dtfixed0 - self.do_advection = False + self.do_advection = True self.limiter_type_scalars = opts.LimiterType.NONE self.limiter_type_velocity = opts.LimiterType.NONE @@ -125,40 +126,38 @@ def __init__(self): self.initial_blending = False self.initial_projection = True - self.tout = [36.0] + self.tout = [360.0] # self.tout = np.arange(0,361,1.0) # self.tout = np.append(self.tout, [720.0]) - self.stepmax = 31 + self.stepmax = 801 self.output_timesteps = True self.autogen_fn = False + self.diag = True + self.diag_updt_targets = False + self.output_base_name = "_lamb_wave" - self.output_type = "test" + self.output_type = "test" if not self.diag_updt_targets else "target" self.aux = "" self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) - self.diag = True - self.diag_updt_targets = False - self.diag_state = DiagnosticState( test_name="test_lamb_wave", - file_name="test_lamb_wave", + file_name="target_lamb_wave", Nx=self.inx - 1, Ny=self.iny - 1, steps=[self.stepmax - 1], ) self.stratification = self.stratification_wrapper - self.rayleigh_bc = self.rayleigh_bc_function + # self.rayleigh_bc = self.rayleigh_bc_function self.init_forcing = self.forcing - self.rayleigh_forcing = True + self.rayleigh_forcing = False self.rayleigh_forcing_type = "func" # func or file - self.rayleigh_forcing_fn = ( - "output_mark_wave_ensemble=1_601_240_bottom_forcing_S16.h5" - ) - self.rayleigh_forcing_path = "./output_mark_wave" + self.rayleigh_forcing_fn = None + self.rayleigh_forcing_path = None def stratification_wrapper(self, dy): return lambda y: self.stratification_function(y, dy) @@ -175,11 +174,6 @@ def stratification_function(self, y, dy): return Theta - # Nsq = self.Nsq_ref * self.t_ref**2 - # g = self.gravity_strength[1] / self.Msq - - # return np.exp(Nsq * y / g) - @staticmethod def rayleigh_bc_function(ud): if ud.bdry_type[1] == opts.BdryType.RAYLEIGH or ud.rayleigh_forcing == True: @@ -302,8 +296,6 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): ud.tcy, ud.tny = bdry.get_tau_y(ud, elem, node, 0.5) if ud.rayleigh_forcing: - # ud.tcy, ud.tny = get_tau_y(ud, elem, node, 0.005) - ud.forcing_tcy, ud.forcing_tny = bdry.get_bottom_tau_y( ud, elem, node, 0.2, cutoff=0.3 ) @@ -329,7 +321,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): ud.stratification = ud.stratification(dy) # Use hydrostatically balanced background - hydrostatics.state(mpv, elem, node, th, ud) + hydrostatics.analytical_state(mpv, elem, node, th, ud) rhobar = mpv.HydroState.rho0.reshape(1, -1) Ybar = mpv.HydroState.Y0.reshape(1, -1) pibar = mpv.HydroState.p20.reshape(1, -1) * ud.Msq @@ -348,8 +340,6 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): if ud.coriolis_strength[2] == 0.0: ud.coriolis_strength[2] += 1e-15 F = ud.coriolis_strength[2] - # if F == 0.0: - # F += 1e-15 G = np.sqrt(9.0 / 40.0) Gamma = G * N / Cs @@ -370,7 +360,6 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): w = ud.w_wind_speed Y = Ybar + Yp - # rho = (((pibar + Msq * pi_p))**th.gm1inv) / Y rho = rhobar Sol.rho[...] = rho @@ -388,9 +377,6 @@ def sol_init(Sol, mpv, elem, node, th, ud, seeds=None): mpv.p2_nodes[...] = pi_n - # if ud.bdry_type[1] == 'RAYLEIGH': - # rayleigh_damping(Sol, mpv, ud, ud.tcy, elem, th) - bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) if hasattr(ud, "mixed_run"): diff --git a/src/tests/test_travelling_vortex.py b/src/tests/test_travelling_vortex.py index 15a4ff6a..0487ae18 100644 --- a/src/tests/test_travelling_vortex.py +++ b/src/tests/test_travelling_vortex.py @@ -131,13 +131,6 @@ def __init__(self): self.tout = [1.0] # np.arange(0.0,10.1,0.1)[1:] self.stepmax = 101 - self.output_base_name = "_travelling_vortex" - - self.output_type = "test" - self.aux = "" - - self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) - self.stratification = self.stratification_function self.rhoe = self.rhoe_function self.output_timesteps = True @@ -145,9 +138,14 @@ def __init__(self): self.diag = True self.diag_updt_targets = False + self.output_base_name = "_travelling_vortex" + self.output_type = "test" if not self.diag_updt_targets else "target" + self.aux = "" + self.output_suffix = "_%i_%i" % (self.inx - 1, self.iny - 1) + self.diag_state = DiagnosticState( test_name="test_travelling_vortex", - file_name="test_travelling_vortex", + file_name="target_travelling_vortex", Nx=self.inx - 1, Ny=self.iny - 1, steps=[self.stepmax - 1], @@ -208,7 +206,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): igxn = node.igx igyn = node.igy - hydrostatics.state(mpv, elem, node, th, ud) + hydrostatics.integrated_state(mpv, elem, node, th, ud) coe = np.zeros((25)) coe[0] = 1.0 / 24.0 diff --git a/src/tests/test_unstable_lamb.py b/src/tests/test_unstable_lamb.py index d4c6b08a..04dfc1f1 100644 --- a/src/tests/test_unstable_lamb.py +++ b/src/tests/test_unstable_lamb.py @@ -69,7 +69,7 @@ def __init__(self): self.dtfixed = self.dtfixed0 self.tout = [36.0] - self.stepmax = 51 + self.stepmax = 31 self.is_compressible = 1 self.is_nonhydrostatic = 1 @@ -110,7 +110,7 @@ def __init__(self): # DIAGNOSTICS ########################################## self.diag = True - self.diag_updt_targets = True + self.diag_updt_targets = False ########################################## # OUTPUTS From a7bcf184335e367e01356a4898682bb294bd1712 Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 5 Jun 2025 01:13:37 -0700 Subject: [PATCH 52/76] extended hydrostatics module to integrate or provide analytical background the former was the default and works for most cases, while the latter is necessary for well-balanced numerical tests. --- src/flow_solver/physics/hydrostatics.py | 42 ++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/flow_solver/physics/hydrostatics.py b/src/flow_solver/physics/hydrostatics.py index d83ee32e..64c720ba 100644 --- a/src/flow_solver/physics/hydrostatics.py +++ b/src/flow_solver/physics/hydrostatics.py @@ -79,7 +79,7 @@ def column(HydroState, HydroState_n, Y, Y_n, elem, node, th, ud): HydroState_n.p0[xc_idx, igy + 1 :] = rhoY_hydro_n[:, igy:] ** th.gamm HydroState_n.p20[xc_idx, igy + 1 :] = pi_hydro_n[:, igy:] / ud.Msq -def state(mpv, elem, node, th, ud): +def integrated_state(mpv, elem, node, th, ud): """ Compute hydrostatic background state for atmospheric model. Handles arbitrary stratification profiles and proper numerical integration. @@ -214,6 +214,46 @@ def state(mpv, elem, node, th, ud): mpv.HydroState_n.S0[:] = 1.0 +def analytical_state(mpv, elem, node, th, ud): + g = ud.gravity_strength[1] + Gamma = th.Gamma + Hex = 1.0 / (th.Gamma * g) + dy = elem.dy + + pi_np = np.exp(-(node.y + 0.5 * dy) / Hex) + pi_nm = np.exp(-(node.y - 0.5 * dy) / Hex) + pi_n = np.exp(-(node.y) / Hex) + + Y_n = - Gamma * g * dy / (pi_np - pi_nm) + P_n = pi_n**th.gm1inv + p_n = pi_n**th.Gammainv + rho_n = P_n / Y_n + + mpv.HydroState_n.p20[...] = pi_n / ud.Msq + mpv.HydroState_n.p0[...] = p_n + mpv.HydroState_n.rho0[...] = rho_n + mpv.HydroState_n.rhoY0[...] = P_n + mpv.HydroState_n.Y0[...] = Y_n + mpv.HydroState_n.S0[...] = 1.0 / Y_n + + pi_cp = np.exp(-(elem.y + 0.5 * dy) / Hex) + pi_cm = np.exp(-(elem.y - 0.5 * dy) / Hex) + pi_c = np.exp(-(elem.y) / Hex) + + Y_c = - Gamma * g * dy / (pi_cp - pi_cm) + P_c = pi_c**th.gm1inv + p_c = pi_c**th.Gammainv + rho_c = P_c / Y_c + + mpv.HydroState.p20[...] = pi_c / ud.Msq + mpv.HydroState.p0[...] = p_c + mpv.HydroState.rho0[...] = rho_c + mpv.HydroState.rhoY0[...] = P_c + mpv.HydroState.Y0[...] = Y_c + mpv.HydroState.S0[...] = 1.0 / Y_c + + + def initial_pressure(Sol, mpv, elem, node, ud, th): Gammainv = th.Gammainv igy = node.igy From 3fae73399e0e246a3b7d9dce177d9c744b78435e Mon Sep 17 00:00:00 2001 From: raychew Date: Thu, 5 Jun 2025 01:14:00 -0700 Subject: [PATCH 53/76] make the rising bubble test work with the intergrated hydrostatic module --- src/tests/test_blending_warm_bubble.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/test_blending_warm_bubble.py b/src/tests/test_blending_warm_bubble.py index 1ae1df55..67022857 100644 --- a/src/tests/test_blending_warm_bubble.py +++ b/src/tests/test_blending_warm_bubble.py @@ -80,7 +80,7 @@ def sol_init(Sol, mpv, elem, node, th, ud, seed=None): y0 = 0.2 r0 = 0.2 - hydrostatics.state(mpv, elem, node, th, ud) + hydrostatics.integrated_state(mpv, elem, node, th, ud) x = elem.x y = elem.y From c5a1575c60c40783af3597adb07331c7e84fccf6 Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 6 Jun 2025 00:13:42 -0700 Subject: [PATCH 54/76] moved tests to a specific subdirectory --- {run_scripts => test_scripts}/test_blending.py | 0 {run_scripts => test_scripts}/test_flow_solver.py | 6 +++++- 2 files changed, 5 insertions(+), 1 deletion(-) rename {run_scripts => test_scripts}/test_blending.py (100%) rename {run_scripts => test_scripts}/test_flow_solver.py (68%) diff --git a/run_scripts/test_blending.py b/test_scripts/test_blending.py similarity index 100% rename from run_scripts/test_blending.py rename to test_scripts/test_blending.py diff --git a/run_scripts/test_flow_solver.py b/test_scripts/test_flow_solver.py similarity index 68% rename from run_scripts/test_flow_solver.py rename to test_scripts/test_flow_solver.py index b7f03ab1..99053894 100644 --- a/run_scripts/test_flow_solver.py +++ b/test_scripts/test_flow_solver.py @@ -14,4 +14,8 @@ def test_single_run(ic): text=True ) - assert result.returncode == 0, result.stderr.splitlines()[-3:] \ No newline at end of file + assert result.returncode == 0, ( + f"Command failed with return code {result.returncode}\n" + f"STDERR:\n{result.stderr.strip()}\n" + f"STDOUT:\n{result.stdout.strip()}" + ) \ No newline at end of file From b43d1f99e09da869cc91813686b00c1aabdc996b Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 6 Jun 2025 00:27:39 -0700 Subject: [PATCH 55/76] moved rayleigh boundary handling to boundary.py (#36) unstable test passed --- src/flow_solver/discretisation/time_update.py | 107 +++++------------- src/flow_solver/utils/boundary.py | 57 ++++++++++ 2 files changed, 84 insertions(+), 80 deletions(-) diff --git a/src/flow_solver/discretisation/time_update.py b/src/flow_solver/discretisation/time_update.py index 1a0bf5de..50ae270b 100644 --- a/src/flow_solver/discretisation/time_update.py +++ b/src/flow_solver/discretisation/time_update.py @@ -217,48 +217,18 @@ def do( # top rayleight damping bdry.rayleigh_damping(Sol, mpv, ud, elem, node) - # bottom rayleigh forcing - if hasattr(ud, "rayleigh_forcing"): - if ud.rayleigh_forcing: - if ud.rayleigh_forcing_type == "file": - reader = io.read_input( - ud.rayleigh_forcing_fn, ud.rayleigh_forcing_path - ) - - Sol_half_new = copy.deepcopy(Sol) - mpv_half_new = copy.deepcopy(mpv) - - time_tag = "%.3d_after_full_step" % step - reader.get_data(Sol_half_new, mpv_half_new, time_tag, half=True) - - # assuming constant background state - up = Sol_half_new.rhou / Sol_half_new.rho - vp = Sol_half_new.rhov / Sol_half_new.rho - Yp = ( - Sol_half_new.rhoY / Sol_half_new.rho - - mpv.HydroState.Y0.reshape(1, -1) - ) - - pi = mpv_half_new.p2_nodes - - bdry.rayleigh_damping( - Sol, mpv, ud, elem, node, [up, vp, Yp, pi, t + 0.5 * dt] - ) - - elif ud.rayleigh_forcing_type == "func": - # boundary.set_explicit_boundary_data(Sol, elem, ud, th, mpv) - - s = 5.0e-3 + 1e-4 + 0e-5 - ud.rf_bot.eigenfunction((t + 0.5 * dt), s) - up, vp, Yp, pi = ud.rf_bot.dehatter(th) - - ud.rf_bot.eigenfunction((t + 0.5 * dt), s, grid="n") - _, _, _, pi_n = ud.rf_bot.dehatter(th, grid="n") - - bdry.rayleigh_damping( - Sol, mpv, ud, elem, node, [up, vp, Yp, pi_n, t + 0.5 * dt] - ) - bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) + bdry.apply_rayleigh_forcing( + Sol, + mpv, + ud, + elem, + node, + t, + step, + dt, + th, + bdry, + ) debug_writer.write(f"{label}_after_ebnaimp") @@ -332,44 +302,21 @@ def do( bdry.rayleigh_damping(Sol, mpv, ud, elem, node) # bottom rayleigh forcing - if hasattr(ud, "rayleigh_forcing"): - if ud.rayleigh_forcing: - if ud.rayleigh_forcing_type == "file": - reader = io.read_input( - ud.rayleigh_forcing_fn, ud.rayleigh_forcing_path - ) - - # misusing hydrostatic blending data containers - time_tag = "%.3d_after_full_step" % step - reader.get_data(Sol_half_new, mpv_half_new, time_tag) - - # assuming constant background state - up = Sol_half_new.rhou / Sol_half_new.rho - vp = Sol_half_new.rhov / Sol_half_new.rho - Yp = ( - Sol_half_new.rhoY / Sol_half_new.rho - - mpv.HydroState.Y0.reshape(1, -1) - ) - # vp = 0.0 - # Yp = 0.0 - pi = mpv_half_new.p2_nodes - - bdry.rayleigh_damping( - Sol, mpv, ud, elem, node, [up, vp, Yp, pi, t + dt] - ) - - elif ud.rayleigh_forcing_type == "func": - s = 5.0e-3 + 1e-4 + 0e-5 - ud.rf_bot.eigenfunction((t + dt), s) - up, vp, Yp, pi = ud.rf_bot.dehatter(th) - - ud.rf_bot.eigenfunction((t + dt), s, grid="n") - _, _, _, pi_n = ud.rf_bot.dehatter(th, grid="n") - - bdry.rayleigh_damping( - Sol, mpv, ud, elem, node, [up, vp, Yp, pi_n, t + dt] - ) - bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) + bdry.apply_rayleigh_forcing( + Sol, + mpv, + ud, + elem, + node, + t, + step, + dt, + th, + bdry, + half=False, + Sol_half_new=Sol_half_new, + mpv_half_new=mpv_half_new, + ) ###################################################### # Blending : Do blending after timestep diff --git a/src/flow_solver/utils/boundary.py b/src/flow_solver/utils/boundary.py index 783c5e29..74209bf9 100644 --- a/src/flow_solver/utils/boundary.py +++ b/src/flow_solver/utils/boundary.py @@ -1,8 +1,10 @@ """ For more details on this module, refer to the write-up :ref:`boundary_handling`. """ +import copy import numpy as np from . import options as opts +from ...utils import io def set_explicit_boundary_data(Sol, elem, ud, th, mpv, step=None): @@ -496,6 +498,61 @@ def get_bottom_tau_y(ud, elem, node, alpha, cutoff=0.5): return tauc_y, taun_y +def apply_rayleigh_forcing( + Sol, + mpv, + ud, + elem, + node, + t, + step, + dt, + th, + bdry, + half=True, + Sol_half_new=None, + mpv_half_new=None, +): + """Apply Rayleigh forcing boundary condition (file or function based).""" + if not (hasattr(ud, "rayleigh_forcing") and ud.rayleigh_forcing): + return + + t_offset = 0.5 * dt if half else dt + + if ud.rayleigh_forcing_type == "file": + reader = io.read_input( + ud.rayleigh_forcing_fn, ud.rayleigh_forcing_path + ) + + if Sol_half_new is None or mpv_half_new is None: + Sol_half_new = copy.deepcopy(Sol) + mpv_half_new = copy.deepcopy(mpv) + + time_tag = "%.3d_after_full_step" % step + reader.get_data(Sol_half_new, mpv_half_new, time_tag, half=half) + + up = Sol_half_new.rhou / Sol_half_new.rho + vp = Sol_half_new.rhov / Sol_half_new.rho + Yp = Sol_half_new.rhoY / Sol_half_new.rho - mpv.HydroState.Y0.reshape(1, -1) + pi = mpv_half_new.p2_nodes + + bdry.rayleigh_damping( + Sol, mpv, ud, elem, node, [up, vp, Yp, pi, t + t_offset] + ) + + elif ud.rayleigh_forcing_type == "func": + s = 5.0e-3 + 1e-4 + 0e-5 + ud.rf_bot.eigenfunction(t + t_offset, s) + up, vp, Yp, pi = ud.rf_bot.dehatter(th) + + ud.rf_bot.eigenfunction(t + t_offset, s, grid="n") + _, _, _, pi_n = ud.rf_bot.dehatter(th, grid="n") + + bdry.rayleigh_damping( + Sol, mpv, ud, elem, node, [up, vp, Yp, pi_n, t + t_offset] + ) + + bdry.set_explicit_boundary_data(Sol, elem, ud, th, mpv) def rayleigh_damping(Sol, mpv, ud, elem, node, forcing=None): u = Sol.rhou / Sol.rho # [elem.i2] From 1aca17855fe0a6929cc0fb281306c30014f83fc5 Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 6 Jun 2025 00:49:27 -0700 Subject: [PATCH 56/76] added a skeleton .coveragerc file I am excluding the data assimilation module for now. --- .coveragerc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 00000000..9670e542 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,20 @@ +[run] +source = src +omit = + src/data_assimilation/* + src/inputs/* + src/utils/debug_helpers.py + */tests/* + */test_* + setup.py + +[report] +exclude_lines = + pragma: no cover + def __repr__ + raise AssertionError + raise NotImplementedError + if __name__ == .__main__.: + +[html] +directory = htmlcov \ No newline at end of file From bbabcbed148b94a5c4467a72955d5d25d4302d67 Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 6 Jun 2025 01:18:00 -0700 Subject: [PATCH 57/76] updated workflow file for tests, coverage, and doc deployment this resolves #28 and #29, and #38 partially. --- .github/workflows/deploy.yml | 64 ++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..ba056cd2 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,64 @@ +name: deploy + +on: [push, pull_request, workflow_dispatch] + +permissions: + contents: write + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + with: + python-version: '3.10.5' + - name: Install dependencies + run: | + pip install -r dev-requirements.txt + pip install . + - name: Run tests with coverage + run: | + pytest --cov=src --cov-report=xml --cov-report=html --cov-report=term + + - name: Upload coverage HTML report + uses: actions/upload-artifact@v3 + with: + name: coverage-html + path: htmlcov/ + + - name: Upload test plots + uses: actions/upload-artifact@v3 + with: + name: test-plots + path: | + outputs/**/*.png + !outputs/**/*.dat + !outputs/**/*.h5 + + docs: + runs-on: ubuntu-latest + needs: test # Only run docs if tests pass + steps: + - uses: actions/checkout@v3 + - uses: ConorMacBride/install-package@v1 + with: + apt: graphviz + - uses: actions/setup-python@v3 + with: + python-version: '3.10.5' + - name: Install dependencies + run: | + pip install -r dev-requirements.txt + pip install . + - name: Sphinx build + run: | + sphinx-build docs/source _build + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + with: + publish_branch: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: _build/ + force_orphan: true \ No newline at end of file From af39d8b8e1301fc8d6efdd8fb70364c03b49e887 Mon Sep 17 00:00:00 2001 From: raychew Date: Fri, 6 Jun 2025 22:31:39 -0700 Subject: [PATCH 58/76] added stripped target outputs for CI tests I can think of a better approach in the future --- ...rget_internal_long_wave_301_10_stripped.h5 | Bin 0 -> 160736 bytes .../target_lamb_wave_151_60_stripped.h5 | Bin 0 -> 444827 bytes ...target_travelling_vortex_64_64_stripped.h5 | Bin 0 -> 223373 bytes .../target_unstable_lamb_301_30_stripped.h5 | Bin 0 -> 1654072 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 outputs/target_internal_long_wave/target_internal_long_wave_301_10_stripped.h5 create mode 100644 outputs/target_lamb_wave/target_lamb_wave_151_60_stripped.h5 create mode 100644 outputs/target_travelling_vortex/target_travelling_vortex_64_64_stripped.h5 create mode 100644 outputs/target_unstable_lamb/target_unstable_lamb_301_30_stripped.h5 diff --git a/outputs/target_internal_long_wave/target_internal_long_wave_301_10_stripped.h5 b/outputs/target_internal_long_wave/target_internal_long_wave_301_10_stripped.h5 new file mode 100644 index 0000000000000000000000000000000000000000..119ed571724241d3c5f3a6938f654f906ab1cc29 GIT binary patch literal 160736 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
GoHW)8!VK+@0kg1>X##zW%IfF> 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 literal 0 HcmV?d00001 diff --git a/outputs/target_lamb_wave/target_lamb_wave_151_60_stripped.h5 b/outputs/target_lamb_wave/target_lamb_wave_151_60_stripped.h5 new file mode 100644 index 0000000000000000000000000000000000000000..7bd460b835085bb6402b52d75d1fc81f80f27176 GIT binary patch literal 444827 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
    raaF?eTnF#habfoh}YU~tJ; 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�i)UHa9rgO+Wtqb1rU)OVW}xQi2SEB^45FY2_ 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

    XfSci7 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 Q;{w)G8yz7nK;@hKGbjc|6~>x!*f2l=(iD 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Āz40&mo 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%0D4Bi3Y?BHQ3@N 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 z

    tr^#TuFnd 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 literal 0 HcmV?d00001 diff --git a/outputs/target_travelling_vortex/target_travelling_vortex_64_64_stripped.h5 b/outputs/target_travelling_vortex/target_travelling_vortex_64_64_stripped.h5 new file mode 100644 index 0000000000000000000000000000000000000000..182a4ef941e79d5ff13fa64d7b1567012cfc72b0 GIT binary patch literal 223373 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 VIbXJz=e&5n{IA@nB|A65-vPI(eh&Zu literal 0 HcmV?d00001 diff --git a/outputs/target_unstable_lamb/target_unstable_lamb_301_30_stripped.h5 b/outputs/target_unstable_lamb/target_unstable_lamb_301_30_stripped.h5 new file mode 100644 index 0000000000000000000000000000000000000000..0c708522373c3f3eb079ea8ef1c9f2859ae0635d GIT binary patch literal 1654072 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