├── ConfigParser.lua ├── Makefile ├── README ├── config.f90 ├── program.f90 └── vals.lua /ConfigParser.lua: -------------------------------------------------------------------------------- 1 | -- This module loads a lua file as a configuration file. 2 | module(...,package.seeall) 3 | 4 | 5 | -- loadfile on the filename but read its values into a table. 6 | function open(filename) 7 | paramtable={} 8 | setmetatable(paramtable,{__index=_G}) 9 | f=loadfile(filename) 10 | setfenv(f,paramtable) 11 | f() 12 | --setmetatable(paramtable,nil) 13 | return paramtable 14 | end 15 | 16 | 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # module swap pgi intel 2 | # module add lua 3 | FFLAGS=-g 4 | INCLUDES=-I$(LUA_INC) 5 | LIBS=-L$(LUA_LIB) -llua 6 | 7 | # This cute snippet stops the makefile if the variables listed in MODVARS aren't defined. 8 | MODVARS := LUA_LIB LUA_INC 9 | LOSTMODS := $(foreach modvar,$(MODVARS),$(if $(subst undefined,,$(origin $(value modvar))),,$(modvar)) ) 10 | UNLOADCNT := $(words $(LOSTMODS)) 11 | ifneq ($(UNLOADCNT),0) 12 | $(error Necessary modules not loaded: $(LOSTMODS)) 13 | endif 14 | 15 | default: calculate 16 | 17 | calculate: config.f90 program.f90 18 | ifort $(FFLAGS) $^ $(INCLUDES) $(LIBS) -o $@ 19 | 20 | clean: 21 | rm -f *.o interp 22 | rm -f calculate 23 | rm -f *~ 24 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | FortLua 5.2 2 | ----------- 3 | 4 | This is a fork of a simple set of Lua bindings for use in Fortran, tested to be compatible with Lua 5.2.3+. 5 | 6 | Most of the original basis work is fully attributed to @adolgert and @adambrozier and creators of Aotus (see attribution clause) below. 7 | 8 | ==Motivation== 9 | 10 | This project shows how to call a Lua file from Fortran. 11 | You can also call a Lua file from C, but doing it from an 12 | even older language seems more dramatic. This also demonstrates 13 | how to call C libraries directly from Fortran using the 14 | iso_c_binding. 15 | 16 | ==Compilation== 17 | 18 | This project assumes that the Intel compiler suite and Lua are local to your path. 19 | On a machine with software modules support do the following: 20 | 21 | module load intel 22 | module load lua 23 | 24 | In your environment, `LUA_INC` and `LUA_LIB` must be predefined. Otherwise the Makefile is unhappy. 25 | 26 | ==Discussion== 27 | 28 | Why call Lua from Fortran? I can think of two good uses for this. 29 | Fortran's string parsing is not pretty, so you could 30 | use a Lua file as a configuration file. You can query environment 31 | variables and do pre-calculations in the configuration file, yielding 32 | a result for Fortran to use. You can even pass in functions for 33 | Fortran to execute. 34 | 35 | You could also write a commonly-modified subroutine in Lua so that 36 | there is no need to recompile the code when you make changes. 37 | 38 | Why Lua? The language is relatively 39 | simple and has basic math included. It's made to embed in programs. 40 | That said, it is not a common language. You could do the same 41 | exercise with Gnu Guile. 42 | 43 | How? Lua is a very small language that is built to be embedded. 44 | It passes all of its state back to the calling program through 45 | a stack (the stack data structure, but stored on the heap) so that 46 | it is simple to retrieve. 47 | 48 | We use Fortran's iso_c_binding to call the Lua C library directly 49 | from Fortran. That binding is a relatively new development in 50 | Fortran, but it works fine. 51 | 52 | Drew Dolgert 53 | adolgert@cornell.edu 54 | Adam Brazier 55 | brazier@cornell.edu 56 | Kevin Manalo 57 | kmanalo@gmail.com 58 | 59 | This modification to FortLua was derived from routines provided by AOTUS, hence 60 | their attribution is listed below: 61 | 62 | Aotus License 63 | ------------- 64 | 65 | Aotus is licensed under the terms of the MIT license reproduced below. 66 | This means that Aotus is free software and can be used for both academic and 67 | commercial purposes at absolutely no cost. You are free to do with the code 68 | whatever you want. 69 | The only requirement is that some credit to the authors is given by putting this 70 | copyright notice somewhere in your project. 71 | The MIT license is chosen for full compatibility with Lua. 72 | 73 | For the license of the underlying Lua library have a look at 74 | http://www.lua.org/license.html. 75 | 76 | =============================================================================== 77 | 78 | Copyright (C) 2011-2013 German Research School for Simulation Sciences GmbH, 79 | Aachen and others. 80 | 2013-2015 University of Siegen. 81 | 82 | Permission is hereby granted, free of charge, to any person obtaining a copy 83 | of this software and associated documentation files (the "Software"), to deal 84 | in the Software without restriction, including without limitation the rights 85 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 86 | copies of the Software, and to permit persons to whom the Software is 87 | furnished to do so, subject to the following conditions: 88 | 89 | The above copyright notice and this permission notice shall be included in 90 | all copies or substantial portions of the Software. 91 | 92 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 93 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 94 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 95 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 96 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 97 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 98 | THE SOFTWARE. 99 | 100 | =============================================================================== 101 | -------------------------------------------------------------------------------- /config.f90: -------------------------------------------------------------------------------- 1 | !> This module loads a Lua file to read values and execute functions. 2 | 3 | MODULE config 4 | ! The USE statement comes first 5 | USE iso_c_binding, only: C_CHAR, C_NULL_CHAR, C_INT, C_PTR, & 6 | C_FUNPTR, C_DOUBLE 7 | IMPLICIT NONE 8 | PRIVATE mluastate !< This is an opaque pointer to the Lua interpreter. 9 | 10 | ! Module scope variables 11 | ! The lua_State pointer is stored opaquely in Fortran in this 12 | ! module-level variable. 13 | TYPE(c_ptr) :: mluastate 14 | INTEGER(c_int) :: LUA_IDSIZE = 60 15 | 16 | INTEGER(c_int) :: LUA_TNIL = 0 17 | INTEGER(c_int) :: LUA_TBOOLEAN = 1 18 | INTEGER(c_int) :: LUA_TLIGHTUSERDATA = 2 19 | INTEGER(c_int) :: LUA_TNUMBER = 3 20 | INTEGER(c_int) :: LUA_TSTRING = 4 21 | INTEGER(c_int) :: LUA_TTABLE = 5 22 | INTEGER(c_int) :: LUA_TFUNCTION = 6 23 | INTEGER(c_int) :: LUA_TUSERDATA = 7 24 | INTEGER(c_int) :: LUA_TTHREAD = 8 25 | 26 | 27 | INTERFACE 28 | ! This interface is a subset of the Lua interface, but you 29 | ! get the point. 30 | ! 31 | ! This uses some of Fortran's ability to bind directly to C. 32 | ! The value option tells Fortran not to pass the argument 33 | ! using a pointer to the argument. 34 | ! For strings, it looks like the proper declaration is 35 | ! an array of CHARACTER(KIND=c_char) but that Fortran will 36 | ! happily translate CHARACTER(KIND=c_char,LEN=*) to the 37 | ! array of single chars. 38 | 39 | 40 | FUNCTION luaL_newstate() bind(C,name="luaL_newstate") 41 | USE iso_c_binding, only: c_ptr, c_funptr 42 | TYPE(c_ptr) :: luaL_newstate 43 | END FUNCTION luaL_newstate 44 | 45 | SUBROUTINE lua_close(lstate) bind(C,name="lua_close") 46 | USE iso_c_binding, only: c_ptr 47 | TYPE(c_ptr), value :: lstate 48 | END SUBROUTINE lua_close 49 | 50 | SUBROUTINE luaL_openlibs(lstate) bind(C,name="luaL_openlibs") 51 | USE iso_c_binding, only: c_ptr 52 | TYPE(c_ptr), value :: lstate 53 | END SUBROUTINE luaL_openlibs 54 | 55 | function luaL_loadfilex(L, filename, mode) bind(c, name="luaL_loadfilex") 56 | use, intrinsic :: iso_c_binding 57 | type(c_ptr), value :: L 58 | character(kind=c_char), dimension(*) :: filename 59 | character(kind=c_char), dimension(*) :: mode 60 | integer(kind=c_int) :: luaL_loadfilex 61 | end function luaL_loadfilex 62 | 63 | FUNCTION lua_gettop(lstate) bind(C, name="lua_gettop") 64 | USE iso_c_binding, only: c_int, c_ptr 65 | INTEGER(c_int) :: lua_gettop 66 | TYPE(c_ptr), value :: lstate 67 | END FUNCTION lua_gettop 68 | 69 | FUNCTION lua_type(lstate, stackIdx) bind(C,name="lua_type") 70 | USE iso_c_binding, only: c_int, c_ptr 71 | INTEGER(c_int) :: lua_type 72 | TYPE(c_ptr), value :: lstate 73 | INTEGER(c_int), value :: stackIdx 74 | END FUNCTION lua_type 75 | 76 | FUNCTION lua_checkstack(lstate, stackIdx) bind(C,name="lua_checkstack") 77 | USE iso_c_binding, only: c_int, c_ptr 78 | INTEGER(c_int) :: lua_checkstack 79 | TYPE(c_ptr), value :: lstate 80 | INTEGER(c_int), value :: stackIdx 81 | END FUNCTION lua_checkstack 82 | 83 | subroutine lua_getglobal(L, k) bind(c, name="lua_getglobal") 84 | use, intrinsic :: iso_c_binding 85 | type(c_ptr), value :: L 86 | character(kind=c_char), dimension(*) :: k 87 | end subroutine lua_getglobal 88 | 89 | !> Set the top of the stack. 90 | !! lua_pop is defined as lua_settop(L,-(n)-1) in a macro for C. 91 | SUBROUTINE lua_settop(lstate,stackIdx) bind(C,name="lua_settop") 92 | USE iso_c_binding, only: c_ptr, c_int 93 | TYPE(c_ptr), value :: lstate 94 | INTEGER(c_int), value :: stackIdx 95 | END SUBROUTINE lua_settop 96 | 97 | SUBROUTINE lua_pushnumber(lstate,setval) bind(C,name="lua_pushnumber") 98 | USE iso_c_binding, only: c_ptr, c_double 99 | TYPE(c_ptr), value :: lstate 100 | REAL(c_double), value :: setval 101 | END SUBROUTINE lua_pushnumber 102 | 103 | function lua_pcallk(L, nargs, nresults, errfunc, ctx, k) bind(c, name="lua_pcallk") 104 | use, intrinsic :: iso_c_binding 105 | type(c_ptr), value :: L 106 | integer(kind=c_int), value :: nargs 107 | integer(kind=c_int), value :: nresults 108 | integer(kind=c_int), value :: errfunc 109 | integer(kind=c_int), value :: ctx 110 | type(c_ptr), value :: k 111 | integer(kind=c_int) :: lua_pcallk 112 | end function lua_pcallk 113 | 114 | FUNCTION lua_isfunction(lstate,stackIdx) bind(C,name="lua_isfunction") 115 | USE iso_c_binding, only: c_ptr, c_int 116 | INTEGER(c_int) :: lua_isfunction 117 | TYPE(c_ptr), value :: lstate 118 | INTEGER(c_int), value :: stackIdx 119 | END FUNCTION lua_isfunction 120 | 121 | FUNCTION lua_isnumber(lstate,stackIdx) bind(C,name="lua_isnumber") 122 | USE iso_c_binding, only: c_ptr, c_int 123 | INTEGER(c_int) :: lua_isnumber 124 | TYPE(c_ptr), value :: lstate 125 | INTEGER(c_int), value :: stackIdx 126 | END FUNCTION lua_isnumber 127 | 128 | function lua_tonumberx(L, index, isnum) bind(c, name="lua_tonumberx") 129 | use, intrinsic :: iso_c_binding 130 | type(c_ptr), value :: L 131 | integer(kind=c_int), value :: index 132 | integer(kind=c_int) :: isnum 133 | real(kind=c_double) :: lua_tonumberx 134 | end function lua_tonumberx 135 | 136 | function lua_tolstring(L, index, length) bind(c, name="lua_tolstring") 137 | use, intrinsic :: iso_c_binding 138 | type(c_ptr), value :: L 139 | integer(kind=c_int), value :: index 140 | integer(kind=c_size_t) :: length 141 | type(c_ptr):: lua_tolstring 142 | end function lua_tolstring 143 | 144 | FUNCTION lua_tointeger(lstate,stackIdx) bind(C,name="lua_tointeger") 145 | USE iso_c_binding, only: c_ptr, c_int, c_size_t 146 | INTEGER(c_size_t) :: lua_tointeger 147 | TYPE(c_ptr), value :: lstate 148 | INTEGER(c_int), value :: stackIdx 149 | END FUNCTION lua_tointeger 150 | 151 | END INTERFACE 152 | 153 | CONTAINS 154 | 155 | function luaL_loadfile(lstate, filename) result(errcode) 156 | use, intrinsic :: iso_c_binding 157 | TYPE(c_ptr), value :: lstate 158 | character(len=*) :: filename 159 | integer :: errcode 160 | 161 | character(len=len_trim(filename)+1) :: c_filename 162 | character(len=3) :: c_mode 163 | integer(kind=c_int) :: c_errcode 164 | 165 | c_filename = trim(filename) // c_null_char 166 | c_mode = "bt" // c_null_char 167 | c_errcode = luaL_loadfilex(lstate, c_filename, c_mode) 168 | errcode = c_errcode 169 | end function luaL_loadfile 170 | 171 | function lua_pcall(lstate, nargs, nresults, errfunc) result(errcode) 172 | use, intrinsic :: iso_c_binding 173 | TYPE(c_ptr), value :: lstate 174 | integer :: nargs 175 | integer :: nresults 176 | integer :: errfunc 177 | integer :: errcode 178 | 179 | integer(kind=c_int) :: c_nargs 180 | integer(kind=c_int) :: c_nresults 181 | integer(kind=c_int) :: c_errfunc 182 | integer(kind=c_int) :: c_errcode 183 | 184 | c_nargs = nargs 185 | c_nresults = nresults 186 | c_errfunc = errfunc 187 | 188 | c_errcode = lua_pcallk(lstate, c_nargs, c_nresults, c_errfunc, & 189 | & 0_c_int, C_NULL_PTR) 190 | errcode = c_errcode 191 | end function lua_pcall 192 | 193 | function lua_tonumber(lstate, index) result(number) 194 | use, intrinsic :: iso_c_binding 195 | TYPE(c_ptr), value :: lstate 196 | integer :: index 197 | real :: number 198 | 199 | integer(kind=c_int) :: c_index 200 | integer(kind=c_int) :: isnum 201 | 202 | c_index = index 203 | number = real(lua_tonumberx(lstate, c_index, isnum), & 204 | & kind=kind(number)) 205 | end function lua_tonumber 206 | 207 | function lua_tostring(lstate, index, len) result(string) 208 | use, intrinsic :: iso_c_binding 209 | TYPE(c_ptr), value :: lstate 210 | integer :: index 211 | integer :: len 212 | character,pointer,dimension(:) :: string 213 | 214 | integer :: string_shape(1) 215 | integer(kind=c_int) :: c_index 216 | integer(kind=c_size_t) :: c_len 217 | type(c_ptr) :: c_string 218 | 219 | c_index = index 220 | c_string = lua_tolstring(lstate, c_index, c_len) 221 | len = int(c_len,kind=kind(len)) 222 | string_shape(1) = len 223 | call c_f_pointer(c_string, string, string_shape) 224 | end function lua_tostring 225 | 226 | !> Open a Lua configuration file by name. 227 | !! The state of the Lua file is held in the module and must be 228 | !! closed when you are done. 229 | INTEGER FUNCTION config_open(fname) 230 | CHARACTER(LEN=*) :: fname 231 | INTEGER(c_int) :: filesuccess, callsuccess 232 | 233 | mluastate=luaL_newstate() 234 | CALL luaL_openlibs(mluastate) 235 | 236 | filesuccess = luaL_loadfile(mluastate, TRIM(fname)//C_NULL_CHAR) 237 | IF ( filesuccess .eq. 0 ) THEN 238 | callsuccess = lua_pcall(mluastate,0,0,0) 239 | IF ( callsuccess .eq. 0 ) THEN 240 | ! This is equivalent to the macro lua_pop. 241 | CALL lua_settop(mluastate,-2) 242 | config_open=1 243 | ELSE 244 | config_open=0 245 | ENDIF 246 | ELSE 247 | config_open=0 248 | ENDIF 249 | 250 | END FUNCTION config_open 251 | 252 | 253 | 254 | !> Close the Lua configuration, which releases the interpreter. 255 | SUBROUTINE config_close 256 | call lua_close(mluastate) 257 | END SUBROUTINE config_close 258 | 259 | 260 | !> Retrieve the value of a character array 261 | subroutine config_string(name,status,string) 262 | character(len=*), intent(out) :: string 263 | character, dimension(:), allocatable :: mystring 264 | CHARACTER(LEN=*) :: name 265 | INTEGER :: status 266 | integer :: length, i 267 | INTEGER(c_int) :: stackstart 268 | character, pointer :: cstring(:) 269 | 270 | CALL lua_getglobal(mluastate,TRIM(name)//C_NULL_CHAR) 271 | 272 | !IF ( lua_isnumber(mluastate,-1) .NE. 0 ) THEN 273 | cstring => lua_tostring(mluastate,-1, length) 274 | allocate(mystring(length)) 275 | do i=1,length 276 | string(i:i) = cstring(i) 277 | !mystring(i:i) = cstring(i) 278 | end do 279 | !print *, mystring 280 | 281 | ! This is the same as Lua pop 1. 282 | CALL lua_settop(mluastate,-2) 283 | status = 0 284 | !ELSE 285 | ! config_string='' 286 | ! status = -1 287 | !ENDIF 288 | !IF (stackstart .ne. lua_gettop(mluastate)) THEN 289 | ! WRITE(*,*) 'The stack is a different size coming out of config_real' 290 | !ENDIF 291 | 292 | END subroutine config_string 293 | 294 | !> Retrieve the value of a floating point variable. 295 | FUNCTION config_real(name,status) 296 | REAL :: config_real 297 | CHARACTER(LEN=*) :: name 298 | INTEGER :: status 299 | INTEGER(c_int) :: stackstart 300 | 301 | ! We compare the stack before and after our work to discover 302 | ! whether we have corrupted it. Otherwise debugging errors 303 | ! can be difficult. 304 | stackstart = lua_gettop(mluastate) 305 | 306 | !DBG CALL lua_getfield(mluastate,LUA_GLOBALSINDEX,TRIM(name)//C_NULL_CHAR) 307 | CALL lua_getglobal(mluastate,TRIM(name)//C_NULL_CHAR) 308 | 309 | IF ( lua_isnumber(mluastate,-1) .NE. 0 ) THEN 310 | config_real=lua_tonumber(mluastate,-1) 311 | ! This is the same as Lua pop 1. 312 | CALL lua_settop(mluastate,-2) 313 | status = 0 314 | ELSE 315 | config_real=0 316 | status = -1 317 | ENDIF 318 | IF (stackstart .ne. lua_gettop(mluastate)) THEN 319 | WRITE(*,*) 'The stack is a different size coming out of config_real' 320 | ENDIF 321 | 322 | END FUNCTION config_real 323 | 324 | 325 | 326 | !> Retrieve the value of an integer variable. 327 | FUNCTION config_integer(name,status) 328 | INTEGER :: config_integer 329 | CHARACTER(LEN=*) :: name 330 | INTEGER :: status 331 | INTEGER(c_int) :: stackstart 332 | 333 | stackstart = lua_gettop(mluastate) 334 | 335 | CALL lua_getglobal(mluastate,TRIM(name)//C_NULL_CHAR) 336 | 337 | IF ( lua_isnumber(mluastate,-1) .NE. 0 ) THEN 338 | config_integer=lua_tonumber(mluastate,-1) 339 | ! This is the same as Lua pop 1. 340 | CALL lua_settop(mluastate,-2) 341 | status = 0 342 | ELSE 343 | config_integer=0 344 | status = -1 345 | ENDIF 346 | IF (stackstart .ne. lua_gettop(mluastate)) THEN 347 | WRITE(*,*) 'The stack is a different size coming out of config_integer' 348 | ENDIF 349 | 350 | END FUNCTION config_integer 351 | 352 | 353 | 354 | 355 | !> Evaluate a function in the config file and get its result. 356 | FUNCTION config_function(name,args,nargs,status) 357 | REAL :: config_function 358 | CHARACTER(LEN=*) :: name 359 | REAL, DIMENSION(*) :: args 360 | REAL(KIND=c_double) :: anarg 361 | INTEGER :: nargs 362 | INTEGER :: status 363 | INTEGER :: iargs 364 | INTEGER(c_int) :: stackstart 365 | 366 | stackstart = lua_gettop(mluastate) 367 | 368 | config_function = 0 369 | 370 | 371 | CALL lua_getglobal(mluastate,TRIM(name)//C_NULL_CHAR) 372 | IF ( lua_type(mluastate,-1) .eq. LUA_TFUNCTION ) THEN 373 | DO iargs = 1,nargs 374 | anarg = args(iargs) 375 | CALL lua_pushnumber(mluastate,anarg) 376 | ENDDO 377 | IF (lua_pcall(mluastate,nargs,1,0) .eq. 0) THEN 378 | if (lua_isnumber(mluastate,-1) .ne. 0) THEN 379 | config_function = lua_tonumber(mluastate,-1) 380 | CALL lua_settop(mluastate,-2) 381 | ELSE 382 | ! Nothing to pop here 383 | status=-3 384 | ENDIF 385 | ELSE 386 | CALL lua_settop(mluastate,-2) 387 | status=-2 388 | ENDIF 389 | ELSE 390 | CALL lua_settop(mluastate,-2) 391 | status=-1 392 | ENDIF 393 | IF (stackstart .ne. lua_gettop(mluastate)) THEN 394 | WRITE(*,*) 'The stack is a different size coming out of config_function' 395 | ENDIF 396 | 397 | END FUNCTION config_function 398 | 399 | 400 | END MODULE config 401 | -------------------------------------------------------------------------------- /program.f90: -------------------------------------------------------------------------------- 1 | ! This program uses a script to configure itself. 2 | 3 | PROGRAM calculate 4 | USE config 5 | 6 | INTEGER :: argument_count 7 | REAL*8 :: pressure 8 | REAL*8 :: time 9 | INTEGER :: step, stepcount 10 | INTEGER :: status 11 | REAL :: temperature_start 12 | REAL, DIMENSION(1) :: pressure_args 13 | INTEGER :: read_status 14 | INTEGER :: cstatus 15 | integer :: newval 16 | 17 | character(50) :: string 18 | character(:), allocatable :: astring 19 | 20 | status = config_open('vals.lua') 21 | 22 | call config_string('string',read_status, string) 23 | astring = trim(string) 24 | 25 | write(*,*) 'string = ', astring 26 | 27 | temperature_start = config_real('temperature',read_status) 28 | IF ( read_status .eq. 0 ) THEN 29 | WRITE (*,*) 'temperature = ', temperature_start 30 | ELSE 31 | WRITE (*,*) 'error reading temperature' 32 | ENDIF 33 | 34 | newval = config_integer('newval',read_status) 35 | IF ( read_status .eq. 0 ) THEN 36 | WRITE (*,*) 'newval = ', newval 37 | ELSE 38 | WRITE (*,*) 'error reading newval' 39 | ENDIF 40 | 41 | stepcount=10 42 | 43 | DO step = 1,stepcount 44 | time = step/1.0 45 | pressure_args(1) = time 46 | pressure=config_function('pressure',pressure_args,1,cstatus) 47 | WRITE (*,*) 'pressure = ', pressure 48 | END DO 49 | 50 | 51 | CALL config_close() 52 | 53 | STOP 54 | END PROGRAM calculate 55 | 56 | -------------------------------------------------------------------------------- /vals.lua: -------------------------------------------------------------------------------- 1 | -- vals.lua 2 | -- This is a configuration file for the Fortran program. 3 | -- Lua isn't too complicated. Check out 4 | -- http://lua-users.org/wiki/TutorialDirectory 5 | 6 | -- Parameters 7 | if os.getenv("BATCH") then 8 | temperature=3.2 9 | else 10 | temperature=5.0 11 | end 12 | 13 | mintemp=3 14 | maxtemp=6 15 | duration=10 -- time to get to 95% 16 | string=10 -- string will be interpreted because that is what this program is looking for 17 | newval=10.5 18 | 19 | function pressure(time) 20 | return mintemp+(maxtemp-mintemp)*math.tanh(1.83*time/duration) 21 | end 22 | 23 | --------------------------------------------------------------------------------