cfdtwin.Project
cfdtwin.Project
A CFDTwin project — a folder on disk, plus optional Fluent connection.
Construct via Project.create(path, name) or Project.open(path) —
Project(path) is reserved for internal use.
create
classmethod
Create a new project folder. Errors if the folder already contains a project_info.json.
open
classmethod
Open an existing project folder. Errors if no project_info.json is found.
set_case_file
Store the .cas / .cas.h5 file reference path. Doesn't touch Fluent.
set_inputs
Declare inputs (no Fluent connection required).
Three accepted entry shapes — choose one per input:
# 1. BC range tuple (lo, hi). bc_type and parameter_path resolve at run time.
project.set_inputs({"inlet|velocity": (0.1, 1.0)})
# 2. BC rich dict — fully declarative, no Fluent needed at any stage.
project.set_inputs({
"inlet|velocity": {
"range": (0.1, 1.0),
"bc_type": "velocity-inlet",
"parameter_path": "vmag.value",
},
})
# 3. Fluent input parameter (named expression with input_parameter=True).
# Key is the expression name; pass category="Input Parameter" and
# the unit string. Easiest path: feed back from list_available_inputs().
project.set_inputs({
"inlet_vel": {
"range": (0.2, 0.8),
"category": "Input Parameter",
"unit": "m/s",
},
})
BC keys use "
list_available_inputs
Discover BCs + input parameters from the connected Fluent session.
Requires a live Fluent connection (call connect_fluent() first).
Each returned dict has at least name, type, category;
Input Parameter entries also carry unit, current_value, and
definition. The dicts can be fed back into set_inputs after
adding a range::
project.connect_fluent()
for item in project.list_available_inputs():
print(item['name'], item['category'])
set_outputs
Declare outputs to extract from each simulation.
Each entry is a dict:
project.set_outputs([
{"name": "outlet_temp", "category": "Report Definition"},
{"name": "mid_plane", "category": "Surface",
"field_variables": ["temperature", "velocity-magnitude"]},
{"name": "fluid", "category": "Cell Zone",
"field_variables": ["temperature"]},
])
category must be one of: "Report Definition", "Surface", "Cell Zone". field_variables is required for Surface and Cell Zone, ignored for Report Definition (the report's value is the only output).
generate_doe
generate_doe(n: int | None = None, method: str = 'lhs', points_per_param: int | None = None, seed: int = 42, append: bool = False) -> int
Generate DOE samples within the ranges from set_inputs(...).
Parameters
n : int, optional Sample count. Required for method='lhs', ignored for 'factorial'. method : str, default 'lhs' 'lhs' (Latin hypercube) or 'factorial' (full grid). points_per_param : int, optional Required for method='factorial'. Total samples = n_per_param ** n_inputs. seed : int, default 42 Random seed for LHS reproducibility. append : bool, default False If True, add to existing samples; otherwise replace.
Returns
int Total number of samples now stored.
connect_fluent
connect_fluent(precision: str | None = None, processor_count: int | None = None, dimension: int | None = None, use_gui: bool | None = None) -> None
Launch Fluent and load the project's case file.
Any kwarg passed here overrides the matching field from the project's
stored solver_settings (or the built-in defaults if none stored).
Pass precision="single" when the case file was saved in single
precision — Fluent will refuse to read a single-precision case in a
double-precision session.
Holds the solver handle on the Project; subsequent calls re-use it.
run_simulations
run_simulations(iterations: int | None = None, reinitialize: bool = True, verbose: bool = False, on_progress: Callable | None = None, on_iteration: Callable | None = None) -> SimulationResult
Run all incomplete DOE simulations. Auto-connects Fluent if needed.
Parameters
iterations
None (default) honors the iteration count baked into the case
file. Pass an int to override for this batch.
reinitialize
Re-run hybrid initialization before each sim. Usually what you want.
verbose
If True, prints one "sim X/N on_progress is supplied — your
callback takes over.
on_progress
callback(idx, total, sim_id, status) — fires when each sim
starts, finishes, or fails.
on_iteration
callback(sim_id, iter_num, total_iters) — fires per Fluent
iteration. Use sparingly; very chatty for long sim batches.
train
train(model_name: str, outputs=None, epochs: int = 500, test_size: float = 0.2, random_seed: int = 42, exclude_range: tuple[int, int] | None = None, excluded_ids: list[int] | None = None, on_progress: Callable | None = None, on_epoch: Callable | None = None, verbose: int = 1) -> TrainingResult
Train surrogate models for the requested outputs.
Parameters
model_name : str
Folder name under project/models/. Auto-suffixed (_2,
_3, ...) on collision; the final name is in
result.model_name. Letters/digits/_/- only.
outputs : None | list[str] | dict, default None
None = train every (location, field_variable) in the project,
with defaults.
**list of str** = train just those model_keys
(``"<location>_<field>"``), with defaults::
outputs=["mid_plane_temperature", "outlet_temp_value"]
**dict** = per-output overrides::
outputs={
"mid_plane_temperature": {
"pod": {"modes": 20}, # OR {"variance": 0.99}
"nn": {"learning_rate": 5e-4, "hidden_layers": [128, 64]},
},
"outlet_temp_value": {
"nn": {"preset": "1d"}, # switch base preset
},
}
epochs, test_size, random_seed, exclude_range : training defaults
excluded_ids : list[int], optional
Arbitrary 1-indexed sim_ids to withhold from training. Combined
with exclude_range (a sample is dropped if either matches).
predict
Run a trained model on input parameters.
Parameters
model_name : str
Name of the model directory under project/models/.
params : dict | list[dict]
dict — single sample::
project.predict("my_run", {"inlet|velocity": 0.5})
**list of dict** — batch (one prediction per dict)::
project.predict("my_run", [
{"inlet|velocity": 0.5},
{"inlet|velocity": 0.7},
])
list_models
Return sorted list of model folder names under project/models/.
model_info
Return the trained-model metadata. Raises KeyError if missing.
For models that bundle multiple sub-models (legacy layout — one folder held both temperature and velocity), this returns metadata for the first metadata.json found. Use a more specific model_name to target the per-field model.
delete_model
Delete a trained model directory. Raises KeyError if not found.