cape.pyfun.casecntl: FUN3D case control module

This module contains the important function casecntl.run_fun3d(), which actually runs nodet or nodet_mpi, along with the utilities that support it.

It also contains FUN3D-specific versions of some of the generic methods from cape.case. For instance the function GetCurrentIter() determines how many FUN3D iterations have been run in the current folder, which is obviously a solver-specific task. It also contains the function LinkPLT(), which creates links to fixed Tecplot file names from the most recent output created by FUN3D.

All of the functions from cape.case are imported here. Thus they are available unless specifically overwritten by specific cape.pyfun versions.

class cape.pyfun.casecntl.CaseRunner(fdir: str | None = None)
checkx_phase(j: int) bool

Apply solver-specific checks for phase j

This generic version always returns True

Call:
>>> q = runner.checkx_phase(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number last completed

Outputs:
q: bool

Whether phase j looks complete

Versions:
  • 2025-04-05 @ddalle: v1.0

  • 2025-04-08 @ddalle: v1.1; add refine/three version

copy_hist(j: int)

Copy all FM and residual histories

Call:
>>> runner.copy_hist(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number to use for storing histories

Versions:
  • 2016-10-28 @ddalle: v1.0 (CopyHist)

  • 2023-07-06 @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

Versions:
  • 2016-04-14 @ddalle: v1.0 (FinalizeFiles)

  • 2023-07-06 @ddalle: v1.1; instance method

  • 2025-04-01 @ddalle: v1.2; only use restart iter

finalize_stdoutfile(j: int)

Move the fun3d.out file to run.{j}.{n}

Call:
>>> runner.finalize_stdoutfile(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2025-04-07 @ddalle: v1.0

find_plt_file(stem: str = 'tec_boundary') str | None

Get most recent plt for one surface/volume/slice

Call:
>>> fplt = runner.get_plt_file(stem="tec_boundary")
Inputs:
runner: CaseRunner

Controller to run one case of solver

stem: {"tec_boundary"} | str

Tecplot file surface/volume name to search for

Outputs:
fplt: str

Name of plt file

Versions:
  • 2025-05-09 @ddalle: v1.0

flow2plt(**kw)

Convert most recent .flow file to Tecplot volume file

Call:
>>> runner.flow2plt()
Inputs:
runner: CaseRunner

Controller to run one case of solver

add-mach: {True} | False

Option to calculate Mach number and add it to PLT file

add-cp: {True} | False

Option to add pressure coefficient and to PLT file

Versions:
  • 2025-04-04 @ddalle: v1.0

  • 2025-05-20 @ddalle: v1.1; use temp file

flow2surfplt(**kw)

Write surface PLT file from most recent .flow file

Call:
>>> runner.flow2surfplt()
Inputs:
runner: CaseRunner

Controller to run one case of solver

add-mach: True | {False}

Option to calculate Mach number and add it to PLT file

add-cp: {True} | False

Option to add pressure coefficient and to PLT file

Versions:
  • 2025-06-09 @ddalle: v1.0

flow2ufunc(**kw)

Convert most recent .flow file to SimSys ufunc file

Call:
>>> runner.flow2ufunc()
Inputs:
runner: CaseRunner

Controller to run one case of solver

add-mach: {True} | False

Option to calculate Mach number and add it to PLT file

add-cp: {True} | False

Option to add pressure coefficient and to PLT file

Versions:
  • 2025-04-04 @aburkhea: v1.0

  • 2025-06-09 @ddalle: v1.1; use temp file

genr8_resid_args() tuple

Get list of args to CaseResid

Call:
>>> args = runner.genr8_resid_args()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
args: tuple[str]

Tuple of one string, project base root name

Versions:
  • 2025-08-05 @ddalle: v1.0

genr8_vizfile_regex(stem: str) str

Create a regex to search for volume/surface/plane/etc file

Call:
>>> pat = runner.genr8_flowviz_regex(stem)
Inputs:
runner: CaseRunner

Controller to run one case of solver

stem: str

Name of surface/volume/etc. file to search for

Outputs:
pat: str

File name regex for candidate output data files

Versions:
  • 2025-08-09 @ddalle: v1.0

get_bc_extension(j: int | None = None) str

Get the file extension for the boundary condition files

File extensions taken from the FUN3D manual:

Format

Grid files

BC File

"aflr3"

.ugrid

.mapbc

"fast"

.fgrid

.mapbc

"fieldview"

.fvgrid_fmt

.mapbc

"fieldview"

.fvgrid_unf

.mapbc

"vgrid"

.cogsg, .bc

.mapbc

"felisa"

.gri, .fro

.bco

Call:
>>> ext = runner.get_grid_extension(j=None)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: {None} | int

Phase index (or current)

Outputs:
ext: str

Grid file extension, "mapbc", ".bco"

Versions:
  • 2025-04-04 @ddalle: v1.0

  • 2025-05-16 @ddalle: v1.1; typo: ma{bp->pb}c

get_dex_args_pre_fm() tuple

Get list of args prior to component name in CaseFM

Call:
>>> args = runner.get_dex_args_pre()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
args: tuple[str]

Tuple of one string, project base root name

Versions:
  • 2025-07-24 @ddalle: v1.0

get_grid_extension(j: int | None = None) str

Get the file extension for the selected grid format

File extensions taken from the FUN3D manual:

Format

Grid files

BC File

"aflr3"

.ugrid

.mapbc

"fast"

.fgrid

.mapbc

"fieldview"

.fvgrid_fmt

.mapbc

"fieldview"

.fvgrid_unf

.mapbc

"vgrid"

.cogsg, .bc

.mapbc

"felisa"

.gri, .fro

.bco

Call:
>>> ext = runner.get_grid_extension(j=None)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: {None} | int

Phase index (or current)

Outputs:
ext: str

Grid file extension, "ugrid", "fgrid", etc.

Versions:
  • 2025-04-04 @ddalle: v1.0

get_grid_file(j: int | None = None, check: bool = False) str | None

Get the most recent grid file for use with phase j

Call:
>>> gridfile = runner.get_grid_file(j=None, check=False)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: {None} | int

Phase number

check: True | {False}

Option to raise exception if no grid file founde

Outputs:
gridfileNone | str

Name of most recent phase j grid file

Versions:
  • 2025-04-08 @ddalle: v1.0

get_grid_format(j: int | None = None) str

Get the grid format option in use for this case

Call:
>>> grid_format = runner.get_grid_format(j=None)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: {None} | int

Phase index (or current)

Outputs:
grid_format: str

Grid format, "fast", "vgrid", "aflr3"

Versions:
  • 2025-04-04 @ddalle: v1.0

get_iter_active() int

Detect number of iters since last completed run

Call:
>>> n = runner.get_iter_active()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
n: int

Iteration number

Versions:
  • 2025-04-01 @ddalle: v1.0

get_iter_restart_active() int

Get number of completed iterations from fun3d.out

Call:
>>> n = runner.get_iter_restart_active()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
n: int

Iteration number

Versions:
  • 2025-04-01 @ddalle: v1.0

  • 2025-04-07 @ddalle: v1.1; move parser to separate meth

get_iter_restart_stdout(fname: str) int

Get iteration number of most recent restart write in STDOUT

Call:
>>> n = runner.get_iter_restart_stdout(fname)
Inputs:
runner: CaseRunner

Controller to run one case of solver

fname: str

Name of STDOUT file to read

Outputs:
n: int

Iteration number

Versions:
  • 2025-04-07 @ddalle: v1.0

get_plt_file(stem: str = 'tec_boundary')

Get most recent boundary plt file and its metadata

Call:
>>> fplt, n, i0, i1 = runner.get_plt_file()
>>> fplt, n, i0, i1 = runner.get_plt_file(stem)
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
fplt: str

Name of plt file

n: int

Number of iterations included

i0: int

First iteration in the averaging

i1: int

Last iteration in the averaging

Versions:
  • 2016-12-20 @ddalle: v1.0 (GetPltFile)

  • 2023-07-06 @ddalle: v1.1; instance method

  • 2024-03-25 @ddalle: v2.0
    • add stem imput

    • search for files w/o _timestep{n} in name

    • include previous runs in n if appropriate

    • more accurate accounting for FUN3D/s iter resets

get_project_baserootname() str

Read namelist and return base project name w/o adapt counter

This would be "pyfun" instead of "pyfun03", for example.

Call:
>>> rname = runner.get_project_baserootname()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
rname: str

Project rootname

Versions:
  • 2024-03-22 @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

Outputs:
rname: str

Project rootname

Versions:
  • 2015-10-19 @ddalle: v1.0

  • 2023-07-05 @ddalle: v1.1; instance method

get_reportfiles() list

Generate list of report files

Call:
>>> filelist = runner.get_reportfiles()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
filelist: list[str]

List of files to protect

Verions:
  • 2024-09-25 @ddalle: v1.0

get_restart_file(j: int | None = None) str

Get the most recent .flow 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

Outputs:
restartfile: str

Name of restart file, ending with .flow

Versions:
  • 2024-11-05 @ddalle: v1.0

get_restartfiles() list

Get recent .flow and grid files to protect from clean

Call:
>>> restartfiles = runner.get_restartfiles()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
restartfiles: list[str]

List of files not to delete during --clean

Versions:
  • 2024-12-12 @ddalle: v1.0

get_returncode()

Check for errors before continuing

Currently the following checks are performed.

  • Check for NaN residual in the output file

Call:
>>> ierr = runner.get_returncode())
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
ierr: int

Return code

Versions:
  • 2016-04-18 @ddalle: v1.0

  • 2023-06-02 @ddalle: v1.1; return bool; don’t raise

  • 2023-07-06 @ddalle: v1.2; instance method

  • 2024-06-17 @ddalle: v1.3; was check_error()

  • 2024-07-16 @ddalle: v1.4; use self.returncode

get_stdoutfiles() list

Get list of STDOUT files in order they were run

Call:
>>> runfiles = runner.get_stdoutfiles()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
runfiles: list[str]

List of run files, in ascending order

Versions:
  • 2024-08-09 @ddalle: v1.0

get_surf_pat() str

Get glob pattern for candidate surface data files

These can have false-positive matches because the actual search will be done by regular expression. Restricting this pattern can have the benefit of reducing how many files are searched by regex.

Call:
>>> pat = runner.get_surf_pat()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
pat: str

Glob file name pattern for candidate surface sol’n files

Versions:
  • 2025-01-24 @ddalle: v1.0

get_surf_regex() str

Get regular expression that all surface output files match

Call:
>>> regex = runner.get_surf_regex()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
regex: str

Regular expression that all surface sol’n files match

Versions:
  • 2025-01-24 @ddalle: v1.0

get_triq_file(stem: str = 'tec_boundary')

Get name of .triq file, creating it if necessary

Call:
>>> ftriq, n, i0, i1 = runner.get_triq_file(stem)
Inputs:
runner: CaseRunner

Controller to run one case of solver

stem: {"tec_boundary"} | str

Base name of surface/manifold to read

Outputs:
ftriq: str

Name of triq file

n: int

Number of iterations included

i0: int

First iteration in the averaging

i1: int

Last iteration in the averaging

Versions:
  • 2024-12-03 @ddalle: v1.0

get_triq_filename_stem() str

Get the infix for surface .triq files

Call:
>>> stem = runner.get_triq_filename_stem()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
stem: str

File name infix, e.g. "surf" or "tec_boundary"

Versions:
  • 2025-08-11 @ddalle: v1.0

get_working_folder() str

Get working folder, ., or Flow/

Call:
>>> fdir = runner.get_working_folder()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
fdir: "Flow" | "."

Location (relative to runner.root_dir) where nodet will be run next

Versions:
  • 2024-07-29 @ddalle: v1.0

getx_iter_histfile(fname: str)

Get the most recent iteration number from a history file

Call:
>>> n = runner.getx_iter_histfile(fname)
Inputs:
fname: {"pyfun_hist.dat"} | str

Name of file to read

Outputs:
n: int | None

Most recent iteration number

Versions:
  • 2016-05-04 @ddalle: v1.0; from GetHistoryIter()

  • 2023-06-27 @ddalle: v2.0; rename GetHistoryIterFile

getx_iter_history()

Get the most recent iteration number for a history file

Call:
>>> nh, n = runner.getx_history_iter()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
nh: int

Iterations from previous cases before Fun3D deleted history

n: int | None

Most recent iteration number

Versions:
  • 2015-10-20 @ddalle: v1.0

  • 2016-04-28 @ddalle: v1.1; for Flow/ folder

  • 2016-10-29 @ddalle: v1.2; handle Fun3D iteration reset

  • 2017-02-23 @ddalle: v1.3; handle adapt project shift

  • 2023-06-27 @ddalle: v2.0; instance method

getx_phase(n: int)

Determine the phase number based on files in folder

Call:
>>> i = casecntl.GetPhaseNumber(rc)
Inputs:
rc: RunControlOpts

Options interface for run control

Outputs:
i: int

Most appropriate phase number for a restart

Versions:
  • 2014-10-02 @ddalle: v1.0 (cape.pycart)

  • 2015-10-19 @ddalle: v1.0 (GetPhaseNumber)

  • 2023-07-06 @ddalle: v1.1; instance method

getx_restart_iter()

Calculate number of iteration if case should restart

Call:
>>> nr = runner.getx_restart_iter()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
nr: int

Restart iteration number

Versions:
  • 2015-10-19 @ddalle: v1.0

  • 2016-04-19 @ddalle: v1.1; check STDIO

  • 2020-01-15 @ddalle: v1.2; sort globs better

  • 2023-07-05 @ddalle: v1.3; moved to instance method

  • 2025-04-01 @ddalle: v2.0; use simple run log methods

infer_tavg_nstats(n: int | None = None, fname: int | None = None) int

Infer num of iters averaged for output at iteration n

Call:
>>> nstats = runner.infer_tavg_nstats(n)
Inputs:
runner: CaseRunner

Controller to run one case of solver

n: int

Iteration number

Outputs:
nstats: int

Number of iterations averaged in viz file

Versions:
  • 2025-08-10 @ddalle: v1.0

infer_vizfile_niter(mtch) int

Determine nIter for a surface/volume output file

Call:
>>> n = runner.infer_vizfile_niter(mtch)
Inputs:
runner: CaseRunner

Controller to run one case of solver

mtch: re.Match

Regular expression match object for viz file

Outputs:
n: int

Iteration number for the viz file

Versions:
  • 2025-08-10 @ddalle: v1.0

infer_vizfile_nstats(mtch) int

Determine nStats for a surface/volume output file

Call:
>>> n = runner.infer_vizfile_nstats(mtch)
Inputs:
runner: CaseRunner

Controller to run one case of solver

mtch: re.Match

Regular expression match object for viz file

Outputs:
n: int

Number of iterations averaged in viz file

Versions:
  • 2025-08-10 @ddalle: v1.0

init_post()

Custom initialization for pyfun

Call:
>>> runner.init_post()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Versions:
  • 2023-06-28 @ddalle: v1.0

Link the most recent Tecplot files to fixed file names

Call:
>>> runner.link_plt()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Versions:
  • 2016-10-24 @ddalle: v1.0 (LinkPLT)

  • 2023-07-06 @ddalle: v1.1; instance method

prep_adapt(j: int)

Prepare required nml options for ‘refine/three’ adapt

Call:
>>> runner.prep_adapt(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2024-09-04 @aburkhea: v1.0

prepare_files(j: int)

Prepare file names appropriate to run phase i of FUN3D

Call:
>>> runner.prepare_files(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2016-04-14 @ddalle: v1.0

  • 2023-07-06 @ddalle: v1.1; instance method

prepare_warmstart()

Process WarmStart settings and copy files if appropriate

Call:
>>> warmstart = runner.prepare_warmstart()
Inputs:
runner: CaseRunner

Controller to run one case of solver

Outputs:
warmstart: True | False

Whether or not case is a valid warm-start

Versions:
  • 2023-03-14 @ddalle: v1.0 (PrepareWarmStart)

  • 2023-07-06 @ddalle: v1.1; instance method

read_mach() float

Read Mach number from namelist file

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

Outputs:
mach: float

Mach number

Versions:
  • 2024-12-03 @ddalle: v1.0

read_namelist(j=None)

Read case namelist file

Call:
>>> nml = runner.read_namelist(j=None)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: {None} | int

Phase number

Outputs:
nml: cape.pyfun.namelist.Namelist

Namelist interface

Versions:
  • 2015-10-19 @ddalle: v1.0

  • 2023-06-27 @ddalle: v2.0; instance method

run_aflr3_fun3d(j: int)

Create volume mesh using aflr3

This version is customized for FUN3D in order to take a single argument.

Call:
>>> runner.run_aflr3_fun3d(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2024-08-22 @ddalle: v1.0

run_intersect_fun3d(j: int)

Run intersect to combine surface triangulations

This version is customized for FUN3D in order to take a single argument.

Call:
>>> runner.run_intersect_fun3d(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

See also:
Versions:
  • 2024-08-22 @ddalle: v1.0

run_nodet(j: int)

Run nodet, the main FUN3D executable

Call:
>>> runner.run_nodet(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2024-08-23 @ddalle: v1.0

  • 2024-04-07 @ddalle: v1.1; fork run_nodet_primal()

run_nodet_adapt(j: int)

Run Fun3D nodet with adaptation for refine/one

Call:
>>> runner.prepare_files(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2023-07-12 @jmeeroff: v1.0; from run_phase

run_nodet_primal(j: int)

Run nodet (the primal solver)

Call:
>>> runner.run_nodet_primal(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2025-04-07 @ddalle: v1.0

run_phase(j: int)

Run one phase using appropriate commands

Call:
>>> runner.run_phase(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2016-04-13 @ddalle: v1.0 (RunPhase())

  • 2023-06-02 @ddalle: v2.0

  • 2023-06-27 @ddalle: v3.0, instance method

  • 2024-08-23 @ddalle: v3.1; toward simple run_phase()

run_post_adapt(j: int)

Prepare namelist and mapbc for phase after ref3 adapt

Call:
>>> runner.run_post_adapt(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2025-01-17 @aburkhea: v1.0

  • 2025-03-31 @ddalle: v1.1; test refine/three

run_refine_loop(j: int)

Run refine loop to adapt grid to target complexity

Call:
>>> runner.prepare_files(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2024-06-07 @aburkhea: v1.0; from run_phase

  • 2025-04-08 @ddalle: v1.1; check for output file

run_refine_translate(j: int)

Run refine transalte to create input meshb file for adaptation

Call:
>>> runner.prepare_files(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2023-07-17 @jmeeroff: v1.0; from run_phase

  • 2025-04-08 @ddalle: v1.1; less hard-code

run_verify_fun3d(j: int)

Run verify to check triangulation if appropriate

This version is customized for FUN3D in order to take a single argument.

Call:
>>> runner.run_verify_fun3d(j)
Inputs:
runner: CaseRunner

Controller to run one case of solver

j: int

Phase number

Versions:
  • 2024-08-22 @ddalle: v1.0

set_restart_read(n: int | None = None)

Set a given check file as the restart point

Call:
>>> runner.set_restart_read(n=None)
Inputs:
rc: RunControlOpts

Run control options

n: {None} | int

Restart iteration number, defaults to latest available

Versions:
  • 2014-10-02 @ddalle: v1.0 (SetRestartIter)

  • 2023-03-14 @ddalle: v1.1; add WarmStart

  • 2023-07-06 @ddalle: v1.2; instance method

tavg2plt(**kw)

Convert most recent TAVG.1 file to Tecplot volume file

Call:
>>> runner.tavg2plt()
Inputs:
runner: CaseRunner

Controller to run one case of solver

add-mach: {True} | False

Option to calculate Mach number and add it to PLT file

add-cp: {True} | False

Option to add pressure coefficient and to PLT file

Versions:
  • 2025-04-14 @ddalle: v1.0

  • 2025-05-20 @ddalle: v1.1; use temp file

tavg2surfplt(**kw)

Convert most recent TAVG.1 file to Tecplot surface file

Call:
>>> runner.tavg2surfplt()
Inputs:
runner: CaseRunner

Controller to run one case of solver

add-mach: True | {False}

Option to calculate Mach number and add it to PLT file

add-cp: {True} | False

Option to add pressure coefficient and to PLT file

Versions:
  • 2025-06-09 @ddalle: v1.0

tavg2x(volume_plt: bool = True, surface_plt: bool = False, volume_ufunc: bool = False, surface_ufunc: bool = False, slices: dict | None = None, **kw)

Convert most recent TAVG.1 file to Tecplot surface file

Call:
>>> runner.tavg2surfplt()
Inputs:
runner: CaseRunner

Controller to run one case of solver

add-mach: True | {False}

Option to calculate Mach number and add it to PLT file

add-cp: {True} | False

Option to add pressure coefficient and to PLT file

Versions:
  • 2025-06-09 @ddalle: v1.0

write_triq(rawdatafile: str, triqfile: str)

Convert CFD data file to .triq format

This enables use with Chimera Grid Tools capabilities and integrates with CAPE’s TriqFM tools.

Call:
>>> runner.write_triq(rawdatafile, triqfile)
Inputs:
runner: CaseRunner

Controller to run one case of solver

Versions:
  • 2025-08-11 @ddalle: v1.0

cape.pyfun.casecntl.GetFromGlob(fglb, fname=None)

Find the most recently edited file matching a glob

Call:
>>> fname = casecntl.GetFromGlob(fglb, fname=None)
>>> fname = casecntl.GetFromGlob(fglbs, fname=None)
Inputs:
fglb: str

Glob for targeted file names

fglbs: list[str]

Multiple glob file name patterns

fname: {None} | str

Optional alternate file name to consider

Outputs:
fbest: str

Name of file matching glob that was most recently modified

Versions:
  • 2016-12-19 @ddalle: v1.0

  • 2023-02-03 @ddalle: v1.1; add fname input

  • 2023-03-26 @ddalle: v1.2; multiple fglbs

  • 2024-06-21 @ddalle: v1.3; disallow links to match globs

cape.pyfun.casecntl.GetPltFile()

Get most recent boundary plt file and its metadata

Call:
>>> fplt, n, i0, i1 = GetPltFile()
Outputs:
fplt: str

Name of plt file

n: int

Number of iterations included

i0: int

First iteration in the averaging

i1: int

Last iteration in the averaging

Versions:
  • 2016-12-20 @ddalle: v1.0 (GetPltFile)

  • 2023-07-06 @ddalle: v1.1; use CaseRunner

cape.pyfun.casecntl.GetTriqFile()

Get (create) most recent boundary triq file and its metadata

Call:
>>> ftriq, n, i0, i1 = GetTriqFile()
Outputs:
ftriq: str

Name of triq file

n: int

Number of iterations included

i0: int

First iteration in the averaging

i1: int

Last iteration in the averaging

Versions:
  • 2024-12-03 @ddalle: v1.0

cape.pyfun.casecntl.LinkFromGlob(fname, fglb)

Link the most recent file to a generic Tecplot file name

Call:
>>> casecntl.LinkFromGlob(fname, fglb)
>>> casecntl.LinkFromGlob(fname, fglbs)
Inputs:
fname: str

Name of unmarked file, like Components.i.plt

fglb: str

Glob for marked file names

fglbs: list[str]

Multiple glob file name patterns

Versions:
  • 2016-10-24 @ddalle: v1.0

  • 2023-03-26 @ddalle: v1.1; multiple fglbs

cape.pyfun.casecntl.LinkPLT()

Link the most recent Tecplot files to fixed file names

Call:
>>> LinkPLT()
Versions:
  • 2016-10-24 @ddalle: v1.0

  • 2023-07-06 @ddalle: v1.1; use CaseRunner

cape.pyfun.casecntl.run_fun3d()

Setup and run the appropriate FUN3D command

Call:
>>> run_fun3d()
Versions:
  • 2015-10-19 @ddalle: v1.0

  • 2016-04-05 @ddalle: v1.1; add AFLR3 hook

  • 2023-07-06 @ddalle: v2.0; use CaseRunner