case_copy.py
Purpose
case_copy.py clones a pre-built CIME case for additional sites without triggering a full rebuild. It is the key optimization that allows OLMT to run multi-site experiments efficiently: the first site goes through the full runcase.py path (create_newcase, case.setup, case.build, case.submit), while every subsequent site reuses the same compiled executable and only patches site-specific configuration files.
Performance benefit: Avoids the ~10–30 minute model rebuild per site. For a 10-site experiment, this reduces total setup time from hours to minutes.
Command-line arguments
- --runroot <path>
Root directory containing CIME case run directories. Default:
../../run
- --case_copy <name>
Name of the parent case to clone from (required).
- --site_orig <code>
Site code used in the original case (required for path/file substitution).
- --site_new <code>
Site code for the new case (required).
- --nyears <int>
Number of years to run. Patches
stop_nandrestart_nindrv_in. Default: 0 (no change).
- --finidat_year <int>
Year for the restart file (
finidat). Patches the year suffix inlnd_in. Default: 0 (no change).
- --finidat_thiscase
Use restart file from this case’s directory (flag).
- --spin_cycle <int>
Number of years in spinup cycle. Adjusts
hist_nhtfrqto write one history file per cycle. Default: 0 (no change).
- --1850_landuse
Disable transient land use (sets
flanduse_timeseries = '',do_transient_pfts = .false.,do_harvest = .false.).
- --1850_co2
Use constant 1850 CO2 (replaces
co2_filewith*_CON.ncvariant).
- --1850_ndep
Use constant 1850 nitrogen deposition (replaces
stream_fldfilename_ndepwith*_CON.ncvariant).
- --suffix <string>
Append a suffix to the new case name (e.g.,
_eCO2). Used for parallel aCO2/eCO2 transient pairs.
- --machine <name>
Target machine name (affects PBS/SLURM submission logic). Default:
cades
- --warming <float>
Warming level to apply (not actively used in patching logic). Default:
0.0
- --tempdir <path>
Staging directory for intermediate files (
surfdata.nc,domain.nc, etc.). Defaults to./temp/run_<pid>_<ms>/.
How site_fullrun.py uses it
site_fullrun.py employs the “firstsite pattern”:
First site (
firstsitevariable):Calls
runcase.pyfor each of the three BGC phases (ad_spinup, final spinup, transient).runcase.pyinvokescreate_newcase,case.setup,case.build, and optionallycase.submit.Full build happens here (~10–30 minutes depending on machine/compiler).
Subsequent sites (all others in the
--sitecomma-list orall):Calls
case_copy.pyfor each phase, passing the first site’s case name via--case_copyand the new site code via--site_new.case_copy.pyshells out tomakepointdata.py(via the parentsite_fullrun.pylogic) to generate newsurfdata.nc,domain.nc, and landuse NetCDF files intempdir.Copies namelists and configuration from the first site’s run directory and patches them in place.
No rebuild occurs: the same executable (
e3sm.exe/cesm.exe) is reused.
The firstsite case name is tracked in site_fullrun.py variables like ad_case_firstsite, fnsp_case_firstsite, transient_case_firstsite.
What gets copied vs patched
Copied from <runroot>/<case_copy>/run/:
All
*_in*files (atm_in,lnd_in,drv_in, etc.)All
*nmlfiles (namelist files)All
*stream*files (DATM streams, except forICBcases)All
*.rcfiles (NUOPC run-sequence config)All
*para*.ncfiles (parameter perturbation NetCDF for ensemble runs)
Patched in place (text substitution via Python open()/write()):
site_orig→site_newin all namelists and streamscasename→casename_<suffix>if--suffixis providedstop_nandrestart_nindrv_inif--nyears> 0finidatyear suffix inlnd_inif--finidat_year> 0hist_nhtfrqinlnd_inif--spin_cycle> 0 (writes one file per cycle)flanduse_timeseries,do_transient_pfts,do_harvestif--1850_landuseco2_filepath if--1850_co2stream_fldfilename_ndeppath if--1850_ndep
Copied from tempdir/ (newly generated via makepointdata.py):
surfdata.ncdomain.nc*pftdyn*.nc(landuse timeseries, only for20TRtransient cases)
Not copied:
*.nchistory/restart files (explicitly deleted:rm <new_dir>/*.nc)Executable (reused from original build location via
diriinlnd_in)CaseDocs/,bld/,Buildconf/(not needed — no rebuild)
Performance benefit over runcase.py
Time savings:
Phase |
|
|
|---|---|---|
|
~10 sec |
0 (skipped) |
|
~5 sec |
0 (skipped) |
|
10–30 min |
0 (skipped) |
Namelist patching |
~2 sec |
~2 sec |
Total |
10–30 min |
~30 sec |
For an N-site experiment:
With
case_copy.py: 1 × (10–30 min) + (N−1) × 30 secWithout: N × (10–30 min)
At 10 sites, this is ~10 minutes vs. ~100–300 minutes.
Constraints
Single-point only: Works only for single-point CLM/ELM cases compiled with
MPI_SERIAL. Regional/global cases cannot be cloned this way because their executable and decomposition are grid-dependent.Pre-built parent required: The
--case_copycase must have completedcase.buildand have all namelists written to<runroot>/<case_copy>/run/.Same model version: The cloned case reuses the same E3SM/CESM source tree and inputdata. Switching model versions requires a new
runcase.pyinvocation.
See also
runcase.py — Full case creation path (first site)
site_fullrun.py — Orchestration script that calls
case_copy.pymakepointdata.py — Generates site-specific
surfdata.nc/domain.ncfor the new site