Skip to content

Commit 0255d34

Browse files
[FXC-3764] Added function to change the header for BET csv files (#1526) (#1576)
* first pass at fixing header files for bet disk * moved csv header update to restart_utils * added unit test and refactor * updated test * fixed tests * black isort pyling * black isort pylint * fixed pylint and isort * add pattern support * added new csv class and fixed pylit and unit tests * split tests * black and isort * fixed names and doc string * black and isort * fixed docstring * fixed tests --------- Co-authored-by: awccoppFC <alexander.coppeans@flexcompute.com>
1 parent 6a64c77 commit 0255d34

File tree

5 files changed

+360
-2
lines changed

5 files changed

+360
-2
lines changed

flow360/component/results/base_results.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from flow360.component.simulation.models.surface_models import BoundaryBase
2626
from flow360.component.simulation.simulation_params import SimulationParams
2727
from flow360.component.v1.flow360_params import Flow360Params
28-
from flow360.exceptions import Flow360ValueError
28+
from flow360.exceptions import Flow360TypeError, Flow360ValueError
2929
from flow360.log import log
3030

3131
# pylint: disable=consider-using-with
@@ -753,3 +753,16 @@ def reload_data(self, filter_physical_steps_only: bool = False, include_time: bo
753753
filter_physical_steps_only=filter_physical_steps_only, include_time=include_time
754754
)
755755
self._filtered_sum()
756+
757+
758+
class LocalResultCSVModel(ResultCSVModel):
759+
"""
760+
CSV Model with no remote file that cannot be downloaded used for locally working with csv data
761+
"""
762+
763+
remote_file_name: Optional[str] = None
764+
765+
def download(
766+
self, to_file: str = None, to_folder: str = ".", overwrite: bool = False, **kwargs
767+
):
768+
raise Flow360TypeError("Cannot download csv from LocalResultCSVModel")

flow360/component/results/case_results.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Case results module"""
22

3+
# pylint: disable=too-many-lines
4+
35
from __future__ import annotations
46

57
import re
@@ -15,6 +17,7 @@
1517
_PHYSICAL_STEP,
1618
_PSEUDO_STEP,
1719
_TIME,
20+
LocalResultCSVModel,
1821
PerEntityResultCSVModel,
1922
ResultBaseModel,
2023
ResultCSVModel,
@@ -32,6 +35,7 @@
3235
_HEAT_FLUX,
3336
_X,
3437
_Y,
38+
BETDiskCSVHeaderOperation,
3539
DiskCoefficientsComputation,
3640
PorousMediumCoefficientsComputation,
3741
_CFx,
@@ -815,6 +819,26 @@ def to_base(self, base: str, params: Flow360Params = None):
815819
self.values["ForceUnits"] = bet.force_x.units
816820
self.values["MomentUnits"] = bet.moment_x.units
817821

822+
def format_headers(
823+
self, params: SimulationParams, pattern: str = "$BETName_$CylinderName"
824+
) -> LocalResultCSVModel:
825+
"""
826+
Renames the header entries from Disk{i}_ to based on an input user pattern
827+
such as $BETName_$CylinderName
828+
Parameters
829+
----------
830+
params : SimulationParams
831+
Simulation parameters
832+
pattern : str
833+
Pattern string to rename header entries. Available patterns
834+
[$BETName, $CylinderName, $DiskLocalIndex, $DiskGlobalIndex]
835+
Returns
836+
-------
837+
LocalResultCSVModel
838+
Model containing csv with updated header
839+
"""
840+
return BETDiskCSVHeaderOperation.format_headers(self, params, pattern)
841+
818842
def compute_coefficients(self, params: SimulationParams) -> BETDiskCoefficientsCSVModel:
819843
"""
820844
Compute disk coefficients from BET disk forces and moments.
@@ -877,6 +901,26 @@ class BETDiskCoefficientsCSVModel(ResultCSVModel):
877901

878902
remote_file_name: str = pd.Field("bet_disk_coefficients_v2.csv", frozen=True)
879903

904+
def format_headers(
905+
self, params: SimulationParams, pattern: str = "$BETName_$CylinderName"
906+
) -> LocalResultCSVModel:
907+
"""
908+
Renames the header entries from Disk{i}_ to based on an input user pattern
909+
such as $BETName_$CylinderName
910+
Parameters
911+
----------
912+
params : SimulationParams
913+
Simulation parameters
914+
pattern : str
915+
Pattern string to rename header entries. Available patterns
916+
[$BETName, $CylinderName, $DiskLocalIndex, $DiskGlobalIndex]
917+
Returns
918+
-------
919+
LocalResultCSVModel
920+
Model containing csv with updated header
921+
"""
922+
return BETDiskCSVHeaderOperation.format_headers(self, params, pattern)
923+
880924

881925
class PorousMediumResultCSVModel(OptionallyDownloadableResultCSVModel):
882926
"""Model for handling porous medium CSV results."""
@@ -953,3 +997,23 @@ class BETForcesRadialDistributionResultCSVModel(OptionallyDownloadableResultCSVM
953997
CaseDownloadable.BET_FORCES_RADIAL_DISTRIBUTION.value, frozen=True
954998
)
955999
_err_msg = "Case does not have any BET disks."
1000+
1001+
def format_headers(
1002+
self, params: SimulationParams, pattern: str = "$BETName_$CylinderName"
1003+
) -> LocalResultCSVModel:
1004+
"""
1005+
Renames the header entries from Disk{i}_ to based on an input user pattern
1006+
such as $BETName_$CylinderName
1007+
Parameters
1008+
----------
1009+
params : SimulationParams
1010+
Simulation parameters
1011+
pattern : str
1012+
Pattern string to rename header entries. Available patterns
1013+
[$BETName, $CylinderName, $DiskLocalIndex, $DiskGlobalIndex]
1014+
Returns
1015+
-------
1016+
LocalResultCSVModel
1017+
Model containing csv with updated header
1018+
"""
1019+
return BETDiskCSVHeaderOperation.format_headers(self, params, pattern)

flow360/component/results/results_utils.py

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77

88
import numpy as np
99

10-
from flow360.component.results.base_results import _PHYSICAL_STEP, _PSEUDO_STEP
10+
from flow360.component.results.base_results import (
11+
_PHYSICAL_STEP,
12+
_PSEUDO_STEP,
13+
LocalResultCSVModel,
14+
ResultCSVModel,
15+
)
16+
from flow360.component.simulation.models.volume_models import BETDisk
1117
from flow360.component.simulation.simulation_params import SimulationParams
1218
from flow360.exceptions import Flow360ValueError
1319
from flow360.log import log
@@ -410,3 +416,73 @@ def compute_coefficients_static(
410416
out[f"{zone_name}_{_CL}"].append(CL_val)
411417

412418
return coefficients_model_class().from_dict(out)
419+
420+
421+
class BETDiskCSVHeaderOperation:
422+
# pylint:disable=too-few-public-methods
423+
"""
424+
Static utilities for renaming BET disk csv output headers to include the name of the BET disk.
425+
426+
This class provides only static methods and should not be instantiated or subclassed.
427+
All methods are self-contained and require explicit parameters.
428+
"""
429+
430+
@staticmethod
431+
def format_headers(
432+
BETCSVModel: ResultCSVModel,
433+
params: SimulationParams,
434+
pattern: str = "$BETName_$CylinderName",
435+
) -> LocalResultCSVModel:
436+
"""
437+
renames the header entries in a BET csv file from Disk{x}_ based on input pattern
438+
$Default option is $BETName_$CylinderName
439+
440+
pattern can take [$BETName, $CylinderName, $DiskLocalIndex, $DiskGlobalIndex]
441+
Parameters
442+
----------
443+
BETCSVModel : ResultCSVModle
444+
Model containing csv entries
445+
params : SimulationParams
446+
Simulation parameters
447+
pattern : str
448+
Pattern string to rename header entries. Available patterns
449+
[$BETName, $CylinderName, $DiskLocalIndex, $DiskGlobalIndex]
450+
Returns
451+
-------
452+
LocalResultCSVModel
453+
Model containing csv with updated header
454+
"""
455+
# pylint:disable=too-many-locals
456+
bet_disks = []
457+
for model in params.models:
458+
if isinstance(model, BETDisk):
459+
bet_disks.append(model)
460+
if not bet_disks:
461+
raise ValueError("No BET Disks in params to rename header.")
462+
463+
csv_data = BETCSVModel.values
464+
new_csv = {}
465+
466+
disk_rename_map = {}
467+
468+
diskCount = 0
469+
for disk in bet_disks:
470+
for disk_local_index, cylinder in enumerate(disk.entities.stored_entities):
471+
new_name = pattern.replace("$BETName", disk.name)
472+
new_name = new_name.replace("$CylinderName", cylinder.name)
473+
new_name = new_name.replace("$DiskLocalIndex", str(disk_local_index))
474+
new_name = new_name.replace("$DiskGlobalIndex", str(diskCount))
475+
disk_rename_map[f"Disk{diskCount}"] = new_name
476+
diskCount = diskCount + 1
477+
478+
for header, values in csv_data.items():
479+
matched = False
480+
for default_prefix, new_prefix in disk_rename_map.items():
481+
if header.startswith(default_prefix):
482+
new_csv[new_prefix + header[len(default_prefix) :]] = values
483+
matched = True
484+
break
485+
if not matched:
486+
new_csv[header] = values
487+
newModel = LocalResultCSVModel().from_dict(new_csv)
488+
return newModel

tests/simulation/results_processing/test_bet_disk_coefficients.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import flow360 as fl
77
from flow360.component.results.case_results import BETForcesResultCSVModel
88
from flow360.component.simulation.framework.param_utils import AssetCache
9+
from flow360.component.simulation.models.volume_models import BETDisk
910
from flow360.component.simulation.services import ValidationCalledBy, validate_model
1011

1112
from .test_helpers import compute_freestream_direction, compute_lift_direction

0 commit comments

Comments
 (0)