Michael M. Tiller《Modelica多领域物理系统建模入门与提高》Chapter 5学习笔记

第五章 函数

5.1 概念

  • 应用场合:当建模过程中,需要含有显性赋值的程序或算法的情况
  • 函数的特点:
    • 所有量必须显性标记为输入或输出
    • 函数没有被连接到其他组件,而是在对表达式赋值时被调用
    • 函数不允许持续保持内部状态(e.g. der算子不能出现在函数中)
    • 函数定义中只能有且仅有一个算法段,用于函数计算
  • 当函数被调用时,函数的输入对象相当于函数的自变量;而当函数用于表达式时,输出对象相当于函数值

5.2 简介

示例函数:从一个元素为名称的数组中搜寻一个特殊的名称,并获得数组中该名称的索引,找不到名称时输出一个错误信息(名称用字符串String类型)

function FindName
	input String names [:];
	// ":"表明数组的长度为任意值
	// 被定位为可以处理任意长度的 一维数组,以增强函数的鲁棒性
	input String name_to_find;
	output Integer index;
protected
// protected关键字:受保护的部分,包含了对所有局部变量的声明,且局部变量仅在函数中可见,用后即删
	Integer i, len = size(names,1);
	// size()函数可以返回正确的数组长度
algorithm
	index :=-1;
	i := 1;
	while index == -1 and i <=len loop
		if names[i] == name_to_find then
			index := i;
		end if;
			i := i+1;
	end while;
	assert (index <> -1,"FindName:failed");
	//assert()函数验证待定的条件,当结果为假,即index=-1时,输出函数中第二个自变量包含的信息
end FindName;

//函数调用
model TestFindName
	parameter String names[:]={"H2O","CO2","N2"};
	parameter Integer CO2 = FindName(names,"CO2");
end TestFindName;
  • 调用函数时,自变量设置需依据函数声明的自变量顺序

5.3 插值函数

一维线性插值函数

function Piecewise "A piecewise linear interpolation"
	input Real x "Independent variable";
	input Real x_grid[:] "Independent variable data points";
	input Real y_grid[:] "Dependent variable data points";
	output Real y "Interpolated result";
protected
	Integer n;
algorithm
	n := size(x_grid,1);
	assert(size(x_grid,1) == size(y_grid,1),"size mismatch");
	// 确保输入数组x_grid和y_grid长度相同
	assert(x>=x_grid[1] and x<= x_grid[n],"out of range");
	//确保x在x_grid自变量给定的范围内
	for i in 1:n-1 loop
	//i是for循环的局部变量,循环开始时创建,end for后删除i,因此无需对i单独声明
		if x>=x_grid[i] and x<= x_grid[i+1] then
		y := y_grid[i] + (y_grid[i+1]-y_grid[i])*((x-x_grid[i])/(x_grid[i+1]-x_grid[i]));
		end if;
	end for;
end Piecewise;

model TestPiecewise
	package SI = Modelica.SIunits;
	parameter SI.Time x_vals(6)={0,2,4,6,8,10};
	parameter Real y_vals(6)={0,0,4,16,36,64};
	Real y;
equation
	y=Piecewise(x=time,x_grid=x_vals,y_grid=y_vals);
end TestPiecewise;

调用函数的两种方法:

  1. 按函数定义中声明的自变量顺序进行数据传递
  2. 为每一个自变量提供一个显性等式

5.4 多重返回值

使用单一循环计算多项式的值和导数

model TestPolyEval
	parameter Real coefs[3]= {2.0,1.0,2.0};
	Real y,fdy,dy;
equation
	(y,fdy)=PolyEval(time.coefs);
	dy=der(y);
end TestPolyEval;

//可以通过比较fdy与dy,验证函数PolyEval

function PolyEval "Evaluate polynomial and derivative"
	input Real x;
	input Real coef[:] "low to high order";
	output Real y;
	output Real dydx "Derivative of polynomial";
	protected
		Integer n;
	algorithm
		n:=size(coef,1);
		y:=coef[n];
		dydx:=0.0;
		for i in n-1 : -1 : 1 loop
			y:=y*x+coef[i];
			dydx:=dydx*x+i*coef[i+1];
		end for;
end PolyEval;

5.5 自变量records

当需要传递大量的自变量给函数时,可以先定义一个record类型,该类型可以用于将几个逻辑上相关的自变量组合在一起,形成一个自变量集

正弦波求和函数:ΣAi sin(2pi x fi + ph_i)

function ComplexWave
	record Data // 局部定义
		constant Integer num "number of waves";
		Real a[num] "Wave amplitudes";
		Modelica.SIunits.Frequency f[num];
		Modelica.SIunits.Angle phase[num];
	end Data;
	input Real x;
	input Data d "Wave data";
	output Real y;
	protected
		Integer n;
		Real s;
	algorithm
		n:=d.num;
		y:=0;
		for i in 1:n loop
			s:=sin(2*Modelica.Constants.pi*d.f[i]*x+d.phase[i]);
			y:=y+d.a[i]*s;
		end for;
end ComplexWave;
	
model TestComplexWave
	parameter ComplexWave.Data wdata(num=3,
		a={1.3,2.2,5.8},
		f={2.0,3.0,7.0},
		phase={0,Modelica.Constants.pi,0});
		// 函数外,record定义必须使用限定名ComplexWave.Data
	Real signal;
equation
	signal=ComplexWave(time,wdata);
end TestComplexWave;

model TestComplexWave2
	parameter ComplexWave.Data wdata(num=3);// 非参数设定
	Real signal;
equation
	signal=ComplexWave(time,wdata);
	wdata.a={1.3,2.2,5.8*exp(-0.54*time};//声明一个含有随时间变化参数的record
	wdata.f={2.0,3.0,7.0};
	wdata.phase={0,Modelica.Constants.pi,0};
end TestComplexWave2;

使用record,可将函数ComplexWave的自变量数减少到2个

5.6 使用外部子程序

在调用外部子程序前,首先需要在Modelica模型中编写一个封装函数。

//调用C子程序compute_enthalpy
function Enthalpy
	input Modelica.SIunits.Pressure P;
	input Modelica.SIunits.Temp_K T;
	output Modelica.SIunits.Enthalpy h;
	external "C" compute_enthalpy(P,T,h);
end Enthalpy;

//调用FORTRAN77子程序的封装函数,有多个返回值
function SteamTable
	input Modelica.SIunits.Pressure P;
	input Modelica.SIunits.Temp_K T;
	output Modelica.SIunits.SpecificEnthalpy h;
	output Modelica.SIunits.SpecificEnergy u;
	output Modelica.SIunits.SpecificHeatCapacity cp;
	output Modelica.SIunits.Density rho;
	external "FORTRAN77" calcprops(P,T,h,u,cp,rho);
end SteamTable;

5.7 Modelica语言基础

  • 分支语句
if x>=0 then
	y:=x;
elseif x<=-3 then
	y:=-6;
else
	y:=-2*x;
end if;
  • 循环语句
//循环用于需要执行迭代的算法
While  "Condition" loop
	// do something
end While;

//for语句对矢量进行运算更方便
for someVar in someVector loop
	//do something
end for;
//for语句尽可能基于矢量(一维数组)进行循环操作
  • 调用函数

    • 用方程给自变量赋值时,自变量顺序不分先后
    • 只要有一个自变量用方程赋值,其余所有自变量都必须用方程赋值
    • 若不用方程赋值,则函数定义中自变量的顺序决定了调用时所需自变量的顺序
    • 函数只有一个返回值时,可以用在表达式中
      y=x*Piecewise(t);
    • 函数有多个返回值时,函数调用只能在方程或赋值中使用,且函数必须完整地置于等式右边,而等式左边是括号中用逗号隔开的获取返回值的变量列表
      (h,u,cp,rho)=SteamTable(P,T);
  • 内置函数

    • 类型分析:analysisType(),使模型可以根据不同的分析类型定制模型的行为,返回一个字符串说明模型当前进行的分析类型。
    • 求绝对值:abs()
    • 符号判别:sign()
    • 求平方根:sqrt()
    • 求最小及最大整数:ceil(),返回大于x的最小整数;floor(),返回小于x的最大整数
    • 取整:integer(),返回一个不大于x的最大整数
    • 整除:div(x,y),返回一个不带小数,即取整为零,的x/y代数商
    • 余数:rem(x,y),返回div()函数丢弃的余数;rem(x,y)=x-div(x,y)*y
    • 模运算:mod(x,y)=x-floor(x/y)*y
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一些关于学习Simscape的推荐书籍: 1. "Physical Modeling in MATLAB" by Allen Downey: 这本书介绍了如何使用MATLAB和Simscape进行物理建模。它提供了许多示例和练习,帮助读者理解和应用Simscape的基本概念和技术。 2. "Modeling and Simulation of Systems Using MATLAB and Simulink" by Devendra K. Chaturvedi: 这本书详细介绍了如何使用MATLAB和Simulink进行系统建模和仿真。其中包括对Simscape的介绍和示例,帮助读者学习如何使用Simscape进行物理建模。 3. "Physical Modeling with Simulink" by Michael Tiller: 这本书专门讲解了如何使用Simulink和Simscape进行物理建模。它涵盖了从基本原理到高级技术的内容,适用于初学者和有经验的用户。 4. "Simscape Power Systems Examples" by MathWorks: 这是MathWorks官方提供的一本示例集,展示了如何使用Simscape Power Systems工具箱进行电力系统建模和仿真。它包含了各种实际应用的示例和教程,适用于电力系统工程师和研究人员。 5. "Simscape Multibody Examples" by MathWorks: 这本书由MathWorks官方提供,介绍了Simscape Multibody工具箱的应用。它包含了多种机械系统建模和仿真示例,有助于读者学习如何使用Simscape Multibody进行机械系统建模。 除了这些书籍,您还可以参考MathWorks官方网站上的文档和教程,以及社区论坛上的讨论和分享资源。这些资源将为您提供更深入的学习Simscape的资料和实践经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值