1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
|
/*@@
@routine WriteGF
@date Tue Apr 1 16:45:35 1997
@author Paul Walker
@desc
Dumps the "0D" data.
@enddesc
@calls
@calledby
@history
@hauthor Thomas Radke @hdate 17 Mar 1999
@hdesc included "cctk_Comm.h" to overload CCTK_GetMyProc() properly
@hendhistory
@@*/
#include <stdio.h>
#include <stdlib.h>
#include "cctk.h"
#include "cctk_Parameters.h"
#include "iobasicGH.h"
void IOBasic_WriteGF (cGH *GH, int index, const char *alias)
{
DECLARE_CCTK_PARAMETERS
int i;
iobasicGH *myGH;
FILE *file;
char *openmode;
char *filename;
char title_start_char;
int reduction_handle;
CCTK_REAL reduction_value;
/* add more reductions to this table if you want, telling it
- the reduction operator
- the label for the file header
- the filename extension (suffixed by ".tl" for trace line) */
const struct {
char *operator;
char *label;
char *extension;
} reductions [] = {
{"minimum", "min", "min"},
{"maximum", "max", "max"},
{"norm1", "norm1", "nm1"},
{"norm2", "norm2", "nm2"},
};
#define NUM_REDUCTIONS (sizeof (reductions) / sizeof (reductions [0]))
/* first, check if variable has storage assigned */
if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (index))) {
char *msg, *fullname;
fullname = CCTK_FullName (index);
msg = (char *) malloc (200 * sizeof (char) + strlen (fullname));
sprintf (msg, "No 0D output for '%s' (no storage)", fullname);
CCTK_WARN (2, msg);
free (fullname);
free (msg);
return;
}
if (CCTK_Equals (outScalar_style, "gnuplot"))
title_start_char = '#';
else
title_start_char = 34; /* this is for xgraph */
myGH = (iobasicGH *) GH->extensions [CCTK_GHExtensionHandle ("IOBasic")];
/* the extra characters should be sufficient
for the longest filename extension */
filename = (char *)
malloc (strlen (myGH->outdirScalar) + strlen (alias) + 20);
/* now loop over all IOBasic reduction operations */
for (i = 0; i < NUM_REDUCTIONS; i++) {
/* get the reduction handle from the reduction operator */
reduction_handle = CCTK_ReductionHandle (reductions [i].operator);
if (reduction_handle < 0) {
char *msg = (char *) malloc (100 + strlen (reductions [i].operator));
sprintf (msg, "Invalid reduction operator '%s'", reductions [i].operator);
CCTK_WARN (3, msg);
free (msg);
continue;
}
/* do the reduction (all processors) */
CCTK_Reduce (GH, 0, reduction_handle, 1, CCTK_VARIABLE_REAL,
&reduction_value, 1, index);
/* dump the reduction value to file by processor 0 */
if (CCTK_MyProc (GH) == 0) {
/* build the filename */
sprintf (filename, "%s/%s_%s.tl", myGH->outdirScalar, alias,
reductions [i].extension);
/* see if output files for this alias name were already created */
if (GetNamedData (myGH->filenameListScalar, filename) == NULL)
openmode = "w";
else
openmode = "a";
file = fopen (filename, openmode);
if (file == NULL) {
char *msg = (char *) malloc (100 + strlen (filename));
sprintf (msg, "Could not open output file '%s'", filename);
CCTK_WARN (3, msg);
free (msg);
continue;
}
/* when creating the file, write the header
and also save the filename in the database */
if (*openmode == 'w') {
fprintf (file, "%c%s %s v time\n", title_start_char, alias,
reductions [i].label);
/* just store a non-NULL pointer in database */
StoreNamedData (&myGH->filenameListScalar, filename, (void *) 1);
}
/* write the data and close the file */
fprintf (file, "%f %25.13f\n", GH->cctk_time, reduction_value);
fclose (file);
}
}
free (filename);
}
|