MACSio  0.9
Multi-purpose, Application-Centric, Scalable I/O Proxy App
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
macsio_exodus.c
Go to the documentation of this file.
1 /*
2 Copyright (c) 2015, Lawrence Livermore National Security, LLC.
3 Produced at the Lawrence Livermore National Laboratory.
4 Written by Mark C. Miller
5 
6 LLNL-CODE-676051. All rights reserved.
7 
8 This file is part of MACSio
9 
10 Please also read the LICENSE file at the top of the source code directory or
11 folder hierarchy.
12 
13 This program is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License (as published by the Free Software
15 Foundation) version 2, dated June 1991.
16 
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU General
20 Public License for more details.
21 
22 You should have received a copy of the GNU General Public License along with
23 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
24 Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26 
27 #include <assert.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include <macsio_clargs.h>
34 #include <macsio_data.h>
35 #include <macsio_iface.h>
36 #include <macsio_log.h>
37 #include <macsio_main.h>
38 #include <macsio_mif.h>
39 #include <macsio_utils.h>
40 
41 #include <exodusII.h>
42 
43 #ifdef HAVE_MPI
44 #include <mpi.h>
45 #endif
46 
47 #define MAX_STRING_LEN 128
48 
59 /* the name you want to assign to the interface */
60 static char const *iface_name = "exodus";
61 static char const *iface_ext = "exoII";
62 static char *cpu_word_size = "double";
63 static char io_word_size[32];
64 static int use_nemesis = 0;
65 static char use_large_model[32];
66 
67 typedef struct _ex_global_init_params {
71  int num_dim;
72  int num_nodes;
73  int num_elems;
77 
78  /* not really global initialization state but is useful to include
79  in this struct to facilitate file open vs. create */
80  int dumpn;
81  double dumpt;
83 
84 static int process_args(int argi, int argc, char *argv[])
85 {
86  const MACSIO_CLARGS_ArgvFlags_t argFlags = {
90  char *io_word_size_ptr = &io_word_size[0];
91  char *use_large_model_ptr = &use_large_model[0];
92 
93  MACSIO_CLARGS_ProcessCmdline(0, argFlags, argi, argc, argv,
94  "--io_word_size %s", "double",
95  "Specify precision of data that lands in exodus file as either \"float\" or \"double\"",
96  &io_word_size_ptr,
97  "--use_nemesis", "",
98  "Output nemesis stuff too",
99  &use_nemesis,
100  "--use_large_model %s", "auto",
101  "Use EX_LARGE_MODEL: specify one of \"always\", \"auto\", \"never\"",
102  &use_large_model_ptr,
104 
105  return 0;
106 }
107 
118 static void *CreateExodusFile(const char *fname, const char *nsname, void *userData)
119 {
120  ex_global_init_params_t *params = (ex_global_init_params_t *) userData;
121  int exoid;
122 
123  if (params->dumpn)
124  {
125  float version;
126  int *exoid_ptr;
127 
128  exoid = ex_open(fname, EX_WRITE, &(params->cpu_word_size), &(params->io_word_size), &version);
129 
130  if (exoid >= 0)
131  {
132  int exo_err = ex_put_time(exoid, params->dumpn+1, &(params->dumpt));
133  if (exo_err == 0)
134  {
135  exoid_ptr = (int *) malloc(sizeof(int));
136  *exoid_ptr = exoid;
137  return exoid_ptr;
138  }
139  }
140 
141  return 0;
142  }
143 
144  exoid = ex_create(fname, params->file_creation_flags,
145  &(params->cpu_word_size), &(params->io_word_size));
146 
147  if (exoid >= 0)
148  {
149  int exo_err;
150  int *exoid_ptr = (int *) malloc(sizeof(int));
151  *exoid_ptr = exoid;
152 
153  exo_err = ex_put_init(exoid, "MACSio performance test of Exodus library",
154  params->num_dim, params->num_nodes, params->num_elems, params->num_elem_block,
155  params->num_node_sets, params->num_side_sets);
156 
157  if (exo_err == 0)
158  exo_err = ex_put_time(exoid, params->dumpn+1, &(params->dumpt));
159 
160  if (exo_err == 0)
161  return exoid_ptr;
162 
163  return 0;
164  }
165 
166  return 0;
167 }
168 
169 #warning HOW DO WE WRITE NEW TIMES TO SAME FILES WITH MACSIO_MIF INTERFACE?
170 static void *OpenExodusFile(const char *fname, const char *nsname, MACSIO_MIF_ioFlags_t ioFlags,
171  void *userData)
172 {
173  static const int OpenExodusFile_should_never_be_called = 1;
174  assert(!OpenExodusFile_should_never_be_called);
175 }
176 
177 static void CloseExodusFile(void *file, void *userData)
178 {
179  int exoid = *((int*) file);
180  if (exoid >= 0)
181  ex_close(exoid);
182  free(file);
183 }
184 
185 static void get_exodus_global_init_params(json_object *main_obj, int dumpn, double dumpt,
186  ex_global_init_params_t* params)
187 {
188  int i;
189  long long num_nodes = 0, num_elems = 0;
190  long long const large_model = (1LL << 31); /* 2 Gigabytes */
191  int num_dumps = JsonGetInt(main_obj, "clargs/num_dumps");
192  json_object *parts = JsonGetObj(main_obj, "problem/parts");
193 
194  params->num_elem_block = json_object_array_length(parts);
195  params->num_dim = JsonGetInt(parts, "0/Mesh/GeomDim");
196 
197  for (i = 0; i < params->num_elem_block; i++)
198  {
199  json_object *part = JsonGetObj(parts, "", i);
200 
201  int nnodes = 1, nzones = 1;
202  int nodes[3], zones[3];
203 
204  nodes[0] = JsonGetInt(part, "Mesh/LogDims", 0);
205  nnodes *= nodes[0];
206  zones[0] = nodes[0]-1;
207  nzones *= zones[0];
208  if (params->num_dim > 1)
209  {
210  nodes[1] = JsonGetInt(part, "Mesh/LogDims", 1);
211  nnodes *= nodes[1];
212  zones[1] = nodes[1]-1;
213  nzones *= zones[1];
214  }
215  if (params->num_dim > 2)
216  {
217  nodes[2] = JsonGetInt(part, "Mesh/LogDims", 2);
218  nnodes *= nodes[2];
219  zones[2] = nodes[2]-1;
220  nzones *= zones[2];
221  }
222 
223  num_nodes += nnodes;
224  num_elems += nzones;
225  }
226 
227  /* word sizes */
228  if (!strncasecmp(cpu_word_size, "double", 6))
229  params->cpu_word_size = sizeof(double);
230  else if (!strncasecmp(cpu_word_size, "float", 5))
231  params->cpu_word_size = sizeof(float);
232 
233  if (!strncasecmp(io_word_size, "double", 6))
234  params->io_word_size = sizeof(double);
235  else if (!strncasecmp(io_word_size, "float", 5))
236  params->io_word_size = sizeof(float);
237 
238  /* File creation flags */
239  params->file_creation_flags = EX_CLOBBER | EX_NOSHARE;
240  if (!strncasecmp(use_large_model, "always", 6))
241  params->file_creation_flags |= EX_LARGE_MODEL;
242  else if (!strncasecmp(use_large_model, "never", 6))
243  params->file_creation_flags |= EX_NORMAL_MODEL;
244  else if (!strncasecmp(use_large_model, "auto", 4))
245  {
246  long long dataset_size = (long long) num_dumps * num_nodes * (long long) params->io_word_size;
247  if (dataset_size > large_model)
248  {
249  params->file_creation_flags |= EX_LARGE_MODEL;
250  MACSIO_LOG_MSG(Warn, ("Auto size estimate %lld requires EX_LARGE_MODEL", dataset_size));
251  }
252  else
253  params->file_creation_flags |= EX_NORMAL_MODEL;
254  }
255 
256  params->num_elems = (int) num_elems;
257  params->num_nodes = (int) num_nodes;
258  if ((long long) params->num_nodes != num_nodes)
259  MACSIO_LOG_MSG(Warn, ("num_nodes %lld too large for int", num_nodes));
260 
261  params->num_node_sets = 0;
262  params->num_side_sets = 0;
263 
264  /* this is needed to facilitate MIF create callback behavior */
265  params->dumpn = dumpn;
266  params->dumpt = dumpt;
267 }
268 
269 static void write_rect_mesh_coords_all_parts(int exoid, ex_global_init_params_t const *params,
270  json_object *parts, int **elem_block_coord_offsets)
271 {
272  int p, exo_err, n = 0;
273 #warning FIX BUG IN JSON-C LIB FOR THIS CALL
274 #if 0
275  int num_parts = JsonGetInt(parts,"");
276 #else
277  int num_parts = json_object_array_length(parts);
278 #endif
279  int *coord_offsets = (int *) malloc(num_parts * sizeof(int));
280  double *exo_x_coords = 0, *exo_y_coords = 0, *exo_z_coords = 0;
281 
282  exo_x_coords = (double *) malloc(params->num_nodes * sizeof(double));
283  if (params->num_dim > 1)
284  exo_y_coords = (double *) malloc(params->num_nodes * sizeof(double));
285  if (params->num_dim > 2)
286  exo_z_coords = (double *) malloc(params->num_nodes * sizeof(double));
287 
288 #warning WE ARE DUPING COORDS ON PART BOUNDARIES AND WE SHOULD NOT BE
289  for (p = 0; p < num_parts; p++)
290  {
291  int i, j, k, dims[3] = {1,1,1};
292  double *coords[3];
293  json_object *coordobj;
294  json_object *part = JsonGetObj(parts, "", p);
295 
296  coordobj = JsonGetObj(part, "Mesh/Coords/XAxisCoords");
297  coords[0] = (double*) json_object_extarr_data(coordobj);
298  dims[0] = JsonGetInt(part, "Mesh/LogDims", 0);
299  if (params->num_dim > 1)
300  {
301  coordobj = JsonGetObj(part, "Mesh/Coords/YAxisCoords");
302  coords[1] = (double*) json_object_extarr_data(coordobj);
303  dims[1] = JsonGetInt(part, "Mesh/LogDims", 1);
304  }
305  if (params->num_dim > 2)
306  {
307  coordobj = JsonGetObj(part, "Mesh/Coords/ZAxisCoords");
308  coords[2] = (double*) json_object_extarr_data(coordobj);
309  dims[2] = JsonGetInt(part, "Mesh/LogDims", 2);
310  }
311 
312  coord_offsets[p] = n;
313 
314  for (i = 0; i < dims[0]; i++)
315  {
316  for (j = 0; j < dims[1]; j++)
317  {
318  for (k = 0; k < dims[2]; k++, n++)
319  {
320  exo_x_coords[n] = coords[0][i];
321  if (params->num_dim > 1)
322  {
323  exo_y_coords[n] = coords[1][j];
324  if (params->num_dim > 2)
325  exo_z_coords[n] = coords[2][k];
326  }
327  }
328  }
329  }
330  }
331 
332  exo_err = ex_put_coord(exoid, exo_x_coords, exo_y_coords, exo_z_coords);
333 
334  if (exo_x_coords) free(exo_x_coords);
335  if (exo_y_coords) free(exo_y_coords);
336  if (exo_z_coords) free(exo_z_coords);
337 
338  *elem_block_coord_offsets = coord_offsets;
339 }
340 
341 static void write_mesh_coords_all_parts(int exoid, ex_global_init_params_t const *params,
342  json_object *parts, int **elem_block_coord_offsets)
343 {
344  if (!strcmp(JsonGetStr(parts, "0/Mesh/MeshType"), "rectilinear"))
345  write_rect_mesh_coords_all_parts(exoid, params, parts, elem_block_coord_offsets);
346 }
347 
348 /* Write the different mesh parts as different element blocks over a
349  single set of coordinates */
350 static void write_mesh_part_blocks_and_vars(int exoid, ex_global_init_params_t const *params,
351  json_object *part, int coord_offset, int dumpn, double dumpt)
352 {
353  int i,j;
354  int num_elems_in_dim[3] = {1,1,1};
355  int elem_block_id = JsonGetInt(part, "Mesh/ChunkID")+1;
356  int nodes_per_elem = params->num_dim==2?4:8;
357  int num_elems_in_block = JsonGetInt(part, "Mesh/LogDims", 0)-1;
358  json_object *vars_array = JsonGetObj(part, "Vars");
359  int *connect;
360 
361  num_elems_in_dim[0] = JsonGetInt(part, "Mesh/LogDims", 0)-1;
362  if (params->num_dim > 1)
363  {
364  num_elems_in_dim[1] = JsonGetInt(part, "Mesh/LogDims", 1)-1;
365  num_elems_in_block *= (JsonGetInt(part, "Mesh/LogDims", 1)-1);
366  }
367  if (params->num_dim > 2)
368  {
369  num_elems_in_dim[2] = JsonGetInt(part, "Mesh/LogDims", 2)-1;
370  num_elems_in_block *= (JsonGetInt(part, "Mesh/LogDims", 2)-1);
371  }
372 
373  ex_put_elem_block(exoid, elem_block_id, params->num_dim==2?"QUAD":"HEX",
374  num_elems_in_block, nodes_per_elem, 0);
375 
376 #warning ONLY NEED TO DO CONNECT STUFF ONCE
377  connect = (int *) malloc(nodes_per_elem * num_elems_in_block * sizeof(int));
378 
379  for (i = 0; i < num_elems_in_block; i++)
380  for (j = 0; j < nodes_per_elem; j++)
381  connect[i*nodes_per_elem+j] =
382  i/(num_elems_in_dim[0]*num_elems_in_dim[1]) + /* Offset for crossing 3D slice dim boundaries */
383  i/num_elems_in_dim[0] + /* Offset for crossing 2D row dim boundaries */
384  coord_offset + /* Offset for coordinates from each block */
385  i + /* Offset into this block of elems */
386  JsonGetInt(part, "Mesh/Topology/Template", j) + /* Offset for nodes in template elem */
387  1; /* Offset for 1-origin indexing */
388 
389  ex_put_elem_conn(exoid, elem_block_id, connect);
390  if (connect) free(connect);
391 
392 #if 0
393  exo_err = ex_put_id_map(exoid, EX_NODE_MAP, node_map);
394  exo_err = ex_put_id_map(exoid, EX_ELEM_MAP, elem_map);
395 #endif
396 
397  /* Output variables */
398  {
399  int ev = 0;
400  int num_elem_vars = 0;
401  char **elem_var_names = 0;
402 
403  for (i = 0; i < json_object_array_length(vars_array); i++)
404  {
405  json_object *varobj = json_object_array_get_idx(vars_array, i);
406  if (strcmp(JsonGetStr(varobj, "centering"), "zone")) continue;
407  num_elem_vars++;
408  }
409  if (num_elem_vars)
410  elem_var_names = (char **) malloc(num_elem_vars * sizeof(char*));
411 
412  ex_put_var_param(exoid, "e", num_elem_vars);
413 
414  for (i = 0; i < json_object_array_length(vars_array); i++)
415  {
416  json_object *varobj = json_object_array_get_idx(vars_array, i);
417  if (strcmp(JsonGetStr(varobj, "centering"), "zone")) continue;
418  elem_var_names[ev] = (char *) malloc((MAX_STRING_LEN+1) * sizeof (char));
419  snprintf(elem_var_names[ev], MAX_STRING_LEN, "%s", JsonGetStr(varobj, "name"));
420  ev++;
421  }
422 
423  if (num_elem_vars)
424  {
425  ex_put_variable_names(exoid, EX_ELEM_BLOCK, num_elem_vars, elem_var_names);
426  for (i = 0; i < num_elem_vars; i++)
427  free(elem_var_names[i]);
428  free(elem_var_names);
429  }
430 
431 #warning MOVE TO MORE GLOBAL PLACE IN DUMP SEQUENCE
432  ex_put_time(exoid, dumpn+1, &dumpt);
433 
434  ev = 1;
435  for (i = 0; i < json_object_array_length(vars_array); i++)
436  {
437  json_object *varobj = json_object_array_get_idx(vars_array, i);
438  json_object *dataobj = JsonGetObj(varobj, "data");
439  json_extarr_type etype = json_object_extarr_type(dataobj);
440  void const *dbuf = json_object_extarr_data(dataobj);
441  void *vbuf = 0;
442 
443  if (strcmp(JsonGetStr(varobj, "centering"), "zone")) continue;
444 
445  if (params->cpu_word_size == sizeof(double) && etype != json_extarr_type_flt64)
446  json_object_extarr_data_as_double(dataobj, (double**) &vbuf);
447  else if (params->cpu_word_size == sizeof(float) && etype != json_extarr_type_flt32)
448  json_object_extarr_data_as_float(dataobj, (float**) &vbuf);
449 
450  ex_put_var(exoid, dumpn+1, EX_ELEM_BLOCK, ev++, elem_block_id, num_elems_in_block, vbuf?vbuf:dbuf);
451 
452  if (vbuf) free(vbuf);
453  }
454  }
455 }
456 
457 static void WriteNemesis(json_object *main_obj, int exoid, int dumpn, MACSIO_MIF_baton_t *bat)
458 {
459  int i, j;
460  char const *file_ext = JsonGetStr(main_obj, "clargs/fileext");
461  char const *file_base = JsonGetStr(main_obj, "clargs/filebase");
462  int numChunks = JsonGetInt(main_obj, "problem/global/TotalParts");
463  char **blockNames = (char **) malloc(numChunks * sizeof(char*));
464  int *blockTypes = (int *) malloc(numChunks * sizeof(int));
465 }
466 
467 static void WriteDecompMesh(json_object *main_obj, int exoid, int dumpn, MACSIO_MIF_baton_t *bat)
468 {
469  int i, ndims = JsonGetInt(main_obj, "clargs/part_dim");
470  int total_parts = JsonGetInt(main_obj, "problem/global/TotalParts");
471  int zdims[3] = {0, 0, 0}, dims[3] = {0, 0, 0};
472  double bounds[6] = {0, 0, 0, 0, 0, 0};
473  char const *coordnames[] = {"X","Y","Z"};
474  double *coords[3];
475  double *color = (double *) malloc(total_parts * sizeof(double));
476 
477  if (ndims >= 1)
478  {
479  double *x, xdelta;
480  dims[0] = JsonGetInt(main_obj, "problem/global/PartsLogDims/0")+1;
481  bounds[0] = JsonGetInt(main_obj, "problem/global/Bounds/0");
482  bounds[3] = JsonGetInt(main_obj, "problem/global/Bounds/3");
483  x = (double*) malloc(dims[0] * sizeof(double));
484  xdelta = MACSIO_UTILS_XDelta(dims, bounds);
485  for (i = 0; i < dims[0]; i++)
486  x[i] = bounds[0] + i * xdelta;
487  coords[0] = x;
488  }
489 
490  if (ndims >= 2)
491  {
492  double *y, ydelta;
493  dims[1] = JsonGetInt(main_obj, "problem/global/PartsLogDims/1")+1;
494  bounds[1] = JsonGetInt(main_obj, "problem/global/Bounds/1");
495  bounds[4] = JsonGetInt(main_obj, "problem/global/Bounds/4");
496  y = (double*) malloc(dims[1] * sizeof(double));
497  ydelta = MACSIO_UTILS_YDelta(dims, bounds);
498  for (i = 0; i < dims[1]; i++)
499  y[i] = bounds[1] + i * ydelta;
500  coords[1] = y;
501  }
502 
503  if (ndims >= 3)
504  {
505  double *z, zdelta;
506  dims[2] = JsonGetInt(main_obj, "problem/global/PartsLogDims/2")+1;
507  bounds[2] = JsonGetInt(main_obj, "problem/global/Bounds/2");
508  bounds[5] = JsonGetInt(main_obj, "problem/global/Bounds/5");
509  z = (double*) malloc(dims[2] * sizeof(double));
510  zdelta = MACSIO_UTILS_ZDelta(dims, bounds);
511  for (i = 0; i < dims[2]; i++)
512  z[i] = bounds[2] + i * zdelta;
513  coords[2] = z;
514  }
515 
516  for (i = 0; i < total_parts; i++)
517  color[i] = MACSIO_DATA_GetRankOwningPart(main_obj, i);
518  for (i = 0; i < ndims; i++)
519  zdims[i] = dims[i]-1;
520 }
521 
522 static void main_dump(int argi, int argc, char **argv, json_object *main_obj, int dumpn, double dumpt)
523 {
524  int numGroups = -1;
525  int rank, size;
526  int *exoid_ptr;
527  int *elem_block_coord_offsets = 0;
528  char fileName[256];
529  ex_global_init_params_t ex_globals;
530  MACSIO_MIF_baton_t *bat;
532  JsonGetInt(main_obj, "clargs/exercise_scr")&0x1};
533 
534  /* Without this barrier, I get strange behavior with MACSIO_MIF interface */
535 #warning CONFIRM THIS IS STILL NEEDED
536  mpi_errno = MPI_Barrier(MACSIO_MAIN_Comm);
537 
538  /* process cl args */
539  process_args(argi, argc, argv);
540 
541  rank = JsonGetInt(main_obj, "parallel/mpi_rank");
542  size = JsonGetInt(main_obj, "parallel/mpi_size");
543 
544 #warning MOVE TO A FUNCTION
545  /* ensure we're in MIF mode and determine the file count */
546  json_object *parfmode_obj = JsonGetObj(main_obj, "clargs/parallel_file_mode");
547  if (parfmode_obj)
548  {
549  json_object *modestr = json_object_array_get_idx(parfmode_obj, 0);
550  json_object *filecnt = json_object_array_get_idx(parfmode_obj, 1);
551  if (modestr && !strcmp(json_object_get_string(modestr), "SIF"))
552  {
553  MACSIO_LOG_MSG(Die, ("Exodus plugin doesn't support SIF mode"));
554  }
555  else if (modestr && strcmp(json_object_get_string(modestr), "MIFMAX"))
556  {
557  MACSIO_LOG_MSG(Warn, ("Exodus plugin supports only MIFMAX mode"));
558  }
559  numGroups = size;
560  }
561  else
562  {
563  char const * modestr = JsonGetStr(main_obj, "clargs/parallel_file_mode");
564  if (!strcmp(modestr, "SIF"))
565  {
566  MACSIO_LOG_MSG(Die, ("Exodus plugin doesn't support SIF mode"));
567  }
568  else if (strcmp(modestr, "MIFMAX"))
569  {
570  MACSIO_LOG_MSG(Warn, ("Exodus plugin supports only MIFMAX mode"));
571  }
572  numGroups = size;
573  }
574 
575  get_exodus_global_init_params(main_obj, dumpn, dumpt, &ex_globals);
576 
577  bat = MACSIO_MIF_Init(numGroups, ioFlags, MACSIO_MAIN_Comm, 1,
579 
580  /* Construct name for the file */
581  sprintf(fileName, "%s_exodus_%05d.%s",
582  JsonGetStr(main_obj, "clargs/filebase"),
583  MACSIO_MIF_RankOfGroup(bat, rank),
584  JsonGetStr(main_obj, "clargs/fileext"));
585 
586  /* Wait for write access to the file. All processors call this.
587  * Some processors (the first in each group) return immediately
588  * with write access to the file. Other processors wind up waiting
589  * until they are given control by the preceeding processor in
590  * the group when that processor calls "HandOffBaton" */
591  exoid_ptr = (int *) MACSIO_MIF_WaitForBaton(bat, fileName, 0);
592 
593  write_mesh_coords_all_parts(*exoid_ptr, &ex_globals,
594  JsonGetObj(main_obj, "problem/parts"), &elem_block_coord_offsets);
595 
596  int numParts = JsonGetInt(main_obj, "problem/parts"); /* returns array length */
597  for (int i = 0; i < numParts; i++)
598  {
599  json_object *this_part = JsonGetObj(main_obj, "problem/parts", i);
600  write_mesh_part_blocks_and_vars(*exoid_ptr, &ex_globals, this_part, elem_block_coord_offsets[i], dumpn, dumpt);
601  }
602  if (elem_block_coord_offsets) free(elem_block_coord_offsets);
603 
604 #if 0
605  /* If this is the 'root' processor, also write Exodus's Nemesis objects */
606  if (rank == 0)
607  {
608  WriteNemesis(main_obj, *exoid_ptr, dumpn, bat);
609 
610 #warning DECOMP MESH SHOULDN'T BE INCLUDED IN PERFORMANCE NUMBERS
611  /* output a top-level quadmesh and vars to indicate processor decomp */
612  if (MACSIO_LOG_DebugLevel >= 2)
613  {
614  WriteDecompMesh(main_obj, *exoid_ptr, dumpn, bat);
615  }
616  }
617 #endif
618 
619  /* Hand off the baton to the next processor. This winds up closing
620  * the file so that the next processor that opens it can be assured
621  * of getting a consistent and up to date view of the file's contents. */
622  MACSIO_MIF_HandOffBaton(bat, exoid_ptr);
623 
624  /* We're done using MACSIO_MIF, so finish it off */
625  MACSIO_MIF_Finish(bat);
626 }
627 
629 {
630  MACSIO_IFACE_Handle_t iface;
631 
632  if (strlen(iface_name) >= MACSIO_IFACE_MAX_NAME)
633  MACSIO_LOG_MSG(Die, ("Interface name \"%s\" too long",iface_name));
634 
635  /* Take this slot in the map */
636  strcpy(iface.name, iface_name);
637  strcpy(iface.ext, iface_ext);
638 
639  /* Must define at least these two methods */
640  iface.dumpFunc = main_dump;
642 
643  if (!MACSIO_IFACE_Register(&iface))
644  MACSIO_LOG_MSG(Die, ("Failed to register interface \"%s\"", iface_name));
645 
646  return 0;
647 }
648 
649 /* this one statement is the only statement requiring compilation by
650  a C++ compiler. That is because it involves initialization and non
651  constant expressions (a function call in this case). This function
652  call is guaranteed to occur during *initialization* (that is before
653  even 'main' is called) and so will have the effect of populating the
654  iface_map array merely by virtue of the fact that this code is linked
655  with a main. */
657 
#define JsonGetObj(OBJ,...)
Get the object at specified path.
Definition: json_object.h:771
static void write_rect_mesh_coords_all_parts(int exoid, ex_global_init_params_t const *params, json_object *parts, int **elem_block_coord_offsets)
int MACSIO_MIF_RankOfGroup(MACSIO_MIF_baton_t const *Bat, int rankInComm)
Rank of the group in which a given (global) rank exists.
Definition: macsio_mif.c:311
static void WriteNemesis(json_object *main_obj, int exoid, int dumpn, MACSIO_MIF_baton_t *bat)
static char io_word_size[32]
Definition: macsio_exodus.c:63
#define JsonGetStr(OBJ,...)
Get the string value at specified path.
Definition: json_object.h:765
void * MACSIO_MIF_WaitForBaton(MACSIO_MIF_baton_t *Bat, char const *fname, char const *nsname)
Wait for exclusive access to the group's file.
Definition: macsio_mif.c:210
static int register_this_interface()
#define MACSIO_CLARGS_WARN
Definition: macsio_clargs.h:35
int mpi_errno
Error code returned by most recent MPI call.
Definition: macsio_log.c:43
#define MACSIO_MIF_WRITE
Definition: macsio_mif.h:149
static char const * iface_name
Definition: macsio_exodus.c:60
void const * json_object_extarr_data(struct json_object *jso)
Definition: json_object.c:1206
static char use_large_model[32]
Definition: macsio_exodus.c:65
#define MACSIO_CLARGS_ASSIGN_ON
Definition: macsio_clargs.h:44
static int dummy
static void get_exodus_global_init_params(json_object *main_obj, int dumpn, double dumpt, ex_global_init_params_t *params)
int MACSIO_CLARGS_ProcessCmdline(void **retobj, MACSIO_CLARGS_ArgvFlags_t flags, int argi, int argc, char **argv,...)
static void WriteDecompMesh(json_object *main_obj, int exoid, int dumpn, MACSIO_MIF_baton_t *bat)
int MACSIO_IFACE_Register(MACSIO_IFACE_Handle_t const *iface)
Definition: macsio_iface.c:35
static void * CreateExodusFile(const char *fname, const char *nsname, void *userData)
MIF Create callback.
void MACSIO_MIF_Finish(MACSIO_MIF_baton_t *bat)
End a MACSIO_MIF I/O operation and free resources.
Definition: macsio_mif.c:191
int MACSIO_LOG_DebugLevel
Definition: macsio_log.c:44
static char const * iface_ext
Definition: macsio_exodus.c:61
ProcessArgsFunc processArgsFunc
Definition: macsio_iface.h:59
static void write_mesh_part_blocks_and_vars(int exoid, ex_global_init_params_t const *params, json_object *part, int coord_offset, int dumpn, double dumpt)
static int process_args(int argi, int argc, char *argv[])
Definition: macsio_exodus.c:84
#define MACSIO_IFACE_MAX_NAME
Definition: macsio_iface.h:33
json_extarr_type
Definition: json_object.h:120
int json_object_array_length(struct json_object *obj)
Definition: json_object.c:854
static void CloseExodusFile(void *file, void *userData)
static void main_dump(int argi, int argc, char **argv, json_object *main_obj, int dumpn, double dumpt)
#define JsonGetInt(OBJ,...)
Get the int value at specified path.
Definition: json_object.h:747
double MACSIO_UTILS_YDelta(int const *dims, double const *bounds)
Definition: macsio_utils.c:236
double MACSIO_UTILS_ZDelta(int const *dims, double const *bounds)
Definition: macsio_utils.c:241
#define MACSIO_CLARGS_END_OF_ARGS
Definition: macsio_clargs.h:53
const char * json_object_get_string(struct json_object *obj)
Definition: json_object.c:751
char ext[MACSIO_IFACE_MAX_NAME]
Definition: macsio_iface.h:55
#define MACSIO_CLARGS_TOMEM
Definition: macsio_clargs.h:39
struct json_object * json_object_array_get_idx(struct json_object *obj, int idx)
Definition: json_object.c:870
int MACSIO_DATA_GetRankOwningPart(json_object *main_obj, int chunkId)
Definition: macsio_data.c:946
#define MAX_STRING_LEN
Definition: macsio_exodus.c:47
MACSIO_MIF_baton_t * MACSIO_MIF_Init(int numFiles, MACSIO_MIF_ioFlags_t ioFlags, MPI_Comm mpiComm, int mpiTag, MACSIO_MIF_CreateCB createCb, MACSIO_MIF_OpenCB openCb, MACSIO_MIF_CloseCB closeCb, void *clientData)
Initialize MACSIO_MIF for a MIF I/O operation.
Definition: macsio_mif.c:102
char name[MACSIO_IFACE_MAX_NAME]
Definition: macsio_iface.h:54
static int use_nemesis
Definition: macsio_exodus.c:64
enum json_extarr_type json_object_extarr_type(struct json_object *jso)
Definition: json_object.c:1143
int json_object_extarr_data_as_float(struct json_object *jso, float **buf)
static void write_mesh_coords_all_parts(int exoid, ex_global_init_params_t const *params, json_object *parts, int **elem_block_coord_offsets)
double MACSIO_UTILS_XDelta(int const *dims, double const *bounds)
Definition: macsio_utils.c:231
static void * OpenExodusFile(const char *fname, const char *nsname, MACSIO_MIF_ioFlags_t ioFlags, void *userData)
static char * cpu_word_size
Definition: macsio_exodus.c:62
MPI_Comm MACSIO_MAIN_Comm
Definition: macsio_main.c:279
void MACSIO_MIF_HandOffBaton(MACSIO_MIF_baton_t const *Bat, void *file)
Release exclusive access to the group's file.
Definition: macsio_mif.c:284
#define MACSIO_LOG_MSG(SEV, MSG)
Convenience macro for logging a message to the main log.
Definition: macsio_log.h:133
struct _ex_global_init_params ex_global_init_params_t
int json_object_extarr_data_as_double(struct json_object *jso, double **buf)