Change a constant in ODE calculations under particular conditions with a flag

前端 未结 1 1696
终归单人心
终归单人心 2020-12-22 01:37

I have an ODE for calculating how acidicity changes. Everything is working just fine, only I would like to change a constant whenever acidicity reaches a critical point. It

相关标签:
1条回答
  • 2020-12-22 02:30

    To do this accurately, you should use event detection within the ODE solver. I can't give you a specific answer because you've only provided the ode15s call it in your question, but you'll need to write an events function and then specify it via odeset. Something like this:

    function acidity_main
    % load c data
    ...
    x0 = ...
    options = odeset('Events',@events); % add any other options too
    
    % integrate until critical value and stop
    [Time1,Results1] = ode15s(@(x,c)f1(x,c),[0 c.length],x0,options);
    
    x0 = Results(end,:); % set new initial conditions
    % pass new parameters -it's not clear how you're passing parameters
    % if desired, change options to turn off events for faster integration
    [Time2,Results2] = ode15s(@(x,c)f1(x,c),[0 c.length],x0,options);
    
    % append outputs, last of 1 is same as first of 2
    Time = [Time1;Time2(2:end)];
    Results = [Results1;Results2(2:end,:)];
    ...
    
    function y=f1(x,c)
    % your integration function
    ...
    
    function [value,isterminal,direction] = events(x,c)
    value = ... % crossing condition, evaluates to zero at event condition
    isterminal = 1; % stop integration when event detected
    direction = ... % see documentation
    

    You'll want to use the events to integrate right to the point where the "acidicity reaches a critical point" and stop the integration. Then call ode15s again with the new value and continue the integration. This may seem crude, but it how this sort of thing can be done accurately.

    You can see an example of basic event detection here. Type ballode in your command window to see the code for this. You can see a slightly more complex version of this demo in my answer here. Here's an example of using events to accurately change an ODE at specified times (rather than your case of specified state values).

    Note: I find it strange that you're passing what you call "constants", c, as the second argument to ode15s. This function has strict input argument requirements: the first is the independent variable (often time), and the second is the array of state variables (same as your initial condition vector). Also if f1 only takes two arguments, @(x,c)f1(x,c) is superfluous – it's sufficient to pass in @f1.

    0 讨论(0)
提交回复
热议问题