Exodus  7.10
/test/testwt-localization.C
/*
* Copyright (c) 2005-2017 National Technology & Engineering Solutions
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
* NTESS, the U.S. Government 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 NTESS 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.
*
*/
#include <array>
#include <iostream>
#include <numeric>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include "exodusII.h"
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define EXCHECK(funcall) \
do { \
if ((error = (funcall)) != NC_NOERR) { \
fprintf(stderr, "ERROR Calling %s, error = %d\n", TOSTRING(funcall), error); \
ex_close(exoid); \
exit(-1); \
} \
} while (0)
int main(int argc, char **argv)
{
/* Specify compute and i/o word size */
int CPU_word_size = 8; /* sizeof(float) */
int IO_word_size = 8; /* (4 bytes) */
int error;
/* create EXODUS II file */
int exoid = ex_create("test.exo", /* filename path */
EX_CLOBBER, /* create mode */
&CPU_word_size, /* CPU float word size in bytes */
&IO_word_size); /* I/O float word size in bytes */
/* initialize file with parameters */
constexpr int num_dim = 3;
constexpr int num_nodes = 64;
constexpr int num_elem = 9;
constexpr int num_elem_blk = 3;
constexpr int num_node_sets = 0;
constexpr int num_side_sets = 0;
std::string title = "This is a test";
EXCHECK(ex_put_init(exoid, title.c_str(), num_dim, num_nodes, num_elem, num_elem_blk,
num_node_sets, num_side_sets));
/* write nodal coordinates values and names to database */
/* Quad #1 */
std::array<double, num_nodes> x;
std::array<double, num_nodes> y;
std::array<double, num_nodes> z;
x[0] = 0.00;
x[1] = 0.75;
x[2] = 1.50;
x[3] = 2.25;
x[4] = 3.00;
x[5] = x[0];
x[6] = 1.125;
x[7] = 1.625;
x[8] = 3.000;
x[9] = x[0];
x[10] = 0.50;
x[11] = 1.00;
x[12] = x[2];
x[13] = 2.00;
x[14] = 2.50;
x[15] = 3.00;
x[16] = x[10];
x[17] = x[11];
x[18] = x[12];
x[19] = x[13];
x[20] = x[14];
x[21] = x[11];
x[22] = x[13];
x[23] = 0.0;
x[24] = x[6];
x[25] = x[7];
x[26] = 3.0;
x[27] = x[0];
x[28] = x[1];
x[29] = x[2];
x[30] = x[3];
x[31] = x[4];
y[0] = y[1] = y[2] = y[3] = y[4] = 0.00;
y[5] = 0.75;
y[6] = 0.50;
y[7] = y[6];
y[8] = y[5];
y[9] = 1.50;
y[10] = 1.25;
y[11] = y[12] = y[13] = 1.00;
y[14] = y[10];
y[15] = y[9];
y[16] = 1.75;
y[17] = y[18] = y[19] = 2.00;
y[20] = y[16];
y[21] = y[22] = y[9];
y[23] = y[26] = 2.25;
y[24] = y[25] = 2.50;
y[27] = y[28] = y[29] = y[30] = y[31] = 3.0;
for (int i = 0; i < num_nodes / 2; i++) {
z[i] = 0.0;
x[i + num_nodes / 2] = x[i];
y[i + num_nodes / 2] = y[i];
z[i + num_nodes / 2] = 1.0;
}
EXCHECK(ex_put_coord(exoid, x.data(), y.data(), z.data()));
std::array<const char *, 3> coord_names = {{"xcoor", "ycoor", "zcoor"}};
EXCHECK(ex_put_coord_names(exoid, (char **)coord_names.data()));
std::array<ex_block, num_elem_blk> blocks;
blocks[0].id = 10;
blocks[0].type = EX_ELEM_BLOCK;
blocks[0].num_entry = 4;
blocks[0].num_nodes_per_entry = 16;
blocks[1].id = 20;
blocks[1].type = EX_ELEM_BLOCK;
blocks[1].num_entry = 4;
blocks[1].num_nodes_per_entry = 12;
blocks[2].id = 30;
blocks[2].type = EX_ELEM_BLOCK;
blocks[2].num_entry = 1;
blocks[2].num_nodes_per_entry = 16;
strncpy(blocks[0].topology, "hex", 32);
strncpy(blocks[1].topology, "wedge", 32);
strncpy(blocks[2].topology, "hex", 32);
std::array<const char *, num_elem_blk> block_names{{"block_10", "block_20", "block_30"}};
EXCHECK(ex_put_block_params(exoid, num_elem_blk, blocks.data()));
/* Write element block names */
for (int i = 0; i < num_elem_blk; i++) {
EXCHECK(ex_put_name(exoid, EX_ELEM_BLOCK, blocks[i].id, block_names[i]));
}
/* write element connectivity */
std::array<int, 64> connect0{{1, 3, 12, 10, 2, 7, 11, 6, 3, 5, 16, 14, 4, 9, 15, 8,
10, 18, 30, 28, 17, 25, 29, 24, 20, 16, 32, 30, 21, 27, 31, 26}};
std::array<int, 48> connect1{{3, 14, 12, 8, 13, 7, 14, 16, 20, 15, 21, 23,
18, 20, 30, 19, 26, 25, 10, 12, 18, 11, 22, 17}};
std::array<int, 16> connect2{{12, 14, 20, 18, 13, 23, 19, 22}};
for (int i = 0; i < blocks[0].num_entry * blocks[0].num_nodes_per_entry / 2; i++) {
connect0[i + 32] = connect0[i] + 32;
}
for (int i = 0; i < blocks[1].num_entry * blocks[1].num_nodes_per_entry / 2; i++) {
connect1[i + 24] = connect1[i] + 32;
}
for (int i = 0; i < blocks[2].num_entry * blocks[2].num_nodes_per_entry / 2; i++) {
connect2[i + 8] = connect2[i] + 32;
}
EXCHECK(ex_put_conn(exoid, EX_ELEM_BLOCK, blocks[0].id, connect0.data(), NULL, NULL));
EXCHECK(ex_put_conn(exoid, EX_ELEM_BLOCK, blocks[1].id, connect1.data(), NULL, NULL));
EXCHECK(ex_put_conn(exoid, EX_ELEM_BLOCK, blocks[2].id, connect2.data(), NULL, NULL));
/* write information records; test empty and just blank-filled records */
constexpr int num_info = 3;
std::array<const char *, num_info> info;
info[0] = "This is the first information record.";
info[1] = "";
info[2] = " ";
EXCHECK(ex_put_info(exoid, num_info, (char **)info.data()));
/* write results variables parameters and names */
const int num_glo_vars = 1;
std::array<const char *, 4> var_names;
var_names[0] = "glo_vars";
EXCHECK(ex_put_variable_param(exoid, EX_GLOBAL, num_glo_vars));
EXCHECK(ex_put_variable_names(exoid, EX_GLOBAL, num_glo_vars, (char **)var_names.data()));
const int num_nod_vars = 2;
/* 12345678901234567890123456789012 */
var_names[0] = "node_variable_a_very_long_name_0";
var_names[1] = "nod_var1";
EXCHECK(ex_put_variable_param(exoid, EX_NODAL, num_nod_vars));
EXCHECK(ex_put_variable_names(exoid, EX_NODAL, num_nod_vars, (char **)var_names.data()));
const int num_ele_vars = 3;
/* 0 1 2 3 */
/* 12345678901234567890123456789012 */
var_names[0] = "this_variable_name_is_short";
var_names[1] = "this_variable_name_is_just_right";
var_names[2] = "this_variable_name_is_tooooo_long";
EXCHECK(ex_put_variable_names(exoid, EX_ELEM_BLOCK, num_ele_vars, (char **)var_names.data()));
// for each time step, write the analysis results;
// the code below fills the arrays glob_var_vals,
// nodal_var_vals, and elem_var_vals with values for debugging purposes;
int whole_time_step = 1;
const int num_time_steps = 10;
std::array<double, num_glo_vars> glob_var_vals;
std::array<double, num_nodes> nodal_var_vals;
std::array<double, 4> elem_var_vals;
for (int i = 0; i < num_time_steps; i++) {
double time_value = (float)(i + 1) / 100.;
/* write time value */
EXCHECK(ex_put_time(exoid, whole_time_step, &time_value));
// write global variables
for (int j = 0; j < num_glo_vars; j++) {
glob_var_vals[j] = (float)(j + 2) * time_value;
}
ex_put_var(exoid, whole_time_step, EX_GLOBAL, 1, 1, num_glo_vars, glob_var_vals.data()));
// write nodal variables
for (int k = 1; k <= num_nod_vars; k++) {
for (int j = 0; j < num_nodes; j++) {
nodal_var_vals[j] = (float)k + ((float)(j + 1) * time_value);
}
EXCHECK(ex_put_var(exoid, whole_time_step, EX_NODAL, k, 1, num_nodes, nodal_var_vals.data()));
}
// write element variables
for (int k = 1; k <= num_ele_vars; k++) {
for (int j = 0; j < num_elem_blk; j++) {
for (int m = 0; m < blocks[j].num_entry; m++) {
elem_var_vals[m] = (float)(k + 1) + (float)(j + 2) + ((float)(m + 1) * time_value);
}
EXCHECK(ex_put_var(exoid, whole_time_step, EX_ELEM_BLOCK, k, blocks[j].id,
blocks[j].num_entry, elem_var_vals.data()));
}
}
whole_time_step++;
// update the data file; this should be done at the end of every time step
// to ensure that no data is lost if the analysis dies
EXCHECK(ex_update(exoid));
}
// close the EXODUS files
EXCHECK(ex_close(exoid));
return 0;
}