SystemSimulation

Hello everybody,

I try to simulate my system with a CSTR and a Lumped Rate Model without pores.
I’m working with Cadet 4.0.1 on a Windows Machine.
When I’m running the code presented below I get the following error message:

Error using MexSimulator/setParameters (line 738)
Expected valid parameters, but parameter 1 is invalid or does not exist.

Error in System_Simulation>Parameter_fitting (line 46)
	sim.setParameters(params, true(2, 1)); 

Is this a common Error within this Cadet version, when using Version 3.1.2, this version does not occur.

My code:

Load CSTR-DPFR model:

sim = createSimulation(t,V_CSTR,Q);

Set model parameters and enable sensitivities:

params = cell(2, 1);

Two parameters are fitted. Column length and dispersion!

params{1} = makeSensitivity([2], {'COL_LENGTH'},       [0], [-1], [-1], [-1], [-1]);
params{2} = makeSensitivity([2], {'COL_DISPERSION'},   [0], [-1], [-1], [-1], [-1]);

The first argument in the ‘makeSensitivity’ function is referring to the Unit operation index, which is the Lumped Rate model without pores.

Set Parameters
sim.setParameters(params, true(2, 1));

Thank you in advance!

The third parameter (component index) of makeSensitivity() looks odd. Since neither the length of the column nor the dispersion coefficient depend on the component, it should be -1:

params{1} = makeSensitivity([2], {'COL_LENGTH'},     [-1], [-1], [-1], [-1], [-1]);
params{2} = makeSensitivity([2], {'COL_DISPERSION'}, [-1], [-1], [-1], [-1], [-1]);
1 Like

Thank you for your fast response!

I still get the same error, if I exchange the [0] with [-1].

In order to further diagnose the problem, we need to see how the model is set up.
Please post the code of the createSimulation() function.

If the function contains sensitive / confidential data, you can insert some dummy values instead or leave the fields empty.

Equivalent circuit of the system with CSTR and DPFR
function sim = createSimulation(t,V_CSTR,Q)

mIn = PiecewiseCubicPolyInlet();
mIn.nComponents = 1;       % Number of components


mIn.constant       = zeros(2, mIn.nComponents);
mIn.linear         = zeros(2, mIn.nComponents);
mIn.quadratic      = zeros(2, mIn.nComponents);
mIn.cubic          = zeros(2, mIn.nComponents);

% Section 1: Pulse

mIn.constant(1,1) =307;

Step 2: Construct a CSTR

       mCSTR = StirredTankModel();
       mCSTR.nComponents = 1; 
   
        %Parameters
       mCSTR.porosity = 1;
   
        %Initial Values 
       mCSTR.initialConcentration = [0];   
       mCSTR.initialVolume = V_CSTR;      

Step 3: Construct a DPFR

    mPFR = LumpedRateModelWithoutPores(); 

    % Discretization
    mPFR.nComponents = 1; 
    mPFR.nCellsColumn = 80;             
    mPFR.nBoundStates = 0; 

    %Initial Values
    mPFR.initialBulk = 0; 

    %Transport
    mPFR.dispersionColumn = 2.4139e-4; 
    mPFR.interstitialVelocity = 1;     

    %Geometry
    mPFR.porosity = 1; 
    mPFR.columnLength = 2.40541;       
    mPFR.crossSectionArea = 2.48e-7;    

Step 4: Construct outlet unit operation

mOut = OutletModel();
mOut.nComponents = 1;

Step 5: Assemble system of unit operations

mSys = ModelSystem();
mSys.models = [mIn, mCSTR, mPFR, mOut];

mSys.connectionStartSection = [0];

mSys.connections = {[  0, 1, -1, -1, -1, -1, Q; ...
                       1, 2, -1, -1, -1, -1, Q;...
                       2, 3, -1, -1, -1, -1, Q]};

Step 7: Create simulator and configure it

sim = Simulator.create();
sim.solutionTimes = t; % [s],  


sim.sectionTimes = [0.0 t(23) t(end)]; % [s]
 sim.sectionContinuity = [false];	

sim.model = mSys;
end

Sorry for the long delay. I’ve been extremely busy lately.

The problem is CADET trying to be too clever. This is what you need to do:

params{1} = makeSensitivity([2], {'COL_LENGTH'},     [-1], [-1], [-1], [-1], [-1]);
params{2} = makeSensitivity([2], {'COL_DISPERSION'},  [0], [-1], [-1], [-1], [-1]);

The question is: Why does the dispersion coefficient depend on the component index?
CADET tries to be clever:

  • If you specifiy as many dispersion coefficients as there are components, it assumes that the dispersion coefficient depends on the component (i.e., each component has a different dispersion coefficient).
  • If you hand over as many coefficients as there are time sections, it will assume that each time section uses a different coefficient (e.g., if flow rates change in each section).
  • If you provide numSections * numComponents values, it guesses that you want the dispersion coefficient to depend on the time section and the component.

Obviously, that doesn’t always work out. Sometimes CADET will not guess correctly (e.g., if numSections = numComponents) or simply not do the thing you actually want. This is why we have settings to control this (COL_DISPERSION_MULTIPLEX in this case, see the manual).

Unfortunately, the Matlab frontend/interface does not implement COL_DISPERSION_MULTIPLEX for the LumpedRateModelWithoutPores. Since you use a single component and provide a single dispersion coefficient, CADET assumes that the dispersion coefficient depends on the component index. This is why you need to set the component index to 0 when addressing the parameter in makeSensitivity().

The column length, however, does never depend on anything (same for all time, same for all components). Here, you need to set the component index to -1.

Note that if you later add more components to the system, you will need

params{2} = makeSensitivity([2], {'COL_DISPERSION'}, [-1], [-1], [-1], [-1], [-1]);

that is, component index -1 (independent). Now CADET sees two components, but only one dispersion coefficient. Hence, it assumes that dispersion is independent of components (and sections).

I’ll create an issue in GitHub to add support for COL_DISPERSION_MULTIPLEX in the Matlab interface of the LumpedRateModelWithoutPores.

params{2} = makeSensitivity([2], {‘COL_DISPERSION’}, [-1], [-1], [-1], [-1], [-1]);

I changed the parameter exactly the way you mentioned, but it still doesn’t work and i’ll get the same error