首页 理论教育LUA脚本基础|FEKO仿真原理与工程应用

LUA脚本基础|FEKO仿真原理与工程应用

【摘要】:1)LUA脚本例子1:--This is a single line comment--[[This isa multi line comment]]变量定义赋值下面的例子2说明了如何对变量进行赋值。表4-5 LUA中的主要转义字符4)LUA脚本例子4:当运行上面的程序时,会得到如下输出:[String 1 is]:Lua\String 2 is\:Tutorial!LUA脚本支持字符串赋值和字符串连接操作等。表4-6 字符串模块5)LUA脚本例子5:字符串大写与小写表示。--string.gsub()functionstring="Lua Tutorial"string1="Tutorial"string2="Language"--replacing stringsnewstring=string.gsubprint运行上述脚本,得到如下输出:The new string is Lua Language7)LUA脚本例子7:字符串的其他操作。

对于LUA脚本的学习,网络资源和FEKO的用户手册是大家可以随时利用和查阅的,为方便大家学习,作为入门内容的一部分,这里将简要介绍LUA脚本的基本语法,并通过实例学习,帮助读者快速掌握和理解,对于具有编程经验的用户,这一部分就更易于掌握了。

1.注释(Comments)

为了便于阅读脚本,支持脚本的注释功能,参考下面的例子,有两种方式来对脚本添加注释说明。

单行注释方法:在注释行前边加入“--”字符

多行注释方法:以“—[[”字符开始,结尾加入“]]”。

1)LUA脚本例子1:

--This is a single line comment

--[[This is

a multi line comment]]

变量定义赋值(Variable assignments)

下面的例子2说明了如何对变量进行赋值。

2)LUA脚本例子2:

--Note:All number types are doubles.There are no integers.

print(type(42),type(42.0))--prints out"number number"

variable_one=1+2-3--This will equal zero.

variable_One="Variables are case sensitive."

a,b=42,101--multiple assignment

a,b=b,a--provides quick value swap

x,y,z=1,2,3,"this value is discarded"

x,y,z,mytext=1,2,3,"this value is discarded"

LUA字符串(Strings):字符串是一个由字符组成的序列,是一种非常常用的高级类型,字符串可以通过以下3种形式被初始化,其中包括:

● 单引号之间的字符。

双引号之间的字符。

● “[[”与“]]”之间的字符。

3)LUA脚本例子3:

string1="Lua"

print("\"string 1 is\"",string1)

string2='Tutorial'

print("String 2 is",string2)

string3=[["Lua Tutorial!"]]

print("String 3 is",string3)

string4=[[Lua Tutorial!]]

print("String 4 is",string4)

当运行上述程序时,会得到如下输出:

"string 1 is"Lua

String 2 is Tutorial

String 3 is"Lua Tutorial!"

String 4 is Lua Tutorial!

转义字符(Escape Sequence)是指,用一些普通字符的组合来代替一些特殊字符,由于其组合改变了原来字符表示的含义,因此称为“转义”。LUA中的主要转义字符见表4-5。

4-5 LUA中的主要转义字符

978-7-111-56144-6-Chapter04-43.jpg

4)LUA脚本例子4:

978-7-111-56144-6-Chapter04-44.jpg

当运行上面的程序时,会得到如下输出:

[String 1 is]:Lua

\String 2 is\:Tutorial!

"String 2 is":"Tutorial!"

String 3 is:

hello

world!

LUA脚本支持字符串赋值和字符串连接操作等。更多高级字符串操作均可以借助于字符串模块(FEKO安装完后会提供字符串模块,可参考安装目录“…\Altair\14.0\feko\shared\lua\pl\stringx.lua”),如 表4-6。

4-6 字符串模块

978-7-111-56144-6-Chapter04-45.jpg

5)LUA脚本例子5:字符串大写与小写表示。

--String upper()&lower()functions

string1="Lua Tutorial!";

print(string.upper(string1))

print(string.lower(string1))

运行上述脚本,得到如下输出:

LUA TUTORIAL!

lua tutorial!

6)LUA脚本例子6:字符串查找与替换操作。

--string.gsub()function

string="Lua Tutorial"

string1="Tutorial"

string2="Language"

--replacing strings

newstring=string.gsub(string,string1,string2)

print("The new string is",newstring)

运行上述脚本,得到如下输出:

The new string is Lua Language

7)LUA脚本例子7:字符串的其他操作。

--string other functions:

string1="Lua"

string2="Tutorial"

--String Concatenations using..

print("Concatenated string is:",string1..string2)

--Length of string

print("the Length of string1 is:",string.len(string1))

--Repeating strings

repeatedString=string.rep(string1,5)

print(repeatedString)

运行上述脚本,得到如下输出:

Concatenated string is:LuaTutorial

the Length of string1 is:3

LuaLuaLuaLuaLua

2.LUA运算符(Operator)

运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算。在一个表达式中可能包含多个由不同运算符连接起来的、具有不同数据类型的数据对象。由于表达式有多种运算,因此不同的运算顺序可能得出不同结果,甚至出现错误运算结果,因为当表达式中含有多种运算时,必须按一定顺序进行结合,才能保证运算的合理性和结果的正确性、唯一性。LUA中有丰富的内置运算符,且运算符提供了以下类型:算术运算符(见表4-7)、关系运算符(见表4-8)、逻辑运算符(见表4-9)、其他运算符(见表4-10)等。

4-7 算术运算符

978-7-111-56144-6-Chapter04-46.jpg

4-8 关系运算符

978-7-111-56144-6-Chapter04-47.jpg

4-9 逻辑运算符

978-7-111-56144-6-Chapter04-48.jpg

4-10 其他运算符

978-7-111-56144-6-Chapter04-49.jpg

3.LUA循环(Loop)

很多情况下需要做一些有规律性的重复操作,因此在程序中就需要重复执行某些语句。一组被重复执行的语句称为循环体,能否继续重复,取决于循环的终止条件。循环结构是在一定条件下反复执行某段程序的流程结构,被反复执行的程序称为循环体。循环语句是由循环体及循环的终止条件两部分组成的。

LUA语言提供的循环处理方式具体见表4-11。

4-11 循环处理方式

978-7-111-56144-6-Chapter04-50.jpg

LUA编程语言中,while循环语句在判断条件为true时会重复执行循环体语句。

LUA编程语言中while循环语法:

while(condition)

do

statements

end

statements(循环体语句)可以是一条或多条语句,condition(条件)可以是任意表达式,在condition(条件)为true时执行循环体语句。

以下实例循环输出a的值:

a=10

while(a<20)

do

print("the value of a is:",a)

a=a+1

end

LUA编程语言中for循环语法格式:

for var=exp1,exp2,exp3 do

<执行体>

end

var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次“执行体”。exp3是可选的,如果不指定,则默认为1。

For循环应用1:

function f(x)

print("function")

return x*2

end

for i=1,f(5)do print(i)

end

for循环应用2:

days={"Suanday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}

for i,v in ipairs(days)do

print(v)

end

4.LUA数组(Arrays)

数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分它们的变量的集合,这个名字称为数组名,编号称为下标。数组可以是一维数组和多维数组。

LUA数组的索引键值可以使用整数表示,数组的大小不是固定的。

1)一维数组,是最简单的数组,其逻辑结构是线性表。一维数组可以用for循环出数组中的元素,示例如下:

array={"Lua","Tutorial"}

for i=0,2 do

print(array[i])

end

以上代码执行输出结果为:

nil

Lua

Tutorial

我们可以使用整数索引来访问数组元素,如果知道的索引没有值,则返回nil。

LUA索引值以1为起始,但也可以指定从0开始。除此之外,还可以以负数为数组索引值,示例如下:

array={}

for i=-2,2 do

array[i]=i*2

end

for i=-2,2 do

print(array[i])

end

2)多维数组,即数组中包含数组或一维数组的索引键对应一个数组。以下是一个3行3列的阵列多维数组示例:

978-7-111-56144-6-Chapter04-51.jpg

978-7-111-56144-6-Chapter04-52.jpg

不同索引键的3行3列阵列多维数组示例如下:

978-7-111-56144-6-Chapter04-53.jpg

数组设定了指定的索引值,这样可以避免出现nil值,有利于节省内存空间。

5.LUA表格(Tables)

table是LUA的一种数据结构,用来帮助用户创建不同的数据类型,如数组、字典等。

LUA table使用关联型数组,用户可以用任意类型的值来作为数组的索引,但这个值不能是nil。LUA table是不固定大小的,用户可以根据需要自行扩容。(www.chuimin.cn)

构造器是创建和初始化表的表达式。表是LUA特有的功能强大的东西。最简单的构造函数是{},用来创建一个空表。用户可以直接初始化数组,示列如下:

--initialize the table

mytable={}

--specify the value for table

mytable[1]="Lua"

--remove the reference

mytable=nil

--luagarbage collection and release the memeory

下边的脚本演示了如何提取Table的元素个数以及如何使用inspect函数读取Table元素:an_array={1,1,2,3,5,8,13}

print(#an_array)--prints"7"

print(an_array[3])--prints"2"

a_table={['bread']="brown",['eggs']=10}--tables are dictionaries or arrays

print(a_table['bread'])--"prints brown"

print(a_table)--prints"table:0x7f63c8001200",the memory location of the table

inspect(a_table)--prints the contents of the table

print(#a_table)--prints"0"since it is not an array(take note)

先定义table a并设置其元素,然后将a赋值给b,则a与b都指向同一个内存。如果a设置为nil,则b同样能访问table的元素。如果没有指定的变量指向a,则LUA的垃圾回收机制会清理相对应的内存。请看如下示例代码:

978-7-111-56144-6-Chapter04-54.jpg

以上代码的执行输出结果为:

the type of mytable is:table

the element in mytable when the index is 1 is:Lua

the element in mytable when then index is wow is:modify before

the lement in alternatetable when the index is 1 is:Lua

the element in mytable when the index is wow is:modify before

the element in mytable when the index is wow is:after modify

alternatetable is:nil

the element in mytable when the index is wow is:after modify

mytable is: nil

Table中的常用几种操作见表4-12。

4-12 Table中的常用操作

978-7-111-56144-6-Chapter04-55.jpg

接下来请看如下这几个方法的实例。

1)Table连接:利用concat方法,代码如下。

fruits={"orange","banana","apple"}

--Return the concated string in table

print("Concated string is:",table.concat(fruits))

--specify the concated string

print("Concated string is:",table.concat(fruits,","))

--spcify the index to concate table

print("Concated string is:",table.concat(fruits,",",2,3))

2)插入和删除:利用insert和remove方法,代码如下。

fruits={"banana","orange","apple"}

--Inserted in the end

table.insert(fruits,"mango")

print("When the index is 4,the element is:",fruits[4])

--Insert new element when Index is 2

table.insert(fruits,2,"grapes")

print("When the index is 2,the element is:",fruits[2])

print("the last element is:",fruits[5])

table.remove(fruits)

print("when remove the last element,the last element is:",fruits[5])

3)排序:利用sort方法,代码如下。

978-7-111-56144-6-Chapter04-56.jpg

6.LUA函数(Function)

在LUA中也可以创建和使用函数功能。函数是对语句和表达式进行抽象的主要方法,它们既可以用来处理一些特殊的工作,也可以用来计算一些值。

LUA提供了许多的内建函数,用户可以很方便地在程序中调用它们,如函数print()可以将传入的参数打印在控制台上。

LUA函数主要有两种用途:

1)完成指定的任务,这种情况下函数作为调用语句使用。

2)计算并返回值,这种情况下函数作为赋值语句的表达式使用。

LUA编程语言函数定义的格式如下:

optional_function_scope function function_name(argument1,argument2,argument3...,argumentn)

function_body

return result_params_comma_separated

end

解析:

● optional_function_scope,该参数是可选的,制订函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果需要设置函数为局部函数需要使用关键字local。

● function_name,指定函数名称。

● argument1,argument2,argument3,…,argumentn,是函数参数,多个参数以逗号隔开,函数也可以不带参数。

● function_body,即函数体,函数中需要执行的代码语句块。

● result_params_comma_separated,是函数返回值,LUA语言函数可以返回多个值,每个值以逗号隔开。

下边的例子说明了如何创建和使用一个函数,同样重要的是,要注意局部(Local)和全局(Global)变量定义的使用范围。建议尽量使用局部变量定义。

示例1:

function myFunction(name)

print('Hello '..name)

var1=100

local var2=99

return"returns nil if you don't have a return statement."

end

myFunction('FEKO user')

print(var1)--prints 100

print(var2)--prints nil,since var2 does not exist outside the function

示例2:此例定义了函数max(),参数为num1,num2,用于比较两值的大小,并返回最大值。

978-7-111-56144-6-Chapter04-57.jpg

978-7-111-56144-6-Chapter04-58.jpg

示例3:多返回值,LUA函数可以返回多个结果值,如string.find,其返回匹配串“开始和结束的下标”(如果不存在匹配串则返回nil)。

s,e=string.find("FEKO is a comprehensive EM simulation software tool","EM")

print(s,e)

示例4:LUA函数中,在return后列出要返回的值的列表即可返回多值。

978-7-111-56144-6-Chapter04-59.jpg

示例5:可变参数,LUA函数可以接受可变数目的参数,和C语言类似,在函数参数列表中使用3个点(...)表示函数有可变的参数。LUA将函数的参数放在一个叫arg的表中,#arg表示传入参数的个数。

978-7-111-56144-6-Chapter04-60.jpg

7.LUA文件I/O

LUA I/O库用于读取和处理文件,分为简单模式(和C语言一样)和完全模式。

1)简单模式(simple model)拥有一个当前输入文件和一个当前输出文件,并且提供针对这些文件相关的操作。

2)完全模式(complete model)使用外部的文件句柄来实现。它以一种面向对象的形式,将所有的文件操作定义为文件句柄的方法。

简单模式在做一些简单的文件操作时较为合适,但是在进行一些高级的文件操作的时候,简单模式就显得力不从心。例如,同时读取多个文件这样的操作,使用完全模式则较为合适。

打开文件操作语句如下:

file=io.open(filename[,mode])

mode的取值见表4-13。

4-13 mode的取值描述

978-7-111-56144-6-Chapter04-61.jpg

(1)简单模式

简单模式使用标准的I/O或使用一个当前输入文件和一个当前输出文件。

以下为file.lua文件代码,操作的文件为test.lua(如果没有,需要自行创建该文件),代码如下:

--以只读方式打开文件

file=io.open("test.lua","r")

--设置默认输入文件为test.lua

io.input(file)

--输出文件第一行

print(io.read())

--关闭打开的文件

io.close(file)

--以附加的方式打开只写文件

file=io.open("test.lua","a")

--设置默认输出文件为test.lua

io.output(file)

--在文件最后一行添加LUA注释

io.write("--test.lua文件末尾注释")

--关闭打开的文件

io.close(file)

在以上示例中我们使用了io."x"方法,其中函数io.read()中没有带参数,参数可以是表4-14中的一个。

4-14 参数描述

978-7-111-56144-6-Chapter04-62.jpg

其他的I/O方法如下:

1)io.tmpfile(),返回一个临时文件句柄,该文件以更新模式打开,程序结束时自动删除。

2)io.type(file),检测obj是否为一个可用的文件句柄。

3)io.flush(),向文件写入缓冲中的所有数据。

4)io.lines(optional file name):返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil,但不关闭文件。

(2)完全模式

通常我们需要在同一时间处理多个文件,此时需要使用file:function_name来代替io.function_name方法。以下示例演示了如何同时处理同一个文件:

--以只读方式打开文件

file=io.open("test.lua","r")

--输出文件第一行

print(file:read())

--关闭打开的文件

file:close()

--以附加的方式打开只写文件

file=io.open("test.lua","a")

--在文件最后一行添加LUA注释

file:write("--test")

--关闭打开的文件

file:close()

其他方法如下:

1)file:seek(optional whence,optional offset),设置和获取当前文件位置,成功则返回最终的文件位置(按字节),失败则返回nil加错误信息。参数whence值可以是:

● set——从文件头开始。

● cur——从当前位置开始(默认)。

● end——从文件尾开始。

● offset——默认为0。

不带参数file:seek()则返回当前位置,file:seek("set")则定位到文件头,file:seek("end")则定位到文件尾并返回文件大小。

2)file:flush(),向文件写入缓冲中的所有数据。

3)io.lines(optional file name),打开指定的文件filename为读模式并返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil并自动关闭文件。

若不带参数时io.lines()<=>io.input():lines();读取默认输入设备的内容,但结束时不关闭文件,如:for line in io.lines("main.lua")do

print(line)

end

以下示例使用了seek方法,定位到文件倒数第25个位置并使用read方法的*a参数,即从当前位置(倒数第25个位置)读取整个文件。

--以只读方式打开文件

file=io.open("test.lua","r")

file:seek("end",-25)

print(file:read("*a"))

--关闭打开的文件

file:close()