Skip to content

Commit

Permalink
Merge pull request #248 from kuanchihwang/staging/implement-dyn-readnl
Browse files Browse the repository at this point in the history
Implement namelist reading and early initialization of MPAS dynamical core
  • Loading branch information
kuanchihwang committed Mar 5, 2024
2 parents ffc0960 + 4c0f612 commit 3f54ce1
Show file tree
Hide file tree
Showing 8 changed files with 1,489 additions and 30 deletions.
8 changes: 6 additions & 2 deletions cime_config/buildlib
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,9 @@ def _setup_mpas(case: Case) -> None:

shutil.copytree(mpas_dycore_src_root, mpas_dycore_bld_root, copy_function=_copy2_as_needed, dirs_exist_ok=True)
shutil.move(os.path.join(mpas_dycore_bld_root, "Makefile"), os.path.join(mpas_dycore_bld_root, "Makefile.CESM"))
_copy2_as_needed(os.path.normpath(os.path.join(mpas_dycore_src_root, os.pardir, os.pardir, "Makefile")), os.path.join(mpas_dycore_bld_root, "Makefile"))
_copy2_as_needed(os.path.normpath(os.path.join(mpas_dycore_src_root, os.pardir, os.pardir, "Makefile.in.CESM")), os.path.join(mpas_dycore_bld_root, "Makefile.in.CESM"))
_copy2_as_needed(os.path.normpath(os.path.join(mpas_dycore_src_root, os.pardir, os.pardir, "driver", "dyn_mpas_subdriver.F90")), os.path.join(mpas_dycore_bld_root, "driver"))
_copy2_as_needed(os.path.normpath(os.path.join(mpas_dycore_src_root, os.pardir, os.pardir, "Makefile")), mpas_dycore_bld_root)
_copy2_as_needed(os.path.normpath(os.path.join(mpas_dycore_src_root, os.pardir, os.pardir, "Makefile.in.CESM")), mpas_dycore_bld_root)

def _copy2_as_needed(src: str, dst: str) -> None:
"""
Expand All @@ -199,6 +200,9 @@ def _copy2_as_needed(src: str, dst: str) -> None:
# `src` and `dst` are both files but their modification time or size differ.
# Example scenario: User modified some existing source code files.
shutil.copy2(src, dst)
elif os.path.isdir(dst) and os.path.isfile(os.path.join(dst, os.path.basename(src))):
dst = os.path.join(dst, os.path.basename(src))
_copy2_as_needed(src, dst)
else:
if os.path.isdir(dst) or os.path.isdir(os.path.dirname(dst)):
# `src` is a new file that does not exist at `dst`.
Expand Down
4 changes: 4 additions & 0 deletions cime_config/cam_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ def __init__(self, case, case_log):
# MPAS dynamical core relies on its upstream build infrastructure for compilation instead of CIME to take advantage of future upstream changes automatically.
self.create_config("dyn_src_dirs", dyn_dirs_desc, ["mpas"],
valid_list_type="str")

# Add XML namelist definition file for MPAS dynamical core.
mpas_dyn_nml_path = os.path.normpath(os.path.join(cime_conf_path, os.pardir, "src", "dynamics", "mpas"))
self._add_xml_nml_file(mpas_dyn_nml_path, "namelist_definition_mpas_dycore.xml")
elif dycore == "none":
# Source code directories
self.create_config("dyn_src_dirs", dyn_dirs_desc, ["none"],
Expand Down
34 changes: 25 additions & 9 deletions src/dynamics/mpas/Makefile.in.CESM
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ endif
#

export CP = cp -afv
export LN = ln -fsv
export MKDIR = mkdir -pv
export RM = rm -frv

Expand Down Expand Up @@ -61,22 +62,29 @@ all:
@echo ' `make libmpas-clean ESM="CESM" LIBROOT="..."`'

.PHONY: libmpas-prepare
libmpas-prepare: libmpas-archiver-script.txt libmpas-no-physics libmpas-preview
libmpas-prepare: libmpas-archiver-script.txt libmpas-no-physics libmpas-prefix-namelist-groups libmpas-preview

# Combine multiple static libraries into `libmpas.a` via archiver/MRI script. This requires GNU or GNU-like archiver (`ar`) program.
libmpas-archiver-script.txt:
@echo "create libmpas.a" > $(@)
@echo "addlib libdycore.a" >> $(@)
@echo "addlib libframework.a" >> $(@)
@echo "addlib libops.a" >> $(@)
@echo "save" >> $(@)
@echo "end" >> $(@)
@echo "create libmpas.a" > $(@)
@echo "addlib libdycore.a" >> $(@)
@echo "addlib libframework.a" >> $(@)
@echo "addlib libops.a" >> $(@)
@echo "addmod dyn_mpas_subdriver.o" >> $(@)
@echo "save" >> $(@)
@echo "end" >> $(@)

# Do not use built-in MPAS/WRF physics.
.PHONY: libmpas-no-physics
libmpas-no-physics:
@sed -E -i -e "s/^ *PHYSICS=.+$$/PHYSICS=/g" core_atmosphere/Makefile

# Prefix `mpas_` to MPAS namelist groups to avoid naming collisions.
.PHONY: libmpas-prefix-namelist-groups
libmpas-prefix-namelist-groups:
@sed -E -i -e "s/(^ *< *nml_record.+name=)\"(mpas_)?(\w+)\"/\1\"mpas_\3\"/g" core_atmosphere/Registry.xml
@sed -E -i -e "s/(^ *< *nml_record.+name=)\"(mpas_)?(\w+)\"/\1\"mpas_\3\"/g" core_atmosphere/diagnostics/Registry_*.xml

.PHONY: libmpas-preview
libmpas-preview:
@echo "Previewing build options for $(LIBROOT)/libmpas.a:"
Expand Down Expand Up @@ -106,13 +114,21 @@ $(LIBROOT)/libmpas.a: libmpas.a
$(MKDIR) $(LIBROOT)
$(CP) $(<) $(@)

libmpas.a: $(AUTOCLEAN_DEPS) dycore externals frame ops
libmpas.a: $(AUTOCLEAN_DEPS) dycore externals frame ops subdrv
$(AR) $(ARFLAGS) < libmpas-archiver-script.txt
@find -P . -name "*.mod" -type f -exec $(LN) "{}" . ";"

.PHONY: libmpas-clean
libmpas-clean: clean
$(RM) $(LIBROOT)/libmpas.a libmpas.a
$(RM) $(LIBROOT)/libmpas.a libmpas.a *.mod *.o

.PHONY: externals
externals: $(AUTOCLEAN_DEPS)
( cd external; $(MAKE) FC="$(FC)" SFC="$(SFC)" CC="$(CC)" SCC="$(SCC)" FFLAGS="$(FFLAGS)" CFLAGS="$(CFLAGS)" CPP="$(CPP)" NETCDF="$(NETCDF)" CORE="$(CORE)" ezxml-lib )

.PHONY: subdrv
subdrv: driver/dyn_mpas_subdriver.o

%.o: %.F90 dycore frame ops
( cd $(<D); $(FC) $(CPPFLAGS) $(FFLAGS) -c $(<F) $(CPPINCLUDES) $(FCINCLUDES) -I../framework -I../operators -I../core_$(CORE) )
$(LN) $(@) .
Loading

0 comments on commit 3f54ce1

Please sign in to comment.