Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/fem/src/Lua.F90
3203 views
1
!/*****************************************************************************/
2
! *
3
! * Elmer, A Finite Element Software for Multiphysical Problems
4
! *
5
! * Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
! *
7
! * This library is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU Lesser General Public
9
! * License as published by the Free Software Foundation; either
10
! * version 2.1 of the License, or (at your option) any later version.
11
! *
12
! * This library is distributed in the hope that it will be useful,
13
! * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
! * Lesser General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU Lesser General Public
18
! * License along with this library (in file ../LGPL-2.1); if not, write
19
! * to the Free Software Foundation, Inc., 51 Franklin Street,
20
! * Fifth Floor, Boston, MA 02110-1301 USA
21
! *
22
! *****************************************************************************/
23
!
24
!/******************************************************************************
25
! *
26
! * Authors: Juhani Kataja
27
! * Email: [email protected]
28
! * Web: http://www.csc.fi/elmer
29
! * Address: CSC - IT Center for Science Ltd.
30
! * Keilaranta 14
31
! * 02101 Espoo, Finland
32
! *
33
! * Original Date: 08 Jun 1997
34
! *
35
! *****************************************************************************/
36
37
#include <../config.h>
38
39
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
40
#define LUA_GLOBALSINDEX (-10002)
41
!-------------------------------------------------------------------------------
42
module Lua ! {{{
43
!-------------------------------------------------------------------------------
44
use ISO_C_BINDING
45
implicit none
46
private
47
48
!-Type declarations-------------------------------------------------------------
49
type, public :: LuaState_t
50
private
51
REAL(KIND=c_double), POINTER, PUBLIC :: tx(:) => NULL() ! This table will hold values for tx array
52
type(c_ptr) :: L = c_null_ptr
53
logical, public :: initialized=.false.
54
end type
55
!-------------------------------------------------------------------------------
56
57
type(LuaState_t), PUBLIC :: LuaState
58
!$OMP THREADPRIVATE(LuaState)
59
60
#ifdef HAVE_LUA
61
public :: lua_init, lua_close, lua_addfun, luaL_checkinteger, luaL_checknumber, &
62
lua_pushnumber, luafun, lua_runfile, lua_dostring, &
63
luaL_checkstring, lua_eval_f, lua_popnumber, lua_getnumber, lua_tolstring, &
64
check_error, lua_getusertable, lua_poptensor, lua_popstring, lua_exec_fun, &
65
lua_popvector
66
67
!-Interfaces-{{{----------------------------------------------------------------
68
interface !
69
type(c_ptr) function lua_touserdata(L, n) bind(C)
70
import
71
type(c_ptr), value :: L
72
integer(kind=c_int), value :: n
73
end function
74
75
function luaopen_array(L) result(n) bind(C, name="create_tx_table")
76
import
77
type(c_ptr), value :: L
78
integer(kind=c_int) :: n
79
end function
80
81
function lua_tolstring_c(L, n, len) result(s) bind(C, name="lua_tolstring")
82
import
83
type(c_ptr), value :: L
84
integer(kind=c_int), value :: n
85
integer(kind=c_int) :: len
86
type(c_ptr) :: s
87
end function
88
89
subroutine lua_pushnumber(L, x) bind(C)
90
import
91
type(c_ptr), value :: L
92
real(kind=c_double), value :: x
93
end subroutine
94
95
function luaL_checknumber(L, n) result(r) bind(C, name="luaL_checknumber")
96
import
97
type(c_ptr), value :: L
98
integer(kind=c_int), value :: n
99
real(kind=c_double) :: r
100
end function
101
102
function lua_tonumber(L, n) result(r) bind(C)
103
import
104
type(c_ptr), value :: L
105
integer(kind=c_int), value :: n
106
real(kind=c_double) :: r
107
end function
108
109
function luaL_checkstring_c(L, n, len) result(s) bind(C, name="luaL_checklstring")
110
import
111
type(c_ptr), value :: L
112
integer(kind=c_int), value :: n
113
integer(kind=c_int) :: len
114
type(c_ptr) :: s
115
end function
116
117
subroutine lua_set_type(L, n) bind(C, name="lua_set_type_c")
118
import
119
type(c_ptr), value :: L
120
integer(kind=c_int), value :: n
121
end subroutine
122
123
function luaL_checkinteger(L, n) result(r) bind(C, name="luaL_checkinteger")
124
import
125
type(c_ptr), value :: L
126
integer(kind=c_int), value :: n
127
integer(kind=c_int) :: r
128
end function
129
130
subroutine printfunloc(fn) bind(C)
131
import
132
type(c_funptr), value :: fn
133
end subroutine
134
135
function lua_init_c() result(L) bind(C, name="lua_init")
136
import
137
type(c_ptr) :: L
138
end function
139
140
subroutine lua_close_c(L) bind(C, name = "lua_close")
141
import
142
type(c_ptr), value :: L
143
end subroutine
144
145
subroutine lua_pushcclosure(L, fun, n) bind(C, name ="lua_pushcclosure")
146
import
147
type(c_ptr), value :: L
148
type(c_funptr), value :: fun
149
integer(kind=c_int), value :: n
150
end subroutine
151
152
function lua_cpcall(L, fun, ud) result(res) bind(C)
153
import
154
type(c_ptr), value :: L, fun, ud
155
integer(kind=c_int) :: res
156
end function
157
158
subroutine lua_setfield(L,g_index, s) bind(C)
159
import
160
type(c_ptr), value :: L
161
character(kind=c_char) :: s(*)
162
integer(kind=c_int), value :: g_index
163
end subroutine
164
165
subroutine lua_getfield(L, g_index, s) bind(C)
166
import
167
type(c_ptr), value :: L
168
character(kind=c_char) :: s(*)
169
integer(kind=c_int), value :: g_index
170
end subroutine
171
172
subroutine lua_runfile_c(L, fname) bind(C, name="lua_runfile")
173
import
174
type(c_ptr), value :: L
175
character(kind=c_char) :: fname(*)
176
end subroutine
177
178
integer(kind=c_int) function luaL_loadstring(L, s) bind(C, name="luaL_loadstring")
179
import
180
type(c_ptr), value :: L
181
character(kind=c_char) :: s(*)
182
end function
183
184
integer(kind=c_int) function lua_pcall(L, a, b, c) bind(C)
185
import
186
type(c_ptr), value :: L
187
integer(kind=c_int), value :: a, b, c
188
end function
189
190
subroutine lua_pop(L, n) bind(C, name="lua_pop_c")
191
import
192
type(c_ptr), value :: L
193
integer(kind=c_int), value :: n
194
end subroutine
195
196
subroutine luaL_error(L, s) bind(C, name="luaL_error")
197
import
198
type(c_ptr), value :: L
199
character(kind=c_char) :: s(*)
200
end subroutine
201
202
subroutine get_userdataptr(L, cp_raw, cp_data, len) bind(C)
203
import
204
type(c_ptr), value :: L, cp_raw
205
type(c_ptr) :: cp_data
206
integer(kind=c_int) :: len
207
end subroutine
208
209
end interface
210
211
abstract interface
212
function luafun(L) result(n)
213
import
214
type(c_ptr), value :: L
215
integer(kind=c_int) :: n
216
end function
217
end interface
218
!-}}}---------------------------------------------------------------------------
219
220
CONTAINS
221
222
FUNCTION lua_getusertable(L, name) result(t)
223
type(LuaState_t) :: L
224
character(kind=c_char) :: name(*)
225
real(kind=c_double), pointer :: t(:)
226
227
type(c_ptr) :: cp_raw, cp_data
228
integer(kind=c_int) :: len
229
t => NULL()
230
231
call lua_getfield(L%L, LUA_GLOBALSINDEX, name)
232
cp_raw = lua_touserdata(L%L,-1)
233
call get_userdataptr(L%L, cp_raw, cp_data, len) ! this should typecase cp_raw to "NumArray*" and extract size and len out of it
234
call c_f_pointer(cp_data, t, shape=[len])
235
end function
236
237
function lua_tolstring(L, n, slen) result(sp)
238
type(c_ptr) :: L
239
integer(kind=c_int) :: n
240
character(kind=c_char), pointer :: sp_arr(:)
241
character(:, kind=c_char), pointer :: sp
242
243
character(kind=c_char, len=:), allocatable :: s
244
type(c_ptr) :: c_s
245
integer(kind=c_int) :: slen
246
247
sp => null()
248
249
c_s = lua_tolstring_c(L, n, slen)
250
if ( slen <= 0 ) return
251
252
call c_f_pointer(c_s, sp_arr, shape=[slen])
253
call char_c_f(slen, sp_arr, sp)
254
end function
255
256
subroutine char_c_f(len, cchar, fchar)
257
INTEGER, intent(in) :: len
258
CHARACTER(kind=c_char, LEN=len), INTENT(in), target :: cchar(1)
259
CHARACTER(:, kind=c_char), INTENT(OUT), pointer :: fchar
260
fchar => cchar(1)
261
end subroutine char_c_f
262
263
function luaL_checkstring(L, n, slen) result(sp)
264
type(c_ptr) :: L
265
integer(kind=c_int) :: n
266
character(kind=c_char), pointer :: sp
267
268
character(kind=c_char, len=:), allocatable :: s
269
type(c_ptr) :: c_s
270
integer(kind=c_int) :: slen
271
272
c_s = luaL_checkstring_c(L, n, slen)
273
call c_f_pointer(c_s, sp)
274
end function
275
276
subroutine lua_runfile(L, fname)
277
type(LuaState_t) :: L
278
character(kind=c_char) :: fname(*)
279
call lua_runfile_c(L%L, fname)
280
end subroutine
281
282
function lua_dostring(L, s, m) result(n)
283
type(LuaState_t) :: L
284
character(kind=c_char) :: s(*)
285
integer(kind=c_int) :: n, m_, load_error, pcall_error
286
integer(kind=c_int), optional :: m
287
if(.not. present(m)) then
288
m_ = -1
289
else
290
m_ = m
291
end if
292
load_error = luaL_loadstring(L%L, s)
293
call check_error(L, load_error)
294
if(load_error == 0) then
295
pcall_error = lua_pcall(L%L, 0, m_, 0)
296
call check_error(L, pcall_error)
297
end if
298
n = IOR(load_error, pcall_error)
299
end function
300
301
real(kind=c_double) function lua_getnumber(L, s)
302
type(LuaState_t) :: L
303
character(kind=c_char) :: s(*)
304
call lua_getfield(L%L, LUA_GLOBALSINDEX, s)
305
lua_getnumber = lua_popnumber(L)
306
end function
307
308
subroutine lua_poptensor(L, t)
309
type(LuaState_t) :: L
310
real(kind=c_double), intent(out) :: t(:,:)
311
312
integer :: n1, n2, i, j
313
n1 = size(t, 1)
314
n2 = size(t, 2)
315
do i = n1,1, -1
316
do j = n2,1,-1
317
t(i,j) = lua_popnumber(L)
318
end do
319
end do
320
end subroutine
321
322
subroutine lua_popvector(L, t)
323
type(LuaState_t) :: L
324
real(kind=c_double), intent(out) :: t(:)
325
integer :: n, i
326
n = size(t, 1)
327
do i = n, 1, -1
328
t(i) = lua_popnumber(L)
329
end do
330
end subroutine
331
332
subroutine lua_eval_f(L, fname, X, y)
333
type(LuaState_t) :: L
334
character(kind=c_char) :: fname(*)
335
real(kind=c_double), intent(in) :: X(:)
336
real(kind=c_double), intent(inout) :: Y(:)
337
338
integer :: nx, ny, i, lstat
339
nx = size(X,1)
340
ny = size(Y,1)
341
CALL lua_getfield(L%L, LUA_GLOBALSINDEX, fname)
342
do i = 1,nx
343
CALL lua_pushnumber(L%L, X(i))
344
end do
345
lstat = lua_pcall(L%L, nx, ny, 0)
346
call check_error(L, lstat)
347
if (lua_pcall(L%L, nx, ny, 0) /= 0) then
348
CALL luaL_error(L%L, "error running '"//fname(1:len(fname))//"': ")
349
end if
350
do i = ny,1,-1
351
Y(i) = lua_tonumber(L%L, -1)
352
CALL lua_pop(L%L,1)
353
end do
354
end subroutine
355
356
!> Execute fname in lua state L, do not collect results from stack but expect user to collect them.
357
subroutine lua_exec_fun(L, fname, nin, nout)
358
type(LuaState_t) :: L
359
character(kind=c_char), intent(in) :: fname(*)
360
integer, intent(in) :: nin, nout
361
integer :: lstat
362
363
CALL lua_getfield(L%L, LUA_GLOBALSINDEX, fname)
364
CALL lua_set_type(L%L, nin)
365
lstat = lua_pcall(L%L, nin, nout, 0)
366
call check_error(L, lstat)
367
end subroutine
368
369
real(kind=c_double) function lua_popnumber(L)
370
type(LuaState_t) :: L
371
lua_popnumber = lua_tonumber(L%L, -1)
372
call lua_pop(L%L,1)
373
end function
374
375
function lua_init() result(L)
376
type(LuaState_t) :: L
377
type(c_ptr) :: ptr
378
L%L = lua_init_c()
379
if(c_associated(L%L)) L % initialized = .true.
380
end function
381
382
subroutine lua_addfun(L, fun, fname)
383
type(LuaState_t) :: L
384
procedure(luafun), pointer :: fun
385
type(c_funptr) :: c_fun
386
character(kind=c_char):: fname
387
388
c_fun = c_funloc(fun)
389
call lua_pushcclosure(L % L, c_fun, 0)
390
call lua_setfield(L % L, LUA_GLOBALSINDEX ,fname)
391
end subroutine
392
393
subroutine lua_close(L)
394
type(LuaState_t) :: L
395
call lua_close_c(L%L)
396
L % initialized = .false.
397
end subroutine
398
399
subroutine check_error(L, lstat)
400
type(LuaState_t) :: L
401
integer(kind=c_int), intent(in) :: lstat
402
character(kind=c_char, len=:), pointer :: s
403
integer(kind=c_int) :: slen
404
if (lstat /= 0) then
405
s => lua_tolstring(L%L, -1, slen)
406
print *, 'Caught LUA error:', s(1:slen)
407
call lua_pop(L%L,1);
408
end if
409
end subroutine
410
411
function lua_popstring(L, slen) result(s)
412
type(LuaState_t) :: L
413
character(kind=c_char, len=:), pointer :: s
414
integer :: slen
415
416
s => lua_tolstring(L%L, -1, slen)
417
call lua_pop(L%L, 1)
418
end function
419
#endif
420
421
!-------------------------------------------------------------------------------
422
end module ! Lua }}}
423
!-------------------------------------------------------------------------------
424
425