[3d993d]: exodus / cbind / src / ex_create.c Maximize Restore History

Download this file

ex_create.c    420 lines (366 with data), 14.7 kB

  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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
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
/*
* Copyright (c) 2005 Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000 with Sandia Corporation, the U.S. Governement
* retains certain rights in this software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of Sandia Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*!
\note The ex_create_int() is an internal function called by
ex_create(). The user should call ex_create() and not ex_create_int().
The function ex_create() creates a new exodus file and returns an ID
that can subsequently be used to refer to the file.
All floating point values in an exodus file are stored as either
4-byte (\c float) or 8-byte (\c double) numbers; no mixing of 4- and
8-byte numbers in a single file is allowed. An application code can
compute either 4- or 8-byte values and can designate that the values
be stored in the exodus file as either 4- or 8-byte numbers;
conversion between the 4- and 8-byte values is performed automatically
by the API routines. Thus, there are four possible combinations of
compute word size and storage (or I/O) word size.
\return In case of an error, ex_create() returns a negative number. Possible
causes of errors include:
- Passing a file name that includes a directory that does not
exist.
- Specifying a file name of a file that exists and also
specifying a no clobber option.
- Attempting to create a file in a directory without permission
to create files there.
- Passing an invalid file clobber mode.
\param path The file name of the new exodus file. This can be given as either an
absolute path name (from the root of the file system) or a relative
path name (from the current directory).
\param cmode Mode. Use one of the following predefined constants:
\arg \c EX_NOCLOBBER To create the new file only if the given file name does not refer to a
file that already exists.
\arg \c EX_CLOBBER To create the new file, regardless of whether a file with the same
name already exists. If a file with the same name does exist, its
contents will be erased.
\arg \c EX_LARGE_MODEL To create a model that can store individual datasets larger than
2 gigabytes. This modifies the internal storage used by exodusII and
also puts the underlying NetCDF file into the \e 64-bit offset'
mode. See largemodel for more details on this
mode. A large model file will also be created if the
environment variable \c EXODUS_LARGE_MODEL is defined
in the users environment. A message will be printed to standard output
if this environment variable is found.
\arg \c EX_NORMAL_MODEL Create a standard model.
\arg \c EX_NETCDF4 To create a model using the HDF5-based NetCDF-4
output. An HDF5-based NetCDF-4 file will also be created if the
environment variable \c EXODUS_NETCDF4 is defined in the
users environment. A message will be printed to standard output if
this environment variable is found.
\arg \c EX_NOSHARE Do not open the underlying NetCDF file in \e share mode. See the
NetCDF documentation for more details.
\arg \c EX_SHARE Do open the underlying NetCDF file in \e share mode. See the NetCDF
documentation for more details.
\param[in,out] comp_ws The word size in bytes (0, 4 or 8) of the floating point variables
used in the application program. If 0 (zero) is passed, the default
sizeof(float) will be used and returned in this variable. WARNING: all
exodus functions requiring floats must be passed floats declared with
this passed in or returned compute word size (4 or 8).}
\param io_ws The word size in bytes (4 or 8) of the floating point
data as they are to be stored in the exodus file.
\param run_version (internally generated) used to verify compatability of libary and include files.
The following code segment creates an exodus file called \file{test.exo}:
\code
#include "exodusII.h"
int CPU_word_size, IO_word_size, exoid;
CPU_word_size = sizeof(float); \comment{use float or double}
IO_word_size = 8; \comment{store variables as doubles}
\comment{create exodus file}
exoid = ex_create ("test.exo" \comment{filename path}
EX_CLOBBER, \comment{create mode}
&CPU_word_size, \comment{CPU float word size in bytes}
&IO_word_size); \comment{I/O float word size in bytes}
\endcode
*/
#include "exodusII.h"
#include "exodusII_int.h"
#include <stdlib.h>
#include <assert.h>
static int warning_output = 0;
int ex_create_int (const char *path,
int cmode,
int *comp_ws,
int *io_ws,
int run_version)
{
int exoid, dims[1];
int status;
int dimid, time_dim;
int old_fill;
int lio_ws;
int filesiz;
float vers;
char errmsg[MAX_ERR_LENGTH];
char *mode_name;
int mode = 0;
#if defined(NC_NETCDF4)
static int netcdf4_mode = -1;
char *option;
#endif /* NC_NETCDF4 */
int int64_status;
unsigned int my_mode = cmode;
assert(my_mode == cmode);
exerrval = 0; /* clear error code */
if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
int run_version_major = run_version / 100;
int run_version_minor = run_version % 100;
int lib_version_major = EX_API_VERS_NODOT / 100;
int lib_version_minor = EX_API_VERS_NODOT % 100;
fprintf(stderr, "EXODUS: Warning: This code was compiled with exodusII version %d.%02d,\n but was linked with exodusII library version %d.%02d\n This is probably an error in the build process of this code.\n",
run_version_major, run_version_minor, lib_version_major, lib_version_minor);
warning_output = 1;
}
/*
* See if any integer data is to be stored as int64 (long long). If
* so, then need to set NC_NETCDF4 and unset NC_CLASSIC_MODEL (or
* set EX_NOCLASSIC. Output meaningful error message if the library
* is not NetCDF-4 enabled...
*/
int64_status = my_mode & (EX_ALL_INT64_DB | EX_ALL_INT64_API);
if ((int64_status & EX_ALL_INT64_DB) != 0) {
#if defined(NC_NETCDF4)
/* Library DOES support netcdf4... Set modes required to use
* netcdf-4 in non-classic mode
*/
my_mode |= EX_NOCLASSIC;
my_mode |= EX_NETCDF4;
#else
/* Library does NOT support netcdf4 */
exerrval = EX_BADPARAM;
sprintf(errmsg,
"EXODUS: Error: 64-bit integer storage requested, but the netcdf library does not support the required netcdf-4 extensions.\n");
ex_err("ex_create",errmsg,exerrval);
return (EX_FATAL);
#endif
}
#if defined(NC_NETCDF4)
if (my_mode & EX_NETCDF4) {
mode |= (NC_NETCDF4);
} else {
if (netcdf4_mode == -1) {
option = getenv("EXODUS_NETCDF4");
if (option != NULL) {
fprintf(stderr, "EXODUS: Using netcdf version 4 selected via EXODUS_NETCDF4 environment variable\n");
netcdf4_mode = NC_NETCDF4;
} else {
netcdf4_mode = 0;
}
}
mode |= netcdf4_mode;
}
if (! (my_mode & EX_NOCLASSIC)) {
mode |= NC_CLASSIC_MODEL;
}
#endif
/*
* See if "large file" mode was specified in a ex_create my_mode. If
* so, then pass the NC_64BIT_OFFSET flag down to netcdf.
* If netcdf4 mode specified, don't use NC_64BIT_OFFSET mode.
*/
if ( (my_mode & EX_LARGE_MODEL) && (my_mode & EX_NORMAL_MODEL)) {
exerrval = EX_BADPARAM;
sprintf(errmsg,
"Warning: conflicting mode specification for file %s, mode %d. Using normal",
path, (int)my_mode);
ex_err("ex_create",errmsg,exerrval);
}
if (my_mode & EX_NORMAL_MODEL)
filesiz = 0;
#if defined(NC_NETCDF4)
else if (mode & NC_NETCDF4)
filesiz = 1;
#endif
else
filesiz = (int)((my_mode & EX_LARGE_MODEL) || (ex_large_model(-1) == 1));
if (
#if defined(NC_NETCDF4)
!(mode & NC_NETCDF4) &&
#endif
filesiz == 1) {
mode |= NC_64BIT_OFFSET;
}
if (my_mode & EX_SHARE) {
mode |= NC_SHARE;
}
/*
* set error handling mode to no messages, non-fatal errors
*/
ex_opts(exoptval); /* call required to set ncopts first time through */
if (my_mode & EX_CLOBBER) {
mode |= NC_CLOBBER;
mode_name = "CLOBBER";
} else {
mode |= NC_NOCLOBBER;
mode_name = "NOCLOBBER";
}
if ((status = nc_create (path, mode, &exoid)) != NC_NOERR) {
exerrval = status;
if (my_mode & EX_NETCDF4) {
sprintf(errmsg,
"Error: file create failed for %s in NETCDF4 and %s mode.\n\tThis library probably does not support netcdf-4 files.",
path, mode_name);
} else {
sprintf(errmsg,
"Error: file create failed for %s, mode: %s",
path, mode_name);
}
ex_err("ex_create",errmsg,exerrval);
return (EX_FATAL);
}
/* turn off automatic filling of netCDF variables
*/
if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to set nofill mode in file id %d",
exoid);
ex_err("ex_create", errmsg, exerrval);
return (EX_FATAL);
}
/* initialize floating point size conversion. since creating new file,
* i/o wordsize attribute from file is zero.
*/
if (ex_conv_ini( exoid, comp_ws, io_ws, 0, int64_status ) != EX_NOERR) {
exerrval = EX_FATAL;
sprintf(errmsg,
"Error: failed to init conversion routines in file id %d",
exoid);
ex_err("ex_create", errmsg, exerrval);
return (EX_FATAL);
}
/* put the EXODUS version number, and i/o floating point word size as
* netcdf global attributes
*/
/* store Exodus API version # as an attribute */
vers = EX_API_VERS;
if ((status=nc_put_att_float(exoid, NC_GLOBAL, ATT_API_VERSION,
NC_FLOAT, 1, &vers)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to store Exodus II API version attribute in file id %d",
exoid);
ex_err("ex_create",errmsg, exerrval);
return (EX_FATAL);
}
/* store Exodus file version # as an attribute */
vers = EX_VERS;
if ((status=nc_put_att_float(exoid, NC_GLOBAL, ATT_VERSION, NC_FLOAT, 1, &vers)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to store Exodus II file version attribute in file id %d",
exoid);
ex_err("ex_create",errmsg, exerrval);
return (EX_FATAL);
}
/* store Exodus file float word size as an attribute */
lio_ws = (int)(*io_ws);
if ((status=nc_put_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, NC_INT, 1, &lio_ws)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to store Exodus II file float word size attribute in file id %d",
exoid);
ex_err("ex_create",errmsg, exerrval);
return (EX_FATAL);
}
/* store Exodus file size (1=large, 0=normal) as an attribute */
if ((status = nc_put_att_int (exoid, NC_GLOBAL, ATT_FILESIZE, NC_INT, 1, &filesiz)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to store Exodus II file size attribute in file id %d",
exoid);
ex_err("ex_create",errmsg, exerrval);
return (EX_FATAL);
}
/* define some dimensions and variables
*/
/* create string length dimension */
if ((status=nc_def_dim (exoid, DIM_STR, (MAX_STR_LENGTH+1), &dimid)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to define string length in file id %d",exoid);
ex_err("ex_create",errmsg,exerrval);
return (EX_FATAL);
}
/* The name string length dimension is delayed until the ex_put_init function */
/* create line length dimension */
if ((status = nc_def_dim(exoid, DIM_LIN, (MAX_LINE_LENGTH+1), &dimid)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to define line length in file id %d",exoid);
ex_err("ex_create",errmsg,exerrval);
return (EX_FATAL);
}
/* create number "4" dimension; must be of type long */
if ((status = nc_def_dim(exoid, DIM_N4, 4L, &dimid)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to define number \"4\" dimension in file id %d",exoid);
ex_err("ex_create",errmsg,exerrval);
return (EX_FATAL);
}
if ((status = nc_def_dim(exoid, DIM_TIME, NC_UNLIMITED, &time_dim)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to define time dimension in file id %d", exoid);
ex_err("ex_create",errmsg,exerrval);
return (EX_FATAL);
}
dims[0] = time_dim;
if ((status = nc_def_var(exoid, VAR_WHOLE_TIME, nc_flt_code(exoid), 1, dims, &dimid)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to define whole time step variable in file id %d",
exoid);
ex_err("ex_create",errmsg,exerrval);
return (EX_FATAL);
}
ex_compress_variable(exoid, dimid, 2);
{
int int64_db_status = int64_status & EX_ALL_INT64_DB;
if ((status=nc_put_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, NC_INT, 1, &int64_db_status)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to add int64_status attribute in file id %d",exoid);
ex_err("ex_put_init_ext",errmsg,exerrval);
return (EX_FATAL);
}
}
if ((status = nc_enddef (exoid)) != NC_NOERR) {
exerrval = status;
sprintf(errmsg,
"Error: failed to complete definition for file id %d", exoid);
ex_err("ex_create",errmsg,exerrval);
return (EX_FATAL);
}
return (exoid);
}