работа с случаями if в разделе уравнений

Мне было интересно, как в 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 может определить, какой случай оператора if верен? Он не может вычислить значение «a» без значения «b», которое определяется в операторе if.


person barbar    schedule 18.01.2014    source источник


Ответы (1)


Во-первых, обратите внимание, что a - это состояние (по крайней мере, на основе приведенных вами уравнений). Это означает, что в настоящее время будет известно a. Из вашего описания также известно c (видимо, это функция времени). Таким образом, в любой момент времени мы знаем, какая ветвь оператора if будет взята.

Таким образом, в любой момент времени мы можем вычислить b и, следовательно, der(a). Настоящий вопрос в том, в какой момент изменяется условие в операторе if.

Ответ заключается в том, что функция "монитора" устанавливается (компилятором Modelica), и когда эта функция монитора пересекает ноль, среда выполнения Modelica отреагирует, остановив интеграцию в этой точке, а затем перезапустив интеграцию (используя другую ветвь). Это связано с тем, что условное выражение в операторе if неявно генерирует события.

Другой способ подумать об этом состоит в том, что существует «скрытая» логическая переменная, которая указывает, берем ли мы ветку или другую. Сначала это звучит безумно, потому что вы предполагаете, что среда выполнения Modelica примет ветку в зависимости от того, a>c.y, но на самом деле это не так. Что он делает, так это определяет начальное значение логического значения на основе значения a>c.y в начале моделирования, а затем пытается выяснить, когда оно действительно изменится. На самом деле он не оценивает a>c.y все время. Это приводит к странным ситуациям, когда одна ветвь выполняется, хотя этого не должно быть. Это произойдет в Modelica и связано с вариантами решений, созданными в то время, когда среда выполнения Modelica пытается определить, где произошло событие.

Я знаю, это звучит сбивающе с толку, но если вы примете понятие «скрытой логической переменной» и поймете, что оно не изменится до тех пор, пока среда выполнения Modelica не сможет окончательно определить точку, в которой должно произойти изменение (на основе некоторой траектории возможного решения), это все имеет смысл.

Надеюсь, это поможет.

person Michael Tiller    schedule 18.01.2014
comment
Думаю, я понял, что ты имеешь в виду. Вы также говорите, что иногда одна ветвь выполняется, а не должна. Это означало бы, что моя программа не очень эффективна. Вы знаете, как лучше реализовать это? - person barbar; 20.01.2014
comment
Думаю, не следует - это слишком сильное слово. Невозможно спорить, следует или не следует выполнять ветвление, пока вы не определите, в какой момент необходимо переключить ветки. Я не думаю, что это обязательно означает, что что-то неэффективно. Вы можете использовать оператор noEvent, чтобы оператор if работал так, как вы ожидаете. Но причина, по которой это не поведение по умолчанию, заключается в том, что это может вызвать гораздо большую путаницу для интегратора, если вы сделаете это таким образом. Проведите сравнительный анализ, прежде чем решите, что он неэффективен. - person Michael Tiller; 21.01.2014