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 case. 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.
- class cape.cfdx.case.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:
- check_complete()¶
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()¶
Check for other errors; rewrite for each solver
- Call:
>>> ierr = runner.check_error()
- Inputs:
- runner:
CaseRunner
Controller to run one case of solver
- runner:
- Outputs:
- ierr:
int
Return code
- ierr:
- Versions:
2023-06-20
@ddalle
: v1.0
- check_running()¶
Check if a case is already running, raise exception if so
- Call:
>>> runner.check_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
- 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
:cfdx
abstract method
- 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
None
if not running
- corehrs:
- Versions:
2015-12-22
@ddalle
: v1.0 (Cntl.GetCPUTimeBoth
)2016-08-30
@ddalle
: v1.1; check forRUNNING
2023-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
None
if 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
None
if no log file found
- corehrs:
- Versions:
2015-12-22
@ddalle
: v1.0 (Cntl.GetCPUTimeFromFile)2023-07-09
@ddalle
: v2.0
- 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 arg
- 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_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;cfdx
abstract version
- 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
- 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
x
in 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 ok
- 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;cfdx
abstract version
- 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
RUNNING
and 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()
- mark_failure(msg='no details')¶
Mark the current folder in failure status using
FAIL
file- 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
RUNNING
otherwise- 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
RUNNING
file if it exists- Call:
>>> mark_stopped()
- Versions:
2023-06-02
@ddalle
: v1.0
- 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 (abstractcfdx
method)
- read_case_json(f=False)¶
Read
case.json
if not already- Call:
>>> rc = runner.read_case_json(f=False)
- Inputs:
- runner:
CaseRunner
Controller to run one case of solver
- f:
True
| {False
} Option to force re-read
- runner:
- Outputs:
- rc:
RunControlOpts
Options interface from
case.json
- rc:
- Versions:
2023-06-15
@ddalle
: v1.0
- read_condition(key: str, f=False)¶
Read
conditions.json
if 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=False)¶
Read
conditions.json
if 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;CaseRunner
method
- 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.0
- 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;
0
for success
- ierr:
- Versions:
2014-10-02
@ddalle
: v1.02021-10-08
@ddalle
: v1.1 (run_overflow
)2023-06-21
@ddalle
: v2.0; instance method
- run_aflr3(j: int, proj: str, fmt='lb8.ugrid')¶
Create volume mesh using
aflr3
This 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
surf
file does not exist, the function attempts to create it by reading thetri
,xml
, andaflr3bc
files usingcape.tri.Tri
. The function then callscape.bin.aflr3()
and finally checks for theFAIL
file.- 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 method
- run_intersect(j: int, proj='Components')¶
Run
intersect
to combine geometries if appropriateThis is a multistep process in order to preserve all the component IDs of the input triangulations. Normally
intersect
requires 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 originaltri
file to a single component. The files involved are tabulated below.Components.tri
: Intersecting components, each with own compIDComponents.c.tri
: Intersecting triangulation, original compIDsComponents.o.tri
: Output ofintersect
, only a few compIDsComponents.i.tri
: Original compIDs mapped to intersected tris
More specifically, these files are
"%s.i.tri" % proj
, etc.; the default project name is"Components"
. This function also calls the Chimera Grid Tools programtriged
to remove unused nodes from the intersected triangulation and optionally remove small triangles.- Call:
>>> runner.run_intersect(j, proj)
- Inputs:
- runner:
CaseRunner
Controller to run one case of solver
- j:
int
Phase number
- proj: {
'Components'
} |str
Project root name
- runner:
- See also:
cape.bin.intersect()
- Versions:
2015-09-07
@ddalle
: v1.0 (CaseIntersect
)2016-04-05
@ddalle
: v1.1; generalize tocfdx
2023-06-21
@ddalle
: v1.2; update name; instance method
- run_more_cases()¶
Submit more cases to the queue
- Call:
>>> runner.run_more_cases()
- Inputs:
- runner:
CaseRunner
Controller to run one case of solver
- runner:
- 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.0
- run_verify(j: int, proj='Components')¶
Run
verify
to 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:
- Versions:
2015-09-07
@ddalle
: v1.0; fromrun_flowCart()
2016-04-05
@ddalle
: v1.1; generalize tocape
2023-06-21
@ddalle
: v2.0; instance method
- 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
RUNNING
file- 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()
- 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;CaseRunner
method
- 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;CaseRunner
method
- cape.cfdx.case.GetTriqFile(proj='Components')¶
Get most recent
triq
file and its associated iterationsThis is a template version with specific implementations for each solver. The
cape.cfdx
version simply returns the most recenttriq
file 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
triq
file- 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.case.StartCase()¶
Empty template for starting a case
The function is empty but does not raise an error
- Call:
>>> cape.case.StartCase()
- See also:
cape.pycart.case.StartCase()
cape.pyfun.case.StartCase()
cape.pyover.case.StartCase()
- Versions:
2015-09-27
@ddalle
: v1.02023-06-02
@ddalle
: v2.0; empty
- cape.cfdx.case.run_rootdir(func)¶
Decorator to run a function within a specified folder
- Call:
>>> func = run_rootdir(func)
- Wrapper Signature:
>>> v = runner.func(*a, **kw)
- Inputs:
- func:
func
Name of function
- runner:
CaseRunner
Controller to run one case of solver
- a:
tuple
Positional args to
cntl.func()
- kw:
dict
Keyword args to
cntl.func()
- func:
- Versions:
2020-02-25
@ddalle
: v1.1 (cape.cntl
)2023-06-16
@ddalle
: v1.0
- cape.cfdx.case.set_rlimit(r, ulim, u, i=0, unit=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()