You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1323 lines
41 KiB
1323 lines
41 KiB
/*
|
|
* Copyright(C) 1999-2021, 2023 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.
|
|
*
|
|
* See packages/seacas/LICENSE for details
|
|
*/
|
|
/* exodus II to matlab m file, copy of
|
|
exo2mat.
|
|
exo2mat was written by mrtabba
|
|
exo2m modifications by gmreese to permit usage on machines without
|
|
the matlab libraries.
|
|
|
|
modified by D. Todd Griffith, 01/12/2006
|
|
to include changes made in versions 1.4 through 1.6 on the
|
|
SEACAS tools repository as the previous modifications dated
|
|
12/08 and 12/15/2005 were made starting with Version 1.3.
|
|
In particular, the only changes are those made here are those
|
|
made in Version 1.6 which include a special provision
|
|
for exodus files which contain no distribution factors
|
|
modified by D. Todd Griffith, 12/15/2005
|
|
to write distribution factors as double precision type
|
|
modified by D. Todd Griffith 12/08/2005
|
|
to include complete writing of side set and node set information
|
|
so it will be available for the mat2exo conversion stage
|
|
|
|
*/
|
|
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cstring> // for strlen, etc
|
|
#include <iostream>
|
|
#include <numeric>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "add_to_log.h" // for add_to_log
|
|
#include "exodusII.h" // for ex_get_variable_param, etc
|
|
#include "fmt/chrono.h"
|
|
#include "fmt/ostream.h"
|
|
#include "fmt/printf.h"
|
|
#include "matio.h" // for Mat_VarCreate, Mat_VarFree, etc
|
|
#include "time_stamp.h"
|
|
|
|
#include <cassert> // for assert
|
|
#include <cstddef> // for size_t
|
|
#include <cstdlib> // for free, calloc, exit
|
|
#include <ctime>
|
|
#if MATIO_VERSION < 151
|
|
#error "MatIO Version 1.5.1 or greater is required"
|
|
#endif
|
|
|
|
#define EXT ".mat"
|
|
static int textfile = 0;
|
|
|
|
static FILE *m_file = nullptr; /* file for m file output */
|
|
static mat_t *mat_file = nullptr; /* file for binary .mat output */
|
|
static bool debug = false;
|
|
|
|
static std::array<std::string, 3> qainfo{"exo2mat", "2021/09/27", "4.08"};
|
|
|
|
void logger(const char *message)
|
|
{
|
|
const std::string tsFormat = "[%H:%M:%S] ";
|
|
fmt::print(std::clog, "{}: {}\n", time_stamp(tsFormat), message);
|
|
}
|
|
|
|
void usage()
|
|
{
|
|
auto v5default = MAT_FT_DEFAULT == MAT_FT_MAT5 ? "[default]" : "";
|
|
auto v7default = MAT_FT_DEFAULT == MAT_FT_MAT73 ? "[default]" : "";
|
|
fmt::print("exo2mat [options] exodus_file_name.\n"
|
|
" the exodus_file_name is required (exodus only).\n"
|
|
" Options:\n"
|
|
" -t write a text (.m) file rather than a binary .mat\n"
|
|
" -o output file name (rather than auto generate)\n"
|
|
" -c use cell arrays for transient variables.\n"
|
|
" -v5 output version 5 mat file {}\n"
|
|
" -v73 output version 7.3 mat file (hdf5-based) {}\n"
|
|
" -v7.3 output version 7.3 mat file (hdf5-based)\n"
|
|
" ** note **\n"
|
|
"Binary files are written by default on all platforms.\n", v5default, v7default);
|
|
}
|
|
|
|
/* put a string into an m file. If the string has
|
|
line feeds, we put it as ints, and use 'char()' to convert it */
|
|
void mPutStr(const std::string &name, const char *str)
|
|
{
|
|
assert(m_file != nullptr);
|
|
if (strchr(str, '\n') == nullptr) {
|
|
fmt::fprintf(m_file, "%s='%s';\n", name, str);
|
|
}
|
|
else {
|
|
fmt::fprintf(m_file, "%s=[", name);
|
|
size_t i;
|
|
size_t j;
|
|
for (j = i = 0; i < std::strlen(str); i++, j++) {
|
|
if (j >= 20) {
|
|
j = 0;
|
|
fmt::fprintf(m_file, "...\n");
|
|
}
|
|
fmt::fprintf(m_file, "%d ", str[i]);
|
|
}
|
|
fmt::fprintf(m_file, "];\n");
|
|
fmt::fprintf(m_file, "%s=char(%s);\n", name, name);
|
|
}
|
|
}
|
|
|
|
/* put double array in m file */
|
|
void mPutDbl(const std::string &name, int n1, int n2, double *pd)
|
|
{
|
|
assert(m_file != nullptr);
|
|
if (n1 == 1 && n2 == 1) {
|
|
fmt::fprintf(m_file, "%s=%15.8e;\n", name, *pd);
|
|
return;
|
|
}
|
|
fmt::fprintf(m_file, "%s=zeros(%d,%d);\n", name, n1, n2);
|
|
for (int i = 0; i < n1; i++) {
|
|
for (int j = 0; j < n2; j++) {
|
|
fmt::fprintf(m_file, "%s(%d,%d)=%15.8e;\n", name, i + 1, j + 1, pd[i * n2 + j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* put integer array in m file */
|
|
void mPutInt(const std::string &name, int pd)
|
|
{
|
|
assert(m_file != nullptr);
|
|
fmt::fprintf(m_file, "%s=%d;\n", name, pd);
|
|
}
|
|
|
|
/* put integer array in m file */
|
|
void mPutInt(const std::string &name, int n1, int n2, int *pd)
|
|
{
|
|
assert(m_file != nullptr);
|
|
if (n1 == 1 && n2 == 1) {
|
|
fmt::fprintf(m_file, "%s=%d;\n", name, *pd);
|
|
return;
|
|
}
|
|
fmt::fprintf(m_file, "%s=zeros(%d,%d);\n", name, n1, n2);
|
|
for (int i = 0; i < n1; i++) {
|
|
for (int j = 0; j < n2; j++) {
|
|
fmt::fprintf(m_file, "%s(%d,%d)=%d;\n", name, i + 1, j + 1, pd[i * n2 + j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* put string in mat file*/
|
|
int matPutStr(const std::string &name, char *str)
|
|
{
|
|
int error = 0;
|
|
matvar_t *matvar = nullptr;
|
|
size_t dims[2];
|
|
|
|
dims[0] = 1;
|
|
dims[1] = std::strlen(str);
|
|
|
|
matvar = Mat_VarCreate(name.c_str(), MAT_C_CHAR, MAT_T_UINT8, 2, dims, str, MAT_F_DONT_COPY_DATA);
|
|
if (matvar != nullptr) {
|
|
error = Mat_VarWrite(mat_file, matvar, MAT_COMPRESSION_NONE);
|
|
Mat_VarFree(matvar);
|
|
}
|
|
else {
|
|
error = 1;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
/* put double in mat file*/
|
|
int matPutDbl(const std::string &name, int n1, int n2, double *pd)
|
|
{
|
|
int error = 0;
|
|
matvar_t *matvar = nullptr;
|
|
|
|
size_t dims[2];
|
|
dims[0] = n1;
|
|
dims[1] = n2;
|
|
|
|
matvar =
|
|
Mat_VarCreate(name.c_str(), MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pd, MAT_F_DONT_COPY_DATA);
|
|
if (matvar != nullptr) {
|
|
error = Mat_VarWrite(mat_file, matvar, MAT_COMPRESSION_ZLIB);
|
|
Mat_VarFree(matvar);
|
|
}
|
|
else {
|
|
error = 1;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
/* put integer in mat file*/
|
|
int matPutInt(const std::string &name, int n1, int n2, int *pd)
|
|
{
|
|
int error = 0;
|
|
matvar_t *matvar = nullptr;
|
|
|
|
size_t dims[2];
|
|
dims[0] = n1;
|
|
dims[1] = n2;
|
|
|
|
matvar = Mat_VarCreate(name.c_str(), MAT_C_INT32, MAT_T_INT32, 2, dims, pd, MAT_F_DONT_COPY_DATA);
|
|
if (matvar != nullptr) {
|
|
error = Mat_VarWrite(mat_file, matvar, MAT_COMPRESSION_ZLIB);
|
|
Mat_VarFree(matvar);
|
|
}
|
|
else {
|
|
error = 1;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
/* wrappers for the output routine types */
|
|
void PutStr(const std::string &name, const std::string &str)
|
|
{
|
|
if (textfile != 0) {
|
|
mPutStr(name, str.c_str());
|
|
}
|
|
else {
|
|
matPutStr(name, const_cast<char *>(str.c_str()));
|
|
}
|
|
}
|
|
|
|
int PutInt(const std::string &name, int pd)
|
|
{
|
|
int error = 0;
|
|
if (textfile != 0) {
|
|
mPutInt(name, pd);
|
|
}
|
|
else {
|
|
error = matPutInt(name, 1, 1, &pd);
|
|
}
|
|
return error;
|
|
}
|
|
|
|
int PutInt(const std::string &name, int n1, int n2, int *pd)
|
|
{
|
|
int error = 0;
|
|
if (textfile != 0) {
|
|
mPutInt(name, n1, n2, pd);
|
|
}
|
|
else {
|
|
error = matPutInt(name, n1, n2, pd);
|
|
}
|
|
return error;
|
|
}
|
|
|
|
int PutDbl(const std::string &name, int n1, int n2, double *pd)
|
|
{
|
|
int error = 0;
|
|
if (textfile != 0) {
|
|
mPutDbl(name, n1, n2, pd);
|
|
}
|
|
else {
|
|
error = matPutDbl(name, n1, n2, pd);
|
|
}
|
|
return error;
|
|
}
|
|
|
|
char **get_exodus_names(size_t count, int size)
|
|
{
|
|
auto names = new char *[count];
|
|
for (size_t i = 0; i < count; i++) {
|
|
names[i] = new char[size + 1];
|
|
std::memset(names[i], '\0', size + 1);
|
|
}
|
|
return names;
|
|
}
|
|
|
|
void delete_exodus_names(char **names, int count)
|
|
{
|
|
for (int i = 0; i < count; i++) {
|
|
delete[] names[i];
|
|
}
|
|
delete[] names;
|
|
}
|
|
|
|
void get_put_user_names(int exo_file, ex_entity_type type, int num_blocks, const std::string &mname)
|
|
{
|
|
int max_name_length = ex_inquire_int(exo_file, EX_INQ_DB_MAX_USED_NAME_LENGTH);
|
|
max_name_length = max_name_length < 32 ? 32 : max_name_length;
|
|
ex_set_max_name_length(exo_file, max_name_length);
|
|
char **names = get_exodus_names(num_blocks, max_name_length + 1);
|
|
ex_get_names(exo_file, type, names);
|
|
|
|
std::string user_names;
|
|
for (int j = 0; j < num_blocks; j++) {
|
|
user_names += names[j];
|
|
user_names += "\n";
|
|
}
|
|
PutStr(mname, user_names);
|
|
delete_exodus_names(names, num_blocks);
|
|
}
|
|
|
|
void get_put_names(int exo_file, ex_entity_type type, int num_vars, const std::string &mname)
|
|
{
|
|
int max_name_length = ex_inquire_int(exo_file, EX_INQ_DB_MAX_USED_NAME_LENGTH);
|
|
max_name_length = max_name_length < 32 ? 32 : max_name_length;
|
|
char **names = get_exodus_names(num_vars, max_name_length + 1);
|
|
|
|
if (debug) {
|
|
logger("\tReading variable names");
|
|
}
|
|
ex_get_variable_names(exo_file, type, num_vars, names);
|
|
|
|
std::string mat;
|
|
for (int i = 0; i < num_vars; i++) {
|
|
mat += names[i];
|
|
mat += "\n";
|
|
}
|
|
if (debug) {
|
|
logger("\tWriting variable names");
|
|
}
|
|
PutStr(mname, mat);
|
|
|
|
delete_exodus_names(names, num_vars);
|
|
}
|
|
|
|
std::vector<std::string> get_names(int exo_file, ex_entity_type type, int num_vars)
|
|
{
|
|
int max_name_length = ex_inquire_int(exo_file, EX_INQ_DB_MAX_USED_NAME_LENGTH);
|
|
max_name_length = max_name_length < 32 ? 32 : max_name_length;
|
|
char **names = get_exodus_names(num_vars, max_name_length + 1);
|
|
|
|
if (debug) {
|
|
logger("\tReading variable names");
|
|
}
|
|
ex_get_variable_names(exo_file, type, num_vars, names);
|
|
|
|
std::vector<std::string> mat(num_vars);
|
|
for (int i = 0; i < num_vars; i++) {
|
|
mat[i] = names[i];
|
|
}
|
|
delete_exodus_names(names, num_vars);
|
|
return mat;
|
|
}
|
|
|
|
void get_put_vars(int exo_file, ex_entity_type type, int num_blocks, int num_vars,
|
|
int num_time_steps, const std::vector<int> &num_per_block,
|
|
const std::string &prefix, bool use_cell_arrays)
|
|
|
|
{
|
|
/* truth table */
|
|
if (debug) {
|
|
logger("\tTruth Table");
|
|
}
|
|
std::vector<int> truth_table(num_vars * num_blocks);
|
|
ex_get_truth_table(exo_file, type, num_blocks, num_vars, truth_table.data());
|
|
|
|
std::vector<int> ids(num_blocks);
|
|
ex_get_ids(exo_file, type, ids.data());
|
|
|
|
size_t num_entity = std::accumulate(num_per_block.begin(), num_per_block.end(), 0);
|
|
|
|
if (use_cell_arrays) {
|
|
std::string var_name = prefix + "var";
|
|
|
|
size_t dims[2];
|
|
dims[0] = 2;
|
|
dims[1] = num_vars;
|
|
matvar_t *cell_array =
|
|
Mat_VarCreate(var_name.c_str(), MAT_C_CELL, MAT_T_CELL, 2, dims, nullptr, 0);
|
|
assert(cell_array);
|
|
|
|
std::vector<double> scr(num_vars * num_time_steps * num_entity);
|
|
dims[0] = num_entity;
|
|
dims[1] = num_time_steps;
|
|
size_t offset = 0;
|
|
|
|
// Get vector of variable names...
|
|
auto names = get_names(exo_file, type, num_vars);
|
|
|
|
std::vector<matvar_t *> cell_element(num_vars * 2);
|
|
|
|
int j = 0;
|
|
for (int i = 0; i < num_vars; i++) {
|
|
size_t sdims[2];
|
|
sdims[0] = 1;
|
|
sdims[1] = names[i].length();
|
|
cell_element[j] = Mat_VarCreate(nullptr, MAT_C_CHAR, MAT_T_UINT8, 2, sdims,
|
|
(void *)names[i].c_str(), MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, j, cell_element[j]);
|
|
j++;
|
|
|
|
cell_element[j] = Mat_VarCreate(nullptr, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &scr[offset],
|
|
MAT_F_DONT_COPY_DATA);
|
|
assert(cell_element[j]);
|
|
Mat_VarSetCell(cell_array, j, cell_element[j]);
|
|
size_t n = 0;
|
|
for (int jj = 0; jj < num_time_steps; jj++) {
|
|
for (int k = 0; k < num_blocks; k++) {
|
|
if (truth_table[num_vars * k + i] == 1) {
|
|
ex_get_var(exo_file, jj + 1, type, i + 1, ids[k], num_per_block[k], &scr[n + offset]);
|
|
}
|
|
n += num_per_block[k];
|
|
}
|
|
}
|
|
offset += num_time_steps * num_entity;
|
|
j++;
|
|
}
|
|
Mat_VarWrite(mat_file, cell_array, MAT_COMPRESSION_NONE);
|
|
Mat_VarFree(cell_array);
|
|
}
|
|
else {
|
|
std::string var_name = prefix + "names";
|
|
get_put_names(exo_file, type, num_vars, var_name);
|
|
|
|
std::vector<double> scr(num_entity * num_time_steps);
|
|
|
|
std::string format = prefix + "var%02d";
|
|
for (int i = 0; i < num_vars; i++) {
|
|
if (debug) {
|
|
logger("\tReading");
|
|
}
|
|
std::fill(scr.begin(), scr.end(), 0.0);
|
|
size_t n = 0;
|
|
std::string str = fmt::sprintf(format.c_str(), i + 1);
|
|
for (int j = 0; j < num_time_steps; j++) {
|
|
for (int k = 0; k < num_blocks; k++) {
|
|
if (truth_table[num_vars * k + i] == 1) {
|
|
ex_get_var(exo_file, j + 1, type, i + 1, ids[k], num_per_block[k], &scr[n]);
|
|
}
|
|
n = n + num_per_block[k];
|
|
}
|
|
}
|
|
if (debug) {
|
|
logger("\tWriting");
|
|
}
|
|
PutDbl(str, num_entity, num_time_steps, scr.data());
|
|
}
|
|
}
|
|
}
|
|
|
|
std::vector<int> handle_element_blocks(int exo_file, int num_blocks, bool use_cell_arrays)
|
|
{
|
|
std::vector<int> ids(num_blocks);
|
|
ex_get_ids(exo_file, EX_ELEM_BLOCK, ids.data());
|
|
|
|
std::vector<int> num_elem_in_block(num_blocks);
|
|
|
|
// Storing:
|
|
// 1) name
|
|
// 2) id
|
|
// 3) block topology type
|
|
// 4) connectivity
|
|
int max_name_length = ex_inquire_int(exo_file, EX_INQ_DB_MAX_USED_NAME_LENGTH);
|
|
max_name_length = max_name_length < 32 ? 32 : max_name_length;
|
|
if (use_cell_arrays) {
|
|
int num_field = 4;
|
|
size_t dims[2];
|
|
dims[0] = num_field;
|
|
dims[1] = num_blocks;
|
|
matvar_t *cell_array =
|
|
Mat_VarCreate("element_blocks", MAT_C_CELL, MAT_T_CELL, 2, dims, nullptr, 0);
|
|
assert(cell_array);
|
|
|
|
std::vector<matvar_t *> cell_element(num_blocks * num_field);
|
|
|
|
std::vector<int> num_node_per_elem(num_blocks);
|
|
|
|
size_t conn_size = 0;
|
|
std::vector<std::string> types(num_blocks);
|
|
|
|
for (int i = 0; i < num_blocks; i++) {
|
|
char type[33];
|
|
int num_elem = 0;
|
|
int num_node = 0;
|
|
int num_attr = 0;
|
|
ex_get_block(exo_file, EX_ELEM_BLOCK, ids[i], type, &num_elem, &num_node, nullptr, nullptr,
|
|
&num_attr);
|
|
types[i] = std::string(type);
|
|
num_elem_in_block[i] = num_elem;
|
|
num_node_per_elem[i] = num_node;
|
|
conn_size += num_elem * num_node;
|
|
}
|
|
|
|
std::vector<int> connect(conn_size);
|
|
size_t conn_off = 0;
|
|
for (int i = 0; i < num_blocks; i++) {
|
|
std::vector<char> name(max_name_length + 1);
|
|
ex_get_name(exo_file, EX_ELEM_BLOCK, ids[i], name.data());
|
|
dims[0] = 1;
|
|
dims[1] = std::strlen(name.data());
|
|
size_t index = num_field * i + 0;
|
|
cell_element[index] =
|
|
Mat_VarCreate(nullptr, MAT_C_CHAR, MAT_T_UINT8, 2, dims, (void *)name.data(), 0);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
dims[0] = 1;
|
|
dims[1] = 1;
|
|
index = num_field * i + 1;
|
|
cell_element[index] =
|
|
Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims, &ids[i], MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
dims[0] = 1;
|
|
dims[1] = types[i].length();
|
|
index = num_field * i + 2;
|
|
cell_element[index] =
|
|
Mat_VarCreate(nullptr, MAT_C_CHAR, MAT_T_UINT8, 2, dims, (void *)types[i].c_str(), 0);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
dims[0] = num_node_per_elem[i];
|
|
dims[1] = num_elem_in_block[i];
|
|
index = num_field * i + 3;
|
|
ex_get_conn(exo_file, EX_ELEM_BLOCK, ids[i], &connect[conn_off], nullptr, nullptr);
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims,
|
|
&connect[conn_off], MAT_F_DONT_COPY_DATA);
|
|
assert(cell_element[index]);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
conn_off += num_node_per_elem[i] * num_elem_in_block[i];
|
|
}
|
|
Mat_VarWrite(mat_file, cell_array, MAT_COMPRESSION_NONE);
|
|
Mat_VarFree(cell_array);
|
|
}
|
|
else {
|
|
std::vector<int> connect;
|
|
std::vector<double> attr;
|
|
|
|
PutInt("blkids", num_blocks, 1, ids.data());
|
|
std::vector<char> type(max_name_length + 1);
|
|
std::string types;
|
|
for (int i = 0; i < num_blocks; i++) {
|
|
int num_elem = 0;
|
|
int num_node = 0;
|
|
int num_attr = 0;
|
|
ex_get_block(exo_file, EX_ELEM_BLOCK, ids[i], type.data(), &num_elem, &num_node, nullptr,
|
|
nullptr, &num_attr);
|
|
types += type.data();
|
|
types += "\n";
|
|
num_elem_in_block[i] = num_elem;
|
|
connect.resize(num_elem * num_node);
|
|
ex_get_conn(exo_file, EX_ELEM_BLOCK, ids[i], connect.data(), nullptr, nullptr);
|
|
std::string str = fmt::sprintf("blk%02d", i + 1);
|
|
PutInt(str, num_node, num_elem, connect.data());
|
|
|
|
// Handle block attributes (if any...)
|
|
attr.resize(num_elem);
|
|
str = fmt::sprintf("blk%02d_nattr", i + 1);
|
|
PutInt(str, num_attr);
|
|
if (num_attr > 0) {
|
|
std::string attr_names;
|
|
char **names = get_exodus_names(num_attr, max_name_length + 1);
|
|
ex_get_attr_names(exo_file, EX_ELEM_BLOCK, ids[i], names);
|
|
for (int j = 0; j < num_attr; j++) {
|
|
attr_names += names[j];
|
|
attr_names += "\n";
|
|
}
|
|
str = fmt::sprintf("blk%02d_attrnames", i + 1);
|
|
PutStr(str, attr_names);
|
|
delete_exodus_names(names, num_attr);
|
|
|
|
for (int j = 0; j < num_attr; j++) {
|
|
str = fmt::sprintf("blk%02d_attr%02d", i + 1, j + 1);
|
|
ex_get_one_attr(exo_file, EX_ELEM_BLOCK, ids[i], j + 1, attr.data());
|
|
PutDbl(str, num_elem, 1, attr.data());
|
|
}
|
|
}
|
|
}
|
|
|
|
get_put_user_names(exo_file, EX_ELEM_BLOCK, num_blocks, "blkusernames");
|
|
PutStr("blknames", types);
|
|
}
|
|
return num_elem_in_block;
|
|
}
|
|
|
|
std::vector<int> handle_node_sets(int exo_file, int num_sets, bool use_cell_arrays)
|
|
{
|
|
std::vector<int> num_nodes(num_sets);
|
|
if (num_sets > 0) {
|
|
if (debug) {
|
|
logger("Node Sets");
|
|
}
|
|
std::vector<int> ids(num_sets);
|
|
ex_get_ids(exo_file, EX_NODE_SET, ids.data());
|
|
|
|
size_t tot_nodes = 0;
|
|
size_t tot_dfac = 0;
|
|
std::vector<int> num_df(num_sets);
|
|
for (int i = 0; i < num_sets; i++) {
|
|
int n1;
|
|
int n2;
|
|
ex_get_set_param(exo_file, EX_NODE_SET, ids[i], &n1, &n2);
|
|
num_nodes[i] = n1;
|
|
num_df[i] = n2;
|
|
tot_nodes += n1;
|
|
tot_dfac += n2;
|
|
}
|
|
|
|
// Storing:
|
|
// 1) name
|
|
// 2) id
|
|
// 3) node list
|
|
// 4) distribution factors
|
|
if (use_cell_arrays) {
|
|
size_t dims[2];
|
|
dims[0] = 4;
|
|
dims[1] = num_sets;
|
|
matvar_t *cell_array =
|
|
Mat_VarCreate("node_sets", MAT_C_CELL, MAT_T_CELL, 2, dims, nullptr, 0);
|
|
assert(cell_array);
|
|
|
|
std::vector<matvar_t *> cell_element(num_sets * 4);
|
|
|
|
std::vector<int> node_list(tot_nodes);
|
|
std::vector<double> dist_fac(tot_dfac);
|
|
size_t nl_off = 0;
|
|
size_t df_off = 0;
|
|
|
|
int max_name_length = ex_inquire_int(exo_file, EX_INQ_DB_MAX_USED_NAME_LENGTH);
|
|
max_name_length = max_name_length < 32 ? 32 : max_name_length;
|
|
|
|
for (int i = 0; i < num_sets; i++) {
|
|
std::vector<char> name(max_name_length + 1);
|
|
ex_get_name(exo_file, EX_NODE_SET, ids[i], name.data());
|
|
dims[0] = 1;
|
|
dims[1] = std::strlen(name.data());
|
|
size_t index = 4 * i + 0;
|
|
cell_element[index] =
|
|
Mat_VarCreate(nullptr, MAT_C_CHAR, MAT_T_UINT8, 2, dims, (void *)name.data(), 0);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
dims[0] = 1;
|
|
dims[1] = 1;
|
|
index = 4 * i + 1;
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims, &ids[i],
|
|
MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
dims[0] = num_nodes[i];
|
|
dims[1] = 1;
|
|
index = 4 * i + 2;
|
|
ex_get_set(exo_file, EX_NODE_SET, ids[i], &node_list[nl_off], nullptr);
|
|
/* nodes list */
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims,
|
|
&node_list[nl_off], MAT_F_DONT_COPY_DATA);
|
|
assert(cell_element[index]);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
/* distribution-factors list */
|
|
ex_get_set_dist_fact(exo_file, EX_NODE_SET, ids[i], &dist_fac[df_off]);
|
|
index = 4 * i + 3;
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims,
|
|
&dist_fac[df_off], MAT_F_DONT_COPY_DATA);
|
|
assert(cell_element[index]);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
nl_off += num_nodes[i];
|
|
df_off += num_df[i];
|
|
}
|
|
Mat_VarWrite(mat_file, cell_array, MAT_COMPRESSION_NONE);
|
|
Mat_VarFree(cell_array);
|
|
}
|
|
else {
|
|
PutInt("nsids", num_sets, 1, ids.data());
|
|
|
|
for (int i = 0; i < num_sets; i++) {
|
|
std::vector<int> node_list(num_nodes[i]);
|
|
ex_get_set(exo_file, EX_NODE_SET, ids[i], node_list.data(), nullptr);
|
|
/* nodes list */
|
|
std::string str;
|
|
str = fmt::sprintf("nsnod%02d", i + 1);
|
|
PutInt(str, node_list.size(), 1, node_list.data());
|
|
|
|
/* distribution-factors list */
|
|
if (num_df[i] > 0) {
|
|
std::vector<double> dist_fac(num_df[i]);
|
|
ex_get_set_dist_fact(exo_file, EX_NODE_SET, ids[i], dist_fac.data());
|
|
str = fmt::sprintf("nsfac%02d", i + 1);
|
|
PutDbl(str, dist_fac.size(), 1, dist_fac.data());
|
|
}
|
|
}
|
|
}
|
|
|
|
get_put_user_names(exo_file, EX_NODE_SET, num_sets, "nsusernames");
|
|
|
|
/* Store # nodes and # dis. factors per node set */
|
|
PutInt("nnsnodes", num_sets, 1, num_nodes.data());
|
|
PutInt("nnsdfac", num_sets, 1, num_df.data());
|
|
}
|
|
return num_nodes;
|
|
}
|
|
|
|
std::vector<int> handle_side_sets(int exo_file, int num_sets, bool use_cell_arrays)
|
|
{
|
|
std::vector<int> num_sideset_sides(num_sets);
|
|
std::vector<int> num_sideset_dfac(num_sets);
|
|
std::vector<int> num_sideset_nodes(num_sets);
|
|
if (num_sets > 0) {
|
|
std::vector<int> ids(num_sets);
|
|
ex_get_ids(exo_file, EX_SIDE_SET, ids.data());
|
|
|
|
// Storing:
|
|
// 1) name
|
|
// 2) id
|
|
// 3) element list
|
|
// 4) side list
|
|
// 5) node count per face
|
|
// 6) face node list
|
|
// 7) distribution factors
|
|
|
|
if (use_cell_arrays) {
|
|
size_t dims[2];
|
|
dims[0] = 7;
|
|
dims[1] = num_sets;
|
|
matvar_t *cell_array =
|
|
Mat_VarCreate("side_sets", MAT_C_CELL, MAT_T_CELL, 2, dims, nullptr, 0);
|
|
assert(cell_array);
|
|
|
|
std::vector<matvar_t *> cell_element(num_sets * 7);
|
|
|
|
size_t num_sides = ex_inquire_int(exo_file, EX_INQ_SS_ELEM_LEN);
|
|
size_t num_nodes = ex_inquire_int(exo_file, EX_INQ_SS_NODE_LEN);
|
|
std::vector<int> elem_list(num_sides);
|
|
std::vector<int> side_list(num_sides);
|
|
std::vector<int> num_nodes_per_side(num_sides);
|
|
std::vector<int> side_nodes(num_nodes);
|
|
|
|
// size_t num_df = ex_inquire_int(exo_file, EX_INQ_SS_DF_LEN);
|
|
// If `num_df == 0` or if it isn't equal to `num_nodes`, then
|
|
// all df will be set to 1.0, but in any case, the size of
|
|
// `ssdfac` should be num_nodes and not num_df.
|
|
std::vector<double> ssdfac(num_nodes);
|
|
|
|
size_t side_off = 0;
|
|
size_t node_off = 0;
|
|
size_t df_off = 0;
|
|
|
|
int max_name_length = ex_inquire_int(exo_file, EX_INQ_DB_MAX_USED_NAME_LENGTH);
|
|
max_name_length = max_name_length < 32 ? 32 : max_name_length;
|
|
|
|
for (int i = 0; i < num_sets; i++) {
|
|
std::vector<char> name(max_name_length + 1);
|
|
ex_get_name(exo_file, EX_SIDE_SET, ids[i], name.data());
|
|
dims[0] = 1;
|
|
dims[1] = std::strlen(name.data());
|
|
size_t index = 7 * i + 0;
|
|
cell_element[index] =
|
|
Mat_VarCreate(nullptr, MAT_C_CHAR, MAT_T_UINT8, 2, dims, (void *)name.data(), 0);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
dims[0] = 1;
|
|
dims[1] = 1;
|
|
index = 7 * i + 1;
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims, &ids[i],
|
|
MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
int n1;
|
|
int n2;
|
|
ex_get_set_param(exo_file, EX_SIDE_SET, ids[i], &n1, &n2);
|
|
num_sideset_sides[i] = n1;
|
|
num_sideset_dfac[i] = n2;
|
|
|
|
bool has_ss_dfac = !(n2 == 0 || n1 == n2);
|
|
if (!has_ss_dfac) {
|
|
num_sideset_dfac[i] = num_sideset_nodes[i];
|
|
}
|
|
|
|
ex_get_side_set_node_list_len(exo_file, ids[i], &num_sideset_nodes[i]);
|
|
|
|
/* element and side list for side sets (dgriffi) */
|
|
ex_get_set(exo_file, EX_SIDE_SET, ids[i], &elem_list[side_off], &side_list[side_off]);
|
|
dims[0] = num_sideset_sides[i];
|
|
dims[1] = 1;
|
|
index = 7 * i + 2;
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims,
|
|
&elem_list[side_off], MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
index = 7 * i + 3;
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims,
|
|
&side_list[side_off], MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
ex_get_side_set_node_list(exo_file, ids[i], &num_nodes_per_side[side_off],
|
|
&side_nodes[node_off]);
|
|
|
|
/* number-of-nodes-per-side list */
|
|
index = 7 * i + 4;
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims,
|
|
&num_nodes_per_side[side_off], MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
dims[0] = num_sideset_nodes[i];
|
|
dims[1] = 1;
|
|
index = 7 * i + 5;
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_INT32, MAT_T_INT32, 2, dims,
|
|
&side_nodes[node_off], MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
/* distribution-factors list */
|
|
if (has_ss_dfac) {
|
|
ex_get_set_dist_fact(exo_file, EX_SIDE_SET, ids[i], &ssdfac[df_off]);
|
|
}
|
|
else {
|
|
n2 = num_sideset_dfac[i];
|
|
for (int j = 0; j < n2; j++) {
|
|
ssdfac[j] = 1.0;
|
|
}
|
|
}
|
|
dims[0] = num_sideset_dfac[i];
|
|
dims[1] = 1;
|
|
index = 7 * i + 6;
|
|
cell_element[index] = Mat_VarCreate(nullptr, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims,
|
|
&ssdfac[df_off], MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, index, cell_element[index]);
|
|
|
|
side_off += num_sideset_sides[i];
|
|
node_off += num_sideset_nodes[i];
|
|
df_off += num_sideset_dfac[i];
|
|
}
|
|
Mat_VarWrite(mat_file, cell_array, MAT_COMPRESSION_NONE);
|
|
Mat_VarFree(cell_array);
|
|
}
|
|
else {
|
|
PutInt("ssids", num_sets, 1, ids.data());
|
|
std::vector<int> elem_list;
|
|
std::vector<int> side_list;
|
|
std::vector<int> num_nodes_per_side;
|
|
std::vector<int> side_nodes;
|
|
std::vector<double> ssdfac;
|
|
for (int i = 0; i < num_sets; i++) {
|
|
int n1;
|
|
int n2;
|
|
ex_get_set_param(exo_file, EX_SIDE_SET, ids[i], &n1, &n2);
|
|
num_sideset_sides[i] = n1;
|
|
num_sideset_dfac[i] = n2;
|
|
|
|
bool has_ss_dfac = (n2 != 0);
|
|
if (n2 == 0 || n1 == n2) {
|
|
ex_get_side_set_node_list_len(exo_file, ids[i], &n2);
|
|
}
|
|
|
|
num_nodes_per_side.resize(n1);
|
|
side_nodes.resize(n2);
|
|
ex_get_side_set_node_list(exo_file, ids[i], num_nodes_per_side.data(), side_nodes.data());
|
|
|
|
/* number-of-nodes-per-side list */
|
|
std::string str;
|
|
str = fmt::sprintf("ssnum%02d", i + 1);
|
|
PutInt(str, n1, 1, num_nodes_per_side.data());
|
|
/* nodes list */
|
|
str = fmt::sprintf("ssnod%02d", i + 1);
|
|
PutInt(str, n2, 1, side_nodes.data());
|
|
|
|
/* distribution-factors list */
|
|
if (has_ss_dfac) {
|
|
ssdfac.resize(n2);
|
|
ex_get_set_dist_fact(exo_file, EX_SIDE_SET, ids[i], ssdfac.data());
|
|
str = fmt::sprintf("ssfac%02d", i + 1);
|
|
PutDbl(str, n2, 1, ssdfac.data());
|
|
}
|
|
|
|
/* element and side list for side sets (dgriffi) */
|
|
elem_list.resize(n1);
|
|
side_list.resize(n1);
|
|
ex_get_set(exo_file, EX_SIDE_SET, ids[i], elem_list.data(), side_list.data());
|
|
str = fmt::sprintf("ssside%02d", i + 1);
|
|
PutInt(str, n1, 1, side_list.data());
|
|
str = fmt::sprintf("sselem%02d", i + 1);
|
|
PutInt(str, n1, 1, elem_list.data());
|
|
}
|
|
}
|
|
get_put_user_names(exo_file, EX_SIDE_SET, num_sets, "ssusernames");
|
|
|
|
/* Store # sides and # dis. factors per side set (dgriffi) */
|
|
PutInt("nsssides", num_sets, 1, num_sideset_sides.data());
|
|
PutInt("nssdfac", num_sets, 1, num_sideset_dfac.data());
|
|
}
|
|
return num_sideset_sides;
|
|
}
|
|
|
|
void handle_coordinates(int exo_file, size_t num_nodes, int num_axes)
|
|
{
|
|
if (debug) {
|
|
logger("Coordinates");
|
|
}
|
|
std::vector<double> x, y, z;
|
|
x.resize(num_nodes);
|
|
if (num_axes >= 2) {
|
|
y.resize(num_nodes);
|
|
}
|
|
if (num_axes == 3) {
|
|
z.resize(num_nodes);
|
|
}
|
|
ex_get_coord(exo_file, x.data(), y.data(), z.data());
|
|
PutDbl("x0", num_nodes, 1, x.data());
|
|
if (num_axes >= 2) {
|
|
PutDbl("y0", num_nodes, 1, y.data());
|
|
}
|
|
if (num_axes == 3) {
|
|
PutDbl("z0", num_nodes, 1, z.data());
|
|
}
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* remove an argument from the list */
|
|
void del_arg(int *argc, char *argv[], int j)
|
|
{
|
|
for (int jj = j + 1; jj < *argc; jj++) {
|
|
argv[jj - 1] = argv[jj];
|
|
}
|
|
(*argc)--;
|
|
argv[*argc] = nullptr;
|
|
}
|
|
/**********************************************************************/
|
|
int main(int argc, char *argv[])
|
|
{
|
|
std::string oname{};
|
|
std::string filename{};
|
|
|
|
std::string str;
|
|
|
|
const char *ext = EXT;
|
|
|
|
int err;
|
|
int num_axes;
|
|
int num_blocks;
|
|
int num_side_sets;
|
|
int num_node_sets;
|
|
int num_time_steps;
|
|
int num_info_lines;
|
|
int num_global_vars;
|
|
int num_nodal_vars;
|
|
int num_element_vars;
|
|
int num_nodeset_vars;
|
|
int num_sideset_vars;
|
|
|
|
size_t num_nodes = 0;
|
|
size_t num_elements = 0;
|
|
|
|
enum mat_ft mat_version = MAT_FT_DEFAULT;
|
|
bool use_cell_arrays = false;
|
|
|
|
/* process arguments */
|
|
for (int j = 1; j < argc && argv[j][0] == '-'; j++) {
|
|
if (strcmp(argv[j], "-t") == 0) { /* write text file (*.m) */
|
|
del_arg(&argc, argv, j);
|
|
textfile = 1;
|
|
j--;
|
|
continue;
|
|
}
|
|
if (strcmp(argv[j], "-h") == 0 || strcmp(argv[j], "--help") == 0) { /* write help info */
|
|
del_arg(&argc, argv, j);
|
|
usage();
|
|
exit(1);
|
|
}
|
|
if (strcmp(argv[j], "-d") == 0) { /* write help info */
|
|
del_arg(&argc, argv, j);
|
|
j--;
|
|
debug = true;
|
|
continue;
|
|
}
|
|
if (strcmp(argv[j], "-c") == 0) { /* use cell arrays */
|
|
del_arg(&argc, argv, j);
|
|
j--;
|
|
use_cell_arrays = true;
|
|
continue;
|
|
}
|
|
if (strcmp(argv[j], "-v73") == 0) { /* Version 7.3 */
|
|
del_arg(&argc, argv, j);
|
|
mat_version = MAT_FT_MAT73;
|
|
j--;
|
|
continue;
|
|
}
|
|
// This matches the option used in matlab
|
|
if ((strcmp(argv[j], "-v7.3") == 0) || (strcmp(argv[j], "-V7.3") == 0)) { /* Version 7.3 */
|
|
del_arg(&argc, argv, j);
|
|
mat_version = MAT_FT_MAT73;
|
|
j--;
|
|
continue;
|
|
}
|
|
if (strcmp(argv[j], "-v5") == 0) { /* Version 5 (default) */
|
|
del_arg(&argc, argv, j);
|
|
mat_version = MAT_FT_MAT5;
|
|
j--;
|
|
continue;
|
|
}
|
|
if (strcmp(argv[j], "-o") == 0) { /* specify output file name */
|
|
del_arg(&argc, argv, j);
|
|
if (argv[j] != nullptr) {
|
|
oname = argv[j];
|
|
del_arg(&argc, argv, j);
|
|
fmt::print("output file: {}\n", oname);
|
|
}
|
|
else {
|
|
fmt::print(stderr, "ERROR: Invalid output file specification.\n");
|
|
return 2;
|
|
}
|
|
j--;
|
|
continue;
|
|
}
|
|
// Unrecognized option...
|
|
fmt::print(stderr, "ERROR: Unrecognized option: '{}'\n", argv[j]);
|
|
usage();
|
|
exit(1);
|
|
}
|
|
|
|
/* QA Info */
|
|
fmt::print("{}: {}, {}\n", qainfo[0], qainfo[2], qainfo[1]);
|
|
|
|
/* usage message*/
|
|
if (argc != 2) {
|
|
usage();
|
|
exit(1);
|
|
}
|
|
|
|
/* open output file */
|
|
if (textfile != 0) {
|
|
ext = ".m";
|
|
}
|
|
if (oname.empty()) {
|
|
filename = argv[1];
|
|
size_t pos = filename.find_last_of('.');
|
|
if (pos != std::string::npos) {
|
|
filename = filename.substr(0, pos);
|
|
}
|
|
filename += std::string(ext);
|
|
}
|
|
else {
|
|
filename = oname;
|
|
}
|
|
|
|
if (textfile != 0) {
|
|
m_file = fopen(filename.c_str(), "w");
|
|
if (m_file == nullptr) {
|
|
fmt::print(stderr, "ERROR: Unable to open '{}'\n", filename);
|
|
exit(1);
|
|
}
|
|
}
|
|
else {
|
|
mat_file = Mat_CreateVer(filename.c_str(), nullptr, mat_version);
|
|
if (mat_file == nullptr) {
|
|
fmt::print(stderr, "ERROR: Unable to create matlab file '{}'\n", filename);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
ex_opts(EX_VERBOSE);
|
|
|
|
/* word sizes */
|
|
int cpu_word_size = sizeof(double);
|
|
int io_word_size = 0;
|
|
|
|
/* open exodus file */
|
|
float exo_version;
|
|
int exo_file = ex_open(argv[1], EX_READ, &cpu_word_size, &io_word_size, &exo_version);
|
|
if (exo_file < 0) {
|
|
fmt::print(stderr, "ERROR: Cannot open '{}'\n", argv[1]);
|
|
exit(1);
|
|
}
|
|
|
|
/* print */
|
|
fmt::print("\ttranslating {} to {}...\n", argv[1], filename);
|
|
|
|
/* read database parameters */
|
|
char *line = reinterpret_cast<char *>(calloc((MAX_LINE_LENGTH + 1), sizeof(char)));
|
|
ex_get_init(exo_file, line, &num_axes, &num_nodes, &num_elements, &num_blocks, &num_node_sets,
|
|
&num_side_sets);
|
|
num_info_lines = ex_inquire_int(exo_file, EX_INQ_INFO);
|
|
num_time_steps = ex_inquire_int(exo_file, EX_INQ_TIME);
|
|
ex_get_variable_param(exo_file, EX_GLOBAL, &num_global_vars);
|
|
ex_get_variable_param(exo_file, EX_NODAL, &num_nodal_vars);
|
|
ex_get_variable_param(exo_file, EX_ELEM_BLOCK, &num_element_vars);
|
|
ex_get_variable_param(exo_file, EX_NODE_SET, &num_nodeset_vars);
|
|
ex_get_variable_param(exo_file, EX_SIDE_SET, &num_sideset_vars);
|
|
|
|
/* export parameters */
|
|
PutInt("naxes", num_axes);
|
|
PutInt("nnodes", num_nodes);
|
|
PutInt("nelems", num_elements);
|
|
PutInt("nblks", num_blocks);
|
|
PutInt("nnsets", num_node_sets);
|
|
PutInt("nssets", num_side_sets);
|
|
PutInt("nsteps", num_time_steps);
|
|
PutInt("ngvars", num_global_vars);
|
|
PutInt("nnvars", num_nodal_vars);
|
|
PutInt("nevars", num_element_vars);
|
|
PutInt("nnsvars", num_nodeset_vars);
|
|
PutInt("nssvars", num_sideset_vars);
|
|
|
|
/* allocate -char- scratch space*/
|
|
int nstr2 = num_info_lines;
|
|
nstr2 = std::max(nstr2, num_blocks);
|
|
nstr2 = std::max(nstr2, num_node_sets);
|
|
nstr2 = std::max(nstr2, num_side_sets);
|
|
char **str2 = get_exodus_names(nstr2, 512);
|
|
|
|
/* title */
|
|
PutStr("Title", line);
|
|
|
|
/* information records */
|
|
if (num_info_lines > 0) {
|
|
ex_get_info(exo_file, str2);
|
|
std::string ostr;
|
|
for (int i = 0; i < num_info_lines; i++) {
|
|
if (std::strlen(str2[i]) > 0) {
|
|
ostr += str2[i];
|
|
ostr += "\n";
|
|
}
|
|
}
|
|
PutStr("info", ostr);
|
|
ostr = "";
|
|
for (int i = 0; i < num_info_lines; i++) {
|
|
if (std::strlen(str2[i]) > 0 && strncmp(str2[i], "cavi", 4) == 0) {
|
|
ostr += str2[i];
|
|
ostr += "\n";
|
|
}
|
|
}
|
|
PutStr("cvxp", ostr);
|
|
}
|
|
|
|
/* nodal coordinates */
|
|
handle_coordinates(exo_file, num_nodes, num_axes);
|
|
|
|
/* side sets */
|
|
if (debug) {
|
|
logger("Side Sets");
|
|
}
|
|
auto num_sideset_sides = handle_side_sets(exo_file, num_side_sets, use_cell_arrays);
|
|
|
|
/* node sets (section by dgriffi) */
|
|
auto num_nodeset_nodes = handle_node_sets(exo_file, num_node_sets, use_cell_arrays);
|
|
|
|
/* element blocks */
|
|
if (debug) {
|
|
logger("Element Blocks");
|
|
}
|
|
auto num_elem_in_block = handle_element_blocks(exo_file, num_blocks, use_cell_arrays);
|
|
|
|
/* time values */
|
|
if (num_time_steps > 0) {
|
|
if (debug) {
|
|
logger("Time Steps");
|
|
}
|
|
std::vector<double> scr(num_time_steps);
|
|
ex_get_all_times(exo_file, scr.data());
|
|
PutDbl("time", num_time_steps, 1, scr.data());
|
|
}
|
|
|
|
/* global variables */
|
|
if (num_global_vars > 0) {
|
|
if (debug) {
|
|
logger("Global Variables");
|
|
}
|
|
|
|
if (use_cell_arrays) {
|
|
size_t dims[2];
|
|
dims[0] = 2;
|
|
dims[1] = num_global_vars;
|
|
matvar_t *cell_array = Mat_VarCreate("gvar", MAT_C_CELL, MAT_T_CELL, 2, dims, nullptr, 0);
|
|
assert(cell_array);
|
|
std::vector<double> scr(num_time_steps * num_global_vars);
|
|
dims[0] = num_time_steps;
|
|
dims[1] = 1;
|
|
size_t offset = 0;
|
|
// Get vector of variable names...
|
|
auto gnames = get_names(exo_file, EX_GLOBAL, num_global_vars);
|
|
|
|
std::vector<matvar_t *> cell_element(num_global_vars * 2);
|
|
int j = 0;
|
|
for (int i = 0; i < num_global_vars; i++) {
|
|
size_t sdims[2];
|
|
sdims[0] = 1;
|
|
sdims[1] = gnames[i].length();
|
|
cell_element[j] = Mat_VarCreate(nullptr, MAT_C_CHAR, MAT_T_UINT8, 2, sdims,
|
|
(void *)gnames[i].c_str(), MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, j, cell_element[j]);
|
|
j++;
|
|
|
|
ex_get_var_time(exo_file, EX_GLOBAL, i + 1, 1, 1, num_time_steps, &scr[offset]);
|
|
cell_element[j] = Mat_VarCreate(nullptr, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &scr[offset],
|
|
MAT_F_DONT_COPY_DATA);
|
|
assert(cell_element[j]);
|
|
Mat_VarSetCell(cell_array, j, cell_element[j]);
|
|
offset += num_time_steps;
|
|
j++;
|
|
}
|
|
Mat_VarWrite(mat_file, cell_array, MAT_COMPRESSION_NONE);
|
|
Mat_VarFree(cell_array);
|
|
}
|
|
else {
|
|
get_put_names(exo_file, EX_GLOBAL, num_global_vars, "gnames");
|
|
std::vector<double> scr(num_time_steps);
|
|
for (int i = 0; i < num_global_vars; i++) {
|
|
str = fmt::sprintf("gvar%02d", i + 1);
|
|
ex_get_var_time(exo_file, EX_GLOBAL, i + 1, 1, 1, num_time_steps, scr.data());
|
|
PutDbl(str, num_time_steps, 1, scr.data());
|
|
}
|
|
}
|
|
}
|
|
|
|
/* nodal variables */
|
|
if (num_nodal_vars > 0) {
|
|
if (debug) {
|
|
logger("Nodal Variables");
|
|
}
|
|
if (debug) {
|
|
logger("\tNames");
|
|
}
|
|
if (use_cell_arrays) {
|
|
size_t dims[2];
|
|
dims[0] = 2;
|
|
dims[1] = num_nodal_vars;
|
|
matvar_t *cell_array = Mat_VarCreate("nvar", MAT_C_CELL, MAT_T_CELL, 2, dims, nullptr, 0);
|
|
assert(cell_array);
|
|
std::vector<double> scr(num_nodal_vars * num_time_steps * num_nodes);
|
|
dims[0] = num_nodes;
|
|
dims[1] = num_time_steps;
|
|
size_t offset = 0;
|
|
// Get vector of variable names...
|
|
auto nnames = get_names(exo_file, EX_NODAL, num_nodal_vars);
|
|
|
|
std::vector<matvar_t *> cell_element(num_nodal_vars * 2);
|
|
int j = 0;
|
|
for (int i = 0; i < num_nodal_vars; i++) {
|
|
size_t sdims[2];
|
|
sdims[0] = 1;
|
|
sdims[1] = nnames[i].length();
|
|
cell_element[j] = Mat_VarCreate(nullptr, MAT_C_CHAR, MAT_T_UINT8, 2, sdims,
|
|
(void *)nnames[i].c_str(), MAT_F_DONT_COPY_DATA);
|
|
Mat_VarSetCell(cell_array, j, cell_element[j]);
|
|
j++;
|
|
|
|
cell_element[j] = Mat_VarCreate(nullptr, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &scr[offset],
|
|
MAT_F_DONT_COPY_DATA);
|
|
assert(cell_element[j]);
|
|
Mat_VarSetCell(cell_array, j, cell_element[j]);
|
|
for (int k = 0; k < num_time_steps; k++) {
|
|
ex_get_var(exo_file, k + 1, EX_NODAL, i + 1, 1, num_nodes, &scr[num_nodes * k + offset]);
|
|
}
|
|
offset += num_time_steps * num_nodes;
|
|
j++;
|
|
}
|
|
Mat_VarWrite(mat_file, cell_array, MAT_COMPRESSION_NONE);
|
|
Mat_VarFree(cell_array);
|
|
}
|
|
else {
|
|
get_put_names(exo_file, EX_NODAL, num_nodal_vars, "nnames");
|
|
|
|
std::vector<double> scr(num_nodes * num_time_steps);
|
|
for (int i = 0; i < num_nodal_vars; i++) {
|
|
str = fmt::sprintf("nvar%02d", i + 1);
|
|
if (debug) {
|
|
logger("\tReading");
|
|
}
|
|
for (int j = 0; j < num_time_steps; j++) {
|
|
ex_get_var(exo_file, j + 1, EX_NODAL, i + 1, 1, num_nodes, &scr[num_nodes * j]);
|
|
}
|
|
if (debug) {
|
|
logger("\tWriting");
|
|
}
|
|
PutDbl(str, num_nodes, num_time_steps, scr.data());
|
|
}
|
|
}
|
|
}
|
|
|
|
/* element variables */
|
|
if (num_element_vars > 0) {
|
|
if (debug) {
|
|
logger("Element Variables");
|
|
}
|
|
get_put_vars(exo_file, EX_ELEM_BLOCK, num_blocks, num_element_vars, num_time_steps,
|
|
num_elem_in_block, "e", use_cell_arrays);
|
|
}
|
|
|
|
/* nodeset variables */
|
|
if (num_nodeset_vars > 0) {
|
|
if (debug) {
|
|
logger("Nodeset Variables");
|
|
}
|
|
get_put_vars(exo_file, EX_NODE_SET, num_node_sets, num_nodeset_vars, num_time_steps,
|
|
num_nodeset_nodes, "ns", use_cell_arrays);
|
|
}
|
|
|
|
/* sideset variables */
|
|
if (num_sideset_vars > 0) {
|
|
if (debug) {
|
|
logger("Sideset Variables");
|
|
}
|
|
get_put_vars(exo_file, EX_SIDE_SET, num_side_sets, num_sideset_vars, num_time_steps,
|
|
num_sideset_sides, "ss", use_cell_arrays);
|
|
}
|
|
|
|
/* node and element number maps */
|
|
if (debug) {
|
|
logger("Node and Element Number Maps");
|
|
}
|
|
ex_opts(0); /* turn off error reporting. It is not an error to have no map*/
|
|
std::vector<int> ids(num_nodes);
|
|
err = ex_get_id_map(exo_file, EX_NODE_MAP, ids.data());
|
|
if (err == 0) {
|
|
PutInt("node_num_map", num_nodes, 1, ids.data());
|
|
}
|
|
|
|
ids.resize(num_elements);
|
|
err = ex_get_id_map(exo_file, EX_ELEM_MAP, ids.data());
|
|
if (err == 0) {
|
|
PutInt("elem_num_map", num_elements, 1, ids.data());
|
|
}
|
|
|
|
if (debug) {
|
|
logger("Closing file");
|
|
}
|
|
ex_close(exo_file);
|
|
|
|
if (textfile != 0) {
|
|
fclose(m_file);
|
|
}
|
|
else {
|
|
Mat_Close(mat_file);
|
|
}
|
|
free(line);
|
|
|
|
delete_exodus_names(str2, nstr2);
|
|
|
|
fmt::print("done...\n");
|
|
|
|
/* exit status */
|
|
add_to_log("exo2mat", 0);
|
|
return (0);
|
|
}
|
|
|