Engee 文档

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) 数组是零碎添加的。 uv 接着是每个元素的正弦计算。

模块化结构

组件、连接器和枚举可以组合到模块中。 模块允许您对相关元素进行分组,以及导出它们并以完全限定的方式在项目的其他部分使用它们,就像在常规Julia代码中一样。

图标

块的外观可以使用设计进行定制 @图标. 您可以使用svg图像作为图标。 例子::

@icon begin
    "icon.svg"
end

缩短的录音也支持没有 開始啦。…​ 结束:

@icon "icon.svg"