Описание проблемы
Я создаю библиотеку для поддержки Системная динамика (SD) , как моделирование в Modelica.В отличие от свободно доступной библиотеки Cellier et al.Я убежден, что вполне можно использовать акаузальные соединители: передача стоимости запаса в качестве «потенциала» через соединители позволяет создавать компактные компоненты (например, потоки = процессы).
В SD мы могли бы выделить материал ("масса ») акции от информационных акций, которые могут стать отрицательными.Чтобы поддержать это, я использую следующие определения для массового порта (здесь дано определение для StockPort
- его аналог, FlowPort
, будет просто иметь логические входные переменные вместо выходных переменных ибудет дано позже):
connector StockPort "Used to represent stock and flow connections"
Real stock "Current value of material in the stock";
flow Real rate "Flow that affects the stock";
// Boolean switches
output Boolean stopInflow "True indicates that nothing can flow into the stock";
output Boolean stopOutflow "True indicates that nothing can flow out of the stock";
end StockPort;
Булевы переключатели указывают для каждого порта акции , разрешено ли заполнение или слив.
Для "Запас материала"Переключатель stopOutflow
должен предотвращать слив материала ниже нуля.К сожалению, в следующем примере это не сработает: Запас будет опустошен чуть ниже нуля.
Минимальный пример с использованием соединителей
В следующих TestModel
используются этистроительные блоки:
function constrainedRate( indicated rate, stopInflow, stopOutflow)
используется для возврата скорости, которая будет соответствовать заданным ограничениям (т. е. логическим переключателям)
connector StockPort
как описано выше
connector FlowPort
аналог StockPort
model MaterialStock
запасного компонента с одним StockPort
, который не должен дренироваться ниже нуля model LinearDecline
элемент потока с одним FlowPort
(т. Е. Раковиной), который моделирует слив подключенного материала с постоянной скоростью (здесь установлено значение 1)
Основная модель просто инициирует stock
с initialValue = 5
, который связан с process
линейного спада с declineRate = 1
.
model TestModel "Stop draining a stock below zero"
function constrainedRate "Set rate for a port according to signals from stock"
input Real indicatedRate "Proposed rate for port of flow element";
input Boolean stopInflow "Signal from connected stock";
input Boolean stopOutflow "Signal from connected stock";
output Real actualRate "The rate to use";
protected
// check whether indicated rate is negative (e.g. an inflow to the connected stock)
Boolean indRateIsInflow = indicatedRate < 0;
algorithm
// set rate to zero if stopSignal matches character of flow
actualRate := if indRateIsInflow and stopInflow
then 0
elseif not indRateIsInflow and stopOutflow
then 0
else indicatedRate;
end constrainedRate;
connector FlowPort "Used to represent stock and flow connections"
Real stock "The current stock level (e.g. Potential) of a connected stock or flow data for special stocks";
flow Real rate "Flows that affect the material stock";
input Boolean stopInflow "True indicates that nothing can flow into the stock";
input Boolean stopOutflow "True indicates that nothing can flow out of the stock";
end FlowPort;
connector StockPort "Used to represent stock and flow connections"
Real stock "Current value of stock";
flow Real rate "Flow that affects the stock";
output Boolean stopInflow "True indicates that nothing can flow into the stock";
output Boolean stopOutflow "True indicates that nothing can flow out of the stock";
end StockPort;
model MaterialStock "Stock that cannot be drained below zero"
StockPort outflow;
parameter Real initialValue;
protected
Real x(start = initialValue);
equation
// rate of change for the stock
der(x) = outflow.rate;
// ports shall have level information for stock
outflow.stock = x;
// inflow to stock is unrestricted
outflow.stopInflow = false;
// provide Boolean signal in case of negative stock
outflow.stopOutflow = x <= 0;
end MaterialStock;
model LinearDecline "Decline of stock at a constant rate"
FlowPort massPort;
parameter Real declineRate(min = 0) "Rate of decline (positive rate diminishes stock)";
protected
// a positive rate should drain the stock (which here matches Modelica's rule for flows)
Real rate(min = 0);
equation
rate = declineRate;
// observe stock signals and constraints
assert(rate >= 0, "Rate must be positive and will be set to zero", level = AssertionLevel.warning);
// set the rate according to constraints given by stock
massPort.rate = constrainedRate( max(rate, 0), massPort.stopInflow, massPort.stopOutflow );
end LinearDecline;
// main model
MaterialStock stock( initialValue = 5 );
LinearDecline process( declineRate = 1 );
equation
connect( stock.outflow, process.massPort );
end TestModel;
Моделирование модели с использованием DASSL от StartTime = 0
доStopTime = 10
показывает ожидаемое поведение переменной stock.outflow.stock
:
![Stock Value](https://i.stack.imgur.com/kEYbH.png)
К сожалению, значение чуть ниже нуля на t = 5.0
и позже.
Каким-то образом событие (фондовая стоимость <= 0) обнаруживается слишком поздно.Что я могу сделать? </strong>
(До сих пор imo unlegant лекарство было использовать событие when
(состояние-событие), чтобы reinit
стоимость акций до нуля. Мои эксперименты с использованием *Оболочки 1084 * для операторов if
и логических условий также не увенчались успехом.)