Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synchronize with NOAA #28

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Lint"
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout Pace repository
uses: actions/[email protected]
with:
submodules: 'recursive'
- name: Step Python 3.8.12
uses: actions/[email protected]
with:
python-version: '3.8.12'
- name: Install OpenMPI for gt4py
run: |
sudo apt-get install libopenmpi-dev
- name: Install Python packages
run: |
python -m pip install --upgrade pip
pip install -r requirements_dev.txt -r requirements_lint.txt
- name: Run lint via pre-commit
run: |
pre-commit run --all-files
27 changes: 27 additions & 0 deletions .github/workflows/main_unit_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Main unit tests"
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]

jobs:
main_unit_tests:
runs-on: ubuntu-latest
steps:
- name: Checkout Pace repository
uses: actions/[email protected]
with:
submodules: 'recursive'
- name: Step Python 3.8.12
uses: actions/[email protected]
with:
python-version: '3.8.12'
- name: Install OpenMPI & Boost for gt4py
run: |
sudo apt-get install libopenmpi-dev libboost1.74-dev
- name: Install Python packages
run: |
python -m pip install --upgrade pip
pip install -r requirements_dev.txt
- name: Run all main tests
run: |
pytest -x tests/main
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Pace is an implementation of the FV3GFS / SHiELD atmospheric model developed by
Full Sphinx documentation can be found at [https://ai2cm.github.io/pace/](https://ai2cm.github.io/pace/).

**WARNING** This repo is under active development - supported features and procedures can change rapidly and without notice.

## Quickstart - bare metal

### Build
Expand All @@ -27,10 +28,13 @@ export BOOST_ROOT=BOOST/ROOT/boost_1_79_0
```

When cloning Pace you will need to update the repository's submodules as well:

```shell
git clone --recursive https://github.com/ai2cm/pace.git
```

or if you have already cloned the repository:

```
git submodule update --init --recursive
```
Expand All @@ -43,6 +47,7 @@ source venv_name/bin/activate
```

Inside of your pace `venv` or conda environment pip install the Python requirements, GT4Py, and Pace:

```shell
pip3 install -r requirements_dev.txt -c constraints.txt
```
Expand All @@ -52,6 +57,7 @@ Shell scripts to install Pace on specific machines such as Gaea can be found in
### Run

With the environment activated, you can run an example baroclinic test case with the following command:

```shell
mpirun -n 6 python3 -m pace.driver.run driver/examples/configs/baroclinic_c12.yaml

Expand All @@ -61,20 +67,33 @@ mpirun -n 6 --oversubscribe python3 -m pace.driver.run driver/examples/configs/b

After the run completes, you will see an output direcotry `output.zarr`. An example to visualize the output is provided in `driver/examples/plot_output.py`. See the [driver example](driver/examples/README.md) section for more details.

### Environment variable configuration

- `PACE_CONSTANTS`: Pace is bundled with various constants (see _util/pace/util/constants.py_).
- `FV3DYCORE` NOAA's FV3 dynamical core constants (original port)
- `GFS` Constant as defined in NOAA GFS
- `GEOS` Constant as defined in GEOS v13
- `PACE_FLOAT_PRECISION`: default precision of the field & scalars in the numerics. Default to 64.
- `PACE_LOGLEVEL`: logging level to display (DEBUG, INFO, WARNING, ERROR, CRITICAL). Default to INFO.

## Quickstart - Docker

### Build

While it is possible to install and build pace bare-metal, we can ensure all system libraries are installed with the correct versions by using a Docker container to test and develop pace.

First, you will need to update the git submodules so that any dependencies are cloned and at the correct version:

```shell
git submodule update --init --recursive
```

Then build the `pace` docker image at the top level.

```shell
make build
```

### Run

```shell
Expand All @@ -94,7 +113,6 @@ This git repository is laid out as a mono-repo, containing multiple independent

![Graph of interdependencies of Pace modules, generated from dependences.dot](./dependencies.svg)


## ML emulation

An example of integration of an ML model replacing the microphysics parametrization is available on the `feature/microphysics-emulator` branch.
Expand Down
102 changes: 102 additions & 0 deletions driver/examples/configs/baroclinic_c12_dp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
stencil_config:
compilation_config:
backend: numpy
rebuild: false
validate_args: true
format_source: false
device_sync: false
grid_config:
type: generated
config:
grid_type: 4
dx_const: 3000.0
dy_const: 3000.0
deglat: 10.0
initialization:
type: baroclinic
performance_config:
collect_performance: true
experiment_name: c12_baroclinic
nx_tile: 12
nz: 79
dt_atmos: 225
minutes: 15
layout:
- 1
- 1
diagnostics_config:
path: output
output_format: netcdf
names:
- u
- v
- ua
- va
- pt
- delp
- qvapor
- qliquid
- qice
- qrain
- qsnow
- qgraupel
z_select:
- level: 65
names:
- pt
dycore_config:
a_imp: 1.0
beta: 0.
consv_te: 0.
d2_bg: 0.
d2_bg_k1: 0.2
d2_bg_k2: 0.1
d4_bg: 0.15
d_con: 1.0
d_ext: 0.0
dddmp: 0.5
delt_max: 0.002
do_sat_adj: true
do_vort_damp: true
fill: true
hord_dp: 6
hord_mt: 6
hord_tm: 6
hord_tr: 8
hord_vt: 6
hydrostatic: false
k_split: 1
ke_bg: 0.
kord_mt: 9
kord_tm: -9
kord_tr: 9
kord_wz: 9
n_split: 1
nord: 3
nwat: 6
p_fac: 0.05
rf_cutoff: 3000.
rf_fast: true
tau: 10.
vtdm4: 0.06
z_tracer: true
do_qa: true
tau_i2s: 1000.
tau_g2v: 1200.
ql_gen: 0.001
ql_mlt: 0.002
qs_mlt: 0.000001
qi_lim: 1.0
dw_ocean: 0.1
dw_land: 0.15
icloud_f: 0
tau_l2v: 300.
tau_v2l: 90.
fv_sg_adj: 0
n_sponge: 48
u_max: 355.0

physics_config:
hydrostatic: false
nwat: 6
do_qa: true
4 changes: 4 additions & 0 deletions driver/pace/driver/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ def from_dict(cls, kwargs: Dict[str, Any]) -> "DriverConfig":
kwargs["grid_config"] = GridInitializerSelector.from_dict(
kwargs["grid_config"]
)
grid_type = kwargs["grid_config"].config.grid_type
# Copy grid_type to the DycoreConfig if it's not the default value
if grid_type != 0:
kwargs["dycore_config"].grid_type = grid_type

if (
isinstance(kwargs["stencil_config"], dict)
Expand Down
19 changes: 15 additions & 4 deletions driver/pace/driver/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,33 @@ class GeneratedGridConfig(GridInitializer):
lon_target: desired center longitude for refined tile (deg)
lat_target: desired center latitude for refined tile (deg)
restart_path: if given, load vertical grid from restart file
grid_type: type of grid, 0 is a gnomonic cubed-sphere, 4 is doubly-periodic
dx_const: constant x-width of grid cells on a dp-grid
dy_const: constant y-width of grid cells on a dp-grid
deglat: latitude to use for coriolis calculations on a dp-grid
"""

stretch_factor: Optional[float] = 1.0
lon_target: Optional[float] = 350.0
lat_target: Optional[float] = -90.0
restart_path: Optional[str] = None
grid_type: Optional[int] = 0
dx_const: Optional[float] = 1000.0
dy_const: Optional[float] = 1000.0
deglat: Optional[float] = 15.0

def get_grid(
self,
quantity_factory: QuantityFactory,
communicator: CubedSphereCommunicator,
) -> Tuple[DampingCoefficients, DriverGridData, GridData]:

metric_terms = MetricTerms(
quantity_factory=quantity_factory, communicator=communicator
quantity_factory=quantity_factory,
communicator=communicator,
grid_type=self.grid_type,
dx_const=self.dx_const,
dy_const=self.dy_const,
deglat=self.deglat,
)
if self.stretch_factor != 1: # do horizontal grid transformation
_transform_horizontal_grid(
Expand Down Expand Up @@ -171,8 +183,7 @@ def get_grid(
quantity_factory: QuantityFactory,
communicator: CubedSphereCommunicator,
) -> Tuple[DampingCoefficients, DriverGridData, GridData]:

backend = quantity_factory.empty(
backend = quantity_factory.zeros(
dims=[pace.util.X_DIM, pace.util.Y_DIM], units="unknown"
).gt4py_backend

Expand Down
5 changes: 1 addition & 4 deletions driver/pace/driver/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ def get_driver_state(
driver_grid_data: pace.util.grid.DriverGridData,
grid_data: pace.util.grid.GridData,
) -> DriverState:

dycore_state = tc_init.init_tc_state(
grid_data=grid_data,
quantity_factory=quantity_factory,
Expand Down Expand Up @@ -323,7 +322,7 @@ def get_driver_state(
driver_grid_data: pace.util.grid.DriverGridData,
grid_data: pace.util.grid.GridData,
) -> DriverState:
backend = quantity_factory.empty(
backend = quantity_factory.zeros(
dims=[pace.util.X_DIM, pace.util.Y_DIM], units="unknown"
).gt4py_backend

Expand All @@ -348,7 +347,6 @@ def _initialize_dycore_state(
communicator: pace.util.CubedSphereCommunicator,
backend: str,
) -> fv3core.DycoreState:

grid = self._get_serialized_grid(communicator=communicator, backend=backend)

ser = self._serializer(communicator)
Expand Down Expand Up @@ -401,7 +399,6 @@ def get_driver_state(
driver_grid_data: pace.util.grid.DriverGridData,
grid_data: pace.util.grid.GridData,
) -> DriverState:

return DriverState(
dycore_state=self.dycore_state,
physics_state=self.physics_state,
Expand Down
Loading