Skip to content

Commit b1fa828

Browse files
committed
fix hlb-pro2pr2 with sample .pr2 output using the command
1 parent e899a5e commit b1fa828

File tree

2 files changed

+125
-5
lines changed

2 files changed

+125
-5
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
DurationSeconds: 0x1.4000000000000p+2
2+
Iolets:
3+
- Centre:
4+
x: 0x0.0p+0
5+
y: 0x0.0p+0
6+
z: -0x1.e000000000000p+4
7+
Name: Inlet1
8+
Normal:
9+
x: 0x0.0p+0
10+
y: 0x0.0p+0
11+
z: 0x1.0000000000000p+0
12+
Pressure:
13+
x: 0x1.0000000000000p+4
14+
y: 0x0.0p+0
15+
z: 0x0.0p+0
16+
Radius: 0x1.8000000000000p-1
17+
Type: Inlet
18+
- Centre:
19+
x: 0x0.0p+0
20+
y: 0x0.0p+0
21+
z: 0x1.e000000000000p+4
22+
Name: Outlet1
23+
Normal:
24+
x: 0x0.0p+0
25+
y: 0x0.0p+0
26+
z: -0x1.0000000000000p+0
27+
Pressure:
28+
x: 0x0.0p+0
29+
y: 0x0.0p+0
30+
z: 0x0.0p+0
31+
Radius: 0x1.8000000000000p-1
32+
Type: Outlet
33+
OutputGeometryFile: poiseuille_flow_test.gmy
34+
OutputXmlFile: poiseuille_flow_test.xml
35+
SeedPoint:
36+
x: -0x1.00da93eaa8180p-1
37+
y: -0x1.156ab416a2440p-6
38+
z: -0x1.f88444ad1efccp+3
39+
StlFile: poiseuille_flow_test.stl
40+
StlFileUnitId: 1
41+
TimeStepSeconds: 0x1.a36e2eb1c432dp-14
42+
VoxelSize: 0x1.568f2c0000000p-3

geometry-tool/HlbGmyTool/Model/Profile.py

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,49 @@
1515
from ..Util.Observer import Observable
1616
from .SideLengthCalculator import AverageSideLengthCalculator
1717
from .Vector import Vector
18-
from .Iolets import ObservableListOfIolets, IoletLoader
18+
# from .Iolets import ObservableListOfIolets, IoletLoader
19+
from .Iolets import ObservableListOfIolets, IoletLoader, Inlet, Outlet # ← added Inlet, Outlet
20+
21+
import types # required for dynamic module creation
22+
23+
class FakeUnpickler(pickle.Unpickler):
24+
def __init__(self, *args, **kwargs):
25+
super().__init__(*args, **kwargs)
26+
self._HST = types.ModuleType("HemeLbSetupTool")
27+
self._classes = {}
28+
29+
def _get_or_make_mod(self, moduleName):
30+
parts = moduleName.split(".")
31+
hst = parts.pop(0)
32+
assert hst == "HemeLbSetupTool"
33+
full = hst
34+
cur = self._HST
35+
while parts:
36+
name = parts.pop(0)
37+
if not hasattr(cur, name):
38+
mod = types.ModuleType(f"{full}.{name}")
39+
mod.__package__ = full
40+
full = mod.__name__
41+
setattr(cur, name, mod)
42+
cur = getattr(cur, name)
43+
return cur
44+
45+
def _get_or_make_class(self, mod, className):
46+
try:
47+
return getattr(mod, className)
48+
except AttributeError:
49+
def __up__(this):
50+
return this # no-op upgrade
51+
fake = type(className, (object,), {"__module__": mod.__name__, "__up__": __up__})
52+
setattr(mod, className, fake)
53+
return fake
54+
55+
def find_class(self, moduleName, className):
56+
if moduleName.startswith("HemeLbSetupTool"):
57+
mod = self._get_or_make_mod(moduleName)
58+
return self._get_or_make_class(mod, className)
59+
return super().find_class(moduleName, className)
60+
1961

2062

2163
class LengthUnit(Observable):
@@ -205,9 +247,45 @@ def LoadProfileV2(self, filename):
205247

206248
def LoadProfileV1(self, filename):
207249
with open(filename, "rb") as f:
208-
restored = pickle.Unpickler(f, fix_imports=True).load()
209-
restored._ResetPaths(filename)
210-
self.CloneFrom(restored)
250+
# restored = pickle.Unpickler(f, fix_imports=True).load()
251+
restored_fake = FakeUnpickler(f).load()
252+
halfway = restored_fake.__up__() # convert fake object to a dict-like profile object
253+
254+
# Manually assign fields instead of using CloneFrom(), to avoid constructor issues
255+
for attr in Profile._Args:
256+
val = getattr(halfway, attr, None)
257+
258+
if attr == 'SeedPoint' and val is not None:
259+
# Upgrade legacy vector to real Vector instance
260+
self.SeedPoint = Vector(val.x, val.y, val.z)
261+
262+
elif attr == 'Iolets' and val is not None:
263+
# Upgrade list of fake Inlet/Outlet objects to real ones
264+
real_iolets = ObservableListOfIolets()
265+
for io in val:
266+
# Choose correct type (Inlet or Outlet)
267+
inlet_or_outlet = Inlet() if getattr(io, 'Name', '').startswith("Inlet") else Outlet()
268+
269+
# Set required fields
270+
inlet_or_outlet.Name = getattr(io, 'Name', None)
271+
inlet_or_outlet.Radius = getattr(io, 'Radius', None)
272+
inlet_or_outlet.Centre = Vector(io.Centre.x, io.Centre.y, io.Centre.z)
273+
inlet_or_outlet.Normal = Vector(io.Normal.x, io.Normal.y, io.Normal.z)
274+
inlet_or_outlet.Pressure = Vector(io.Pressure.x, io.Pressure.y, io.Pressure.z)
275+
276+
real_iolets.append(inlet_or_outlet)
277+
278+
self.Iolets = real_iolets
279+
280+
elif val is not None:
281+
# Default assignment for all other attributes
282+
setattr(self, attr, val)
283+
284+
# Adjust file paths to be relative to the profile file
285+
self._ResetPaths(filename)
286+
287+
# restored._ResetPaths(filename)
288+
# self.CloneFrom(restored)
211289
return
212290

213291
def _ResetPaths(self, filename):
@@ -280,4 +358,4 @@ def IsFileValid(path, ext=None, exists=None):
280358
if ending != ext:
281359
return False
282360
pass
283-
return True
361+
return True

0 commit comments

Comments
 (0)