Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/fem/src/Load.c
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
! * Utilities for dynamic loading of user functions, and other operating
25
! * system interfaces.
26
! *
27
! ******************************************************************************
28
! *
29
! * Authors: Juha Ruokolainen
30
! * Email: [email protected]
31
! * Web: http://www.csc.fi/elmer
32
! * Address: CSC - IT Center for Science Ltd.
33
! * Keilaranta 14
34
! * 02101 Espoo, Finland
35
! *
36
! * Original Date: 02 Jun 1997
37
! *
38
! *****************************************************************************/
39
40
#include <stdio.h>
41
#include <stdlib.h>
42
#include <string.h>
43
#include <stdint.h>
44
/* #include <elmer/matc.h> maybe in the future */
45
46
/* eg. FC_CHAR_PTR and FC_FUNC is defined here */
47
48
#include "../config.h"
49
50
#if defined(WIN32) | defined(MINGW32)
51
# include <direct.h>
52
# include <windows.h>
53
#define ELMER_PATH_SEPARATOR ";"
54
#else
55
#include <strings.h>
56
# include <dlfcn.h>
57
# include <sys/stat.h>
58
#define ELMER_PATH_SEPARATOR ":"
59
#endif
60
61
#define MAX_PATH_LEN 512
62
#define ERROR_BUF_LEN 10*MAX_PATH_LEN
63
64
/* pc needs more bits on 64bit arch */
65
#ifdef ARCH_32_BITS
66
#define f_ptr int32_t *
67
#else
68
#define f_ptr int64_t *
69
#endif
70
71
/*#if defined(MINGW32)*/
72
/*--------------------------------------------------------------------------
73
work around mingw rxvt shell stdio/err buffering troubles
74
-------------------------------------------------------------------------*/
75
/*void STDCALLBULL FC_FUNC_(set_stdio_bufs,SET_STDIO_BUFS) ()*/
76
/*[>void set_stdio_bufs_()<]*/
77
/*{*/
78
/*setvbuf( stdout, NULL, _IOLBF, 2048 );*/
79
/*setvbuf( stderr, NULL, _IONBF, 2048 );*/
80
/*}*/
81
/*#endif*/
82
83
/*--------------------------------------------------------------------------
84
This routine will return the home directory of elmer solver.
85
-------------------------------------------------------------------------*/
86
#ifdef USE_ISO_C_BINDINGS
87
void STDCALLBULL getsolverhome( char *solverDir, int *len)
88
#else
89
void STDCALLBULL FC_FUNC(getsolverhome,GETSOLVERHOME)
90
( char *solverDir, int *len)
91
#endif
92
{
93
*len = 0;
94
95
char *elmer_home = getenv("ELMER_HOME");
96
97
if(elmer_home != NULL) {
98
/* Return solver home relative to ELMER_HOME*/
99
#if defined(WIN32) || defined(MINGW32)
100
_snprintf(solverDir, MAX_PATH_LEN, "%s\\share\\elmersolver", elmer_home);
101
#else
102
snprintf(solverDir, MAX_PATH_LEN, "%s/share/elmersolver", elmer_home);
103
#endif
104
*len = strlen(elmer_home) + 18;
105
if(*len > MAX_PATH_LEN) *len = MAX_PATH_LEN;
106
return;
107
}
108
109
#if defined(WIN32) || defined(MINGW32)
110
static char appPath[MAX_PATH_LEN] = "";
111
static char appDir[MAX_PATH_LEN] = "";
112
char *exeName = NULL;
113
int n = 0;
114
115
/* Get the full module file name */
116
GetModuleFileName(NULL, appPath, MAX_PATH_LEN);
117
if(appPath == NULL) return;
118
exeName = strrchr(appPath, '\\');
119
if(exeName == NULL) return;
120
n = (int)(exeName - appPath);
121
if(n < 0) return; /* play safe */
122
if(n > MAX_PATH_LEN) n = MAX_PATH_LEN;
123
124
/* This is where the executable resides */
125
strncpy(appDir, appPath, n);
126
127
/* Return solver home relative to appDir */
128
_snprintf(solverDir, MAX_PATH_LEN, "%s\\..\\share\\elmersolver", appDir);
129
*len = n + 21;
130
if(*len > MAX_PATH_LEN) *len = MAX_PATH_LEN;
131
#else
132
133
/* Use the directory defined in config.h */
134
snprintf(solverDir, MAX_PATH_LEN, "%s", ELMER_SOLVER_HOME);
135
*len = strlen(ELMER_SOLVER_HOME);
136
if(*len > MAX_PATH_LEN) *len = MAX_PATH_LEN;
137
#endif
138
}
139
140
/*--------------------------------------------------------------------------
141
This routine will create a directory given name of the directory.
142
-------------------------------------------------------------------------*/
143
#ifdef USE_ISO_C_BINDINGS
144
void STDCALLBULL makedirectory(char *Name)
145
#else
146
void STDCALLBULL FC_FUNC(makedirectory,MAKEDIRECTORY)
147
(char *Name)
148
#endif
149
{
150
#if defined(WIN32) || defined(MINGW32)
151
if ( _mkdir( Name ) != 0 ) {
152
#else
153
if ( mkdir( Name, 0750 ) != 0 ) {
154
// chmod( Name, 0750 );
155
#endif
156
}
157
}
158
159
#ifndef USE_ISO_C_BINDINGS
160
/*--------------------------------------------------------------------------
161
This routine execute a operating system command.
162
-------------------------------------------------------------------------*/
163
void STDCALLBULL FC_FUNC(systemc,SYSTEMC) ( char *str )
164
{
165
system( str );
166
}
167
168
/*--------------------------------------------------------------------------
169
This routine will return value of a environment variable to a
170
given string variable.
171
-------------------------------------------------------------------------*/
172
void STDCALLBULL FC_FUNC(envir,ENVIR) (char *Name, char *Value, int *len)
173
{
174
if ( getenv( Name ) ) {
175
strncpy( Value,(char *)getenv(Name), MAX_PATH_LEN );
176
*len = strlen( Value );
177
} else {
178
*len = 0;
179
*Value = '\0';
180
}
181
}
182
#endif
183
184
/*--------------------------------------------------------------------------
185
Internal: convert function names into to fortran mangled form for dynamical
186
loading
187
---------------------------------------------------------------------------*/
188
static void STDCALLBULL fortranMangle(char *orig, char *mangled)
189
{
190
int uscore, i;
191
192
strcpy( mangled, orig );
193
194
if(ELMER_LINKTYP == 1 || ELMER_LINKTYP == 3 || ELMER_LINKTYP == 4)
195
{
196
for( i=0 ; i<strlen(mangled) ; i++ ) /* to lower case */
197
{
198
if ( mangled[i] >= 'A' && mangled[i] <= 'Z' )
199
mangled[i] += 'a' - 'A';
200
}
201
}
202
if(ELMER_LINKTYP == 2)
203
{
204
for( i=0; i<strlen(mangled); i++ ) /* to upper case */
205
{
206
if ( mangled[i] >= 'a' && mangled[i] <= 'z' )
207
mangled[i] += 'A' - 'a';
208
}
209
}
210
211
if(ELMER_LINKTYP == 1) /* underscore */
212
{
213
strcat( mangled, "_" );
214
}
215
else if(ELMER_LINKTYP == 4) /* 1-2 underscores */
216
{
217
uscore = 0;
218
for( i=0; i<strlen(mangled); i++ )
219
if(mangled[i] == '_')
220
uscore++;
221
222
if(uscore == 0)
223
{
224
strcat( mangled, "_" );
225
}
226
else
227
{
228
strcat( mangled, "__" );
229
}
230
}
231
232
}
233
234
/*--------------------------------------------------------------------------
235
INTERNAL: Appends two paths with slash checking
236
Args: path1, path2 - string to join
237
-------------------------------------------------------------------------*/
238
static void STDCALLBULL append_path(char *path1, char *path2)
239
{
240
size_t len1;
241
242
len1 = strnlen(path1, 2*MAX_PATH_LEN);
243
#if defined(WIN32) || defined(MINGW)
244
if (path1[len1-1] != '\\') {
245
strncat(path1, "\\", 2*MAX_PATH_LEN-1);
246
}
247
#else
248
if (path1[len1-1] != '/') {
249
strncat(path1, "/", 2*MAX_PATH_LEN-1);
250
}
251
#endif
252
strncat(path1, path2, 2*MAX_PATH_LEN-1);
253
}
254
255
/*--------------------------------------------------------------------------
256
INTERNAL: Tries to open library with dlopen, first without
257
any extensions and then with SHL_EXTENSION.
258
Args: Libname - name of the library file
259
Handle - handle to the dl, NULL if fails
260
error_buf - string buffer for error messages
261
-------------------------------------------------------------------------*/
262
static void STDCALLBULL try_dlopen(char *LibName, void **Handle, char *errorBuf)
263
{
264
static char dl_names[2][2*MAX_PATH_LEN];
265
char error_tmp[MAX_PATH_LEN];
266
int i;
267
268
strncpy(dl_names[0], LibName, 2*MAX_PATH_LEN);
269
strncpy(dl_names[1], LibName, 2*MAX_PATH_LEN);
270
271
strncat(dl_names[1], SHL_EXTENSION, MAX_PATH_LEN-1);
272
273
for (i = 0; i < 2; i++) {
274
#ifdef HAVE_DLOPEN_API
275
if ((*Handle = dlopen(dl_names[i], RTLD_NOW)) == NULL) {
276
strncat(errorBuf, dlerror(), MAX_PATH_LEN-1);
277
strncat(errorBuf, "\n", MAX_PATH_LEN)-1;
278
} else {
279
break;
280
}
281
#elif defined(HAVE_LOADLIBRARY_API)
282
if ((*Handle = LoadLibrary(dl_names[i])) == NULL) {
283
sprintf(error_tmp, "Can not find %s.\n", dl_names[i]);
284
strncat(errorBuf, error_tmp, ERROR_BUF_LEN-1);
285
} else {
286
break;
287
}
288
#endif
289
}
290
}
291
292
/*--------------------------------------------------------------------------
293
INTERNAL: Parses the search path and tries to open a solver.
294
First search is done without any path prefixes.
295
Args: SearchPath - colon separated list of search paths
296
Library - name of the library file to be opened
297
Handle - handle to the dl file, NULL if fails
298
error_buf - string buffer for error messages
299
--------------------------------------------------------------------------*/
300
static void STDCALLBULL
301
try_open_solver(char *SearchPath, char *Library, void **Handle, char *errorBuf)
302
{
303
static char CurrentLib[2*MAX_PATH_LEN];
304
char *tok;
305
306
/* Try to open first without any prefixes */
307
try_dlopen(Library, Handle, errorBuf);
308
309
/* and then using the provided paths */
310
if (*Handle == NULL) {
311
312
tok = strtok(SearchPath, ELMER_PATH_SEPARATOR);
313
while (tok != NULL) {
314
strncpy(CurrentLib, tok, 2*MAX_PATH_LEN);
315
append_path(CurrentLib, Library);
316
317
try_dlopen(CurrentLib, Handle, errorBuf);
318
if (*Handle != NULL)
319
break;
320
tok = strtok(NULL, ELMER_PATH_SEPARATOR);
321
}
322
}
323
}
324
325
/*--------------------------------------------------------------------------
326
This routine will return address of a function given path to a dynamically
327
loaded library and name of the routine.
328
-------------------------------------------------------------------------*/
329
#ifdef USE_ISO_C_BINDINGS
330
void *STDCALLBULL loadfunction_c( int *Quiet, int *abort_not_found,
331
char *Library, char *Name, int *mangle )
332
#else
333
void *STDCALLBULL FC_FUNC(loadfunction,LOADFUNCTION) ( int *Quiet, int *abort_not_found,
334
char *Library, char *Name, int *mangle )
335
#endif
336
{
337
/*--------------------------------------------------------------------------*/
338
void (*Function)(),*Handle;
339
char *cptr;
340
static char ElmerLib[2*MAX_PATH_LEN], NewLibName[3*MAX_PATH_LEN],
341
NewName[MAX_PATH_LEN], ErrorBuffer[ERROR_BUF_LEN];
342
/*--------------------------------------------------------------------------*/
343
static char appPath[MAX_PATH_LEN] = "";
344
char *exeName = NULL;
345
int n = 0;
346
/*--------------------------------------------------------------------------*/
347
memset(appPath, 0, MAX_PATH_LEN);
348
memset(ElmerLib, 0, 2*MAX_PATH_LEN);
349
memset(NewLibName, 0, 3*MAX_PATH_LEN);
350
memset(NewName, 0, MAX_PATH_LEN);
351
memset(ErrorBuffer, 0, ERROR_BUF_LEN);
352
/*--------------------------------------------------------------------------*/
353
if(*mangle) {
354
fortranMangle( Name, NewName );
355
} else {
356
strncpy( NewName, Name, MAX_PATH_LEN-1 );
357
}
358
strncpy( NewLibName, Library, 3*MAX_PATH_LEN );
359
360
if ( *Quiet==0 ) {
361
fprintf(stdout,"Loading user function library: [%s]...[%s]\n", Library, Name );
362
fflush(stdout);
363
}
364
365
/* First path is always current directory (.) */
366
strncpy(ElmerLib, ".", 2*MAX_PATH_LEN);
367
cptr = (char *)getenv( "ELMER_LIB" );
368
if ( cptr != NULL ) {
369
strncat( ElmerLib, ELMER_PATH_SEPARATOR, 2*MAX_PATH_LEN-1 );
370
strncat( ElmerLib, cptr, 2*MAX_PATH_LEN-1 );
371
} else {
372
cptr = (char *)getenv("ELMER_HOME");
373
if ( cptr != NULL ) {
374
strncat( ElmerLib, ELMER_PATH_SEPARATOR, 2*MAX_PATH_LEN-1);
375
strncat( ElmerLib, cptr, 2*MAX_PATH_LEN-1 );
376
strncat( ElmerLib, "/share/elmersolver/lib", 2*MAX_PATH_LEN-1 );
377
} else {
378
#if defined(WIN32) || defined(MINGW32)
379
/* Should not get here unless WIN32 implements DLOPEN_API */
380
GetModuleFileName(NULL, appPath, MAX_PATH_LEN);
381
exeName = strrchr(appPath, '\\');
382
n = (int)(exeName - appPath);
383
if(n < 0) n = 0;
384
if(n > MAX_PATH_LEN) n = MAX_PATH_LEN;
385
strncat(ElmerLib, ELMER_PATH_SEPARATOR, 2*MAX_PATH_LEN-1);
386
strncat(ElmerLib, appPath, n);
387
strncat(ElmerLib, "\\..\\share\\elmersolver\\lib", 2*MAX_PATH_LEN-1);
388
#else
389
strncat( ElmerLib, ELMER_PATH_SEPARATOR, 2*MAX_PATH_LEN-1 );
390
strncat( ElmerLib, ELMER_SOLVER_HOME, 2*MAX_PATH_LEN-1 );
391
strncat( ElmerLib, "/lib", 2*MAX_PATH_LEN-1 );
392
#endif
393
}
394
}
395
396
cptr = (char *)getenv( "ELMER_MODULES_PATH" );
397
if ( cptr != NULL ) {
398
strncat( ElmerLib, ELMER_PATH_SEPARATOR, 2*MAX_PATH_LEN-1);
399
strncat( ElmerLib, cptr, 2*MAX_PATH_LEN-1);
400
}
401
402
try_open_solver(ElmerLib, Library, &Handle, ErrorBuffer);
403
if ( Handle == NULL ) {
404
fprintf(stderr, "%s", ErrorBuffer);
405
exit(0);
406
}
407
408
#ifdef HAVE_DLOPEN_API
409
410
if ( (Function = (void(*)())dlsym( Handle,NewName)) == NULL && *abort_not_found )
411
{
412
fprintf( stderr, "Load: FATAL: Can't find procedure [%s]\n", NewName );
413
exit(0);
414
}
415
416
#elif defined(HAVE_LOADLIBRARY_API)
417
418
if ( (Function = (void *)GetProcAddress(Handle,NewName)) == NULL && *abort_not_found )
419
{
420
fprintf( stderr,"Load: FATAL: Can't find procedure [%s]\n", NewName );
421
exit(0);
422
}
423
424
#endif
425
426
return (void *)Function;
427
}
428
429
/*--------------------------------------------------------------------------
430
INTERNAL: Execute given function returning integer value
431
-------------------------------------------------------------------------*/
432
static int IntExec( int (STDCALLBULL *Function)(void *),void *Model )
433
{
434
return (*Function)( Model );
435
}
436
437
/*--------------------------------------------------------------------------
438
Execute given function returning integer value
439
-------------------------------------------------------------------------*/
440
#ifdef USE_ISO_C_BINDINGS
441
int STDCALLBULL execintfunction_c( f_ptr Function,void *Model )
442
#else
443
int STDCALLBULL FC_FUNC(execintfunction,EXECINTFUNCTION) ( f_ptr Function,void *Model )
444
#endif
445
{
446
return IntExec( (int (STDCALLBULL *)())*Function,Model );
447
}
448
449
/*--------------------------------------------------------------------------
450
INTERNAL: Execute given function returning double value
451
-------------------------------------------------------------------------*/
452
static void DoubleArrayExec(
453
double *(STDCALLBULL *Function)(void *, int *, double *, double *),
454
void *Model, int *Node, double *Value, double *Array )
455
{
456
(*Function)( Model,Node,Value,Array );
457
}
458
459
/*--------------------------------------------------------------------------
460
Execute given function returning double value
461
-------------------------------------------------------------------------*/
462
#ifdef USE_ISO_C_BINDINGS
463
void STDCALLBULL execrealarrayfunction_c( f_ptr Function, void *Model,
464
int *Node, double *Value, double *Array )
465
#else
466
void STDCALLBULL FC_FUNC(execrealarrayfunction,EXECREALARRAYFUNCTION)
467
( f_ptr Function,
468
void *Model, int *Node, double *Value, double *Array )
469
#endif
470
{
471
DoubleArrayExec(
472
(double*(STDCALLBULL *)(void *, int *, double *, double *)) *Function,
473
Model, Node, Value, Array );
474
}
475
476
/*--------------------------------------------------------------------------
477
INTERNAL: Execute given function returning double value
478
-------------------------------------------------------------------------*/
479
static double DoubleExec(
480
double (STDCALLBULL *Function)(void *, int *, double *),
481
void *Model, int *Node, double *Value )
482
{
483
return (*Function)( Model,Node,Value );
484
}
485
486
/*--------------------------------------------------------------------------
487
Execute given function returning double value
488
-------------------------------------------------------------------------*/
489
#ifdef USE_ISO_C_BINDINGS
490
double STDCALLBULL execrealfunction_c( f_ptr Function, void *Model,
491
int *Node, double *Value )
492
#else
493
double STDCALLBULL FC_FUNC(execrealfunction,EXECREALFUNCTION)
494
( f_ptr Function, void *Model,
495
int *Node, double *Value )
496
#endif
497
{
498
return DoubleExec(
499
(double (STDCALLBULL *)(void *, int *, double *)) *Function,
500
Model, Node, Value );
501
}
502
503
/*--------------------------------------------------------------------------
504
INTERNAL: Execute given function returning double value
505
-------------------------------------------------------------------------*/
506
static double ConstDoubleExec(
507
double (STDCALLBULL *Function)(void *, double *, double *, double *),
508
void *Model, double *x, double *y, double *z )
509
{
510
return (*Function)( Model, x,y,z );
511
}
512
513
/*--------------------------------------------------------------------------
514
Execute given function returning double value
515
-------------------------------------------------------------------------*/
516
#ifdef USE_ISO_C_BINDINGS
517
double STDCALLBULL execconstrealfunction_c( f_ptr Function, void *Model,
518
double *x, double *y, double *z )
519
#else
520
double STDCALLBULL FC_FUNC(execconstrealfunction,EXECCONSTREALFUNCTION)
521
( f_ptr Function, void *Model,
522
double *x, double *y, double *z )
523
#endif
524
{
525
return ConstDoubleExec(
526
(double (STDCALLBULL *)(void *, double *, double *, double *)) *Function,
527
Model, x, y, z );
528
}
529
530
531
/*--------------------------------------------------------------------------
532
Return argument (just to fool Fortran type checking)
533
-------------------------------------------------------------------------*/
534
#ifdef USE_ISO_C_BINDINGS
535
void *STDCALLBULL addrfunc_c( void *Function )
536
#else
537
void *STDCALLBULL FC_FUNC(addrfunc,ADDRFUNC) ( void *Function )
538
#endif
539
{
540
return (void *)Function;
541
}
542
543
/*--------------------------------------------------------------------------
544
INTERNAL: Call solver routines at given address
545
-------------------------------------------------------------------------*/
546
static void DoExecSolver(
547
void (STDCALLBULL *SolverProc)(void *, void *, void *, void *),
548
void *Model, void *Solver, void *dt, void *Transient)
549
{
550
(*SolverProc)( Model,Solver,dt,Transient );
551
return;
552
}
553
554
/*--------------------------------------------------------------------------
555
Call solver routines at given address
556
-------------------------------------------------------------------------*/
557
#ifdef USE_ISO_C_BINDINGS
558
void STDCALLBULL execsolver_c( f_ptr *SolverProc, void *Model, void *Solver,
559
void *dt, void *Transient )
560
#else
561
void STDCALLBULL FC_FUNC(execsolver,EXECSOLVER)
562
( f_ptr *SolverProc, void *Model, void *Solver, void *dt, void *Transient )
563
#endif
564
{
565
DoExecSolver(
566
(void (STDCALLBULL *)(void *, void *, void *, void *))*SolverProc,
567
Model, Solver, dt, Transient );
568
}
569
570
/*--------------------------------------------------------------------------
571
INTERNAL: Call lin. solve routines at given address
572
-------------------------------------------------------------------------*/
573
static int DoLinSolveProcs(
574
int (STDCALLBULL *SolverProc)(void *, void *, void *, void *, void *, void *, void *, void *),
575
void *Model, void *Solver, void *Matrix, void *b,
576
void *x, void *n, void *DOFs, void *Norm )
577
{
578
return (*SolverProc)( Model,Solver,Matrix,b,x,n, DOFs,Norm );
579
}
580
581
582
/*--------------------------------------------------------------------------
583
Call lin. solver routines at given address
584
-------------------------------------------------------------------------*/
585
#ifdef USE_ISO_C_BINDINGS
586
int STDCALLBULL execlinsolveprocs_c( f_ptr *SolverProc, void *Model, void *Solver,
587
void *Matrix, void *b, void *x, void *n, void *DOFs, void *Norm )
588
#else
589
int STDCALLBULL FC_FUNC(execlinsolveprocs,EXECLINSOLVEPROCS)
590
( f_ptr *SolverProc, void *Model, void *Solver, void *Matrix, void *b, void *x, void *n, void *DOFs, void *Norm )
591
#endif
592
{
593
return DoLinSolveProcs(
594
(int (STDCALLBULL *)(void *, void *, void *, void *, void *, void *, void *, void *)) *SolverProc,
595
Model, Solver, Matrix, b, x, n, DOFs, Norm );
596
}
597
598
char *mtc_domath(char *);
599
void mtc_init(FILE *,FILE *, FILE *);
600
601
/*--------------------------------------------------------------------------
602
This routine will call matc and return matc variable array values
603
-------------------------------------------------------------------------*/
604
#ifdef USE_ISO_C_BINDINGS
605
void STDCALLBULL matc_get_array(char *name, double *values, int *nrows, int *ncols )
606
#else
607
void STDCALLBULL FC_FUNC_(matc_get_array,MATC_GET_ARRAY) (char *name,
608
double *values, int *nrows, int *ncols )
609
#endif
610
{
611
void var_copy_transpose(char *name,double *values,int nrows,int ncols);
612
var_copy_transpose(name,values,*nrows,*ncols);
613
}
614
615
/*--------------------------------------------------------------------------
616
This routine will call matc and return matc result
617
-------------------------------------------------------------------------*/
618
#ifdef USE_ISO_C_BINDINGS
619
void STDCALLBULL matc_c( char *cmd, int *len, char *result, int *reslen )
620
#else
621
void STDCALLBULL FC_FUNC(matc_c,MATC) (char *cmd,int *cmdlen,char *result,*reslen)
622
#endif
623
{
624
#define MAXLEN 8192
625
626
static int been_here = 0;
627
char *ptr, c, cc[32], *ccmd;
628
int slen, start;
629
#pragma omp threadprivate(been_here)
630
631
/* MB: Critical section removed since Matc library
632
* modified to be thread safe */
633
634
slen = *len;
635
if ( been_here==0 ) {
636
mtc_init( NULL, stdout, stderr );
637
strcpy( cc, "format( 12,\"rowform\")" );
638
mtc_domath( cc );
639
been_here = 1;
640
}
641
642
ccmd = (char *)malloc(slen+1);
643
strncpy( ccmd, cmd, slen);
644
ccmd[slen] = '\0';
645
646
start = 0;
647
if (strncmp(ccmd,"nc:",3)==0) start=3;
648
649
ptr = (char *)mtc_domath(&ccmd[start]);
650
if (ptr) {
651
slen = strlen(ptr)-1; /* ignore linfeed! */
652
} else {
653
slen = 0;
654
}
655
656
if(slen >= *reslen) {
657
fprintf( stderr, "MATC result too long %d %d\n", *len, *reslen );
658
exit(0);
659
} else if (slen>0) {
660
*reslen = slen;
661
strncpy(result, (const char*)ptr, slen);
662
663
if ( strncmp(result, "MATC ERROR:",11)==0 || strncmp(result,"WARNING:",8)==0 ) {
664
if (start==0) {
665
fprintf( stderr, "Solver input file error: %s\n", result );
666
fprintf( stderr, "...offending input line: %s\n", ccmd );
667
exit(0);
668
} else {
669
result[0]=' ';
670
*reslen = 0;
671
}
672
}
673
} else {
674
*reslen = 0;
675
*result = ' ';
676
}
677
free(ccmd);
678
}
679
680
/*--------------------------------------------------------------------------
681
INTERNAL: execute user material function
682
-------------------------------------------------------------------------*/
683
static double DoViscFunction(
684
double (STDCALLBULL *SolverProc)(void *, void *, void *, void *, void *, void *, void *, void *, void *),
685
void *Model, void *Element, void *Nodes, void *n,
686
void *Basis, void *GradBasis, void *Viscosity, void *Velo, void *GradV )
687
{
688
double s;
689
s = (*SolverProc)( Model,Element,Nodes,n,Basis,GradBasis,
690
Viscosity, Velo, GradV );
691
return s;
692
}
693
694
/*--------------------------------------------------------------------------
695
This routine will call user defined material def. function
696
-------------------------------------------------------------------------*/
697
#ifdef USE_ISO_C_BINDINGS
698
double STDCALLBULL materialuserfunction_c( f_ptr Function, void *Model, void *Element,
699
void *Nodes, void *n, void *nd, void *Basis, void *GradBasis, void *Viscosity, void *Velo, void *gradV )
700
#else
701
double STDCALLBULL FC_FUNC(materialuserfunction,MATERIALUSERFUNCTION)
702
( f_ptr Function, void *Model, void *Element, void *Nodes, void *n, void *nd, void *Basis, void *GradBasis, void *Viscosity, void *Velo, void *gradV )
703
#endif
704
{
705
return DoViscFunction(
706
(double (STDCALLBULL *)(void *, void *, void *, void *, void *, void *, void *, void *, void *)) *Function,
707
Model, Element, Nodes, n, Basis, GradBasis, Viscosity, Velo, gradV );
708
}
709
710
/*--------------------------------------------------------------------------
711
INTERNAL: execute user material function
712
-------------------------------------------------------------------------*/
713
static void DoSimulationProc( void (STDCALLBULL *SimulationProc)(void *), void *Model )
714
{
715
(*SimulationProc)( Model );
716
}
717
718
/*--------------------------------------------------------------------------
719
This routine will call user defined material def. function
720
-------------------------------------------------------------------------*/
721
#ifdef USE_ISO_C_BINDINGS
722
void STDCALLBULL execsimulationproc_c( f_ptr Function, void *Model )
723
#else
724
void STDCALLBULL FC_FUNC(execsimulationproc,EXECSIMULATIONPROC)
725
( f_ptr Function, void *Model )
726
#endif
727
{
728
DoSimulationProc( (void (STDCALLBULL *)(void *)) *Function, Model );
729
}
730
731
732
/*--------------------------------------------------------------------------
733
INTERNAL: execute (Krylov) iterator
734
-------------------------------------------------------------------------*/
735
static void DoIterCall(
736
void (STDCALLBULL *iterProc)(void *,void *,void *,void *,void *,
737
void (STDCALLBULL *)(),
738
void (STDCALLBULL *)(),
739
void (STDCALLBULL *)(),
740
void (STDCALLBULL *)(),
741
void (STDCALLBULL *)(),
742
void (STDCALLBULL *)()),
743
void *x,void *b,void *ipar,void *dpar,void *work,
744
void (STDCALLBULL *mvProc)(),
745
void (STDCALLBULL *pcondProc)(),
746
void (STDCALLBULL *pcondrProc)(),
747
void (STDCALLBULL *dotProc)(),
748
void (STDCALLBULL *normProc)(),
749
void (STDCALLBULL *STOPC)() )
750
{
751
(*iterProc)( x,b,ipar,dpar,work,mvProc,pcondProc,
752
pcondrProc,dotProc,normProc,STOPC );
753
}
754
755
/*--------------------------------------------------------------------------
756
This routine will call (Krylov) iterator
757
-------------------------------------------------------------------------*/
758
#ifdef USE_ISO_C_BINDINGS
759
void STDCALLBULL itercall_c( f_ptr iterProc, void *x, void *b, void *ipar, void *dpar, void *work,
760
f_ptr mvProc, f_ptr pcondProc, f_ptr pcondrProc, f_ptr dotProc, f_ptr normProc, f_ptr STOPC )
761
#else
762
void STDCALLBULL FC_FUNC(itercall,ITERCALL)
763
( f_ptr iterProc, void *x, void *b, void *ipar, void *dpar, void *work,
764
f_ptr mvProc, f_ptr pcondProc, f_ptr pcondrProc, f_ptr dotProc, f_ptr normProc, f_ptr STOPC )
765
#endif
766
{
767
DoIterCall( (void (STDCALLBULL *)(void *,void *,void *,void *,void *,
768
void (STDCALLBULL *)(),
769
void (STDCALLBULL *)(),
770
void (STDCALLBULL *)(),
771
void (STDCALLBULL *)(),
772
void (STDCALLBULL *)(),
773
void (STDCALLBULL *)())) *iterProc,
774
x,b,ipar,dpar,work,
775
(void (STDCALLBULL *)())*mvProc,
776
(void (STDCALLBULL *)())*pcondProc,
777
(void (STDCALLBULL *)())*pcondrProc,
778
(void (STDCALLBULL *)())*dotProc,
779
(void (STDCALLBULL *)())*normProc,
780
(void (STDCALLBULL *)())*STOPC );
781
}
782
783
/*--------------------------------------------------------------------------
784
INTERNAL: execute localmatrix call
785
-------------------------------------------------------------------------*/
786
static void DoLocalCall(
787
void (STDCALLBULL *localProc)(void *, void *, void *, void *, void *, void *, void *),
788
void *Model, void *Solver, void *G, void *F, void *Element, void *n, void *nd )
789
{
790
(*localProc)( Model, Solver, G, F, Element, n, nd );
791
}
792
793
/*--------------------------------------------------------------------------
794
This routine will call local matrix add-on
795
-------------------------------------------------------------------------*/
796
#ifdef USE_ISO_C_BINDINGS
797
void STDCALLBULL execlocalproc_c( f_ptr localProc, void *Model,void *Solver,
798
void *G, void *F, void *Element,void *n,void *nd )
799
#else
800
void STDCALLBULL FC_FUNC(execlocalproc, EXECLOCALPROC )
801
( f_ptr localProc, void *Model,void *Solver,void *G, void *F, void *Element,void *n,void *nd )
802
#endif
803
{
804
DoLocalCall(
805
(void (STDCALLBULL *)(void *, void *, void *, void *, void *, void *, void *)) *localProc,
806
Model, Solver, G, F, Element, n, nd );
807
}
808
809
810
811
/*--------------------------------------------------------------------------
812
INTERNAL: execute complete localmatrix call
813
-------------------------------------------------------------------------*/
814
static void DoLocalAssembly(
815
void (STDCALLBULL *LocalAssembly)(void *, void *, void *, void *, void *, void *, void *,void *, void *, void *, void *),
816
void *Model,void *Solver,void *dt,void *transient,void *M, void *D, void *S,void *F, void *Element,void *n,void *nd )
817
{
818
(*LocalAssembly)( Model, Solver, dt, transient, M, D, S, F, Element, n, nd );
819
}
820
821
/*--------------------------------------------------------------------------
822
This routine will call complete local matrix add-on
823
-------------------------------------------------------------------------*/
824
#ifdef USE_ISO_C_BINDINGS
825
void STDCALLBULL execlocalassembly_c( f_ptr LocalAssembly, void *Model,
826
void *Solver,void *dt,void *transient,
827
void *M, void *D, void *S,void *F,
828
void *Element,void *n,void *nd )
829
#else
830
void STDCALLBULL FC_FUNC(execlocalassembly, EXECLOCALASSEMBLY )
831
( f_ptr LocalAssembly, void *Model,void *Solver,void *dt,void *transient,void *M, void *D, void *S,void *F,void *Element,void *n,void *nd )
832
#endif
833
{
834
DoLocalAssembly(
835
(void (STDCALLBULL *)(void *, void *, void *, void *, void *, void *, void *,void *, void *, void *, void *)) *LocalAssembly,
836
Model, Solver, dt, transient, M, D, S, F, Element, n, nd );
837
}
838
839
840
841
/*--------------------------------------------------------------------------
842
INTERNAL: execute complete localmatrix call
843
-------------------------------------------------------------------------*/
844
static void DoMatVecSubr(
845
void (STDCALLBULL *matvec)(void **, void *, void *, void *,void *, void *, void *, void *),
846
void **SpMV, void *n, void *rows, void *cols, void *vals, void *u, void *v, void *reinit )
847
{
848
(*matvec)( SpMV,n,rows,cols,vals,u,v,reinit);
849
}
850
851
/*--------------------------------------------------------------------------
852
This routine will call complete local matrix add-on
853
-------------------------------------------------------------------------*/
854
#ifdef USE_ISO_C_BINDINGS
855
void STDCALLBULL matvecsubrext_c( f_ptr matvec, void **SpMV, void *n, void *rows,
856
void *cols, void *vals, void *u, void *v,void *reinit )
857
#else
858
void STDCALLBULL FC_FUNC(matvecsubr, MMATVECSUBR)
859
( f_ptr matvec, void **SpMV, void *n, void *rows, void *cols, void *vals, void *u, void *v,void *reinit )
860
#endif
861
{
862
DoMatVecSubr(
863
(void (STDCALLBULL *)(void **, void *, void *, void *,void *, void *, void *, void *)) *matvec,
864
SpMV, n, rows, cols, vals, u, v, reinit);
865
}
866
867