Engee物理建模语言的枚举、分支、循环和模块
|
页面进行中。 |
本文包含Engee物理建模语言的构造,用于控制组件的逻辑和结构:枚举,分支(静态和动态),循环,模块化代码组织,函数以及通过图标自定义块的外观。
转帐
当参数必须采用预定义值之一时,使用枚举。 它们便于设置操作模式、选择组件的型号或配置。
@descriptive_enumeration CustomEnum begin
first = 1, "One"
second = 2, "Two"
third = 3, "Three"
end
在示例中,将创建一个枚举 [医]海关 有三种可能的选择:
-
海关。第一个-1的值显示为"一"; -
海关。第二-值为2,显示为"二"; -
海关。第三-值3显示为"三".
为了使参数在*Engee*界面(块设置窗口)中显示为具有枚举选项的下拉列表,必须显式指定其类型。:
@engeemodel CustomComponent begin
@parameters begin
math_model::CustomEnum = CustomEnum.first
end
end
这里是参数 数学模型 有一个类型 [医]海关 默认情况下,它等于 海关。第一个. 在*Engee*接口中,这样的参数将由下拉列表表示,其中只有枚举中的值可用。
函数结果的类型
有时参数或变量不会直接获取它们的值,而是通过对自定义函数的调用。 如果这样的函数返回一个数组,则布尔值(布尔)或枚举(枚举),那么必须为变量或参数指定显式类型。
make_vector(n) = [i for i in 1:n]
check_positive(x) = x > 0
@engeemodel Component begin
@parameters begin
a[:]=make_vector(3)#返回的函数为[1,2,3]
flag::Bool=check_positive(-5)#函数返回false
end
end
这里:
-
在组件之前声明两个函数:
-
make_vector(n)创建一个从1到n. -
检查正定(x)检查数字是否为正数并返回真的或错误.
-
-
在建设
@参数:-
a[:]=make_vector(3)-参数a获取数组[1, 2, 3]. 数组类型设置在方括号中[:]. -
标志::Bool=check_positive(-5)-参数旗帜获取验证结果错误,并且类型被显式指定为布尔.
-
没有显式指定类型(例如, [:] 对于数组或 ::布尔 为逻辑变量),模型将无法正常工作。
分行
*分支*是一种根据参数值描述组件不同行为的方法。 在分支内部设置一个规则:"如果满足条件,则使用一个代码块,否则使用另一个代码块。"
Engee物理建模语言中有两种类型的分支。:
-
静态分支(
如果…elseif…else…结束)-在模型启动时执行一次。 它们仅取决于参数。 此代码部署在模型装配阶段,在建模过程中不会更改。 它们用于在开始计算之前选择结构,公式或元素数量。 -
动态分支(
ifelse(。..))-在计算过程中检查条件并更改结果。 分支的选择取决于变量的当前值,并且结果可能在每个积分步骤中更改。 这样的分支允许您描述动态切换的操作模式。
因此,在启动前需要静态分支来配置模型,并且需要动态分支来描述系统随时间的行为。
静态分支
当条件取决于参数的值时,使用静态分支。 该分支在模型启动时选择一次,并且不会进一步更改。
@descriptive_enumeration Model begin
simple = 1, "Simple"
adv = 2, "Advanced"
end
@engeemodel Example begin
@parameters begin
has_option::Bool = true
model::Model = Model.simple
end
@variables begin
x = 0
y = 0
end
if has_option
@equations begin
y ~ 2 * x
end
else
if model == Model.simple
@equations begin
y ~ 5 * x
end
else
@equations begin
y ~ 5 * x^2
end
end
end
end
条件 has_option和模型==模型。简单 它在启动模型时工作,并为变量选择适当的方程组 x.
使用方法 如果…… 如果块外的条件中有变量 @方程 这是不可能的-这样的分支是由初始值固定的,并且在模拟过程中不会改变。 对于变量,应用 ifelse(。..) 或 如果。.. 其他人。.. 其他 块内 @方程.
|
动态分支
动态分支在仿真过程中起作用,取决于变量的值。 为此,请使用函数 ifelse(条件,expr1,expr2). 它允许您描述动态切换方程。 例子::
@variables begin
x = 0
y = 0
end
@equations begin
y ~ ifelse(x < 10, x, -x)
end
这里:
-
如果
x<10然后y=x; -
如果
x>=10然后y=-x.
与静态相反 如果 在模拟的每一步检查这样的条件。
使用时 ifelse 启用事件检测:求解器尝试尽可能准确地确定条件的结果从变化的时刻 真的 上 错误 反之亦然。 此时,系统正在重新初始化。
|
特殊功能用于避免事件检测。:
-
gt;gt--更多; -
lt--少; -
通用电气--大于或等于; -
勒--小于或等于; -
情商--等于; -
neq--不相等。
使用方法 ifelse(。..) 当需要状态切换的确切时刻,并且 gt/lt/ge/le/eq/neq 当重要的是避免事件和系统的不必要的重新计算。
|
使用分支 如果。.. 其他人。.. 别的。.. 结束 结构内部 @方程 相当于功能 ifelse:
@equations begin
#用事件按条件切换
y ~ ifelse(x < 10, x, -x)
#无事件比较
if gt(x, 0.5)
u ~ 1
v ~ 2
elseif x<0#此条件将创建一个事件
if lt(y,1)#此条件不会创建事件
u ~ 3
else
u ~ 4
end
v ~ 5
else
u ~ 6
v ~ 7
end
end
-
ifelse(x<10,x,-x)更改时切换表达式x. -
功能
gt;gt,lt,通用电气,勒,情商,neq它们允许您在不检测事件的情况下编写条件。 -
每个分支中的方程数必须匹配。 支票
断言检查余额时不考虑它们。
周期
循环允许您一次声明多个端口,子组件和方程,这对于相同类型元素的数组很方便。 例子::
@structural_parameters begin
n::Int = 3
end
@variables begin
v[:] = zeros(n)
end
@nodes begin
pins = [EngeePhysicalFoundation.Electrical.Pin() for i in 1:n]
end
@equations begin
[v[i] ~ pins[i].v for i in 1:n]
end
这里:
-
在建设
@结构参数参数被声明n=3. 它决定了数组的维度。 -
在建设
@变量向量变量由带维度的应力声明n. -
在建设
@节点正在创建一个数组别针的3个电气端口(别针). 数组的每个元素对应于一个单独的端口,端口名称将是pins_1,pins_2,。.. pins_n. -
在建设
@方程使用循环,形成方程的阵列:电压v[i]它与相应端口的电压通信销[i]。v.
因此,一个代码块一次描述了3个相同的连接。 如果更改值 n,端口和方程的数量会自动改变。
子组件的阵列
相同的技术可用于子组件。 就像我们刚刚制作了一个端口和方程的数组一样,您也可以创建相同类型的组件的数组。 这允许例如从几个电阻器、电容器或二极管快速组装电路。
@engeemodel ArrayExample begin
@components begin
res = [EngeePhysicalFoundation.Electrical.Elements.Resistor() for i in 1:5]
cap = [EngeePhysicalFoundation.Electrical.Elements.Capacitor() for i in 1:3]
end
end
它正在这里创建:
-
5个电阻器的阵列;
-
3个电容器的阵列。
在外面,元素将具有名称 资源_1, 资源_2, … 和 第1章, 第2章, … . 每个元素都可以通过索引访问,以及用于化合物和方程。
循环在 @组件 它们的工作原理与端口和方程相同:一个模板—多个副本。
矢量方程
以矢量形式设置方程通常很方便,而不是一次一个。 例子::
@variables begin
x_vector[:] = [0, 0, 0]
c[:] = [1, 2, 3]
end
@equations begin
x_vector ~ c
end
这样的声明相当于三个方程: x_vector[1]~c[1], x_vector[2]~c[2] 等。
对于数组的元素操作也支持点语法。:
@equations begin
x_vector .~ c .* 2
y .~ sin.(u .+ v)
end
在这里 x_vector。~c.* 2 每个元素 x_探测器 等于相应的元素 c 乘以2,并在 y.~罪。(u.+v) 数组是零碎添加的。 u 和 v 接着是每个元素的正弦计算。