Когда использовать оператор noEvent в языке Modelica?

Оператор noEvent в Modelica не использует итерацию для определения точного момента времени, в который было инициировано событие.

введите здесь описание изображения

Похоже, это приведет к ошибке расчета. Вот пример, который я нашел на следующем веб-сайте https://mbe.modelica.university/behavior/discrete/decay/ Итак, должен ли я гарантировать плавность работы функции при использовании оператора noEvent? Какая цель использования оператора noEvent, если он не может гарантировать точность?

введите здесь описание изображения


person Jack    schedule 22.02.2020    source источник
comment
Можете ли вы добавить ссылку / ссылку на первый добавленный скриншот? Часть перед «Дополнительно, noEvent() ...» мне кажется немного странной. Я хотел бы получить более подробный контекст ...   -  person Markus A.    schedule 24.02.2020
comment
Это со страницы 238 бесплатной электронной книги, вы можете скачать ее со страницы e-uned.es/product/product.php?prdctID=759, это учебник для MOOC (iedra.uned.es/courses/course-v1:UNED+Modelsimul_02+2020_T1/)   -  person Jack    schedule 24.02.2020
comment
Я думаю, если бы я мог найти подробный процесс того, как оператор noEvent находит правильную точку для перехода от одной ветки к другой, было бы более ясно решить этот вопрос. Может ли кто-нибудь сказать мне, где найти соответствующую информацию?   -  person Jack    schedule 27.02.2020
comment
При следующих настройках ошибки не будет. imgur.com/RAcRaCp   -  person Jack    schedule 28.02.2020
comment
Думаю, читая mbe.modelica.university/behavior/discrete/events, включая ссылку to Подавление событий должно дать хорошее представление о том, когда использовать noEvent и, возможно, smooth().   -  person Markus A.    schedule 26.03.2020


Ответы (3)


Хотя на этот вопрос уже дан ответ, я хотел бы добавить несколько моментов, так как я думаю, что это может быть полезно для многих.

Есть несколько распространенных причин для использования оператора noEvent():

  1. Защитные выражения: используется для предотвращения оценки функции за пределами их диапазона допустимости. Типичный пример - der(x) = if x>=0 then sqrt(x) else 0;, который отлично работает на большинстве распространенных языков программирования. Это не всегда работает в Modelica по следующей причине: при поиске времени, когда условие x>=0 становится ложным, возможно, что обе ветви оцениваются со значениями x, варьирующимися около 0. Тот же факт упоминается на опубликованном скриншоте. by marvel Это приводит к сбою, если вычисляется квадратный корень из отрицательного x. Следовательно, der(x) = if noEvent(x>=0) then -sqrt(x) else 0; используется для подавления итерации для поиска времени пересечения, оставляя обработку разрыва решающей программе (часто упоминается как «выражения принимаются буквально вместо генерации функций пересечения»). В случае использования решающей программы с переменным размером шага это заставляет решающую программу уменьшить размер шага, чтобы обеспечить относительную устойчивость к ошибкам, что, вероятно, приведет к снижению производительности. Кроме того, это может быть критичным, если описанная функция недостаточно гладкая, что приводит к неточному или даже нестабильному моделированию.

  2. Непрерывные выражения: когда функция является непрерывной, событие фактически не требуется. Это сводится к тому, что события используются для описания разрывов. Так что, если его нет, обычно событие просто лишнее и поэтому может быть подавлено. Фактически это покрывается оператором smooth() в Modelica, но в спецификации сказано, что инструмент может по-прежнему генерировать события. По моему опыту, инструменты генерируют события, если изменение функции относительно велико. Следовательно, имеет смысл иметь noEvent() в smooth().

  3. Избегайте болтовни: здесь может помочь noEvent, но на самом деле болтовня - более общая проблема. Поэтому я бы рекомендовал решить проблемы, связанные с болтовней, перестроив модель.

Если ничего из вышеперечисленного не соответствует действительности, следует внимательно рассмотреть возможность использования noEvent.

person Markus A.    schedule 01.04.2020

Я думаю, что Modelica Language Specification Version 3.4, раздел 3.7.3.2. и Раздел 8.5. поможет вам здесь (в случае, если вы еще не проверили это).

Насколько я знаю, его следует использовать только по соображениям эффективности, и в большинстве случаев следует использовать smooth() вместо или вместе.

person kabdelhak    schedule 24.02.2020
comment
Я уже читал эти два раздела, но меня смутил так называемый способ работы с математикой буквально с помощью noEvent, я имею в виду, требует ли noEvent математическая функция достаточно гладкой, чтобы не было ошибок, подобных моему вопросу выше. - person Jack; 24.02.2020
comment
Я бы сказал, что noEvent следует использовать только при необходимости, например, если noEvent (d ›0, затем d ^ 0,5 else - (- d) ^ 0,5; без noEvent будет оценивать неправильную ветвь, когда d переключает знак, который не выполняется; а не по соображениям эффективности.Технически это не обязательно должно быть гладким - так что вы можете написать if noEvent (d ›0) then d ^ 0.5 else 2, но я не рекомендую это делать. - person Hans Olsson; 25.02.2020
comment
Мое главное замешательство состоит в том, что если noEvent точно не вычисляет правильное время, в которое запускается событие, как интегратор может обеспечить точность в следующем коде if noEvent(d>0 then d^0.5 else -(-d)^0.5)? - person Jack; 26.02.2020
comment
Это не так, и в этом суть. Использование noEvent() означает, что с этим можно справиться небрежно и не будет большого эффекта, если событие произойдет в немного неподходящее время. Ганс прав, хотя насчет его примера использования я не думал об этом случае (скобки неправильные, это должно быть if noEvent(d>0) then d^0.5 else -(-d)^0.5). В этом конкретном случае это не имеет значения, поскольку разрыв по-прежнему является гладким в результате, и в этом случае можно было бы использовать что-то вроде sign(d)*abs(d)^0.5, но это не всегда легко найти или оно даже не существует. - person kabdelhak; 26.02.2020

Основываясь на двух разных способах работы с событием. Если используется оператор noEvent, интегрирование не останавливается, но числовой решатель предполагает, что функция должна быть гладкой, а с негладкими функциями будут численные ошибки.

введите здесь описание изображения

person Jack    schedule 03.03.2020
comment
У вас есть источник скриншота? - person Markus A.; 25.03.2020
comment
Не могу вспомнить, где именно найти эту картинку, попробую разобраться. - person Jack; 25.03.2020