2014-01-18 4 views
1

мне было интересно, как возможно следующее в Modelica:работает с, если дела в секции уравнения

suppose variables a,b 
Timetable object c 

    equation 
    if a>c.y then 
     b = f(a) // with f a mathematical function 
    else 
     b = g(a) // with g a mathematical function 
    end if; 

    der(a) = h(a,b) //with h a mathematical function 

Как Modelica может определить, какой случай, если заявление верно? Он не может вычислить значение «a» без значения «b», которое определяется в выражении if.

ответ

3

Во-первых, обратите внимание, что 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 не сможет окончательно определить точку, в которой должно произойти изменение (на основе некоторого решения кандидата траектория), все это имеет смысл.

Я надеюсь, что это поможет.

+0

Я думаю, что понимаю, что вы имеете в виду. Вы также говорите, что иногда одна ветка выполняется, пока она не должна. Это будет означать, что моя программа не очень эффективна. Знаете ли вы способ реализовать его лучше? – barbar

+0

Я думаю, что «не должно» слишком сильное слово. Нельзя спорить о том, должен ли он или не должен выполнять ветвь, пока вы не сможете определить, в какой момент необходимо переключить ветви. Я не думаю, что это обязательно означает, что что-то неэффективно. Вы можете использовать оператор 'noEvent', чтобы оператор' if' работал так, как вы ожидаете. Но причина, по которой это не по умолчанию, заключается в том, что это может вызвать гораздо большую путаницу для интегратора, если вы сделаете это именно так. Контролируйте его, прежде чем вы решите, что он неэффективен. –