Skip to content

OSError: exception: access violation when using CAPI with MCT #236

Closed
@hannahlanzrath

Description

@hannahlanzrath

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions