Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/fem/src/LoadMod.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: Mikko Byckling
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: 17 Feb 2014
34
! *
35
! *****************************************************************************/
36
37
! Module for wrapping and replacing functionality in Load.c
38
39
MODULE LoadMod
40
USE Types
41
USE, INTRINSIC :: ISO_C_BINDING
42
USE huti_interfaces
43
IMPLICIT NONE
44
45
#ifdef ARCH_32_BITS
46
#define CAddrInt c_int32_t
47
#else
48
#define CAddrInt c_int64_t
49
#endif
50
51
#include "huti_fdefs.h"
52
#include "../config.h"
53
54
! GENERAL ROUTINES
55
56
! TODO: getsolverhome and makedirectory can be implemented with Fortran
57
INTERFACE
58
SUBROUTINE getsolverhome(solverDir, len) BIND(C,name='getsolverhome')
59
USE, INTRINSIC :: iso_c_binding
60
CHARACTER(C_CHAR) :: solverDir(*)
61
INTEGER(C_INT) :: len
62
END SUBROUTINE getsolverhome
63
END INTERFACE
64
65
INTERFACE
66
SUBROUTINE makedirectory(name) BIND(C,name='makedirectory')
67
USE, INTRINSIC :: iso_c_binding
68
CHARACTER(C_CHAR) :: name(*)
69
END SUBROUTINE makedirectory
70
END INTERFACE
71
72
! MATC
73
74
INTERFACE
75
SUBROUTINE matc_get_array(name, values, nrows, ncols) &
76
BIND(C,name='matc_get_array')
77
USE, INTRINSIC :: ISO_C_BINDING
78
CHARACTER(C_CHAR) :: name(*)
79
REAL(C_DOUBLE) :: values(*)
80
INTEGER(C_INT) :: nrows, ncols
81
END SUBROUTINE matc_get_array
82
END INTERFACE
83
84
INTERFACE
85
SUBROUTINE matc_c(cmd,cmdlen,res,reslen) BIND(C,name='matc_c')
86
USE, INTRINSIC :: ISO_C_BINDING
87
INTEGER(C_INT) :: cmdlen,reslen
88
CHARACTER(C_CHAR) :: cmd(*), res(*)
89
END SUBROUTINE matc_c
90
END INTERFACE
91
92
! CPUTime.c
93
INTERFACE
94
FUNCTION cputime() RESULT(dbl) BIND(C,name='cputime')
95
USE, INTRINSIC :: ISO_C_BINDING
96
REAL(C_DOUBLE) :: dbl
97
END FUNCTION cputime
98
END INTERFACE
99
100
INTERFACE
101
FUNCTION realtime() RESULT(dbl) BIND(C,name='realtime')
102
USE, INTRINSIC :: ISO_C_BINDING
103
REAL(C_DOUBLE) :: dbl
104
END FUNCTION realtime
105
END INTERFACE
106
107
INTERFACE
108
FUNCTION cpumemory() RESULT(dbl) BIND(C,name='cpumemory')
109
USE, INTRINSIC :: ISO_C_BINDING
110
REAL(C_DOUBLE) :: dbl
111
END FUNCTION cpumemory
112
END INTERFACE
113
114
! fft.c
115
TYPE, BIND(C) :: C_FFTCMPLX
116
REAL(C_DOUBLE) :: rval
117
REAL(C_DOUBLE) :: ival
118
END TYPE C_FFTCMPLX
119
120
INTERFACE
121
SUBROUTINE frfftb( N, F, T ) BIND(C,name='frfftb')
122
USE, INTRINSIC :: ISO_C_BINDING
123
IMPORT C_FFTCMPLX
124
INTEGER(C_INT) :: N
125
TYPE(C_FFTCMPLX) :: F(*)
126
REAL(C_DOUBLE) :: T(*)
127
END SUBROUTINE frfftb
128
END INTERFACE
129
130
INTERFACE
131
SUBROUTINE fcfftb( N, F, T ) BIND(C,name='fcfftb')
132
USE, INTRINSIC :: ISO_C_BINDING
133
IMPORT C_FFTCMPLX
134
INTEGER(C_INT) :: N
135
TYPE(C_FFTCMPLX) :: F(*), T(*)
136
END SUBROUTINE fcfftb
137
END INTERFACE
138
139
#if 0
140
! Overloads for AddrFunc
141
INTERFACE AddrFunc
142
MODULE PROCEDURE AddrFuncSub, &
143
AddrFuncInt, AddrFuncLong, &
144
AddrFuncReal, AddrFuncDbl, &
145
AddrFuncCmp, AddrFuncDblCmp
146
END INTERFACE AddrFunc
147
#endif
148
149
! Overloads for IterCall
150
INTERFACE IterCall
151
MODULE PROCEDURE IterCallFTNR, IterCallFTNC
152
END INTERFACE IterCall
153
154
CONTAINS
155
156
FUNCTION matc(cmd, res, inlen) RESULT(reslen)
157
INTEGER :: reslen
158
CHARACTER(*) :: cmd, res
159
INTEGER, OPTIONAL :: inlen
160
161
INTEGER :: cmdlen
162
163
reslen = LEN(res)
164
IF(PRESENT(inlen)) THEN
165
cmdlen = inlen
166
ELSE
167
cmdlen = LEN_TRIM(cmd)
168
END IF
169
CALL matc_c(cmd,cmdlen,res,reslen)
170
END FUNCTION matc
171
172
SUBROUTINE systemc(cmd)
173
IMPLICIT NONE
174
CHARACTER(LEN=*) :: cmd
175
CHARACTER(LEN=40) :: buf
176
INTEGER :: estat, cstat
177
178
INTERFACE
179
! int system(const char *command)
180
FUNCTION system(command) RESULT(retval)
181
USE, INTRINSIC :: ISO_C_BINDING
182
CHARACTER(C_CHAR), INTENT(IN) :: command(*)
183
INTEGER(C_INT) :: retval
184
END FUNCTION system
185
END INTERFACE
186
187
#ifdef HAVE_EXECUTECOMMANDLINE
188
estat = 0; cstat = 0
189
CALL EXECUTE_COMMAND_LINE(cmd, .TRUE., EXITSTAT=estat, CMDSTAT=cstat)
190
#else
191
! Workaround for Fortran compilers which do not
192
! support EXECUTE_COMMAND_LINE intrinsic function
193
cstat = 0
194
estat = system(TRIM(cmd) // C_NULL_CHAR)
195
IF (estat == -1) THEN
196
cstat = estat
197
estat = 0
198
END IF
199
#endif
200
IF (estat /= 0) THEN
201
WRITE (buf, '(A,I0)') 'Command exit status was ', estat
202
CALL Error('systemc',TRIM(BUF))
203
END IF
204
IF (cstat /= 0) THEN
205
CALL Error('systemc','Unable to execute system command')
206
END IF
207
END SUBROUTINE systemc
208
209
SUBROUTINE envir(name, value, len)
210
IMPLICIT NONE
211
CHARACTER(LEN=*) :: name
212
CHARACTER(LEN=*) :: value
213
INTEGER :: len
214
INTEGER :: estat
215
216
CALL GET_ENVIRONMENT_VARIABLE(name, value, len)
217
END SUBROUTINE envir
218
219
#if 0
220
! FUNCTION ADDRESS (overloaded methods for different function return values)
221
FUNCTION AddrFuncSub(fn) RESULT(addr)
222
IMPLICIT NONE
223
PROCEDURE() :: fn
224
INTEGER(KIND=AddrInt) :: addr
225
226
TYPE(C_FUNPTR) :: cptr
227
cptr = C_FUNLOC(fn)
228
addr = TRANSFER(cptr, addr)
229
END FUNCTION AddrFuncSub
230
231
FUNCTION AddrFuncInt(fn) RESULT(addr)
232
IMPLICIT NONE
233
PROCEDURE(INTEGER(KIND=selected_int_kind(9))) :: fn
234
INTEGER(KIND=AddrInt) :: addr
235
236
TYPE(C_FUNPTR) :: cptr
237
cptr = C_FUNLOC(fn)
238
addr = TRANSFER(cptr, addr)
239
END FUNCTION AddrFuncInt
240
241
FUNCTION AddrFuncLong(fn) RESULT(addr)
242
IMPLICIT NONE
243
PROCEDURE(INTEGER(KIND=selected_int_kind(18))) :: fn
244
INTEGER(KIND=AddrInt) :: addr
245
246
TYPE(C_FUNPTR) :: cptr
247
cptr = C_FUNLOC(fn)
248
addr = TRANSFER(cptr, addr)
249
END FUNCTION AddrFuncLong
250
251
FUNCTION AddrFuncReal(fn) RESULT(addr)
252
IMPLICIT NONE
253
PROCEDURE(REAL(KIND=SELECTED_REAL_KIND(6))) :: fn
254
INTEGER(KIND=AddrInt) :: addr
255
256
TYPE(C_FUNPTR) :: cptr
257
cptr = C_FUNLOC(fn)
258
addr = TRANSFER(cptr, addr)
259
END FUNCTION AddrFuncReal
260
261
FUNCTION AddrFuncDbl(fn) RESULT(addr)
262
IMPLICIT NONE
263
PROCEDURE(REAL(KIND=dp)) :: fn
264
INTEGER(KIND=AddrInt) :: addr
265
266
TYPE(C_FUNPTR) :: cptr
267
cptr = C_FUNLOC(fn)
268
addr = TRANSFER(cptr, addr)
269
END FUNCTION AddrFuncDbl
270
271
FUNCTION AddrFuncCmp(fn) RESULT(addr)
272
IMPLICIT NONE
273
PROCEDURE(COMPLEX(KIND=SELECTED_REAL_KIND(6))) :: fn
274
INTEGER(KIND=AddrInt) :: addr
275
276
TYPE(C_FUNPTR) :: cptr
277
cptr = C_FUNLOC(fn)
278
addr = TRANSFER(cptr, addr)
279
END FUNCTION AddrFuncCmp
280
281
FUNCTION AddrFuncDblCmp(fn) RESULT(addr)
282
IMPLICIT NONE
283
PROCEDURE(COMPLEX(KIND=dp)) :: fn
284
INTEGER(KIND=AddrInt) :: addr
285
286
TYPE(C_FUNPTR) :: cptr
287
cptr = C_FUNLOC(fn)
288
addr = TRANSFER(cptr, addr)
289
END FUNCTION AddrFuncDblCmp
290
#endif
291
292
! DYNAMIC LOADING (wrapper via module procedure for typecasting)
293
FUNCTION loadfunction(quiet, abort_not_found, library, fname,mangle) RESULT(ptr)
294
IMPLICIT NONE
295
INTEGER :: quiet, abort_not_found, mangle
296
CHARACTER :: library(*), fname(*)
297
! TYPE(C_FUNPTR) :: ptr
298
INTEGER(KIND=AddrInt) :: ptr
299
TYPE(C_PTR) :: cptr
300
301
INTERFACE
302
FUNCTION loadfunction_c(quiet, abort_not_found, library, fname, mangle ) RESULT(cptr) &
303
BIND(C,name='loadfunction_c')
304
USE, INTRINSIC :: ISO_C_BINDING
305
INTEGER(C_INT) :: quiet
306
INTEGER(C_INT) :: abort_not_found, mangle
307
CHARACTER(C_CHAR) :: library(*), fname(*)
308
! INTEGER(CAddrInt) :: fptr
309
TYPE(C_PTR) :: cptr
310
END FUNCTION loadfunction_c
311
END INTERFACE
312
313
! Ugly hack, store C function pointer as integer
314
cptr = loadfunction_c(quiet, abort_not_found, library, fname, mangle)
315
ptr = TRANSFER(cptr, ptr)
316
END FUNCTION loadfunction
317
318
! DYNAMIC FUNCTION CALLS (wrappers via module procedures)
319
RECURSIVE FUNCTION execintfunction(fptr, model ) RESULT(intval)
320
IMPLICIT NONE
321
INTEGER(KIND=AddrInt) :: fptr
322
TYPE(Model_t), POINTER :: model
323
INTEGER :: intval
324
325
INTERFACE
326
FUNCTION ElmerIntFn(model) RESULT(intval)
327
IMPORT Model_t
328
TYPE(Model_t) :: model
329
INTEGER :: intval
330
END FUNCTION ElmerIntFn
331
END INTERFACE
332
TYPE(C_FUNPTR) :: cfptr
333
PROCEDURE(ElmerIntFn), POINTER :: pptr
334
335
! Ugly hack, fptr should be stored as C function pointer
336
cfptr = TRANSFER(fptr, cfptr)
337
CALL C_F_PROCPOINTER(cfptr, pptr)
338
intval = pptr(model)
339
END FUNCTION execintfunction
340
341
RECURSIVE FUNCTION execconstrealfunction(fptr, model, x, y, z) RESULT(realval)
342
IMPLICIT NONE
343
INTEGER(KIND=AddrInt) :: fptr
344
TYPE(Model_t), POINTER :: model
345
REAL(KIND=dp) :: x, y, z
346
REAL(KIND=dp) :: realval
347
348
INTERFACE
349
FUNCTION ElmerConstRealFn(model, x, y, z) RESULT(realval)
350
IMPORT Model_t, dp
351
TYPE(Model_t) :: model
352
REAL(KIND=dp) :: x, y, z
353
REAL(KIND=dp) :: realval
354
END FUNCTION ElmerConstRealFn
355
END INTERFACE
356
TYPE(C_FUNPTR) :: cfptr
357
PROCEDURE(ElmerConstRealFn), POINTER :: pptr
358
359
! Ugly hack, fptr should be stored as C function pointer
360
cfptr = TRANSFER(fptr, cfptr)
361
CALL C_F_PROCPOINTER(cfptr, pptr)
362
realval = pptr(model, x, y, z)
363
END FUNCTION execconstrealfunction
364
365
RECURSIVE FUNCTION execrealfunction(fptr, model, node, val) RESULT(realval)
366
IMPLICIT NONE
367
INTEGER(KIND=AddrInt) :: fptr
368
TYPE(Model_t), POINTER :: model
369
INTEGER :: node
370
REAL(KIND=dp) :: val(*)
371
REAL(KIND=dp) :: realval
372
373
INTERFACE
374
FUNCTION ElmerRealFn(model, node, val ) RESULT(realval)
375
IMPORT Model_t, dp
376
TYPE(Model_t) :: model
377
INTEGER :: node
378
REAL(KIND=dp) :: val(*)
379
REAL(KIND=dp) :: realval
380
END FUNCTION ElmerRealFn
381
END INTERFACE
382
TYPE(C_FUNPTR) :: cfptr
383
PROCEDURE(ElmerRealFn), POINTER :: pptr
384
385
! Ugly hack, fptr should be stored as C function pointer
386
cfptr = TRANSFER(fptr, cfptr)
387
CALL C_F_PROCPOINTER(cfptr, pptr)
388
realval = pptr(model, node, val)
389
END FUNCTION execrealfunction
390
391
RECURSIVE SUBROUTINE execrealarrayfunction(fptr, model, node, val, arr )
392
IMPLICIT NONE
393
INTEGER(KIND=AddrInt) :: fptr
394
TYPE(Model_t), POINTER :: model
395
INTEGER :: node
396
REAL(KIND=dp) :: val(*)
397
REAL(KIND=dp) :: arr(:,:)
398
399
INTERFACE
400
SUBROUTINE ElmerRealArrFn(model, node, val, arr)
401
IMPORT Model_t, dp
402
TYPE(Model_t) :: model
403
INTEGER :: node
404
REAL(KIND=dp) :: val(*)
405
REAL(KIND=dp) :: arr(:,:)
406
END SUBROUTINE ElmerRealArrFn
407
END INTERFACE
408
TYPE(C_FUNPTR) :: cfptr
409
PROCEDURE(ElmerRealArrFn), POINTER :: pptr
410
411
! Ugly hack, fptr should be stored as C function pointer
412
cfptr = TRANSFER(fptr, cfptr)
413
CALL C_F_PROCPOINTER(cfptr, pptr)
414
CALL pptr(model, node, val, arr)
415
END SUBROUTINE execrealarrayfunction
416
417
RECURSIVE SUBROUTINE execrealvectorfunction(fptr, model, node, val, arr )
418
IMPLICIT NONE
419
INTEGER(KIND=AddrInt) :: fptr
420
TYPE(Model_t), POINTER :: model
421
INTEGER :: node
422
REAL(KIND=dp) :: val(*), arr(:)
423
424
INTERFACE
425
SUBROUTINE ElmerRealArrFn(model, node, val, arr)
426
IMPORT Model_t, dp
427
TYPE(Model_t) :: model
428
INTEGER :: node
429
REAL(KIND=dp) :: val(*), arr(:)
430
END SUBROUTINE ElmerRealArrFn
431
END INTERFACE
432
TYPE(C_FUNPTR) :: cfptr
433
PROCEDURE(ElmerRealArrFn), POINTER :: pptr
434
435
! Ugly hack, fptr should be stored as C function pointer
436
cfptr = TRANSFER(fptr, cfptr)
437
CALL C_F_PROCPOINTER(cfptr, pptr)
438
CALL pptr(model, node, val, arr)
439
END SUBROUTINE execrealvectorfunction
440
441
RECURSIVE SUBROUTINE execsolver(fptr, model, solver, dt, transient)
442
IMPLICIT NONE
443
INTEGER(KIND=AddrInt) :: fptr
444
TYPE(Model_t) :: model
445
TYPE(Solver_t) :: solver
446
REAL(KIND=dp) :: dt
447
LOGICAL :: transient
448
449
INTERFACE
450
SUBROUTINE ElmerSolverFn(model, solver, dt, transient)
451
IMPORT Solver_t, Model_t, dp
452
TYPE(Model_t) :: model
453
TYPE(Solver_t) :: solver
454
REAL(KIND=dp) :: dt
455
LOGICAL :: transient
456
END SUBROUTINE ElmerSolverFn
457
END INTERFACE
458
TYPE(C_FUNPTR) :: cfptr
459
PROCEDURE(ElmerSolverFn), POINTER :: pptr
460
461
! Ugly hack, fptr should be stored as C function pointer
462
cfptr = TRANSFER(fptr, cfptr)
463
CALL C_F_PROCPOINTER(cfptr, pptr)
464
CALL pptr(model, solver, dt, transient)
465
END SUBROUTINE execsolver
466
467
468
SUBROUTINE execmortarprojector(fptr, mesh, slavemesh, mastermesh, bcind, projector )
469
IMPLICIT NONE
470
INTEGER(KIND=AddrInt) :: fptr
471
TYPE(Mesh_t) :: mesh, slavemesh, mastermesh
472
INTEGER :: bcind
473
TYPE(Matrix_t) :: projector
474
475
INTERFACE
476
SUBROUTINE MortarProjectorFn(mesh, slavemesh, mastermesh, bcind, projector )
477
IMPORT Mesh_t, Matrix_t
478
TYPE(Mesh_t) :: mesh, slavemesh, mastermesh
479
INTEGER :: bcind
480
TYPE(Matrix_t) :: projector
481
END SUBROUTINE MortarProjectorFn
482
END INTERFACE
483
TYPE(C_FUNPTR) :: cfptr
484
PROCEDURE(MortarProjectorFn), POINTER :: pptr
485
486
! Ugly hack, fptr should be stored as C function pointer
487
cfptr = TRANSFER(fptr, cfptr)
488
CALL C_F_PROCPOINTER(cfptr, pptr)
489
CALL pptr(mesh, slavemesh, mastermesh, bcind, projector )
490
END SUBROUTINE execmortarprojector
491
492
FUNCTION enhancementfactoruserfunction( fptr, model, element, nodes, n, nd, &
493
Basis, dBasisdx, Viscosity,Velo, dVelodx,sinvsq,localip ) &
494
RESULT(realval)
495
IMPLICIT NONE
496
INTEGER(KIND=AddrInt) :: fptr
497
TYPE(Model_t) :: model
498
TYPE(Element_t), POINTER :: element
499
TYPE(Nodes_t) :: nodes
500
INTEGER :: n,nd,localip
501
REAL(KIND=dp) :: Basis(:),dBasisdx(:,:),Viscosity, &
502
Velo(:), dVelodx(:,:),sinvsq
503
REAL(KIND=dp) :: realval
504
505
INTERFACE
506
FUNCTION ElmerEnhancemntFactorFn(model, element, nodes, n, nd, &
507
Basis, dBasisdx, Viscosity, Velo, dVelodx, sinvsq,localip) RESULT(realval)
508
IMPORT Model_t, Element_t, Nodes_t, dp
509
TYPE(Model_t) :: model
510
TYPE(Element_t), POINTER :: element
511
TYPE(Nodes_t) :: nodes
512
INTEGER :: n,nd,localip
513
REAL(KIND=dp) :: Basis(:),dBasisdx(:,:),Viscosity, &
514
Velo(:), dVelodx(:,:), sinvsq
515
REAL(KIND=dp) :: realval
516
END FUNCTION ElmerEnhancemntFactorFn
517
END INTERFACE
518
TYPE(C_FUNPTR) :: cfptr
519
PROCEDURE(ElmerEnhancemntFactorFn), POINTER :: pptr
520
521
! Ugly hack, fptr should be stored as C function pointer
522
cfptr = TRANSFER(fptr, cfptr)
523
CALL C_F_PROCPOINTER(cfptr, pptr)
524
realval = pptr(model, element, nodes, n, nd, &
525
Basis, dBasisdx, Viscosity,Velo, dVelodx,sinvsq,localip)
526
END FUNCTION enhancementfactoruserfunction
527
528
529
FUNCTION materialuserfunction( fptr, model, element, nodes, n, nd, &
530
Basis, dBasisdx, Viscosity,Velo, dVelodx ) &
531
RESULT(realval)
532
IMPLICIT NONE
533
INTEGER(KIND=AddrInt) :: fptr
534
TYPE(Model_t) :: model
535
TYPE(Element_t), POINTER :: element
536
TYPE(Nodes_t) :: nodes
537
INTEGER :: n,nd
538
REAL(KIND=dp) :: Basis(:),dBasisdx(:,:),Viscosity, &
539
Velo(:), dVelodx(:,:)
540
REAL(KIND=dp) :: realval
541
542
INTERFACE
543
FUNCTION ElmerMaterialFn(model, element, nodes, n, nd, &
544
Basis, dBasisdx, Viscosity, Velo, dVelodx) RESULT(realval)
545
IMPORT Model_t, Element_t, Nodes_t, dp
546
TYPE(Model_t) :: model
547
TYPE(Element_t), POINTER :: element
548
TYPE(Nodes_t) :: nodes
549
INTEGER :: n,nd
550
REAL(KIND=dp) :: Basis(:),dBasisdx(:,:),Viscosity, &
551
Velo(:), dVelodx(:,:)
552
REAL(KIND=dp) :: realval
553
END FUNCTION ElmerMaterialFn
554
END INTERFACE
555
TYPE(C_FUNPTR) :: cfptr
556
PROCEDURE(ElmerMaterialFn), POINTER :: pptr
557
558
! Ugly hack, fptr should be stored as C function pointer
559
cfptr = TRANSFER(fptr, cfptr)
560
CALL C_F_PROCPOINTER(cfptr, pptr)
561
realval = pptr(model, element, nodes, n, nd, &
562
Basis, dBasisdx, Viscosity,Velo, dVelodx)
563
END FUNCTION materialuserfunction
564
565
SUBROUTINE execsimulationproc(fptr, model)
566
IMPLICIT NONE
567
INTEGER(KIND=AddrInt) :: fptr
568
TYPE(Model_t) :: model
569
570
INTERFACE
571
SUBROUTINE ElmerSimulationFn(model)
572
IMPORT Model_t
573
TYPE(Model_t) :: model
574
END SUBROUTINE ElmerSimulationFn
575
END INTERFACE
576
TYPE(C_FUNPTR) :: cfptr
577
PROCEDURE(ElmerSimulationFn), POINTER :: pptr
578
579
! Ugly hack, fptr should be stored as C function pointer
580
cfptr = TRANSFER(fptr, cfptr)
581
CALL C_F_PROCPOINTER(cfptr, pptr)
582
CALL pptr(model)
583
END SUBROUTINE execsimulationproc
584
585
RECURSIVE FUNCTION execlinsolveprocs(fptr, model, solver, mtr, b, x, n, DOFs, nrm) RESULT(intval)
586
IMPLICIT NONE
587
INTEGER(KIND=AddrInt) :: fptr
588
TYPE(Model_t) :: model
589
TYPE(Solver_t) :: solver
590
TYPE(Matrix_t), POINTER :: mtr
591
INTEGER :: n, DOFs
592
REAL(KIND=dp) :: x(n), b(n), nrm
593
INTEGER :: intval
594
595
INTERFACE
596
FUNCTION ElmerLinSolveFn(model, solver, mtr, b, x, n, DOFs, nrm) RESULT(intval)
597
IMPORT Solver_t, Model_t, Matrix_t, dp
598
TYPE(Model_t) :: model
599
TYPE(Solver_t) :: solver
600
TYPE(Matrix_t), POINTER :: mtr
601
INTEGER :: n, DOFs
602
REAL(KIND=dp) :: x(n),b(n), nrm
603
INTEGER :: intval
604
END FUNCTION ElmerLinSolveFn
605
END INTERFACE
606
TYPE(C_FUNPTR) :: cfptr
607
PROCEDURE(ElmerLinSolveFn), POINTER :: pptr
608
609
! Ugly hack, fptr should be stored as C function pointer
610
cfptr = TRANSFER(fptr, cfptr)
611
CALL C_F_PROCPOINTER(cfptr, pptr)
612
intval = pptr(model, solver, mtr, b, x, n, DOFs, nrm)
613
END FUNCTION execlinsolveprocs
614
615
SUBROUTINE execlocalproc(fptr, model, solver, G, F, element, n, nd)
616
IMPLICIT NONE
617
INTEGER(KIND=AddrInt) :: fptr
618
TYPE(Model_t) :: model
619
TYPE(Solver_t) :: solver
620
REAL(KIND=dp) :: G(:,:), F(:)
621
TYPE(Element_t) :: element
622
INTEGER :: n, nd
623
624
INTERFACE
625
SUBROUTINE ElmerLocalFn(model, solver, G, F, element, n, nd)
626
IMPORT Model_t, Solver_t, Element_t, dp
627
TYPE(Model_t) :: model
628
TYPE(Solver_t) :: solver
629
REAL(KIND=dp) :: G(:,:), F(:)
630
TYPE(Element_t) :: element
631
INTEGER :: n, nd
632
END SUBROUTINE ElmerLocalFn
633
END INTERFACE
634
TYPE(C_FUNPTR) :: cfptr
635
PROCEDURE(ElmerLocalFn), POINTER :: pptr
636
637
! Ugly hack, fptr should be stored as C function pointer
638
cfptr = TRANSFER(fptr, cfptr)
639
CALL C_F_PROCPOINTER(cfptr, pptr)
640
CALL pptr(model, solver, G, F, element, n, nd)
641
END SUBROUTINE execlocalproc
642
643
SUBROUTINE execlocalassembly(fptr, model, solver, dt, transient, &
644
M, D, S, F, element, nrow, ncol)
645
IMPLICIT NONE
646
INTEGER(KIND=AddrInt) :: fptr
647
TYPE(Model_t) :: model
648
TYPE(Solver_t) :: solver
649
REAL(KIND=dp) :: dt
650
LOGICAL :: transient
651
REAL(KIND=dp) :: M(:,:), D(:,:), S(:,:), F(:)
652
TYPE(Element_t) :: element
653
INTEGER :: nrow, ncol
654
655
INTERFACE
656
SUBROUTINE ElmerLocalAssemblyFn(model, solver, dt, transient, &
657
M, D, S, F, element, Nrow, Ncol )
658
IMPORT Model_t, Solver_t, Element_t, dp
659
TYPE(Model_t) :: model
660
TYPE(Solver_t) :: solver
661
REAL(KIND=dp) :: dt
662
LOGICAL :: transient
663
REAL(KIND=dp) :: M(:,:), D(:,:), S(:,:), F(:)
664
TYPE(Element_t) :: element
665
INTEGER :: nrow, ncol
666
END SUBROUTINE ElmerLocalAssemblyFn
667
END INTERFACE
668
TYPE(C_FUNPTR) :: cfptr
669
PROCEDURE(ElmerLocalAssemblyFn), POINTER :: pptr
670
671
! Ugly hack, fptr should be stored as C function pointer
672
cfptr = TRANSFER(fptr, cfptr)
673
CALL C_F_PROCPOINTER(cfptr, pptr)
674
CALL pptr(model, solver, dt, transient, &
675
M, D, S, F, element, nrow, ncol)
676
END SUBROUTINE execlocalassembly
677
678
SUBROUTINE matvecsubrext(fptr, spmv, n, rows, cols, vals, u, v, reinit)
679
IMPLICIT NONE
680
681
INTEGER(KIND=AddrInt) :: fptr
682
INTEGER(KIND=AddrInt) :: spmv
683
INTEGER :: n
684
INTEGER, POINTER CONTIG :: rows(:), cols(:)
685
REAL(KIND=dp), POINTER CONTIG :: vals(:)
686
REAL(KIND=dp), DIMENSION(*) :: u
687
REAL(KIND=dp), DIMENSION(*) :: v
688
INTEGER :: reinit
689
690
INTERFACE
691
SUBROUTINE matvecsubrext_c(fptr, spmv, n, rows, cols, vals, u, v, reinit) &
692
BIND(C,name='matvecsubrext_c')
693
USE, INTRINSIC :: ISO_C_BINDING
694
INTEGER(CAddrInt) :: fptr
695
INTEGER(CAddrInt) :: spmv
696
INTEGER(C_INT) :: n
697
INTEGER(C_INT) :: rows(*), cols(*)
698
REAL(C_DOUBLE) :: vals(*)
699
REAL(C_DOUBLE) :: u(*),v(*)
700
INTEGER(C_INT) :: reinit
701
END SUBROUTINE
702
END INTERFACE
703
704
! TODO: interface should be properly tested
705
CALL matvecsubrext_c(fptr, spmv, n, rows, cols, vals, u, v, reinit)
706
END SUBROUTINE matvecsubrext
707
708
RECURSIVE SUBROUTINE itercallR(fptr, x, b, ipar, dpar, work, &
709
mvptr, pcondptr, pcondrptr, dotptr, normptr, stopcptr )
710
IMPLICIT NONE
711
712
INTEGER(KIND=AddrInt) :: fptr
713
REAL(KIND=dp), DIMENSION(:) CONTIG :: x,b
714
INTEGER :: ipar(50)
715
REAL(KIND=dp) :: dpar(50)
716
REAL(KIND=dp) :: work(:,:)
717
INTEGER(KIND=Addrint) :: mvptr, pcondptr, pcondrptr, &
718
dotptr, normptr, stopcptr
719
INTERFACE
720
SUBROUTINE itercall_c(fptr, x, b, ipar, dpar, work, &
721
mvptr, pcondptr, pcondrptr, dotptr, normptr, stopcptr ) &
722
BIND(C,name='itercall_c')
723
USE, INTRINSIC :: ISO_C_BINDING
724
INTEGER(CAddrInt) :: fptr
725
REAL(C_DOUBLE) :: x(*), b(*)
726
INTEGER(C_INT) :: ipar(50)
727
REAL(C_DOUBLE) :: dpar(50)
728
REAL(C_DOUBLE) :: work(*)
729
INTEGER(CAddrInt) :: mvptr, pcondptr, pcondrptr, dotptr, &
730
normptr, stopcptr
731
END SUBROUTINE itercall_c
732
END INTERFACE
733
734
CALL itercall_c(fptr, x, b, ipar, dpar, work, &
735
mvptr, pcondptr, pcondrptr, dotptr, normptr, stopcptr)
736
END SUBROUTINE itercallR
737
738
RECURSIVE SUBROUTINE itercallC(fptr, x, b, ipar, dpar, work, &
739
mvptr, pcondptr, pcondrptr, dotptr, normptr, stopcptr )
740
IMPLICIT NONE
741
742
INTEGER(KIND=AddrInt) :: fptr
743
COMPLEX(KIND=dp), DIMENSION(:) CONTIG :: x,b
744
INTEGER :: ipar(50)
745
REAL(KIND=dp) :: dpar(50)
746
REAL(KIND=dp) :: work(:,:)
747
INTEGER(KIND=Addrint) :: mvptr, pcondptr, pcondrptr, &
748
dotptr, normptr, stopcptr
749
INTERFACE
750
SUBROUTINE itercall_c(fptr, x, b, ipar, dpar, work, &
751
mvptr, pcondptr, pcondrptr, dotptr, normptr, stopcptr ) &
752
BIND(C,name='itercall_c')
753
USE, INTRINSIC :: ISO_C_BINDING
754
INTEGER(CAddrInt) :: fptr
755
COMPLEX(C_DOUBLE_COMPLEX) :: x(*), b(*)
756
INTEGER(C_INT) :: ipar(50)
757
REAL(C_DOUBLE) :: dpar(50)
758
REAL(C_DOUBLE) :: work(*)
759
INTEGER(CAddrInt) :: mvptr, pcondptr, pcondrptr, dotptr, &
760
normptr, stopcptr
761
END SUBROUTINE itercall_c
762
END INTERFACE
763
764
CALL itercall_c(fptr, x, b, ipar, dpar, work, &
765
mvptr, pcondptr, pcondrptr, dotptr, normptr, stopcptr)
766
END SUBROUTINE itercallC
767
768
RECURSIVE SUBROUTINE itercallFTNR(fptr, x, b, ipar, dpar, work, &
769
mvptr, pcondptr, pcondrptr, dotptr, normptr, stopcptr )
770
IMPLICIT NONE
771
772
INTEGER(KIND=AddrInt) :: fptr
773
REAL(KIND=dp), DIMENSION(:) CONTIG :: x,b
774
INTEGER :: ipar(HUTI_IPAR_DFLTSIZE)
775
REAL(KIND=dp) :: dpar(HUTI_DPAR_DFLTSIZE)
776
REAL(KIND=dp) :: work(:,:)
777
INTEGER(KIND=Addrint) :: mvptr, pcondptr, pcondrptr, &
778
dotptr, normptr, stopcptr
779
780
781
TYPE(C_FUNPTR) :: cfptr
782
PROCEDURE(mv_iface_d), POINTER :: mvfun
783
PROCEDURE(pc_iface_d), POINTER :: pcondfun, pcondrfun
784
PROCEDURE(dotp_iface_d), POINTER :: dotfun
785
PROCEDURE(norm_iface_d), POINTER :: normfun
786
PROCEDURE(stopc_iface_d), POINTER :: stopcfun
787
PROCEDURE(huti_itercall_d), POINTER :: iterfun
788
789
! Initialize pointers
790
mvfun => NULL()
791
pcondfun => NULL()
792
pcondrfun => NULL()
793
dotfun => NULL()
794
normfun => NULL()
795
iterfun => NULL()
796
797
! Transfer address integers back to Fortran function pointers
798
799
! Matrix-vector operator
800
cfptr = TRANSFER(mvptr, cfptr)
801
CALL C_F_PROCPOINTER(cfptr, mvfun)
802
! Preconditioner operators
803
cfptr = TRANSFER(pcondptr, cfptr)
804
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, pcondfun)
805
cfptr = TRANSFER(pcondrptr, cfptr)
806
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, pcondrfun)
807
! Dot product operator
808
cfptr = TRANSFER(dotptr, cfptr)
809
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, dotfun)
810
! Norm operator
811
cfptr = TRANSFER(normptr, cfptr)
812
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, normfun)
813
! Stopping criterion operator
814
cfptr = TRANSFER(stopcptr, cfptr)
815
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, stopcfun)
816
817
! Finally, do the itercall
818
cfptr = TRANSFER(fptr, cfptr)
819
CALL C_F_PROCPOINTER(cfptr, iterfun)
820
CALL iterfun(x, b, ipar, dpar, work, &
821
mvfun, pcondfun, pcondrfun, dotfun, normfun, stopcfun)
822
END SUBROUTINE itercallFTNR
823
824
RECURSIVE SUBROUTINE itercallFTNC(fptr, x, b, ipar, dpar, work, &
825
mvptr, pcondptr, pcondrptr, dotptr, normptr, stopcptr )
826
IMPLICIT NONE
827
828
INTEGER(KIND=AddrInt) :: fptr
829
COMPLEX(KIND=dp), DIMENSION(:) CONTIG :: x,b
830
INTEGER :: ipar(HUTI_IPAR_DFLTSIZE)
831
REAL(KIND=dp) :: dpar(HUTI_DPAR_DFLTSIZE)
832
COMPLEX(KIND=dp) :: work(:,:)
833
INTEGER(KIND=Addrint) :: mvptr, pcondptr, pcondrptr, &
834
dotptr, normptr, stopcptr
835
836
837
TYPE(C_FUNPTR) :: cfptr
838
PROCEDURE(mv_iface_z), POINTER :: mvfun
839
PROCEDURE(pc_iface_z), POINTER :: pcondfun, pcondrfun
840
PROCEDURE(dotp_iface_z), POINTER :: dotfun
841
PROCEDURE(norm_iface_z), POINTER :: normfun
842
PROCEDURE(stopc_iface_z), POINTER :: stopcfun
843
PROCEDURE(huti_itercall_z), POINTER :: iterfun
844
845
! Initialize pointers
846
mvfun => NULL()
847
pcondfun => NULL()
848
pcondrfun => NULL()
849
dotfun => NULL()
850
normfun => NULL()
851
iterfun => NULL()
852
853
! Transfer address integers back to Fortran function pointers
854
855
! Matrix-vector operator
856
cfptr = TRANSFER(mvptr, cfptr)
857
CALL C_F_PROCPOINTER(cfptr, mvfun)
858
! Preconditioner operators
859
cfptr = TRANSFER(pcondptr, cfptr)
860
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, pcondfun)
861
cfptr = TRANSFER(pcondrptr, cfptr)
862
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, pcondrfun)
863
! Dot product operator
864
cfptr = TRANSFER(dotptr, cfptr)
865
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, dotfun)
866
! Norm operator
867
cfptr = TRANSFER(normptr, cfptr)
868
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, normfun)
869
! Stopping criterion operator
870
cfptr = TRANSFER(stopcptr, cfptr)
871
IF (C_ASSOCIATED(cfptr)) CALL C_F_PROCPOINTER(cfptr, stopcfun)
872
873
! Finally, do the itercall
874
cfptr = TRANSFER(fptr, cfptr)
875
CALL C_F_PROCPOINTER(cfptr, iterfun)
876
CALL iterfun(x, b, ipar, dpar, work, &
877
mvfun, pcondfun, pcondrfun, dotfun, normfun, stopcfun)
878
END SUBROUTINE itercallFTNC
879
880
881
SUBROUTINE UMATusersubrtn( fptr, &
882
STRESS, STATEV, DDSDDE, SSE, SPD, SCD, &
883
rpl, ddsddt, drplde, drpldt, STRAN, DSTRAN, TIME, DTIME, TEMP, dTemp, &
884
predef, dpred, CMNAME, NDI, NSHR, NTENS, NSTATEV, PROPS, NPROPS, &
885
coords, drot, pnewdt, celent, DFRGRD0, DFRGRD1, NOEL, NPT, layer, kspt, &
886
kstep, kinc)
887
888
IMPLICIT NONE
889
890
INTEGER(KIND=AddrInt) :: fptr
891
REAL(KIND=dp), INTENT(INOUT) :: STRESS(NTENS)
892
REAL(KIND=dp), INTENT(INOUT) :: STATEV(NSTATEV)
893
REAL(KIND=dp), INTENT(OUT) :: DDSDDE(NTENS,NTENS)
894
REAL(KIND=dp), INTENT(INOUT) :: SSE, SPD, SCD
895
REAL(KIND=dp), INTENT(OUT) :: rpl
896
REAL(KIND=dp), INTENT(OUT) :: ddsddt(NTENS), drplde(NTENS), drpldt
897
REAL(KIND=dp), INTENT(IN) :: STRAN(NTENS)
898
REAL(KIND=dp), INTENT(IN) :: DSTRAN(NTENS)
899
REAL(KIND=dp), INTENT(IN) :: TIME(2)
900
REAL(KIND=dp), INTENT(IN) :: DTIME
901
REAL(KIND=dp), INTENT(IN) :: TEMP
902
REAL(KIND=dp), INTENT(IN) :: dtemp
903
REAL(KIND=dp), INTENT(IN) :: predef(1), dpred(1)
904
CHARACTER(len=80), INTENT(IN) :: CMNAME
905
INTEGER, INTENT(IN) :: NDI
906
INTEGER, INTENT(IN) :: NSHR
907
INTEGER, INTENT(IN) :: NTENS
908
INTEGER, INTENT(IN) :: NSTATEV
909
REAL(KIND=dp), INTENT(IN) :: PROPS(NPROPS)
910
INTEGER, INTENT(IN) :: NPROPS
911
REAL(KIND=dp), INTENT(IN) :: coords(3)
912
REAL(KIND=dp), INTENT(IN) :: drot(3,3)
913
REAL(KIND=dp), INTENT(INOUT) :: pnewdt
914
REAL(KIND=dp), INTENT(IN) :: celent
915
REAL(KIND=dp), INTENT(IN) :: DFRGRD0(3,3)
916
REAL(KIND=dp), INTENT(IN) :: DFRGRD1(3,3)
917
INTEGER, INTENT(IN) :: NOEL
918
INTEGER, INTENT(IN) :: NPT
919
INTEGER, INTENT(IN) :: layer, kspt, kstep, kinc
920
921
INTERFACE
922
SUBROUTINE UMATsubrtn( STRESS, STATEV, DDSDDE, SSE, SPD, SCD, &
923
rpl, ddsddt, drplde, drpldt, STRAN, DSTRAN, TIME, DTIME, TEMP, dTemp, &
924
predef, dpred, CMNAME, NDI, NSHR, NTENS, NSTATEV, PROPS, NPROPS, &
925
coords, drot, pnewdt, celent, DFRGRD0, DFRGRD1, NOEL, NPT, layer, kspt, &
926
kstep, kinc)
927
928
USE Types
929
IMPLICIT NONE
930
931
REAL(KIND=dp), INTENT(INOUT) :: STRESS(NTENS)
932
REAL(KIND=dp), INTENT(INOUT) :: STATEV(NSTATEV)
933
REAL(KIND=dp), INTENT(OUT) :: DDSDDE(NTENS,NTENS)
934
REAL(KIND=dp), INTENT(INOUT) :: SSE, SPD, SCD
935
REAL(KIND=dp), INTENT(OUT) :: rpl
936
REAL(KIND=dp), INTENT(OUT) :: ddsddt(NTENS), drplde(NTENS), drpldt
937
REAL(KIND=dp), INTENT(IN) :: STRAN(NTENS)
938
REAL(KIND=dp), INTENT(IN) :: DSTRAN(NTENS)
939
REAL(KIND=dp), INTENT(IN) :: TIME(2)
940
REAL(KIND=dp), INTENT(IN) :: DTIME
941
REAL(KIND=dp), INTENT(IN) :: TEMP
942
REAL(KIND=dp), INTENT(IN) :: dtemp
943
REAL(KIND=dp), INTENT(IN) :: predef(1), dpred(1)
944
CHARACTER(len=80), INTENT(IN) :: CMNAME
945
INTEGER, INTENT(IN) :: NDI
946
INTEGER, INTENT(IN) :: NSHR
947
INTEGER, INTENT(IN) :: NTENS
948
INTEGER, INTENT(IN) :: NSTATEV
949
REAL(KIND=dp), INTENT(IN) :: PROPS(NPROPS)
950
INTEGER, INTENT(IN) :: NPROPS
951
REAL(KIND=dp), INTENT(IN) :: coords(3)
952
REAL(KIND=dp), INTENT(IN) :: drot(3,3)
953
REAL(KIND=dp), INTENT(INOUT) :: pnewdt
954
REAL(KIND=dp), INTENT(IN) :: celent
955
REAL(KIND=dp), INTENT(IN) :: DFRGRD0(3,3)
956
REAL(KIND=dp), INTENT(IN) :: DFRGRD1(3,3)
957
INTEGER, INTENT(IN) :: NOEL
958
INTEGER, INTENT(IN) :: NPT
959
INTEGER, INTENT(IN) :: layer, kspt, kstep, kinc
960
END SUBROUTINE UMATsubrtn
961
END INTERFACE
962
963
964
TYPE(C_FUNPTR) :: cfptr
965
PROCEDURE(UMATsubrtn), POINTER :: pptr
966
967
! Ugly hack, fptr should be stored as C function pointer
968
cfptr = TRANSFER(fptr, cfptr)
969
CALL C_F_PROCPOINTER(cfptr, pptr)
970
971
CALL pptr( STRESS, STATEV, DDSDDE, SSE, SPD, SCD, &
972
rpl, ddsddt, drplde, drpldt, STRAN, DSTRAN, TIME, DTIME, TEMP, dTemp, &
973
predef, dpred, CMNAME, NDI, NSHR, NTENS, NSTATEV, PROPS, NPROPS, &
974
coords, drot, pnewdt, celent, DFRGRD0, DFRGRD1, NOEL, NPT, layer, kspt, &
975
kstep, kinc )
976
END SUBROUTINE UMATusersubrtn
977
978
979
END MODULE LoadMod
980
981