Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/tbrom 241 public api refactoring #96

Merged
merged 25 commits into from
Jul 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d74b0e8
Refactor public methods signature and remove useless public methods a…
Jun 27, 2023
9b59c30
Refactor test_tbrom module
Jun 27, 2023
588987f
Update example 06
Jun 27, 2023
d8cfbef
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 27, 2023
c7637c6
Signature renaming
Jun 27, 2023
8a188e8
Merge branch 'feat/tbrom_241_public_api_refactoring' of https://githu…
Jun 27, 2023
4b0cb94
Signature renaming
Jun 27, 2023
83c7fa4
Fix docstring
Jun 27, 2023
313bbf8
Fix issue with test_each_twin_model_has_a_subfolder_in_wd
Jun 28, 2023
6923c46
Remove TwinModel.tbroms as public property
Jun 28, 2023
fc7238b
Add debug print
Jun 28, 2023
e88e6a9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 28, 2023
f8d0822
Simplify tbrom_init logic
Jun 28, 2023
c944fbe
Add more debug info
Jun 28, 2023
8fcacf3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 28, 2023
6dced6e
Fix TbRom unit test issue due to field inputs order is OS dependant
Jun 28, 2023
2bc6331
Merge with remote
Jun 28, 2023
4e06426
Fix TbRom unit test issue related to field input names order that dep…
Jun 29, 2023
8d9c35b
Rework TbRom instantiation and initialization logic
Jun 29, 2023
4416ee7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 29, 2023
b59a0fb
Refactor error message handling in TbRom and update unittests
Jun 30, 2023
461f4c9
Fix merge with remote branch
Jun 30, 2023
f9cb5d9
Fix unit test issue with field name order
Jun 30, 2023
70244b7
Code cleaning
Jun 30, 2023
ae8ad28
Remove usage of pytest.raises() in unit tests
Jun 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions examples/evaluate/06-TBROM_input_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,25 +166,25 @@ def norm_vector_field(field: list):
twin_model.initialize_evaluation()
print(f"TBROMs part of the twin : {twin_model.tbrom_names}")
romname = twin_model.tbrom_names[0]
print(f"Input fields associated with the TBROM {romname} : {twin_model.get_rom_inputfieldsnames(romname)}")
fieldname = twin_model.get_rom_inputfieldsnames(romname)[0]
print(f"Named selections associated with the TBROM {romname} : {twin_model.get_rom_nslist(romname)}")
ns = twin_model.get_rom_nslist(romname)[1]
print(f"Input fields associated with the TBROM {romname} : {twin_model.get_field_input_names(romname)}")
fieldname = twin_model.get_field_input_names(romname)[0]
print(f"Named selections associated with the TBROM {romname} : {twin_model.get_named_selections(romname)}")
ns = twin_model.get_named_selections(romname)[1]

input_name = input_name_without_mcs[0]
for i in range(0, len(rom_inputs)):
# initialize twin with input values and collect output value
dp = rom_inputs[i]
dp_input = {input_name: dp}
dp_field_input = {romname: {fieldname: inputfieldsnapshots[i]}}
twin_model.initialize_evaluation(inputs=dp_input, inputfields=dp_field_input)
twin_model.initialize_evaluation(inputs=dp_input, field_inputs=dp_field_input)
outputs = [dp]
for item in output_name_without_mcs:
outputs.append(twin_model.outputs[item])
outfield = twin_model.snapshot_generation(romname, False) # generating the field output on the entire domain
outfieldns = twin_model.snapshot_generation(romname, False, ns) # generating the field output on "Group_2"
twin_model.points_generation(romname, True, ns) # generating the points file on "Group_2"
twin_model.snapshot_generation(romname, True, ns) # generating the field snapshot on "Group_2"
outfield = twin_model.generate_snapshot(romname, False) # generating the field output on the entire domain
outfieldns = twin_model.generate_snapshot(romname, False, ns) # generating the field output on "Group_2"
twin_model.generate_points(ns, romname, True) # generating the points file on "Group_2"
twin_model.generate_snapshot(romname, True, ns) # generating the field snapshot on "Group_2"
outputs.append(max(norm_vector_field(outfield)))
outputs.append(max(norm_vector_field(outfieldns)))
results.append(outputs)
Expand Down
109 changes: 52 additions & 57 deletions src/ansys/pytwin/evaluate/tbrom.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class TbRom:
"""
Instantiates a TBROM that is part of a Twin file created by Ansys Twin Builder.
Instantiates a TBROM that is part of a TWIN file created by Ansys Twin Builder.

After a twin model is initialized and its TBROM is instantiated, additional functionalities
are available to generate snapshots (in memory or on disk) and project input field data
Expand All @@ -16,9 +16,11 @@ class TbRom:
Parameters
----------
tbrom_name : str
Name of the TBROM included in the twin file.
Name of the TBROM included in the TWIN file (it is the name of the TBROM component inserted in the Twin Builder
subsheet used to assemble the TWIN model).
tbrom_path : str
File path to the folder with TBROM files.
File path to the folder with TBROM files (it is the temporary directory used by the Twin Runtime SDK for the
evaluation of this TBROM).
"""

IN_F_KEY = "binaryInputField"
Expand All @@ -29,7 +31,7 @@ class TbRom:

def __init__(self, tbrom_name: str, tbrom_path: str):
self._tbrom_path = tbrom_path
self._tbrom_name = tbrom_name
self._name = tbrom_name
self._infmcs = None
self._outmcs = None
self._infbasis = None
Expand Down Expand Up @@ -58,7 +60,7 @@ def __init__(self, tbrom_name: str, tbrom_path: str):
self._outunit = unit
self._outputfilespath = None

def points_generation(self, on_disk: bool, output_file_path: str, named_selection: str = None):
def generate_points(self, named_selection: str, on_disk: bool, output_file_path: str):
"""
Generate a point file for the full field or a specific part.

Expand All @@ -78,7 +80,7 @@ def points_generation(self, on_disk: bool, output_file_path: str, named_selectio
pointpath = os.path.join(self._tbrom_path, TbRom.OUT_F_KEY, TbRom.TBROM_POINTS)
vec = np.array(TbRom._read_binary(pointpath))
if named_selection is not None:
pointsids = self.namedselectionids(named_selection)
pointsids = self.named_selection_indexes(named_selection)
listids = []
for i in pointsids:
for k in range(0, 3):
Expand All @@ -90,7 +92,7 @@ def points_generation(self, on_disk: bool, output_file_path: str, named_selectio
else:
return vec

def snapshot_generation(self, on_disk: bool, output_file_path: str, named_selection: str = None):
def generate_snapshot(self, on_disk: bool, output_file_path: str, named_selection: str = None):
"""
Generate a field snapshot based on current states of the TBROM for the
full field or a specific part.
Expand All @@ -117,62 +119,56 @@ def snapshot_generation(self, on_disk: bool, output_file_path: str, named_select
mnp = np.array(basis[i])
vec = vec + mc[i] * mnp
if named_selection is not None:
pointsids = self.namedselectionids(named_selection)
pointsids = self.named_selection_indexes(named_selection)
listids = []
for i in pointsids:
for k in range(0, self.outputfielddimensionality):
listids.append(i * self.outputfielddimensionality + k)
for k in range(0, self.field_output_dim):
listids.append(i * self.field_output_dim + k)
vec = vec[listids]
if on_disk:
TbRom._write_binary(output_file_path, vec)
return output_file_path
else:
return vec

def snapshot_projection(self, snapshot: str, fieldname: str = None):
def _reduce_field_input(self, name: str, snapshot_filepath: str):
"""
Project a snapshot file associated to the input field name ``fieldname``

Parameters
----------
snapshot: str
snapshot_filepath: str
Path of the input field snapshot file
fieldname: str (optional)
name: str (optional)
Name of the input field to project the snapshot. The name of the field must be specified in case the TBROM
is parameterized with multiple input fields.
"""
mc = []
vec = TbRom._read_binary(snapshot)
vec = TbRom._read_binary(snapshot_filepath)
vecnp = np.array(vec)
if fieldname is None or self.numberinputfields == 1:
if name is None or self.field_input_count == 1:
basis = list(self._infbasis.values())[0]
else:
basis = self._infbasis[fieldname]
basis = self._infbasis[name]
nb_mc = len(basis)
for i in range(nb_mc):
mnp = np.array(basis[i])
mci = mnp.dot(vecnp)
mc.append(mci)
if fieldname is None or self.numberinputfields == 1:
if name is None or self.field_input_count == 1:
index = 0
for item, key in self._infmcs[self.nameinputfields[0]].items():
self._infmcs[self.nameinputfields[0]][item] = mc[index]
for item, key in self._infmcs[self.field_input_names[0]].items():
self._infmcs[self.field_input_names[0]][item] = mc[index]
index = index + 1
else:
index = 0
for item, key in self._infmcs[fieldname].items():
self._infmcs[fieldname][item] = mc[index]
for item, key in self._infmcs[name].items():
self._infmcs[name][item] = mc[index]
index = index + 1

def namedselectionids(self, nsname: str):
def named_selection_indexes(self, nsname: str):
return self._nsidslist[nsname]

def fieldinputmodecoefficients(self, fieldname: str):
return self._infmcs[fieldname]

def hasinfmcs(self, fieldname: str):
return self._hasinfmcs[fieldname]

def input_field_size(self, fieldname: str):
return len(self._infbasis[fieldname][0])

Expand Down Expand Up @@ -203,10 +199,12 @@ def _read_binary(file):

@staticmethod
def _write_binary(fn, vec):
fw = open(fn, "wb")
fw.write(struct.pack("Q", len(vec)))
for i in vec:
fw.write(struct.pack("d", i))
if os.path.exists(fn):
os.remove(fn)
with open(fn, "xb") as fw:
fw.write(struct.pack("Q", len(vec)))
for i in vec:
fw.write(struct.pack("d", i))
return True

@staticmethod
Expand Down Expand Up @@ -238,41 +236,38 @@ def read_snapshot_size(file):
return nbdof

@property
def outmcs(self):
return self._outmcs

@property
def hasoutmcs(self):
return self._hasoutmcs

@property
def tbromname(self):
return self._tbrom_name

@property
def numberinputfields(self):
def field_input_count(self):
"""Return the number of field input(s) that can be used for this TBROM."""
return len(self._infbasis)

@property
def nameinputfields(self):
return list(self._infbasis.keys())

@property
def infmcs(self):
return self._infmcs
def field_input_names(self):
"""Return a list of the input field names that can be used for this TBROM."""
if self._infbasis is not None:
return list(self._infbasis.keys())
else:
return []

@property
def nsnames(self):
return list(self._nsidslist.keys())
def field_output_dim(self):
"""Return the dimension of the field output."""
return self._outdim

@property
def outputfieldname(self):
def field_output_name(self):
"""Return the field output name."""
return self._outname

@property
def outputfieldunit(self):
def field_output_unit(self):
"""Return the field output unit."""
return self._outunit

@property
def outputfielddimensionality(self):
return self._outdim
def named_selections(self):
"""Return the list of named selections available for this TBROM."""
return list(self._nsidslist.keys())

@property
def name(self):
return self._name
Loading