Во-первых, обратите внимание, что a
является состоянием (по крайней мере, на основе приведенных уравнений). Это означает, что в настоящее время будет известна a
. Из вашего описания также известен c
(это, по-видимому, функция времени). Поэтому в любой момент времени мы знаем, какая ветвь оператора if
будет принята.
Таким образом, для любого заданного времени мы можем вычислить b
и, следовательно, der(a)
. Реальный вопрос: в какой момент меняется условие в инструкции if
.
Ответ заключается в том, что функция «монитор» устанавливается (компилятором Modelica), и когда эта функция монитора пересекает нуль, тогда среда выполнения Modelica будет реагировать, прекратив интеграцию в этой точке, а затем перезапустив интеграцию (используя другую филиал). Это связано с тем, что условное выражение в операторе if
неявно генерирует события.
Другой способ думать об этом заключается в том, что существует «скрытая» логическая переменная, которая указывает, берем ли мы ветку или другую. Во-первых, это звучит безумно, потому что вы предполагаете, что среда исполнения Modelica примет ветвь на основе того, a>c.y
, но это на самом деле не так. То, что он делает, это определить начальное значение логического значения на основе значения a>c.y
в начале моделирования, а затем оно пытается выяснить, когда оно действительно изменится. Он действительно не оценивает a>c.y
все время. Это приводит к странным ситуациям, когда одна ветка выполняется, хотя она не должна. Этот будет произойти в Modelica и связан с генерируемыми решениями-кандидатами , а ModelMan runtime пытается определить, где произошло событие.
Я знаю, что это звучит запутанно, но если вы примете понятие «скрытая логическая переменная» и понимаете, что оно не изменяется до тех пор, пока среда исполнения Modelica не сможет окончательно определить точку, в которой должно произойти изменение (на основе некоторого решения кандидата траектория), все это имеет смысл.
Я надеюсь, что это поможет.
Я думаю, что понимаю, что вы имеете в виду. Вы также говорите, что иногда одна ветка выполняется, пока она не должна. Это будет означать, что моя программа не очень эффективна. Знаете ли вы способ реализовать его лучше? – barbar
Я думаю, что «не должно» слишком сильное слово. Нельзя спорить о том, должен ли он или не должен выполнять ветвь, пока вы не сможете определить, в какой момент необходимо переключить ветви. Я не думаю, что это обязательно означает, что что-то неэффективно. Вы можете использовать оператор 'noEvent', чтобы оператор' if' работал так, как вы ожидаете. Но причина, по которой это не по умолчанию, заключается в том, что это может вызвать гораздо большую путаницу для интегратора, если вы сделаете это именно так. Контролируйте его, прежде чем вы решите, что он неэффективен. –