Description
On setting simulator.use_dll=True
I am getting
Exception ignored on calling ctypes callback function: <function param_provider_get_double_array at 0x000002996D31ADE0>
Traceback (most recent call last):
File "C:\Users\h.lanzrath\CADET\CADET-Python\cadet\cadet_dll_utils.py", line 232, in param_provider_get_double_array
val[0] = np.ctypeslib.as_ctypes(o)
~~~^^^
TypeError: incompatible types, c_double_Array_1_Array_2_Array_2 instance instead of LP_c_double instance
Exception ignored on calling ctypes callback function: <function param_provider_get_double_array_item at 0x000002996D31AF20>
Traceback (most recent call last):
File "C:\Users\h.lanzrath\CADET\CADET-Python\cadet\cadet_dll_utils.py", line 329, in param_provider_get_double_array_item
float_val = float(o[index])
^^^^^^^^^^^^^^^
TypeError: only length-1 arrays can be converted to Python scalars
Exception ignored on calling ctypes callback function: <function param_provider_get_double_array_item at 0x000002996D31AF20>
Traceback (most recent call last):
File "C:\Users\h.lanzrath\CADET\CADET-Python\cadet\cadet_dll_utils.py", line 329, in param_provider_get_double_array_item
float_val = float(o[index])
^^^^^^^^^^^^^^^
TypeError: only length-1 arrays can be converted to Python scalars
Exception ignored on calling ctypes callback function: <function param_provider_get_double_array_item at 0x000002996D31AF20>
Traceback (most recent call last):
File "C:\Users\h.lanzrath\CADET\CADET-Python\cadet\cadet_dll_utils.py", line 329, in param_provider_get_double_array_item
float_val = float(o[index])
~^^^^^^^
IndexError: index 2 is out of bounds for axis 0 with size 2
Exception ignored on calling ctypes callback function: <function param_provider_get_double_array_item at 0x000002996D31AF20>
...
File "C:\Users\h.lanzrath\CADET\CADET-Python\cadet\cadet_dll.py", line 1790, in run
returncode = self._api.runSimulation(self._driver, ctypes.byref(pp))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: exception: access violation reading 0x0000000000000000
only for the Multichannel Transport (MCT) model! I am running the latest (dev) versions for each CADET Package. I know that running with the DLL worked before, but I am unsure when it stopped working.
For MRE / debugging, you can run the create_LWE
test with the use_dll = True
option I added in #237. I would be very happy if someone can run it so I can make sure the issue is not connected to my setup. 🤞 (EDIT: It fails for Ron only for the MCT as well.)
Side note: Upon investigating the issue, I noticed, that the test case for the MCT in CADET-Python is missing, so I opened cadet/CADET-Python#50 as well.
I am really unsure why this happens, but maybe @schmoelder or @ronald-jaepel has an idea?
Important to mention is, that when I set use_dll=True
in CADET-Python, it works fine so either this is a CADET-Process issue or my CADET-Python setup is not correct.
from cadet import Cadet
import numpy as np
from addict import Dict
# The time at which the solution will be evaluated (start,end,steps/resolution)
t = np.linspace(0,400,599)
# Main unit of the MCT model
def get_mct_unit(params):
MCTUnit = Dict()
# Model Parameters
MCTUnit.unit_type = 'MULTI_CHANNEL_TRANSPORT'
MCTUnit.ncomp = 1
MCTUnit.col_length = params.col_length
MCTUnit.channel_cross_section_areas = params.channel_cross_section_areas
MCTUnit.col_dispersion = params.col_dispersion
MCTUnit.init_c = params.init_c
MCTUnit.exchange_matrix = params.e
# Discretization Parameters
MCTUnit.discretization.use_analytic_jacobian = 1
MCTUnit.discretization.weno.boundary_model = 0
MCTUnit.discretization.weno.weno_eps = 1e-10
MCTUnit.discretization.weno.weno_order = 3
MCTUnit.discretization.max_restarts = 10
MCTUnit.discretization.ncol = params.ncol
MCTUnit.nchannel = params.nchannel
# Simulate Tracer Decay via the reaction model
decay = params.decay
MCTUnit.reaction_model = 'MASS_ACTION_LAW'
MCTUnit.reaction_bulk.mal_kfwd_bulk = [decay]
MCTUnit.reaction_bulk.mal_kbwd_bulk = [0]
MCTUnit.reaction_bulk.mal_stoichiometry_bulk = [-1]
MCTUnit.mal_exponents_bulk_fwd = [
0, 1,
1, 0
]
return MCTUnit
# Inlet unit
def get_inlet_unit(params):
InletUnit = Dict()
InletUnit.inlet_type = 'PIECEWISE_CUBIC_POLY'
InletUnit.unit_type = 'INLET'
InletUnit.ncomp = 1
return InletUnit
# Solver and Solution settings
def solution_solver_settings(cadet,n_units):
# Which solutions should be calculated and displayed
cadet.root.input.model.nunits = n_units
cadet.root.input['return'].split_components_data = False
cadet.root.input['return'].split_ports_data = 1
cadet.root.input['return'].unit_000.write_solution_inlet = 1
cadet.root.input['return'].unit_000.write_solution_outlet = 1
cadet.root.input['return'].unit_000.write_solution_bulk = 1
cadet.root.input['return'].unit_000.write_solution_particle = 1
cadet.root.input['return'].unit_000.write_solution_solid = 1
cadet.root.input['return'].unit_000.write_solution_flux = 1
cadet.root.input['return'].unit_000.write_solution_volume = 1
cadet.root.input['return'].unit_000.write_coordinates = 1
cadet.root.input['return'].unit_000.write_sens_outlet = 1
for unit in range(3):
cadet.root.input['return']['unit_{0:03d}'.format(unit)] = cadet.root.input['return'].unit_000
# Tolerances for the time integrator
cadet.root.input.solver.time_integrator.abstol = 1e-10
cadet.root.input.solver.time_integrator.algtol = 1e-12
cadet.root.input.solver.time_integrator.reltol = 1e-10
cadet.root.input.solver.time_integrator.init_step_size = 1e-10
cadet.root.input.solver.time_integrator.max_steps = 1000000
# Solver settings
cadet.root.input.model.solver.gs_type = 1
cadet.root.input.model.solver.max_krylov = 0
cadet.root.input.model.solver.max_restarts = 10
cadet.root.input.model.solver.schur_safety = 1e-8
# Run the simulation on single thread
cadet.root.input.solver.nthreads = 1
cadet.root.input.solver.sections.nsec = 2
cadet.root.input.solver.sections.section_times = [0.0, t[-1]/2, t[-1]] # s
cadet.root.input.solver.sections.section_continuity = [0]
cadet.root.input.model.unit_000.sec_000.const_coeff = [1.0,] # mM
cadet.root.input.model.unit_000.sec_000.lin_coeff = [0.0,]
cadet.root.input.model.unit_000.sec_000.quad_coeff = [0.0,]
cadet.root.input.model.unit_000.sec_000.cube_coeff = [0.0,]
cadet.root.input.model.unit_000.sec_001.const_coeff = [0.0,] # mM
cadet.root.input.model.unit_000.sec_001.lin_coeff = [0.0,]
cadet.root.input.model.unit_000.sec_001.quad_coeff = [0.0,]
cadet.root.input.model.unit_000.sec_001.cube_coeff = [0.0,]
unit_params=Dict()
unit_params.col_dispersion = 0
unit_params.col_length = 200
unit_params.init_c = [0]
unit_params.ncol = 2**8
unit_params.decay=0.000567*60
unit_params.channel_cross_section_areas = [1,1,1]
unit_params.nchannel=3
# The number of channels and the number of parameters
# as well as their place in the exchange matrix define
# the specific model of the model class
# M13
e = 1e-2
a12=3*e
a21=1*e
a23=0.5*e
unit_params.e = [
0, a12, 0,
a21, 0, a23,
0, 0, 0 ]
inlet_params=Dict()
cadet = Cadet(use_dll=True)
# Inlet unit
cadet.root.input.model.unit_000 = get_inlet_unit(inlet_params)
# MCT unit
cadet.root.input.model.unit_001 = get_mct_unit(unit_params)
# Outlet unit
cadet.root.input.model.unit_002.unit_type = 'OUTLET'
cadet.root.input.model.unit_002.ncomp = 1
# Give number of units to Solutions and Solver Settings
solution_solver_settings(cadet,3)
# Define unit connections
Q = 1.2
cadet.root.input.model.connections.nswitches = 1
cadet.root.input.model.connections.switch_000.section = 0
cadet.root.input.model.connections.switch_000.connections = [
0, 1, 0, 0, -1, -1, Q, # unit_000, unit_001, all components, all components, Q/ m^3/s
1, 2, 0, 0, -1, -1, Q,
]
#Running simulation
data=cadet.run()
data