AxFEM is an application specific finite element code written in C++ and Lua. It is used to compute vibration frequency, Bryan's factor, and quality factor of axisymmetric linear elastic objects. The main application is an extended version of Lua front-end with special libraries.

In this tutorial, we will review basics of programming in Lua. If you are already familiar with this language you can skip this tutorial. You can consult Lua Manual for reference.

Lua Language

Lua is a fast, portable, embeddable, lightweight scripting language. It can also be extended with external libraries. You can run the modified front end, axfem, which provides a prompt and an interpreter environment similar to Python.

Comments

-- Single line comments start with two dashes

Multiline comments start with --[[ and end with ]]

Nil

By default variables have value nil if they are not assigned. We can assign nil to variables to delete them.

print(x) -- global variable `x' is not assigned to anything

nil

will be printed on the screen.

a = 1   -- variable `a` is created by assigning a value to it
a = nil -- this will delete the variable 

Numbers

Lua has only one number type which represents double precision floating point numbers. For example: 1, 1.2, 3.5e-5, 0.7e21, 9e+23

Arithmetic Operators

Strings

A string is a sequence of characters. Strings can be concatenated using the operator ..

s1 = 'example ' -- we can use single 
s2 = "string"   -- or double quotes
print(s1..s2)   -- this will print `example string'

Boolean

Lua has two values for boolean types: true and false. Anything other than false and nil are considered to be true.

Logical Operators

and and or have short circuiting property.

print(5 or nil) -- will print 5
print(1 and  3) -- will print 3
print(0 or   1) -- will print 0, remember 0 is not false!!

Relational Operators

Conditionals

We can use if-then-else statement to control the path of execution. If we have more conditions elseif keyword can be used.

x = 7; -- semicolons are optional separators for statements

if x > 5 then 
   print('x is greater than 5')
elseif x == 5 then
   print('x is equal to 5')
else
   print('x is less than 5')
end 
 

This will print x is greater than 5 on the screen.

Loops

Lua provides for,while and repeat loops. All of the following chunks find the sum of odd integers between 1 and 100.

s = 0
for i=1,100,2 do -- start_value,end_value,increment
  s = s + i
end
print(s)

s = 0; i = 1
while i < 100 do
  s = s + i
  i = i + 2
end
print(s)

s = 0; i = 1
repeat
   s = s + i
   i = i + 2
until i > 100
print(s) 

Scope

We can define local variables using local. Otherwise variables are global.

n = 8  -- global variable 

for i=1,5 do 
   local n = i%5  -- local variable inside the loop
   print('local value '..n) -- n is converted to a string before concatenated
end

print('global value '..n) 

Tables

Tables are central to Lua. They can be used as key value pairs. If no key is provided, we consider them as arrays with starting index 1. Curly brackets are used to construct tables.

t = {} -- an empty table

for i=1,5 do    -- i takes values 1,2,3,4,5
   t[i] = i^2;  -- indexing is done with the operator[]
                -- t becomes {1,4,9,16,25}
end

print('Length of array: '..#t) -- # operator returns the length of the arrays
                               --   and the strings 

Here is an another example where the keys are strings.

wdays = {Mon=1,Tue=2,Wed=3,Thu=4,Fri=5,Sat=6,Sun=7}

for k,v in pairs(wdays) do -- keys are strings, values are integers
   print(v.." "..k) 
end

Functions

Function prototype starts with the keyword function, followed by function name and input variables inside parenthesis. We use return statement to output values.

function average (t)
  local n = #t;
  if n == 0 then return nil end

  local sum = 0;
  for i,v in pairs(t) do  
     sum = sum + v
  end  
  return sum/n 
end

print('Average: '..average(t)) -- average{1,4,9,16,25} will return 11

You can store functions in variables.

function sum(t)
   local n = #t
   if n == 0 then return nil end
   local s = 0
   for i,v in pairs(t) do
      s = s + v
   end
   return s
end

f = average; print(f(t)) -- will print 11
f = sum;     print(f(t)) -- will print 55

Scripting

You can save your code to text files and run them using the front end. You can provide the name of your script file when you run axfem from the command line.

axfem myscript.lua

You can include libraries in the path using require. You can also run a file using dofile function in Lua.

dofile "myscript.lua"

Please see Lua Manual for details.

Exercise 0.1

Could you write a function to print the standard deviation of numbers in an array?

Solution

function stddev(t)
   local n = #t
   if n < 1 then return nil end
   
   local function mean (t)  -- you can embed functions within functions
      local s = 0           -- scope of s is mean function 
      for i,v in pairs(t) do 
         s = s + v
      end
      return s/n            -- scope of n is within stddev
   end  

   local s = 0
   local m = mean(t)
   for i,v in pairs(t) do
      s = s + (v-m)^2
   end
   
   return math.sqrt(s/(n-1))-- we use function sqrt from the math library
end 

-- Let's test it
t = {1,4,9,16,25,36,49,64,81,100}
print(stddev(t)) -- should print 34.1736