![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include "moab/ProgOptions.hpp"
#include "moab/Core.hpp"
#include "netcdf.h"
#include <cmath>
#include <sstream>
Go to the source code of this file.
Defines | |
#define | INS_ID(stringvar, prefix, id) sprintf( stringvar, prefix, id ) |
#define | GET_DIM(ncdim, name, val) |
#define | GET_DIMB(ncdim, name, varname, id, val) |
#define | GET_VAR(name, id, dims) |
#define | GET_1D_INT_VAR(name, id, vals) |
#define | GET_1D_DBL_VAR(name, id, vals) |
#define | GET_1D_FLT_VAR(name, id, vals) |
Functions | |
int | main (int argc, char *argv[]) |
Variables | |
int | ncFile |
#define GET_1D_DBL_VAR | ( | name, | |
id, | |||
vals | |||
) |
{ \
std::vector< int > dum_dims; \
GET_VAR( name, id, dum_dims ); \
if( -1 != ( id ) ) \
{ \
size_t ntmp; \
int dvfail = nc_inq_dimlen( ncFile, dum_dims[0], &ntmp ); \
if( NC_NOERR != dvfail ) \
{ \
MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get dimension length" ); \
} \
( vals ).resize( ntmp ); \
size_t ntmp1 = 0; \
dvfail = nc_get_vara_double( ncFile, id, &ntmp1, &ntmp, &( vals )[0] ); \
if( NC_NOERR != dvfail ) \
{ \
MB_SET_ERR( MB_FAILURE, "addncdata:: Problem getting variable " << ( name ) ); \
} \
} \
}
Definition at line 100 of file addncdata.cpp.
Referenced by main().
#define GET_1D_FLT_VAR | ( | name, | |
id, | |||
vals | |||
) |
{ \
std::vector< int > dum_dims; \
GET_VAR( name, id, dum_dims ); \
if( -1 != ( id ) ) \
{ \
size_t ntmp; \
int dvfail = nc_inq_dimlen( ncFile, dum_dims[0], &ntmp ); \
if( NC_NOERR != dvfail ) \
{ \
MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get dimension length" ); \
} \
( vals ).resize( ntmp ); \
size_t ntmp1 = 0; \
dvfail = nc_get_vara_float( ncFile, id, &ntmp1, &ntmp, &( vals )[0] ); \
if( NC_NOERR != dvfail ) \
{ \
MB_SET_ERR( MB_FAILURE, "addncdata:: Problem getting variable " << ( name ) ); \
} \
} \
}
Definition at line 122 of file addncdata.cpp.
Referenced by main().
#define GET_1D_INT_VAR | ( | name, | |
id, | |||
vals | |||
) |
{ \
GET_VAR( name, id, vals ); \
if( -1 != ( id ) ) \
{ \
size_t ntmp; \
int ivfail = nc_inq_dimlen( ncFile, ( vals )[0], &ntmp ); \
if( NC_NOERR != ivfail ) \
{ \
MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get dimension length" ); \
} \
( vals ).resize( ntmp ); \
size_t ntmp1 = 0; \
ivfail = nc_get_vara_int( ncFile, id, &ntmp1, &ntmp, &( vals )[0] ); \
if( NC_NOERR != ivfail ) \
{ \
MB_SET_ERR( MB_FAILURE, "addncdata:: Problem getting variable " << ( name ) ); \
} \
} \
}
Definition at line 79 of file addncdata.cpp.
Referenced by main().
#define GET_DIM | ( | ncdim, | |
name, | |||
val | |||
) |
{ \
int gdfail = nc_inq_dimid( ncFile, name, &( ncdim ) ); \
if( NC_NOERR == gdfail ) \
{ \
size_t tmp_val; \
gdfail = nc_inq_dimlen( ncFile, ncdim, &tmp_val ); \
if( NC_NOERR != gdfail ) \
{ \
MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get dimension length" ); \
} \
else \
( val ) = tmp_val; \
} \
else \
( val ) = 0; \
}
Definition at line 37 of file addncdata.cpp.
#define GET_DIMB | ( | ncdim, | |
name, | |||
varname, | |||
id, | |||
val | |||
) |
INS_ID( name, varname, id ); \
GET_DIM( ncdim, name, val );
Definition at line 55 of file addncdata.cpp.
#define GET_VAR | ( | name, | |
id, | |||
dims | |||
) |
{ \
( id ) = -1; \
int gvfail = nc_inq_varid( ncFile, name, &( id ) ); \
if( NC_NOERR == gvfail ) \
{ \
int ndims; \
gvfail = nc_inq_varndims( ncFile, id, &ndims ); \
if( NC_NOERR == gvfail ) \
{ \
( dims ).resize( ndims ); \
gvfail = nc_inq_vardimid( ncFile, id, &( dims )[0] ); \
if( NC_NOERR != gvfail ) \
{ \
MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get variable dimension IDs" ); \
} \
} \
} \
}
Definition at line 59 of file addncdata.cpp.
Referenced by main().
#define INS_ID | ( | stringvar, | |
prefix, | |||
id | |||
) | sprintf( stringvar, prefix, id ) |
Definition at line 35 of file addncdata.cpp.
int main | ( | int | argc, |
char * | argv[] | ||
) |
Definition at line 144 of file addncdata.cpp.
References ProgOptions::addOpt(), moab::Range::begin(), moab::Range::end(), ErrorCode, moab::fail(), GET_1D_DBL_VAR, GET_1D_FLT_VAR, GET_1D_INT_VAR, moab::Core::get_entities_by_dimension(), GET_VAR, moab::Range::index(), moab::Core::load_file(), mb, MB_CHK_SET_ERR, MB_FILE_DOES_NOT_EXIST, MB_SET_ERR, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, ncFile, ProgOptions::parseCommandLine(), moab::Range::size(), moab::Core::tag_get_data(), moab::Core::tag_get_handle(), moab::Core::tag_get_length(), moab::Core::tag_set_data(), and moab::Core::write_file().
{
ErrorCode rval;
ProgOptions opts;
std::string inputfile, outfile( "out.h5m" ), netcdfFile, variable_name, sefile_name;
opts.addOpt< std::string >( "input,i", "input mesh filename", &inputfile );
opts.addOpt< std::string >( "netcdfFile,n", "netcdf file aligned with the mesh input file", &netcdfFile );
opts.addOpt< std::string >( "output,o", "output mesh filename", &outfile );
opts.addOpt< std::string >( "var,v", "variable to extract and add to output file", &variable_name );
opts.addOpt< std::string >( "sefile,s", "spectral elements file (coarse SE mesh)", &sefile_name );
opts.parseCommandLine( argc, argv );
Core* mb = new Core();
rval = mb->load_file( inputfile.c_str() );MB_CHK_SET_ERR( rval, "can't load input file" );
std::cout << " opened " << inputfile << " with initial h5m data.\n";
// open the netcdf file, and see if it has that variable we are looking for
Range nodes;
rval = mb->get_entities_by_dimension( 0, 0, nodes );MB_CHK_SET_ERR( rval, "can't get nodes" );
Range edges;
rval = mb->get_entities_by_dimension( 0, 1, edges );MB_CHK_SET_ERR( rval, "can't get edges" );
Range cells;
rval = mb->get_entities_by_dimension( 0, 2, cells );MB_CHK_SET_ERR( rval, "can't get cells" );
std::cout << " it has " << nodes.size() << " vertices " << edges.size() << " edges " << cells.size() << " cells\n";
// construct maps between global id and handles
std::map< int, EntityHandle > vGidHandle;
std::map< int, EntityHandle > eGidHandle;
std::map< int, EntityHandle > cGidHandle;
std::vector< int > gids;
Tag gid;
rval = mb->tag_get_handle( "GLOBAL_ID", gid );MB_CHK_SET_ERR( rval, "can't get global id tag" );
gids.resize( nodes.size() );
rval = mb->tag_get_data( gid, nodes, &gids[0] );MB_CHK_SET_ERR( rval, "can't get global id on vertices" );
int i = 0;
for( Range::iterator vit = nodes.begin(); vit != nodes.end(); vit++ )
{
vGidHandle[gids[i++]] = *vit;
}
gids.resize( edges.size() );
rval = mb->tag_get_data( gid, edges, &gids[0] );MB_CHK_SET_ERR( rval, "can't get global id on edges" );
i = 0;
for( Range::iterator vit = edges.begin(); vit != edges.end(); vit++ )
{
eGidHandle[gids[i++]] = *vit;
}
gids.resize( cells.size() );
rval = mb->tag_get_data( gid, cells, &gids[0] );MB_CHK_SET_ERR( rval, "can't get global id on cells" );
i = 0;
for( Range::iterator vit = cells.begin(); vit != cells.end(); vit++ )
{
cGidHandle[gids[i++]] = *vit;
}
// Open netcdf/exodus file
int fail = nc_open( netcdfFile.c_str(), 0, &ncFile );
if( NC_NOWRITE != fail )
{
MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, "ReadNCDF:: problem opening Netcdf II file " << netcdfFile );
}
std::cout << " opened " << netcdfFile << " with new data \n";
std::vector< int > dims;
int nc_var;
size_t recs;
char recname[NC_MAX_NAME + 1];
std::cout << " looking for variable " << variable_name << "\n";
GET_VAR( variable_name.c_str(), nc_var, dims );
std::cout << " it has " << dims.size() << " dimensions\n";
int dimIndex = -1; // index of the dimension of interest
bool vertex_data = false;
bool cell_data = false;
for( size_t j = 0; j < dims.size(); j++ )
{
fail = nc_inq_dim( ncFile, dims[j], recname, &recs );
if( NC_NOERR != fail ) MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get dimension" );
std::string name_dim( recname );
std::cout << " dimension index " << j << " in file: " << dims[j] << " name: " << name_dim << " recs:" << recs
<< "\n";
if( recs == nodes.size() )
{
dimIndex = j;
vertex_data = true;
}
if( recs == cells.size() )
{
dimIndex = j;
cell_data = true;
}
}
int otherDim = 1 - dimIndex; // used only if 2 dimensions ; could be 0 or 1;
size_t size_tag = 1; // good for one dimension
std::vector< int > evals; // size of size_tag
std::vector< double > dvals; // size of size_tag
nc_type dataType;
// read the variable, and set it to the tag
fail = nc_inq_vartype( ncFile, nc_var, &dataType );
if( NC_NOERR != fail ) MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get variable type" );
DataType mbtype = MB_TYPE_DOUBLE;
bool float_var = false;
if( NC_INT == dataType )
mbtype = MB_TYPE_INTEGER;
else if( NC_DOUBLE != dataType && NC_FLOAT != dataType )
MB_CHK_SET_ERR( MB_FAILURE, "unknown type" );
if( NC_FLOAT == dataType ) float_var = true;
int time_id = -1;
fail = nc_inq_varid( ncFile, "time", &time_id );
if( NC_NOERR != fail ) MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get time variable id" );
std::vector< float > times;
if( NC_NOERR == fail )
{
int ii;
GET_1D_FLT_VAR( "time", ii, times );
}
Tag newTag;
if( ( dims.size() >= 1 && dims.size() <= 2 ) && ( vertex_data || cell_data ) )
{
if( dims.size() == 2 )
{
fail = nc_inq_dim( ncFile, dims[otherDim], recname, &size_tag );
if( NC_NOERR != fail ) MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get dimension" );
}
int def_val = 0;
rval = mb->tag_get_handle( variable_name.c_str(), (int)size_tag, mbtype, newTag, MB_TAG_CREAT | MB_TAG_DENSE,
&def_val );MB_CHK_SET_ERR( rval, "can't define new tag" );
if( NC_INT == dataType )
{
std::vector< int > vals;
if( 1 == dims.size() )
{
GET_1D_INT_VAR( variable_name.c_str(), dims[0], vals );
if( vertex_data )
{
for( size_t k = 0; k < vals.size(); k++ )
{
EntityHandle vh = vGidHandle[k + 1];
rval = mb->tag_set_data( newTag, &vh, 1, &vals[k] );MB_CHK_SET_ERR( rval, "can't set tag on vertex" );
}
}
else // cell_data
{
for( size_t k = 0; k < vals.size(); k++ )
{
EntityHandle ch = cGidHandle[k + 1]; // cell handle
rval = mb->tag_set_data( newTag, &ch, 1, &vals[k] );MB_CHK_SET_ERR( rval, "can't set tag on cell" );
}
}
}
else // dims.size() == 2
{
// Single var for all coords
size_t start[2] = { 0, 0 }, count[2] = { 1, 1 };
count[dimIndex] = recs;
count[otherDim] = size_tag;
vals.resize( recs * size_tag );
fail = nc_get_vara_int( ncFile, nc_var, start, count, &vals[0] );
evals.resize( size_tag );
if( vertex_data )
{
for( size_t k = 0; k < recs; k++ )
{
EntityHandle vh = vGidHandle[k + 1];
size_t start_in_vals = k * size_tag, stride = 1;
for( size_t j = 0; j < size_tag; j++ )
evals[j] = vals[start_in_vals + j * stride];
rval = mb->tag_set_data( newTag, &vh, 1, &evals[0] );MB_CHK_SET_ERR( rval, "can't set tag on vertex" );
}
}
else // cell_data
{
for( size_t k = 0; k < recs; k++ )
{
EntityHandle ch = cGidHandle[k + 1]; // cell handle
size_t start_in_vals = k * size_tag, stride = 1;
for( size_t j = 0; j < size_tag; j++ )
evals[j] = vals[start_in_vals + j * stride];
rval = mb->tag_set_data( newTag, &ch, 1, &evals[0] );MB_CHK_SET_ERR( rval, "can't set tag on cell" );
}
}
}
}
else
{
std::vector< double > vals;
if( 1 == dims.size() )
{
GET_1D_DBL_VAR( variable_name.c_str(), dims[0], vals );
if( vertex_data )
{
for( size_t k = 0; k < vals.size(); k++ )
{
EntityHandle vh = vGidHandle[k + 1];
rval = mb->tag_set_data( newTag, &vh, 1, &vals[k] );MB_CHK_SET_ERR( rval, "can't set tag on vertex" );
}
}
else // cell_data
{
for( size_t k = 0; k < vals.size(); k++ )
{
EntityHandle ch = cGidHandle[k + 1]; // cell handle
rval = mb->tag_set_data( newTag, &ch, 1, &vals[k] );MB_CHK_SET_ERR( rval, "can't set tag on vertex" );
}
}
}
else // dims.size() == 2
{
// Single var for all coords
size_t start[2] = { 0, 0 }, count[2] = { 1, 1 };
count[dimIndex] = recs;
count[otherDim] = size_tag;
vals.resize( recs * size_tag );
fail = nc_get_vara_double( ncFile, nc_var, start, count, &vals[0] );
dvals.resize( size_tag );
if( vertex_data )
{
for( size_t k = 0; k < recs; k++ )
{
EntityHandle vh = vGidHandle[k + 1];
size_t start_in_vals = k * size_tag, stride = 1;
for( size_t j = 0; j < size_tag; j++ )
dvals[j] = vals[start_in_vals + j * stride];
rval = mb->tag_set_data( newTag, &vh, 1, &dvals[0] );MB_CHK_SET_ERR( rval, "can't set tag on vertex" );
}
}
else // cell_data
{
for( size_t k = 0; k < recs; k++ )
{
EntityHandle ch = cGidHandle[k + 1]; // cell handle
size_t start_in_vals = k * size_tag, stride = 1;
for( size_t j = 0; j < size_tag; j++ )
dvals[j] = vals[start_in_vals + j * stride];
rval = mb->tag_set_data( newTag, &ch, 1, &dvals[0] );MB_CHK_SET_ERR( rval, "can't set tag on cell" );
}
}
}
}
}
else if( ( dims.size() == 3 ) && vertex_data && dimIndex == 2 &&
mbtype == MB_TYPE_DOUBLE ) // the last one is the vertex
{
// the case when the last dim is ncol (for homme type mesh))
size_t dim0, dim1; // dim 2 is ncol..
char recname0[NC_MAX_NAME + 1], recname1[NC_MAX_NAME + 1];
fail = nc_inq_dim( ncFile, dims[0], recname0, &dim0 );
if( NC_NOERR != fail ) MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get dimension" );
fail = nc_inq_dim( ncFile, dims[1], recname1, &dim1 );
if( NC_NOERR != fail ) MB_SET_ERR( MB_FAILURE, "addncdata:: Couldn't get dimension" );
std::string name0( recname0 );
std::string name1( recname1 );
std::string timestr( "time" );
size_t start[3] = { 0, 0, 0 };
size_t count[3] = { 1, 0, 0 };
count[1] = dim1;
count[2] = nodes.size();
// create a few tags, with name inserted
if( name0.compare( "time" ) == 0 )
{
std::vector< double > dvalues( dim1 * count[2] );
std::vector< float > fvalues( dim1 * count[2] );
std::vector< double > transp( dim1 * count[2] );
// get the variable time
for( size_t k = 0; k < dim0; k++ )
{
// create a tag for each time, and
std::stringstream tag_name;
tag_name << variable_name << "_t" << times[k];
std::vector< double > defvals( dim1, 0. );
rval = mb->tag_get_handle( tag_name.str().c_str(), (int)dim1, mbtype, newTag,
MB_TAG_CREAT | MB_TAG_DENSE, &defvals[0] );MB_CHK_SET_ERR( rval, "can't define new tag" );
start[0] = k;
if( float_var )
{
fail = nc_get_vara_float( ncFile, nc_var, start, count, &fvalues[0] );
// now arrange them in a tag, transpose data
for( size_t ii = 0; ii < dim1; ii++ )
for( size_t j = 0; j < count[2]; j++ )
{
transp[j * dim1 + ii] = fvalues[ii * count[2] + j];
}
}
else // double
{
fail = nc_get_vara_double( ncFile, nc_var, start, count, &dvalues[0] );
// now arrange them in a tag, transpose data
for( size_t ii = 0; ii < dim1; ii++ )
for( size_t j = 0; j < count[2]; j++ )
{
transp[j * dim1 + ii] = dvalues[ii * count[2] + j];
}
}
for( size_t ii = 0; ii < nodes.size(); ii++ )
{
EntityHandle vh = vGidHandle[ii + 1];
rval = mb->tag_set_data( newTag, &vh, 1, &transp[ii * dim1] );MB_CHK_SET_ERR( rval, "can't set tag on nodes" );
}
}
}
}
rval = mb->write_file( outfile.c_str() );MB_CHK_SET_ERR( rval, "can't write file" );
std::cout << " wrote file " << outfile << "\n";
// now, if s option, load the coarse mesh and put data on each element, according to a matrix
if( !sefile_name.empty() )
{
// load the file, check for GLOBAL_DOFS tag, and create a new tag with the data associated
Core* mb2 = new Core();
rval = mb2->load_file( sefile_name.c_str() );MB_CHK_SET_ERR( rval, "can't load spectral element file" );
std::cout << " loaded spectral file " << sefile_name << "\n";
// look for GLOBAL_DOFS tag
Tag gdofeTag;
rval = mb2->tag_get_handle( "GLOBAL_DOFS", gdofeTag );MB_CHK_SET_ERR( rval, "file does not have GLOBAL_DOFS file" );
int sizeTag;
rval = mb2->tag_get_length( gdofeTag, sizeTag );MB_CHK_SET_ERR( rval, "can't get size of tag" );
int np = (int)sqrt( 1.0 * sizeTag );
std::cout << " size of tag: " << sizeTag << " np = " << np << "\n";
std::vector< int > gdofs;
Range cells2;
rval = mb2->get_entities_by_dimension( 0, 2, cells2 );MB_CHK_SET_ERR( rval, "can't get cells on spectral mesh" );
gdofs.resize( cells2.size() * sizeTag );
rval = mb2->tag_get_data( gdofeTag, cells2, &gdofs[0] );MB_CHK_SET_ERR( rval, "can't get global dofs tag" );
// create a new tag for element data arranged as DFIELD
std::vector< double > dfield;
dfield.resize( sizeTag, 0.0 );
Tag newTag2;
rval = mb2->tag_get_handle( variable_name.c_str(), (int)sizeTag, mbtype, newTag2, MB_TAG_CREAT | MB_TAG_DENSE,
&dfield[0] );MB_CHK_SET_ERR( rval, "can't define new tag" );
int i1 = 0; // index in the gdofs array, per element
// get the tag values from the other moab core, for newTag
int dataTagLen;
rval = mb->tag_get_length( newTag, dataTagLen );MB_CHK_SET_ERR( rval, "can't get size of newTag" );
//
std::vector< double > oldData;
oldData.resize( dataTagLen * nodes.size() ); //
// get the "old" values
rval = mb->tag_get_data( newTag, nodes, &oldData[0] );MB_CHK_SET_ERR( rval, "can't get old values" );
for( Range::iterator it = cells2.begin(); it != cells2.end(); it++ )
{
EntityHandle cel = *it;
// gdofs per element are gdofs[i:i+np*np];
for( int k = 0; k < sizeTag; k++ )
{
int gdof = gdofs[i1 + k];
EntityHandle node = vGidHandle[gdof];
int index = nodes.index( node );
// get last layer of data
double val = oldData[index * dataTagLen + dataTagLen - 1]; //
dfield[k] = val;
}
i1 = i1 + sizeTag;
rval = mb2->tag_set_data( newTag2, &cel, 1, &dfield[0] );MB_CHK_SET_ERR( rval, "can't set new tag" );
}
// write the appended file with the new field:
rval = mb2->write_file( "atm2.h5m" );MB_CHK_SET_ERR( rval, "can't write new spectral file" );
std::cout << " wrote file atm2.h5m \n";
}
return 0;
}
int ncFile |
Definition at line 33 of file addncdata.cpp.
Referenced by main().