Newer
Older
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
/****************************************************************************/
/* */
/* File: pv3if.c */
/* */
/* Purpose: Interface to pV3 */
/* */
/* Author: Michael Lampe */
/* IWR Uni Heidelberg */
/* Im Neuenheimer Feld 368 */
/* 69120 Heidelberg */
/* Email: Michael.Lampe@iwr.uni-heidelberg.de */
/* */
/* History: 20030130 begin, ug3.8 */
/* */
/* Remarks: Don't despair. pV3 is written in Fortran 77 ;-) */
/* */
/* TODO: 1) support for on-line visualization */
/* 2) give pV3 info about partition boundaries */
/* */
/****************************************************************************/
/****************************************************************************/
/* */
/* include files */
/* system include files */
/* application include files */
/* */
/****************************************************************************/
#include <config.h>
#include <string.h>
#include <pV3.h>
#include "general.h"
#include "parallel.h"
#include "gm.h"
#include "shapes.h"
#include "commands.h"
#include "pv3if.h"
/****************************************************************************/
/* */
/* defines in the following order */
/* */
/* compile time constants defining static data size (i.e. arrays) */
/* other constants */
/* macros */
/* */
/****************************************************************************/
#define MAX_ITEM 50
#undef MIN
#define MIN(a, b) ((a)<=(b) ? (a) : (b))
#define SURFACE_LOOP_BEGIN(mg, e) \
{ \
int _i; \
for (_i = 0; _i <= TOPLEVEL(mg); _i++) \
for (e = FIRSTELEMENT(GRID_ON_LEVEL(mg, _i)); e != NULL; e = SUCCE(e)) { \
if (!EstimateHere(e)) continue;
#define SURFACE_LOOP_END \
} \
}
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/****************************************************************************/
/* */
/* definition of variables global to this source file only (static!) */
/* */
/****************************************************************************/
/* initialization data */
static char title[]="UG Output"; /* title string */
static int cid; /* client id */
static char cname[]=" "; /* client name */
static char dname[]=" "; /* not needed */
static int iopt; /* unsteady control parameter */
static int npgcut=0; /* # of programmer defined cuts */
static char tpgcut[MAX_ITEM][32]; /* title for each cut */
static int nkeys=0; /* # of active keyboard keys */
static int ikeys[MAX_ITEM]; /* X-keypress return code for each key */
static char tkeys[MAX_ITEM][32]; /* title for each key */
static int fkeys[MAX_ITEM]; /* type of function controlled */
static float flims[MAX_ITEM][2]; /* function limits/scales */
static int mirror=0; /* not needed */
static float repmat[16]; /* not needed */
static int maxblk=0; /* not needed */
static int istat; /* startup/terminate state */
/* evaluation data */
static union {
EVALUES *s;
EVECTOR *v;
} eval[MAX_ITEM];
static char eval_name[MAX_ITEM][NAMESIZE];
/****************************************************************************/
/* */
/* utility functions */
/* */
/****************************************************************************/
static void fstring(char *d, const char *s, size_t n)
{
int i;
strncpy(d, s, n);
for(i = MIN(strlen(s), n); i < n; i++)
d[i]=' ';
}
static void ClearVertexMarkers(MULTIGRID *mg)
{
VERTEX *v;
int i;
for (i = 0; i <= TOPLEVEL(mg); i++)
for (v = FIRSTVERTEX(GRID_ON_LEVEL(mg, i)); v != NULL; v = SUCCV(v))
SETUSED(v,0);
}
/****************************************************************************/
/* */
/* callback for grid statistics */
/* */
/****************************************************************************/
void pVSTRUC(int *knode, int *kequiv, int *kcel1, int *kcel2, int *kcel3,
int *kcel4, int *knptet, int *kptet, int *knblock, int *blocks,
int *kphedra, int *ksurf, int *knsurf, int *hint)
{
MULTIGRID *mg;
ELEMENT *e;
VERTEX *v;
int i;
*knode = *kcel1 = *kcel2 = *kcel3 = *kcel4 = *ksurf = 0;
mg = GetCurrentMultigrid();
ClearVertexMarkers(mg);
SURFACE_LOOP_BEGIN(mg, e)
switch (TAG(e))
{
case TETRAHEDRON :
(*kcel1)++;
break;
case PYRAMID :
(*kcel2)++;
break;
case PRISM :
(*kcel3)++;
break;
case HEXAHEDRON :
(*kcel4)++;
}
for (i = 0; i < CORNERS_OF_ELEM(e); i++) {
v = MYVERTEX(CORNER(e, i));
if (USED(v)) continue;
SETUSED(v, 1);
ID(v) = *knode; /* number vertices */
(*knode)++;
}
/* check for domain boundary sides */
if (OBJT(e) == BEOBJ) {
for (i = 0; i < SIDES_OF_ELEM(e); i++)
(*ksurf)++;
}
*kequiv = 0;
*knptet = 0;
*kptet = 0;
*knblock = 0;
*kphedra = 0;
}
/****************************************************************************/
/* */
/* callback for element vertices */
/* */
/****************************************************************************/
void pVCELL(int *cel1, int *cel2, int *cel3, int *cel4, int *nptet, int *ptet)
{
MULTIGRID *mg;
ELEMENT *e;
mg = GetCurrentMultigrid();
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
SURFACE_LOOP_BEGIN(mg, e)
switch (TAG(e))
{
case TETRAHEDRON :
cel1[0] = ID(MYVERTEX(CORNER(e, 3)))+1;
cel1[1] = ID(MYVERTEX(CORNER(e, 0)))+1;
cel1[2] = ID(MYVERTEX(CORNER(e, 1)))+1;
cel1[3] = ID(MYVERTEX(CORNER(e, 2)))+1;
cel1 += 4;
break;
case PYRAMID :
cel2[0] = ID(MYVERTEX(CORNER(e, 0)))+1;
cel2[1] = ID(MYVERTEX(CORNER(e, 1)))+1;
cel2[2] = ID(MYVERTEX(CORNER(e, 2)))+1;
cel2[3] = ID(MYVERTEX(CORNER(e, 3)))+1;
cel2[4] = ID(MYVERTEX(CORNER(e, 4)))+1;
cel2 += 5;
break;
case PRISM :
cel3[0] = ID(MYVERTEX(CORNER(e, 1)))+1;
cel3[1] = ID(MYVERTEX(CORNER(e, 4)))+1;
cel3[2] = ID(MYVERTEX(CORNER(e, 5)))+1;
cel3[3] = ID(MYVERTEX(CORNER(e, 2)))+1;
cel3[4] = ID(MYVERTEX(CORNER(e, 3)))+1;
cel3[5] = ID(MYVERTEX(CORNER(e, 0)))+1;
cel3 += 6;
break;
case HEXAHEDRON :
cel4[0] = ID(MYVERTEX(CORNER(e, 0)))+1;
cel4[1] = ID(MYVERTEX(CORNER(e, 1)))+1;
cel4[2] = ID(MYVERTEX(CORNER(e, 2)))+1;
cel4[3] = ID(MYVERTEX(CORNER(e, 3)))+1;
cel4[4] = ID(MYVERTEX(CORNER(e, 4)))+1;
cel4[5] = ID(MYVERTEX(CORNER(e, 5)))+1;
cel4[6] = ID(MYVERTEX(CORNER(e, 6)))+1;
cel4[7] = ID(MYVERTEX(CORNER(e, 7)))+1;
cel4 += 8;
break;
}
/****************************************************************************/
/* */
/* callback for vertex coordinates */
/* */
/****************************************************************************/
void pVGRID(float *xyz)
{
MULTIGRID *mg;
ELEMENT *e;
VERTEX *v;
int i;
mg = GetCurrentMultigrid();
ClearVertexMarkers(mg);
SURFACE_LOOP_BEGIN(mg, e)
for (i = 0; i < CORNERS_OF_ELEM(e); i++) {
v = MYVERTEX(CORNER(e, i));
if (USED(v)) continue;
SETUSED(v, 1);
*xyz++ = XC(v);
*xyz++ = YC(v);
*xyz++ = ZC(v);
}
/****************************************************************************/
/* */
/* callback for surface data */
/* */
/****************************************************************************/
void pVSURFACE(int *nsurf, int *scon, int *scel, char *tsurf, int tsurf_len)
{
MULTIGRID *mg;
ELEMENT *e;
VERTEX *v;
int i, j, n;
mg = GetCurrentMultigrid();
/* domain surface */
n = 0;
for (i = 0; i < SIDES_OF_ELEM(e); i++)
scel[3] = 0;
for (j = 0; j < CORNERS_OF_SIDE(e, i); j++)
scel[j] = ID(MYVERTEX(CORNER(e, CORNER_OF_SIDE(e, i, j))))+1;
scel += 4;
n++;
}
}
SURFACE_LOOP_END
nsurf[0] = n;
nsurf[1] = 2;
nsurf[2] = 1;
fstring(tsurf, "Domain Surface", 20);
}
/****************************************************************************/
/* */
/* callback for scalar data */
/* */
/****************************************************************************/
void pVSCAL(int *key, float *s)
{
MULTIGRID *mg;
ELEMENT *e;
VERTEX *v;
PreprocessingProcPtr pre;
ElementEvalProcPtr foo;
double *cc[MAX_CORNERS_OF_ELEM], lc[3];
int i, k;
k = (*key)-1;
mg = GetCurrentMultigrid();
pre = eval[k].s->PreprocessProc;
if (pre != NULL) pre(eval_name[k], mg);
foo = eval[k].s->EvalProc;
mg = GetCurrentMultigrid();
ClearVertexMarkers(mg);
SURFACE_LOOP_BEGIN(mg, e)
for (i = 0; i < CORNERS_OF_ELEM(e); i++)
cc[i] = CVECT(MYVERTEX(CORNER(e, i)));
for (i = 0; i < CORNERS_OF_ELEM(e); i++) {
v = MYVERTEX(CORNER(e, i));
if (USED(v)) continue;
SETUSED(v, 1);
LocalCornerCoordinates(3, TAG(e), i, lc);
*s++ = (float)foo(e, cc, lc);
}
/****************************************************************************/
/* */
/* callback for vector data */
/* */
/****************************************************************************/
void pVVECT(int *key, float *V)
{
MULTIGRID *mg;
ELEMENT *e;
VERTEX *v;
PreprocessingProcPtr pre;
ElementVectorProcPtr foo;
double *cc[MAX_CORNERS_OF_ELEM], lc[3], vv[3];
int i, k;
k = (*key)-1;
mg = GetCurrentMultigrid();
pre = eval[k].v->PreprocessProc;
if (pre != NULL) pre(eval_name[k], mg);
foo = eval[k].v->EvalProc;
mg = GetCurrentMultigrid();
ClearVertexMarkers(mg);
SURFACE_LOOP_BEGIN(mg, e)
for (i = 0; i < CORNERS_OF_ELEM(e); i++)
cc[i] = CVECT(MYVERTEX(CORNER(e, i)));
for (i = 0; i < CORNERS_OF_ELEM(e); i++) {
v = MYVERTEX(CORNER(e, i));
if (USED(v)) continue;
SETUSED(v, 1);
LocalCornerCoordinates(3, TAG(e), i, lc);
foo(e, cc, lc, vv);
*V++ = (float)vv[0];
*V++ = (float)vv[1];
*V++ = (float)vv[2];
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
}
/****************************************************************************/
/* */
/* pv3scal $k <key> $T <title> $ns <eval> $s <scal> $f <from> $t <to> */
/* */
/****************************************************************************/
static INT pv3ScalCommand(INT argc, char **argv)
{
char k, T[32], ns[NAMELEN], s[NAMELEN];
float f, t;
if (strncmp(argv[1],"k",1) != 0) return PARAMERRORCODE;
sscanf(argv[1], "k %c", &k);
if (strncmp(argv[2],"T",1) != 0) return PARAMERRORCODE;
sscanf(argv[2], "T %s", T);
if (strncmp(argv[3],"ns",2) != 0) return PARAMERRORCODE;
sscanf(argv[3], "ns %s", ns);
if (strncmp(argv[4],"s",1) != 0) return PARAMERRORCODE;
sscanf(argv[4], "s %s", s);
if (strncmp(argv[5],"f",1) != 0) return PARAMERRORCODE;
sscanf(argv[5], "f %f", &f);
if (strncmp(argv[6],"t",1) != 0) return PARAMERRORCODE;
sscanf(argv[6], "t %f", &t);
ikeys[nkeys] = k;
fstring(tkeys[nkeys], T, 32);
fkeys[nkeys] = 1;
flims[nkeys][0] = f;
flims[nkeys][1] = t;
eval[nkeys].s = GetElementValueEvalProc(ns);
strcpy(eval_name[nkeys], s);
nkeys++;
return OKCODE;
}
/****************************************************************************/
/* */
/* pv3vect $k <key> $T <title> $nv <eval> $s <vect> $f <scale> */
/* */
/****************************************************************************/
static INT pv3VectCommand(INT argc, char **argv)
{
char k, T[32], nv[NAMELEN], s[NAMELEN];
float f;
if (strncmp(argv[1],"k",1) != 0) return PARAMERRORCODE;
sscanf(argv[1], "k %c", &k);
if (strncmp(argv[2],"T",1) != 0) return PARAMERRORCODE;
sscanf(argv[2], "T %s", T);
if (strncmp(argv[3],"nv",2) != 0) return PARAMERRORCODE;
sscanf(argv[3], "nv %s", nv);
if (strncmp(argv[4],"s",1) != 0) return PARAMERRORCODE;
sscanf(argv[4], "s %s", s);
if (strncmp(argv[5],"f",1) != 0) return PARAMERRORCODE;
sscanf(argv[5], "f %f", &f);
ikeys[nkeys] = k;
fstring(tkeys[nkeys], T, 32);
fkeys[nkeys] = 2;
flims[nkeys][0] = f;
flims[nkeys][1] = f;
eval[nkeys].v = GetElementVectorEvalProc(nv);
strcpy(eval_name[nkeys], s);
nkeys++;
return OKCODE;
}
/****************************************************************************/
/* */
/* pv3plot */
/* */
/****************************************************************************/
static INT pv3PlotCommand(INT argc, char **argv)
{
iopt = 0; /* steady grid & data */
istat = 3; /* wait for and terminate with pV3 server */
cid = me+1;
pV_INIT(title, &cid, cname, dname, &iopt, &npgcut, tpgcut[0],
&nkeys, ikeys, tkeys[0], fkeys, flims[0], &mirror, repmat,
&maxblk, &istat, strlen(title), strlen(cname), strlen(dname),
32, 32);
if (istat != 0) return CMDERRORCODE;
return OKCODE;
}
/****************************************************************************/
INT InitPV3(void)
{
if (CreateCommand("pv3scal", pv3ScalCommand) == NULL) return __LINE__;
if (CreateCommand("pv3vect", pv3VectCommand) == NULL) return __LINE__;
if (CreateCommand("pv3plot", pv3PlotCommand) == NULL) return __LINE__;
return 0;
}