cape.cfdx.case: Case control module¶
This module contains templates for interacting with and executing individual cases. Since this is one of the most highly customized modules of the CAPE system, there are few functions here, and the functions that are present are mostly templates.
In general, the case module is used for actually running the CFD
solver (and any additional binaries that may be required as part of the
run process), and it contains other capabilities for renaming files and
determining the settings for a particular casecntl. CAPE saves many settings
for the CFD solver and archiving in a file called case.json within
each case folder, which allows for the settings of one case to diverge
from the other cases in the same run matrix.
Actual functionality is left to individual modules listed below.
cape.pycart.case
cape.pyfun.case
cape.pyover.case
- class cape.cfdx.casecntl.CaseRunner(fdir=None)¶
Class to handle running of individual CAPE cases
- Call:
>>> runner = CaseRunner(fdir=None)
- Inputs:
- fdir: {
None} |str Optional case folder (by default
os.getcwd())
- fdir: {
- Outputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- archive(test: bool = False)¶
Run the
--archivearchiving action- Call:
>>> runner.archive(test=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- test:
True| {False} Option to log all actions but not actually copy/delete
- runner:
- Versions:
2024-09-18 ``@ddalle`: v1.0
- assert_not_running()¶
Check if a case is already running, raise exception if so
- Call:
>>> runner.assert_not_running()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Versions:
2023-06-02
@ddalle: v1.02023-06-20
@ddalle: v1.1; instance method2024-06-16
@ddalle: v2.0; wascheck_running()
- callf(cmdi: list, f: str | None = None, e: str | None = None, shell: bool = False) int¶
Execute a function and save returncode
- Call:
>>> ierr = runner.callf(cmdi, f=None, e=None)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- f: {
None} |str Name of file to write STDOUT
- e: {f} |
str Name of file to write STDERR
- shell:
True| {False} Option to run subprocess in shell
- runner:
- Outputs:
- ierr:
int Return code
- ierr:
- Versions:
2024-07-16
@ddalle: v1.02024-08-03
@ddalle: v1.1; add log messages
- check_complete() bool¶
Check if a case is complete (DONE)
- Call:
>>> q = runner.check_complete()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Versions:
2023-06-20
@ddalle: v1.02023-07-08
@ddalle: v1.1; supportSTOP
- check_error() bool¶
Check for other errors; rewrite for each solver
- Call:
>>> q = runner.check_error()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- q:
bool Whether case appears to be an error
- q:
- Versions:
2023-06-20
@ddalle: v1.0
- check_exit(ja: int) bool¶
Check if a case should exit for any reason
Reasons a case should exit include
The case is finished.
A
CAPE-STOP-PHASEfile was found.A
CAPE-STOP-ITERfile was found.The relevant StartNextPhase option is
False.The relevant RestartSamePhase option is
False.
- Call:
>>> q = runner.check_exit(ja)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- ja:
int Phase at beginning of run
- runner:
- Outputs:
- q:
True|False Whether case should exit
- q:
- Versions:
2025-05-26
@ddalle: v1.0
- check_running() bool¶
Check if a case is currently running
- Call:
>>> q = runner.check_running()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- q:
bool Whether case appears to be running
- q:
- Versions:
2023-06-16
@ddalle: v1.0
- clean(test: bool = False)¶
Run the
--cleanarchiving action- Call:
>>> runner.clean(test=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- test:
True| {False} Option to log all actions but not actually copy/delete
- runner:
- Versions:
2024-09-18 ``@ddalle`: v1.0
- copy_file(src: str, dst: str, f: bool = False)¶
Copy a file and log results
- Call:
>>> runner.copy_file(src, dst, f=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- src:
str Name of input file, before renaming
- dst:
str Name of renamed file
- f:
True| {False} Option to overwrite existing dst
- runner:
- Versions:
2024-08-14
@ddalle: v1.0
- extend_case(m: int = 1, j: int | None = None, nmax: int | None = None) int | None¶
Extend the case by one execution of final phase
- Call:
>>> nnew = runner.extend_case(m=1, nmax=None)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- m: {
1} |int Number of additional times to execute final phase
- j: {
None} |int Phase to extend
- nmax: {
None} |int Do not exceed this iteration
- runner:
- Outputs:
- nnew:
None|int Number of iters after extension, if changed
- nnew:
- Versions:
2024-08-26
@ddalle: v1.0
- finalize_files(j: int)¶
Clean up files after running one cycle of phase j
- Call:
>>> runner.finalize_files(j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- runner:
- Versions:
2023-06-20
@ddalle: v1.0 (abstract method)
- get_archivist() CaseArchivist¶
Get or read archivist instance
- Call:
>>> a = runner.get_archivist()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- a:
CaseArchivist Archive controller for one case
- a:
- Versions:
2024-09-13
@ddalle: v1.02024-12-09
@ddalle: v1.1; prefer cntl opts over case
- get_cape_stdoutfiles() list¶
Get list of STDOUT files in order they were run
- Call:
>>> runfiles = runner.get_cape_stdoutfiles()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- Versions:
2024-08-09
@ddalle: v1.0
- get_case_index() int | None¶
Get index of a case in the current run matrix
- Call:
>>> i = runner.get_case_index()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- i:
int|None Index of case with name frun in run matrix, if present
- i:
- Versions:
2024-08-15
@ddalle: v1.0
- get_case_name() str¶
Get name of this case according to CAPE run matrix
- Call:
>>> casename = runner.get_case_name()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- casename:
str Name of case, using
/as path sep
- casename:
- Versions:
2024-08-15
@ddalle: v1.0
- get_cntl_rootdir() str¶
Get name of this case according to CAPE run matrix
- Call:
>>> rootdir = runner.get_cntl_rootdir()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- rootdir:
str Absolute path to base of run matrix that runs this case
- rootdir:
- Versions:
2024-08-26
@ddalle: v1.0
- get_cpu_time()¶
Read most appropriate total CPU usage for current case
- Call:
>>> corehrs = runner.get_cpu_time()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- corehrs:
None|float Core hours since last start or
Noneif not running
- corehrs:
- Versions:
2015-12-22
@ddalle: v1.0 (Cntl.GetCPUTimeBoth)2016-08-30
@ddalle: v1.1; check forRUNNING2023-07-09
@ddalle: v2.0; rename,CaseRunner
- get_cpu_time_start()¶
Read total core hours since start of current running phase
- Call:
>>> corehrs = runner.get_cpu_time_start()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- corehrs:
None|float Core hours since last start or
Noneif not running
- corehrs:
- Versions:
2015-08-30
@ddalle: v1.0 (Cntl.GetCPUTimeFromStart)2023-07-09
@ddalle: v2.0
- get_cpu_time_user()¶
Read total core hours from completed phase cycles
- Call:
>>> corehrs = runner.get_cpu_time_user()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- corehrs:
None|float Total core hours used or
Noneif no log file found
- corehrs:
- Versions:
2015-12-22
@ddalle: v1.0 (Cntl.GetCPUTimeFromFile)2023-07-09
@ddalle: v2.0
- get_funcname(frame: int = 1) str¶
Get name of calling function, mostly for log messages
- Call:
>>> funcname = runner.get_funcname(frame=1)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- frame: {
1} |int Depth of function to seek title of
- runner:
- Outputs:
- funcname:
str Name of calling function
- funcname:
- Versions:
2024-08-16
@ddalle
- get_iter(f=True)¶
Detect most recent iteration
- Call:
>>> n = runner.get_iter(f=True)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- f: {
True} |False Force recalculation of phase
- runner:
- Outputs:
- n:
int Iteration number
- n:
- Versions:
2023-06-20
@ddalle: v1.0
- get_job_id() str¶
Get PBS/Slurm job ID, if any
- Call:
>>> job_id = runner.get_job_id()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- job_id:
str Text form of job ID;
''if no job found
- job_id:
- Versions:
2023-06-16
@ddalle: v1.02023-07-05
@ddalle: v1.1; eliminate j arg2024-06-10
@ddalle: v2.0; use get_job_ids()
- get_job_ids() list¶
Get list of PBS/Slurm job IDs, if appropriate
- Call:
>>> job_id = runner.get_job_id()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- Versions:
2024-06-10
@ddalle: v1.0
- get_last_iter() int¶
Get min iteration required for a given case
- Call:
>>> nmax = runner.get_last_iter()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- nmax:
int Number of iterations
- nmax:
- Versions:
2024-06-17
@ddalle: v1.02024-07-18
@ddalle: v1.1; better exception handling
- get_last_phase() int¶
Get min phase required for a given case
- Call:
>>> jmax = runner.get_last_phase()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- jmax:
int Min phase required for job
- jmax:
- Versions:
2024-06-17
@ddalle: v1.02024-07-18
@ddalle: v1.1; force reread, handle errors
- get_logger() CaseLogger¶
Get or create logger instance
- Call:
>>> logger = runner.get_logger()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- logger:
CaseLogger Logger instance
- logger:
- Versions:
2024-08-16
@ddalle: v1.0
- get_mach() float¶
Get Mach number even if mach is not a run matrix key
This uses
cape.cfdx.runmatrix.RunMatrix.GetMach()to combine information from all run matrix keys.- Call:
>>> mach = runner.get_mach()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- key:
str Name of run matrix key to query
- f:
True| {False} Option to force re-read
- runner:
- Outputs:
- mach:
float Mach number
- mach:
- Versions:
2024-12-03
@ddalle: v1.0
- get_next_phase(j: int) int | None¶
Get the number of the phase that follows j
- Call:
>>> jnext = runner.get_next_phase(j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Current phase number
- runner:
- Outputs:
- jnext:
int|None Next phase number, if applicable
- jnext:
- Versions:
2024-08-11
@ddalle: v1.0
- get_pbs_script(j=None)¶
Get file name of PBS script
… or Slurm script or execution script
- Call:
>>> fpbs = runner.get_pbs_script(j=None)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j: {
None} |int Phase number
- runner:
- Outputs:
- fpbs:
str Name of main script to run case
- fpbs:
- Versions:
2014-12-01
@ddalle: v1.0 (pycart)2015-10-19
@ddalle: v1.0 (pyfun)2023-06-18
@ddalle: v1.1; instance method
- get_phase(f=True) int¶
Determine phase number in present case
- Call:
>>> j = runner.get_phase(n, f=True)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- f: {
True} |False Force recalculation of phase
- runner:
- Outputs:
- j:
int Phase number for next restart
- j:
- Versions:
2014-10-02
@ddalle: v1.02015-10-19
@ddalle: v1.1; FUN3D version2016-04-14
@ddalle: v1.2; CFDX version2023-06-16
@ddalle: v2.0; CaseRunner method
- get_phase_index(j: int) int | None¶
Get index of phase in
"PhaseSequence"- Call:
>>> k = runner.get_phase_index(j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- runner:
- Outputs:
- k:
None|int Index of j in PhaseSequence;
Noneif j is not one of the prescribed phases
- k:
- Versions:
2024-08-11
@ddalle: v1.0
- get_phase_iters(j: int) int¶
Get min iteration required for completion of phase j
- Call:
>>> nmax = runner.get_phase_iters(j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase index
- runner:
- Outputs:
- n:
int Number of iterations
- n:
- Versions:
2024-07-18
@ddalle: v1.0
- get_phase_sequence() list¶
Get list of prescribed phases for a case
- Call:
>>> phases = runner.get_phase_sequence()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- Versions:
2024-07-18
@ddalle: v1.0
- get_project_rootname(j: int | None = None) str¶
Read namelist and return project namelist
- Call:
>>> rname = runner.get_project_rootname(j=None)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j: {
None} |int Phase number
- runner:
- Outputs:
- rname:
str Project rootname
- rname:
- Versions:
2024-11-05
@ddalle: v1.0
- get_reportfiles() list¶
Generate list of report files
- Call:
>>> filelist = runner.get_reportfiles()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- Verions:
2024-09-14
@ddalle: v1.0
- get_restart_file(j: int | None = None) str¶
Get the most recent restart file for phase j
- Call:
>>> restartfile = runner.get_restart_file(j=None)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j: {
None} |int Phase number
- runner:
- Versions:
2024-11-05
@ddalle: v1.0
- get_restart_iter(f=True)¶
Get number of iteration if case should restart
- Call:
>>> nr = runner.get_restart_iter(f=True)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- f: {
True} |False Force recalculation of phase
- runner:
- Outputs:
- nr:
int Restart iteration number
- nr:
- Versions:
2023-06-20
@ddalle: v1.0;cfdxabstract version
- get_restartfiles() list¶
Generate list of restart files
- Call:
>>> filelist = runner.get_restartfiles()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- Verions:
2024-09-14
@ddalle: v1.0
- get_returncode() int¶
Check for other errors; rewrite for each solver
- Call:
>>> ierr = runner.get_returncode()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- ierr:
int Return code
- ierr:
- Versions:
2023-06-20
@ddalle: v1.02024-06-17
@ddalle: v1.1; wascheck_error()2024-07-16
@ddalle: v1.2; use self.returncode
- get_runlog() ndarray¶
Create a 2D array of CAPE exit phases and iters
Each row of the output is the phase number and iteration at which CAPE exited. The array is sorted by ascending phase then iteration.
- Call:
>>> runlog = runner.get_runlog()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- runlog:
np.ndarray[int] 2D array of all CAPE exit phase and iteration numbers
- runlog:
- Versions:
20254-03-23
@ddalle: v1.0
- get_runlog_iter()¶
Get phase and iteration from most recent CAPE log file name
- Call:
>>> phase, iter = runner.get_runlog_iter()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- Versions:
2024-03-22
@ddalle: v1.0
- get_status() str¶
Calculate status of current job
- Call:
>>> sts = runner.get_status()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- sts:
str One of several possible job statuses
DONE: not running and meets finishing criteriaERROR: error detectedRUNNING: case is currently runningINCOMP: case not running and not finished
- sts:
- get_stop_iter()¶
Read iteration at which to stop
- Call:
>>> nstop = runner.get_stop_iter()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- nstop:
int|None Iteration at which to stop, if any
- nstop:
- Versions:
2023-06-20
@ddalle: v1.0
- get_working_folder() str¶
Get working folder,
.for generic solver- Call:
>>> fdir = runner.get_working_folder()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- fdir:
"." Working folder relative to roo, where next phase is run
- fdir:
- Versions:
2024-08-11
@ddalle: v1.0
- get_working_folder_() str¶
Get working folder, but replace
'.'with''This results in cleaner results with
os.path.join().- Call:
>>> fdir = runner.get_working_folder()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- fdir:
""|str Working folder relative to roo, where next phase is run
- fdir:
- Versions:
2024-08-14
@ddalle: v1.0
- getx_iter()¶
Calculate most recent iteration
- Call:
>>> n = runner.getx_iter()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- n:
int Iteration number
- n:
- Versions:
2023-06-20
@ddalle: v1.0
- getx_phase(n: int)¶
Calculate phase based on present files
The
xin the title implies this case might be rewritten for each module.- Call:
>>> j = runner.getx_phase(n)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- n:
int Iteration number
- runner:
- Outputs:
- j:
int Phase number for next restart
- j:
- Versions:
2023-06-16
@ddalle: v1.02023-07-06
@ddalle: v1.1; PhaseSequence repeats ok2024-08-12
@ddalle: v1.2; refine file names slightly
- getx_restart_iter()¶
Calculate number of iteration if case should restart
- Call:
>>> nr = runner.gets_restart_iter()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- nr:
int Restart iteration number
- nr:
- Versions:
2023-06-20
@ddalle: v1.0;cfdxabstract version
- import_cntlmod()¶
Import appropriate run matrix-level cntl module
- Call:
>>> mod = runner.import_cntlmod()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- mod:
module Module imported
- mod:
- Versions:
2024-08-14
@ddalle: v1.02024-09-07
@ddalle: v1.1; mod for moving cntl to cfdx
- init_post()¶
Custom initialization hook
- Call:
>>> runner.init_post()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Versions:
2023-06-28
@ddalle: v1.0
- init_timer()¶
Mark a case as
RUNNINGand initialize a timer- Call:
>>> tic = runner.init_timer()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- tic:
datetime.datetime Time at which case was started
- tic:
- Versions:
2021-10-21
@ddalle: v1.0; fromrun_fun3d()2023-06-20
@ddalle: v1.1; instance method, no mark()
- link_file(src: str, dst: str, f: bool = False)¶
Copy a link and log results
- Call:
>>> runner.link_file(src, dst, f=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- src:
str Name of input file, before renaming
- dst:
str Name of renamed file
- f:
True| {False} Option to overwrite existing dst
- runner:
- Versions:
2024-08-14
@ddalle: v1.0
- log_both(msg: str, title: str | None = None, parent: int = 0)¶
Write a message to both primary and verbose logs
- Call:
>>> runner.log_both(title, msg)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- msg:
str Primary content of message
- title: {
None} |str Manual title (default is name of calling function)
- parent: {
0} |int Extra levels to use for calling function name
- runner:
- Versions:
2024-08-01
@ddalle: v1.0
- log_data(data: dict, title: str | None = None, parent: int = 0)¶
Write
dictto verbose log as JSON- Call:
>>> runner.log_data(title, data)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- data:
dict Parameters to write to verbose log as JSON
- msg:
str Primary content of message
- title: {
None} |str Manual title (default is name of calling function)
- parent: {
0} |int Extra levels to use for calling function name
- runner:
- Versions:
2024-08-01
@ddalle: v1.0
- log_main(msg: str, title: str | None = None, parent: int = 0)¶
Write a message to primary log
- Call:
>>> runner.log_main(msg, title, parent=0)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- msg:
str Primary content of message
- title: {
None} |str Manual title (default is name of calling function)
- parent: {
0} |int Extra levels to use for calling function name
- runner:
- Versions:
2024-08-01
@ddalle: v1.0
- log_verbose(msg: str, title: str | None = None, parent: int = 0)¶
Write a message to verbose log
- Call:
>>> runner.log_verbose(title, msg)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- msg:
str Primary content of message
- title: {
None} |str Manual title (default is name of calling function)
- parent: {
0} |int Extra levels to use for calling function name
- runner:
- Versions:
2024-08-01
@ddalle: v1.0
- mark_failure(msg='no details')¶
Mark the current folder in failure status using
FAILfile- Call:
>>> runner.mark_failure(msg="no details")
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- msg:
{"no details"}|str Error message for output file
- runner:
- Versions:
2023-06-02
@ddalle: v1.02023-06-20
@ddalle: v1.1; instance method
- mark_running()¶
Check if cases already running and create
RUNNINGotherwise- Call:
>>> runner.mark_running()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Versions:
2023-06-02
@ddalle: v1.02023-06-20
@ddalle: v1.1; instance method, no check()
- mark_stopped()¶
Delete the
RUNNINGfile if it exists- Call:
>>> mark_stopped()
- Versions:
2023-06-02
@ddalle: v1.02024-08-03
@ddalle: v1.1; add log message
- prepare_env(j: int)¶
Set environment vars, alter resource limits (
ulimit)This function relies on the system module
resource- Call:
>>> runner.prepare_env(rc, i=0)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- runner:
- See also:
- Versions:
2015-11-10
@ddalle: v1.0 (PrepareEnvironment())- 2023-06-02
@ddalle: v1.1; fix logic for appending E.g.
"PATH": "+$HOME/bin"This is designed to append to path
- 2023-06-02
2023-06-20
@ddalle: v1.2; instance mthod
- prepare_files(j: int)¶
Prepare files for phase j
- Call:
>>> runner.prepare_files(j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase index
- runner:
- Versions:
2021-10-21
@ddalle: v1.0 (abstractcfdxmethod)
- read_archive_opts() ArchiveOpts¶
Read the Archive options for this case
This prefers the parent-folder JSON settings to those found in
case.json. If no run matrix JSON settings can be read, thecase.jsonsettings will be used.- Call:
>>> opts = runner.read_archive_opts()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- opts:
ArchiveOpts Options interface from
case.json
- opts:
- Versions:
2024-08-28
@ddalle: v1.02024-12-09
@ddalle: v2.0; prefer top-level JSON
- read_case_json() RunControlOpts¶
Read
case.jsonif not already- Call:
>>> rc = runner.read_case_json()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- rc:
RunControlOpts Options interface from
case.json
- rc:
- Versions:
2023-06-15
@ddalle: v1.02024-07-18
@ddalle: v2.0; remove f option, use mtime
- read_cntl()¶
Read the parent run-matrix control that owns this case
- Call:
>>> cntl = runner.read_cntl()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- cntl:
Cntl|None Run matrix control instance
- cntl:
- Versions:
2024-08-15
@ddalle: v1.02024-08-28
@ddalle: v1.1; can work w/o case.json
- read_condition(key: str, f=False)¶
Read
conditions.jsonif not already- Call:
>>> v = runner.read_condition(key, f=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- key:
str Name of run matrix key to query
- f:
True| {False} Option to force re-read
- runner:
- Outputs:
- Versions:
2023-06-16
@ddalle: v1.0
- read_conditions(f: bool = False) dict¶
Read
conditions.jsonif not already- Call:
>>> xi = runner.read_conditions(f=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- f:
True| {False} Option to force re-read
- runner:
- Outputs:
- xi:
dict Run matrix conditions for this case
- xi:
- Versions:
2023-06-16
@ddalle: v1.0
- read_start_time()¶
Read the most recent start time to file
- Call:
>>> nProc, tic = runner.read_start_time()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- fname:
str Name of file containing CPU usage history
- runner:
- Outputs:
- nProc:
None|int Number of cores
- tic:
None|datetime.datetime Time at which most recent run was started
- nProc:
- Versions:
2016-08-30
@ddalle: v1.0 (stand-alone)2023-06-17
@ddalle: v2.0;CaseRunnermethod
- read_stop_phase() Tuple[bool, int | None]¶
Read
CAPE-STOP-PHASEfile for local stopping criterion- Call:
>>> q, j = runner.read_stop_phase()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- q:
True|False Whether
CAPE-STOP-PHASEfile exists- j:
None|int Phase at which to stop (every phase if
None)
- q:
- Versions:
2024-05-26
@ddalle: v1.0
- relpath(fname: str) str¶
Get path to file relative to case root directory
- Call:
>>> frel = runner.relpath(fname)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- fname:
str File name, relative to PWD or absolute
- runner:
- Outputs:
- frel:
str Path to fname relative to runner.root_dir
- frel:
- Versions:
2024-08-14
@ddalle: v1.0
- remove_link(dst: str, f: bool = False)¶
Delete a link [file if f] if it exists
- Call:
>>> runner.remove_link(dst, f=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- dst:
str Name of link to delete
- f:
True| {False} Option to overwrite dst, even if not a link
- runner:
- Versions:
2024-08-14
@ddalle: v1.0
- rename_file(src: str, dst: str, f: bool = False)¶
Rename a file and log results
- Call:
>>> runner.rename_file(src, dst, f=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- src:
str Name of input file, before renaming
- dst:
str Name of renamed file
- f:
True| {False} Option to overwrite existing dst
- runner:
- Versions:
2024-08-13
@ddalle: v1.0
- resubmit_case(j0: int)¶
Resubmit a case as a new job if appropriate
- Call:
>>> q = runner.resubmit_case(j0)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j0:
int Index of phase most recently run prior (may differ from current phase)
- runner:
- Outputs:
- q:
True|False Whether or not a new job was submitted to queue
- q:
- Versions:
2022-01-20
@ddalle: v1.0 (cape.pykes.case)2023-06-02
@ddalle: v1.02024-05-25
@ddalle: v1.1; rename options
- run()¶
Setup and run appropriate solver commands
- Call:
>>> ierr = runner.run()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- ierr:
int Return code;
0for success
- ierr:
- Versions:
2014-10-02
@ddalle: v1.02021-10-08
@ddalle: v1.1 (run_overflow)2023-06-21
@ddalle: v2.0; instance method2024-05-26
@ddalle: v2.1; more exit causes
- run_aflr3(j: int, proj: str, fmt='lb8.ugrid')¶
Create volume mesh using
aflr3This function looks for several files to determine the most appropriate actions to take:
{proj}.i.tri: Triangulation file{proj}.surf: AFLR3 surface file{proj}.aflr3bc: AFLR3 boundary conditions{proj}.xml: Surface component ID mapping file{proj}.{fmt}: Output volume mesh{proj}.FAIL.surf: AFLR3 surface indicating failure
If the volume grid file already exists, this function takes no action. If the
surffile does not exist, the function attempts to create it by reading thetri,xml, andaflr3bcfiles usingcape.trifile.Tri. The function then callscape.bin.aflr3()and finally checks for theFAILfile.- Call:
>>> runner.run_aflr3(j, proj, fmt='lb8.ugrid')
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- proj:
str Project root name
- fmt: {
"lb8.ugrid"} |str AFLR3 volume mesh format
- runner:
- Versions:
2016-04-05
@ddalle: v1.0 (CaseAFLR3())2023-06-02
@ddalle: v1.1; useget_aflr3_run()2023-06-20
@ddalle: v1.1; instance method2024-08-22
@ddalle: v1.2; add log messages
- run_intersect(j: int, proj: str = 'Components')¶
Run
intersectto combine surface triangulationsThis is a multi-step process in order to preserve all the component IDs of the input triangulations. Normally
intersectrequires each intersecting component to have a single component ID, and each component must be a water-tight surface.Cape utilizes two input files,
Components.c.tri, which is the original triangulation file with intersections and the original component IDs, andComponents.tri, which maps each individual originaltrifile to a single component. The files involved are tabulated below.Components.tri: Intersecting comps, each w/ single compIDComponents.c.tri: Original intersecting tris and compIDsComponents.o.tri: Output ofintersectw/ few compIDsComponents.i.tri: Orig compIDs mapped to intersected tris
More specifically, these files are
{proj}.i.tri, etc.; the default project name is"Components". This function also calls the Chimera Grid Tools programtrigedto remove unused nodes from the intersected triangulation and optionally remove small triangles.- Call:
>>> runner.run_intersect(j, proj="Components")
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- proj: {
'Components'} |str Project root name
- runner:
- See also:
cape.trifile.Tri
- Versions:
2015-09-07
@ddalle: v1.0 (CaseIntersect)2016-04-05
@ddalle: v1.1; generalize tocfdx2023-06-21
@ddalle: v1.2; update name, instance method2024-08-22
@ddalle: v1.3; add log messages
- run_more_cases() int¶
Submit more cases to the queue
- Call:
>>> ierr = runner.run_more_cases()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- ierr:
int Return code,
0if no new cases submitted
- ierr:
- Versions:
2023-12-13
@dvicker: v1.0
- run_phase(j: int) int¶
Run one phase using appropriate commands
- Call:
>>> ierr = runner.run_phase(j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- runner:
- Outputs:
- ierr:
int Return code
- ierr:
- Versions:
2023-06-05
@ddalle: v1.0 (pyover)2023-06-14
@ddalle: v1.0
- run_post_shell_cmds(j: int)¶
Run PostShellCmds after successful
run_phase()exit- Call:
>>> runner.run_post_shell_cmds(j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- runner:
- Versions:
2023-07-17
@ddalle: v1.02024-08-21
@ddalle: v1.1; log messages
- run_verify(j: int, proj='Components')¶
Run
verifyto check triangulation if appropriateThis function checks the validity of triangulation in file
"%s.i.tri" % proj. It callscape.bin.verify().- Call:
>>> runner.run_verify(j, proj='Components', fpre='run')
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- proj: {
'Components'} |str Project root name
- runner:
- Versions:
2015-09-07
@ddalle: v1.0; fromrun_flowCart()2016-04-05
@ddalle: v1.1; generalize tocape2023-06-21
@ddalle: v2.0; instance method2024-08-22
@ddalle: v2.1; add log messages
- save_reportfiles()¶
Update list of protected files for generating reports
- Call:
>>> runner.save_reportfiles()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Versions:
2024-09-14
@ddalle: v1.0
- save_restartfiles()¶
Update list of protected files for restarting case
- Call:
>>> runner.save_restartfiles()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Versions:
2024-09-14
@ddalle: v1.0
- set_rlimit(r: int, u: str, j: int = 0, unit: int = 1024)¶
Set resource limit for one variable
- Call:
>>> runner.set_rlimit(r, u, j=0, unit=1024)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- r:
int Integer code of particular limit, from
resource- u:
str Name of limit to set
- j: {
0} |int Phase number
- unit: {
1024} |int Multiplier, usually for a kbyte
- runner:
- See also:
cape.options.ulimit
- Versions:
2016-03-13
@ddalle: v1.02021-10-21
@ddalle: v1.1; check if Windows2023-06-20
@ddalle: v1.2; wasSetResourceLimit()
- skeleton(test: bool = False)¶
Run the
--skeletonarchiving action- Call:
>>> runner.skeleton(test=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- test:
True| {False} Option to log all actions but not actually copy/delete
- runner:
- Versions:
2024-09-18 ``@ddalle`: v1.0
- start()¶
Start or submit initial job
- Call:
>>> ierr, job_id = runner.start()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Outputs:
- Versions:
2023-06-23
@ddalle: v1.0
- stop_case()¶
Stop a case by deleting PBS job and removing
RUNNINGfile- Call:
>>> runner.stop_case()
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- runner:
- Versions:
2014-12-27
@ddalle: v1.0 (StopCase())2023-06-20
@ddalle: v1.1; instance method2023-07-05
@ddalle: v1.2; use CaseRunner.get_job_id()
- touch_file(fname: str)¶
Create an empty file if necessary, or update mtime
- Call:
>>> runner.touch_file(fname)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- fname:
str Name of file to “touch”
- runner:
- Version:
2024-08-14
@ddalle: v1.0
- unarchive(test: bool = False)¶
Run the
--unarchivearchiving action- Call:
>>> runner.unarchive(test=False)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- test:
True| {False} Option to log all actions but not actually copy/delete
- runner:
- Versions:
2024-09-20 ``@ddalle`: v1.0
- validate_dstfile(dst: str)¶
Check that dst is a valid destination for rename/copy
Checks that dst is inside case folder
- Call:
>>> runner.validate_dstfile(dst)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- src:
str Name of input file, before renaming
- runner:
- Versions:
2024-08-14
@ddalle: v1.0
- validate_srcfile(src: str)¶
Check that src exists and is a file
Checks that src is a file or a valid link.
- Call:
>>> runner.validate_srcfile(src)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- src:
str Name of input file, before renaming
- runner:
- Versions:
2024-08-14
@ddalle: v1.0
- write_case_json(rc: RunControlOpts)¶
Write the current settinsg to
case.json- Call:
>>> runner.write_case_json(rc)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- rc:
RunControlOpts Options interface from
case.json
- runner:
- Versions:
2024-08-24
@ddalle: v1.0
- write_start_time(j: int)¶
Write current start time, runner.tic, to file
- Call:
>>> runner.write_start_time(tic, j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- runner:
- Versions:
2015-12-09
@ddalle: v1.0 (pycart)2015-12-22
@ddalle: v1.0; module function2023-06-16
@ddalle: v2.0;CaseRunnermethod
- write_user_time(j: int)¶
Write time usage since time tic to file
- Call:
>>> runner.write_user_time(tic, j)
- Inputs:
- runner:
CaseRunner Controller to run one case of solver
- j:
int Phase number
- runner:
- Versions:
2015-12-09
@ddalle: v1.0 (pycart)2015-12-22
@ddalle: v1.0; module function2023-06-16
@ddalle: v2.0;CaseRunnermethod
- cape.cfdx.casecntl.GetTriqFile(proj='Components')¶
Get most recent
triqfile and its associated iterationsThis is a template version with specific implementations for each solver. The
cape.cfdxversion simply returns the most recenttriqfile in the folder with no iteration information.- Call:
>>> ftriq, n, i0, i1 = GetTriqFile(proj='Components')
- Inputs:
- proj: {
"Components"} |str File root name
- proj: {
- Outputs:
- ftriq:
str Name of most recently modified
triqfile- n: {
None} Number of iterations included
- i0: {
None} First iteration in the averaging
- i1: {
None} Last iteration in the averaging
- ftriq:
- Versions:
2016-12-19
@ddalle: v1.0
- cape.cfdx.casecntl.StartCase()¶
Empty template for starting a case
The function is empty but does not raise an error
- Call:
>>> cape.casecntl.StartCase()
- See also:
cape.pycart.casecntl.StartCase()cape.pyfun.casecntl.StartCase()cape.pyover.casecntl.StartCase()
- Versions:
2015-09-27
@ddalle: v1.02023-06-02
@ddalle: v2.0; empty
- cape.cfdx.casecntl.set_rlimit(r: int, ulim: ULimitOpts, u: str, i: int = 0, unit: int = 1024)¶
Set resource limit for one variable
- Call:
>>> set_rlimit(r, ulim, u, i=0, unit=1024)
- Inputs:
- See also:
cape.options.ulimit
- Versions:
2016-03-13
@ddalle: v1.02021-10-21
@ddalle: v1.1; check if Windows2023-06-20
@ddalle: v1.2; wasSetResourceLimit()