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

Fix DLL #42

Merged
merged 8 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ jobs:
- name: Test with pytest
run: |
pip install .[testing]
mamba install cadet>5.0.2 -c conda-forge
mamba install -c conda-forge cadet>=5.0.3
pytest tests --rootdir=tests -m "not slow and not local"
32 changes: 17 additions & 15 deletions cadet/cadet.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,55 +474,57 @@ def inverse_transform(self, x: str) -> str:
"""
return str.lower(x)

def run(
def run_load(
self,
timeout: Optional[int] = None,
clear: bool = True
) -> ReturnInformation:
"""
Run the CADET simulation.
Run the CADET simulation and load the results.

Parameters
----------
timeout : Optional[int]
Maximum time allowed for the simulation to run, in seconds.
clear : bool
If True, clear previous results after loading new ones.

Returns
-------
ReturnInformation
Information about the simulation run.
"""
return_information = self.cadet_runner.run(
self,
timeout=timeout,
)
return_information = self.run(timeout)

if return_information.return_code == 0:
self.load_results()

if clear:
self.clear()
return return_information

def run_load(
def run(
self,
timeout: Optional[int] = None,
clear: bool = True
) -> ReturnInformation:
"""
Run the CADET simulation and load the results.
Run the CADET simulation.

Parameters
----------
timeout : Optional[int]
Maximum time allowed for the simulation to run, in seconds.
clear : bool
If True, clear previous results after loading new ones.

Returns
-------
ReturnInformation
Information about the simulation run.
"""
return_information = self.run(timeout)
self.load_results()
return_information = self.cadet_runner.run(
self,
timeout=timeout,
)

if clear:
self.clear()
return return_information

def load_results(self) -> None:
Expand Down
23 changes: 17 additions & 6 deletions cadet/cadet_dll.py
Original file line number Diff line number Diff line change
Expand Up @@ -2037,51 +2037,62 @@ def _load_solution_io(
solution = addict.Dict()
_, out, dims = data

# Retrieve configuration options
split_components_data = sim.root.input['return'].get('split_components_data', 1)
split_ports_data = sim.root.input['return'].get('split_ports_data', 1)
single_as_multi_port = sim.root.input['return'].get('single_as_multi_port', 0)

# Identify dimension indices and sizes
nComp_idx = dims.index('nComp')
nComp = out.shape[nComp_idx]
try:
nPort_idx = dims.index('nPort')
nPort = out.shape[nPort_idx]
except ValueError:
nPort_idx = None
nPort = 1
nPort_idx = dims.index('nPort') if 'nPort' in dims else None
nPort = out.shape[nPort_idx] if nPort_idx is not None else 1

# Process data based on the split settings
if split_components_data:
if split_ports_data:
# Case: Split both components and ports
if nPort == 1:
if single_as_multi_port:
# Treat single port as multiple ports
for comp in range(nComp):
comp_out = out[..., 0, comp]
solution[f'{solution_str}_port_000_comp_{comp:03d}'] = comp_out
else:
# Default case for single port
for comp in range(nComp):
comp_out = out[..., comp]
solution[f'{solution_str}_comp_{comp:03d}'] = comp_out
else:
# Multi-port case
for port in range(nPort):
for comp in range(nComp):
comp_out = out[..., port, comp]
solution[f'{solution_str}_port_{port:03d}_comp_{comp:03d}'] = comp_out
else:
# Case: Split components only
for comp in range(nComp):
comp_out = out[..., comp]
if nPort == 1 and nPort_idx is not None:
comp_out = comp_out[:, 0] # Single-port adjustment
solution[f'{solution_str}_comp_{comp:03d}'] = comp_out
else:
if split_ports_data:
# Case: Split ports only
if nPort == 1:
if single_as_multi_port:
if nPort_idx is not None:
out = out[:, 0] # Adjust for single-port case
solution[f'{solution_str}_port_000'] = out
else:
solution[solution_str] = out[..., 0, :]
else:
# Multi-port case
for port in range(nPort):
port_out = out[..., port, :]
solution[f'{solution_str}_port_{port:03d}'] = port_out
else:
# Default case: No splitting
if nPort == 1 and nPort_idx is not None:
solution[solution_str] = out[..., 0, :]
else:
Expand Down
5 changes: 5 additions & 0 deletions cadet/cadet_dll_parameterprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,28 @@ def __init__(self, simulation: "Cadet") -> None:
self.popScope = self._fields_[17][1](utils.param_provider_pop_scope)

_fields_ = [
# 0 (Position must match indices in __init__ method.)
('userData', ctypes.py_object),

# 1
('getDouble', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, ctypes.POINTER(ctypes.c_double))),
('getInt', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, point_int)),
('getBool', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint8))),
('getString', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, ctypes.POINTER(ctypes.c_char_p))),

# 5
('getDoubleArray', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, point_int, array_double)),
('getIntArray', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, point_int, ctypes.POINTER(point_int))),
('getBoolArray', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, point_int, ctypes.POINTER(ctypes.POINTER(ctypes.c_uint8)))),
('getStringArray', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, point_int, ctypes.POINTER(ctypes.POINTER(ctypes.c_char_p)))),

# 9
('getDoubleArrayItem', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, ctypes.c_int, ctypes.POINTER(ctypes.c_double))),
('getIntArrayItem', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, ctypes.c_int, point_int)),
('getBoolArrayItem', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, ctypes.c_int, ctypes.POINTER(ctypes.c_uint8))),
('getStringArrayItem', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, ctypes.c_int, ctypes.POINTER(ctypes.c_char_p))),

# 13
('exists', ctypes.CFUNCTYPE(ctypes.c_int, ctypes.py_object, ctypes.c_char_p)),
('isArray', ctypes.CFUNCTYPE(c_cadet_result, ctypes.py_object, ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint8))),
('numElements', ctypes.CFUNCTYPE(ctypes.c_int, ctypes.py_object, ctypes.c_char_p)),
Expand Down
Loading
Loading