2018-06-11 14:19:05 -05:00
|
|
|
/*
|
|
|
|
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
|
|
|
|
|
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
|
|
|
|
|
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2014-09-09 13:42:13 -05:00
|
|
|
#include "IO/MeshDatabase.h"
|
2014-11-05 15:54:18 -06:00
|
|
|
#include "IO/IOHelpers.h"
|
2014-11-04 20:58:20 -06:00
|
|
|
#include "IO/Mesh.h"
|
2021-01-04 22:35:10 -06:00
|
|
|
#include "IO/PackData.h"
|
|
|
|
#include "common/MPI.h"
|
2014-09-09 13:42:13 -05:00
|
|
|
#include "common/Utilities.h"
|
|
|
|
|
2021-03-17 09:24:14 -05:00
|
|
|
#include <cstdio>
|
2014-09-09 13:42:13 -05:00
|
|
|
#include <map>
|
|
|
|
#include <set>
|
2021-03-17 09:24:14 -05:00
|
|
|
#include <vector>
|
2015-02-04 08:55:22 -06:00
|
|
|
|
2014-09-09 13:42:13 -05:00
|
|
|
#include <ProfilerApp.h>
|
|
|
|
|
|
|
|
|
2021-03-18 08:41:39 -05:00
|
|
|
// Default pack/unpack
|
|
|
|
// clang-format off
|
|
|
|
#define INSTANTIATE_PACK( TYPE ) \
|
|
|
|
template<> \
|
|
|
|
size_t packsize<TYPE>( const TYPE &rhs ) \
|
|
|
|
{ \
|
|
|
|
return sizeof( TYPE ); \
|
|
|
|
} \
|
|
|
|
template<> \
|
|
|
|
void pack<TYPE>( const TYPE &rhs, char *buffer ) \
|
|
|
|
{ \
|
|
|
|
memcpy( buffer, &rhs, sizeof( IO::MeshType ) ); \
|
|
|
|
} \
|
|
|
|
template<> \
|
|
|
|
void unpack<TYPE>( TYPE &data, const char *buffer ) \
|
|
|
|
{ \
|
|
|
|
memcpy( &data, buffer, sizeof( IO::MeshType ) ); \
|
|
|
|
}
|
|
|
|
INSTANTIATE_PACK( IO::VariableType )
|
|
|
|
INSTANTIATE_PACK( IO::DataType )
|
|
|
|
INSTANTIATE_PACK( IO::MeshType )
|
|
|
|
INSTANTIATE_PACK( IO::FileFormat )
|
|
|
|
// clang-format on
|
|
|
|
|
2014-11-04 20:58:20 -06:00
|
|
|
|
|
|
|
// DatabaseEntry
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
size_t packsize<IO::DatabaseEntry>( const IO::DatabaseEntry &rhs )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
return packsize( rhs.name ) + packsize( rhs.file ) + packsize( rhs.offset );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
void pack<IO::DatabaseEntry>( const IO::DatabaseEntry &rhs, char *buffer )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
size_t i = 0;
|
|
|
|
pack( rhs.name, &buffer[i] );
|
|
|
|
i += packsize( rhs.name );
|
|
|
|
pack( rhs.file, &buffer[i] );
|
|
|
|
i += packsize( rhs.file );
|
|
|
|
pack( rhs.offset, &buffer[i] );
|
|
|
|
i += packsize( rhs.offset );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
void unpack<IO::DatabaseEntry>( IO::DatabaseEntry &data, const char *buffer )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
size_t i = 0;
|
|
|
|
unpack( data.name, &buffer[i] );
|
|
|
|
i += packsize( data.name );
|
|
|
|
unpack( data.file, &buffer[i] );
|
|
|
|
i += packsize( data.file );
|
|
|
|
unpack( data.offset, &buffer[i] );
|
|
|
|
i += packsize( data.offset );
|
2014-11-06 13:23:57 -06:00
|
|
|
}
|
|
|
|
// VariableDatabase
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
size_t packsize<IO::VariableDatabase>( const IO::VariableDatabase &rhs )
|
2014-11-06 13:23:57 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
return packsize( rhs.name ) + packsize( rhs.type ) + packsize( rhs.dim );
|
2014-11-06 13:23:57 -06:00
|
|
|
}
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
void pack<IO::VariableDatabase>( const IO::VariableDatabase &rhs, char *buffer )
|
2014-11-06 13:23:57 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
size_t i = 0;
|
|
|
|
pack( rhs.name, &buffer[i] );
|
|
|
|
i += packsize( rhs.name );
|
|
|
|
pack( rhs.type, &buffer[i] );
|
|
|
|
i += packsize( rhs.type );
|
|
|
|
pack( rhs.dim, &buffer[i] );
|
|
|
|
i += packsize( rhs.dim );
|
2014-11-06 13:23:57 -06:00
|
|
|
}
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
void unpack<IO::VariableDatabase>( IO::VariableDatabase &data, const char *buffer )
|
2014-11-06 13:23:57 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
size_t i = 0;
|
|
|
|
unpack( data.name, &buffer[i] );
|
|
|
|
i += packsize( data.name );
|
|
|
|
unpack( data.type, &buffer[i] );
|
|
|
|
i += packsize( data.type );
|
|
|
|
unpack( data.dim, &buffer[i] );
|
|
|
|
i += packsize( data.dim );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
|
|
|
// MeshDatabase
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
size_t packsize<IO::MeshDatabase>( const IO::MeshDatabase &data )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
return packsize( data.name ) + packsize( data.type ) + packsize( data.meshClass ) +
|
|
|
|
packsize( data.format ) + packsize( data.domains ) + packsize( data.variables ) +
|
|
|
|
packsize( data.variable_data );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
void pack<IO::MeshDatabase>( const IO::MeshDatabase &rhs, char *buffer )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
|
|
|
size_t i = 0;
|
2021-03-17 09:24:14 -05:00
|
|
|
pack( rhs.name, &buffer[i] );
|
|
|
|
i += packsize( rhs.name );
|
|
|
|
pack( rhs.type, &buffer[i] );
|
|
|
|
i += packsize( rhs.type );
|
|
|
|
pack( rhs.meshClass, &buffer[i] );
|
|
|
|
i += packsize( rhs.meshClass );
|
|
|
|
pack( rhs.format, &buffer[i] );
|
|
|
|
i += packsize( rhs.format );
|
|
|
|
pack( rhs.domains, &buffer[i] );
|
|
|
|
i += packsize( rhs.domains );
|
|
|
|
pack( rhs.variables, &buffer[i] );
|
|
|
|
i += packsize( rhs.variables );
|
|
|
|
pack( rhs.variable_data, &buffer[i] );
|
|
|
|
i += packsize( rhs.variable_data );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
|
|
|
template<>
|
2021-03-17 09:24:14 -05:00
|
|
|
void unpack<IO::MeshDatabase>( IO::MeshDatabase &data, const char *buffer )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
size_t i = 0;
|
|
|
|
unpack( data.name, &buffer[i] );
|
|
|
|
i += packsize( data.name );
|
|
|
|
unpack( data.type, &buffer[i] );
|
|
|
|
i += packsize( data.type );
|
|
|
|
unpack( data.meshClass, &buffer[i] );
|
|
|
|
i += packsize( data.meshClass );
|
|
|
|
unpack( data.format, &buffer[i] );
|
|
|
|
i += packsize( data.format );
|
|
|
|
unpack( data.domains, &buffer[i] );
|
|
|
|
i += packsize( data.domains );
|
|
|
|
unpack( data.variables, &buffer[i] );
|
|
|
|
i += packsize( data.variables );
|
|
|
|
unpack( data.variable_data, &buffer[i] );
|
|
|
|
i += packsize( data.variable_data );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-11 10:54:41 -06:00
|
|
|
namespace IO {
|
|
|
|
|
|
|
|
|
2014-11-06 13:23:57 -06:00
|
|
|
/****************************************************
|
2021-03-17 09:24:14 -05:00
|
|
|
* VariableDatabase *
|
|
|
|
****************************************************/
|
|
|
|
bool VariableDatabase::operator==( const VariableDatabase &rhs ) const
|
2014-11-06 13:23:57 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
return type == rhs.type && dim == rhs.dim && name == rhs.name;
|
2014-11-06 13:23:57 -06:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
bool VariableDatabase::operator!=( const VariableDatabase &rhs ) const
|
2014-11-06 13:23:57 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
return type != rhs.type || dim != rhs.dim || name != rhs.name;
|
2014-11-06 13:23:57 -06:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
bool VariableDatabase::operator>=( const VariableDatabase &rhs ) const
|
2014-11-06 13:23:57 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
return operator>( rhs ) || operator==( rhs );
|
2014-11-06 13:23:57 -06:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
bool VariableDatabase::operator<=( const VariableDatabase &rhs ) const { return !operator>( rhs ); }
|
|
|
|
bool VariableDatabase::operator>( const VariableDatabase &rhs ) const
|
2014-11-06 13:23:57 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
if ( name > rhs.name )
|
2014-11-06 13:23:57 -06:00
|
|
|
return true;
|
2021-03-17 09:24:14 -05:00
|
|
|
else if ( name < rhs.name )
|
2014-11-06 13:23:57 -06:00
|
|
|
return false;
|
2021-03-17 09:24:14 -05:00
|
|
|
if ( type > rhs.type )
|
2014-11-06 13:23:57 -06:00
|
|
|
return true;
|
2021-03-17 09:24:14 -05:00
|
|
|
else if ( type < rhs.type )
|
2014-11-06 13:23:57 -06:00
|
|
|
return false;
|
2021-03-17 09:24:14 -05:00
|
|
|
if ( dim > rhs.dim )
|
2014-11-06 13:23:57 -06:00
|
|
|
return true;
|
2021-03-17 09:24:14 -05:00
|
|
|
else if ( dim < rhs.dim )
|
2014-11-06 13:23:57 -06:00
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
bool VariableDatabase::operator<( const VariableDatabase &rhs ) const
|
2014-11-06 13:23:57 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
return !operator>( rhs ) && operator!=( rhs );
|
2014-11-06 13:23:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-04 20:58:20 -06:00
|
|
|
/****************************************************
|
2021-03-17 09:24:14 -05:00
|
|
|
* MeshDatabase *
|
|
|
|
****************************************************/
|
|
|
|
MeshDatabase::MeshDatabase() {}
|
|
|
|
MeshDatabase::~MeshDatabase() {}
|
|
|
|
MeshDatabase::MeshDatabase( const MeshDatabase &rhs )
|
|
|
|
{
|
|
|
|
name = rhs.name;
|
|
|
|
type = rhs.type;
|
|
|
|
meshClass = rhs.meshClass;
|
|
|
|
format = rhs.format;
|
|
|
|
domains = rhs.domains;
|
|
|
|
variables = rhs.variables;
|
2014-11-04 20:58:20 -06:00
|
|
|
variable_data = rhs.variable_data;
|
2014-09-09 13:42:13 -05:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
MeshDatabase &MeshDatabase::operator=( const MeshDatabase &rhs )
|
2014-09-09 13:42:13 -05:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
this->name = rhs.name;
|
|
|
|
this->type = rhs.type;
|
|
|
|
this->meshClass = rhs.meshClass;
|
|
|
|
this->format = rhs.format;
|
|
|
|
this->domains = rhs.domains;
|
|
|
|
this->variables = rhs.variables;
|
2014-11-04 20:58:20 -06:00
|
|
|
this->variable_data = rhs.variable_data;
|
|
|
|
return *this;
|
2014-09-09 13:42:13 -05:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
VariableDatabase MeshDatabase::getVariableDatabase( const std::string &varname ) const
|
2017-02-03 10:26:08 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
for ( size_t i = 0; i < variables.size(); i++ ) {
|
2017-02-03 10:26:08 -06:00
|
|
|
if ( variables[i].name == varname )
|
|
|
|
return variables[i];
|
|
|
|
}
|
|
|
|
return VariableDatabase();
|
|
|
|
}
|
2014-09-09 13:42:13 -05:00
|
|
|
|
|
|
|
|
2014-11-04 20:58:20 -06:00
|
|
|
/****************************************************
|
2021-03-17 09:24:14 -05:00
|
|
|
* DatabaseEntry *
|
|
|
|
****************************************************/
|
|
|
|
std::string DatabaseEntry::write() const
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
|
|
|
char tmp[1000];
|
2021-03-17 09:24:14 -05:00
|
|
|
sprintf( tmp, "%s; %s; %lu", name.c_str(), file.c_str(), offset );
|
|
|
|
return std::string( tmp );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
DatabaseEntry::DatabaseEntry( const char *line )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
auto list = splitList( line, ';' );
|
|
|
|
name = list[0];
|
|
|
|
file = list[1];
|
|
|
|
offset = atol( list[2].c_str() );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
void DatabaseEntry::read( const char *line )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
auto list = splitList( line, ';' );
|
|
|
|
name = list[0];
|
|
|
|
file = list[1];
|
|
|
|
offset = atol( list[2].c_str() );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
void DatabaseEntry::read( const std::string &line )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
auto list = splitList( line.c_str(), ';' );
|
|
|
|
name = list[0];
|
|
|
|
file = list[1];
|
|
|
|
offset = atol( list[2].c_str() );
|
2014-09-09 13:42:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Gather the mesh databases from all processors
|
2021-03-17 09:24:14 -05:00
|
|
|
inline int tod( int N ) { return ( N + 7 ) / sizeof( double ); }
|
|
|
|
std::vector<MeshDatabase> gatherAll(
|
|
|
|
const std::vector<MeshDatabase> &meshes, const Utilities::MPI &comm )
|
2014-09-09 13:42:13 -05:00
|
|
|
{
|
2021-01-04 22:35:10 -06:00
|
|
|
if ( comm.getSize() == 1 )
|
2014-11-11 10:54:41 -06:00
|
|
|
return meshes;
|
2021-03-17 09:24:14 -05:00
|
|
|
PROFILE_START( "gatherAll" );
|
|
|
|
PROFILE_START( "gatherAll-pack", 2 );
|
2021-01-04 22:35:10 -06:00
|
|
|
int size = comm.getSize();
|
|
|
|
// First pack the mesh data to local buffers
|
|
|
|
int localsize = 0;
|
2021-03-17 09:24:14 -05:00
|
|
|
for ( size_t i = 0; i < meshes.size(); i++ )
|
|
|
|
localsize += tod( packsize( meshes[i] ) );
|
2021-01-04 22:35:10 -06:00
|
|
|
auto localbuf = new double[localsize];
|
2021-03-17 09:24:14 -05:00
|
|
|
int pos = 0;
|
|
|
|
for ( size_t i = 0; i < meshes.size(); i++ ) {
|
|
|
|
pack( meshes[i], (char *) &localbuf[pos] );
|
|
|
|
pos += tod( packsize( meshes[i] ) );
|
2021-01-04 22:35:10 -06:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
PROFILE_STOP( "gatherAll-pack", 2 );
|
2021-01-04 22:35:10 -06:00
|
|
|
// Get the number of bytes each processor will be sending/recieving
|
2021-03-17 09:24:14 -05:00
|
|
|
PROFILE_START( "gatherAll-send1", 2 );
|
|
|
|
auto recvsize = comm.allGather( localsize );
|
2021-01-04 22:35:10 -06:00
|
|
|
int globalsize = recvsize[0];
|
2021-03-17 09:24:14 -05:00
|
|
|
auto disp = new int[size];
|
|
|
|
disp[0] = 0;
|
|
|
|
for ( int i = 1; i < size; i++ ) {
|
|
|
|
disp[i] = disp[i - 1] + recvsize[i];
|
2021-01-04 22:35:10 -06:00
|
|
|
globalsize += recvsize[i];
|
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
PROFILE_STOP( "gatherAll-send1", 2 );
|
2021-01-04 22:35:10 -06:00
|
|
|
// Send/recv the global data
|
2021-03-17 09:24:14 -05:00
|
|
|
PROFILE_START( "gatherAll-send2", 2 );
|
2021-01-04 22:35:10 -06:00
|
|
|
auto globalbuf = new double[globalsize];
|
2021-03-17 09:24:14 -05:00
|
|
|
comm.allGather( localbuf, localsize, globalbuf, recvsize.data(), disp, true );
|
|
|
|
PROFILE_STOP( "gatherAll-send2", 2 );
|
2021-01-04 22:35:10 -06:00
|
|
|
// Unpack the data
|
2021-03-17 09:24:14 -05:00
|
|
|
PROFILE_START( "gatherAll-unpack", 2 );
|
|
|
|
std::map<std::string, MeshDatabase> data;
|
2021-01-04 22:35:10 -06:00
|
|
|
pos = 0;
|
|
|
|
while ( pos < globalsize ) {
|
|
|
|
MeshDatabase tmp;
|
2021-03-17 09:24:14 -05:00
|
|
|
unpack( tmp, (char *) &globalbuf[pos] );
|
|
|
|
pos += tod( packsize( tmp ) );
|
|
|
|
std::map<std::string, MeshDatabase>::iterator it = data.find( tmp.name );
|
|
|
|
if ( it == data.end() ) {
|
2021-01-04 22:35:10 -06:00
|
|
|
data[tmp.name] = tmp;
|
|
|
|
} else {
|
2021-03-17 09:24:14 -05:00
|
|
|
for ( size_t i = 0; i < tmp.domains.size(); i++ )
|
|
|
|
it->second.domains.push_back( tmp.domains[i] );
|
|
|
|
for ( size_t i = 0; i < tmp.variables.size(); i++ )
|
|
|
|
it->second.variables.push_back( tmp.variables[i] );
|
|
|
|
it->second.variable_data.insert( tmp.variable_data.begin(), tmp.variable_data.end() );
|
2021-01-04 22:35:10 -06:00
|
|
|
}
|
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
for ( auto it = data.begin(); it != data.end(); ++it ) {
|
2021-01-04 22:35:10 -06:00
|
|
|
// Get the unique variables
|
2021-03-17 09:24:14 -05:00
|
|
|
std::set<VariableDatabase> data2(
|
|
|
|
it->second.variables.begin(), it->second.variables.end() );
|
|
|
|
it->second.variables = std::vector<VariableDatabase>( data2.begin(), data2.end() );
|
2021-01-04 22:35:10 -06:00
|
|
|
}
|
|
|
|
// Free temporary memory
|
2021-03-17 09:24:14 -05:00
|
|
|
delete[] localbuf;
|
|
|
|
delete[] disp;
|
|
|
|
delete[] globalbuf;
|
2021-01-04 22:35:10 -06:00
|
|
|
// Return the results
|
2021-03-17 09:24:14 -05:00
|
|
|
std::vector<MeshDatabase> data2( data.size() );
|
|
|
|
size_t i = 0;
|
2021-03-18 08:41:39 -05:00
|
|
|
for ( auto it = data.begin(); it != data.end(); ++it, ++i )
|
2021-01-04 22:35:10 -06:00
|
|
|
data2[i] = it->second;
|
2021-03-17 09:24:14 -05:00
|
|
|
PROFILE_STOP( "gatherAll-unpack", 2 );
|
|
|
|
PROFILE_STOP( "gatherAll" );
|
2021-01-04 22:35:10 -06:00
|
|
|
return data2;
|
2014-09-09 13:42:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//! Write the mesh databases to a file
|
2021-03-17 09:24:14 -05:00
|
|
|
void write( const std::vector<MeshDatabase> &meshes, const std::string &filename )
|
|
|
|
{
|
|
|
|
PROFILE_START( "write" );
|
|
|
|
FILE *fid = fopen( filename.c_str(), "wb" );
|
|
|
|
for ( size_t i = 0; i < meshes.size(); i++ ) {
|
|
|
|
fprintf( fid, "%s\n", meshes[i].name.c_str() );
|
2021-03-18 08:41:39 -05:00
|
|
|
fprintf( fid, " type: %s\n", getString( meshes[i].type ).data() );
|
2021-03-17 09:24:14 -05:00
|
|
|
fprintf( fid, " meshClass: %s\n", meshes[i].meshClass.c_str() );
|
2021-03-18 08:41:39 -05:00
|
|
|
fprintf( fid, " format: %s\n", getString( meshes[i].format ).data() );
|
2021-03-17 09:24:14 -05:00
|
|
|
for ( size_t j = 0; j < meshes[i].domains.size(); j++ )
|
|
|
|
fprintf( fid, " domain: %s\n", meshes[i].domains[j].write().c_str() );
|
|
|
|
fprintf( fid, " variables: " );
|
|
|
|
for ( size_t j = 0; j < meshes[i].variables.size(); j++ ) {
|
|
|
|
const VariableDatabase &var = meshes[i].variables[j];
|
2021-03-18 08:41:39 -05:00
|
|
|
fprintf( fid, "%s|%s|%i; ", var.name.data(), getString( var.type ).data(), var.dim );
|
2014-09-09 13:42:13 -05:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
fprintf( fid, "\n" );
|
2021-03-18 08:41:39 -05:00
|
|
|
for ( auto it = meshes[i].variable_data.begin(); it != meshes[i].variable_data.end();
|
|
|
|
++it ) {
|
2021-03-17 09:24:14 -05:00
|
|
|
const char *domain = it->first.first.c_str();
|
|
|
|
const char *variable = it->first.second.c_str();
|
|
|
|
fprintf(
|
|
|
|
fid, " variable(%s,%s): %s\n", domain, variable, it->second.write().c_str() );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
2014-09-09 13:42:13 -05:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
fclose( fid );
|
|
|
|
PROFILE_STOP( "write" );
|
2014-09-09 13:42:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//! Read the mesh databases from a file
|
2021-03-17 09:24:14 -05:00
|
|
|
std::vector<MeshDatabase> read( const std::string &filename )
|
2014-09-09 13:42:13 -05:00
|
|
|
{
|
|
|
|
std::vector<MeshDatabase> meshes;
|
2021-03-17 09:24:14 -05:00
|
|
|
PROFILE_START( "read" );
|
|
|
|
FILE *fid = fopen( filename.c_str(), "rb" );
|
|
|
|
if ( fid == NULL )
|
|
|
|
ERROR( "Error opening file" );
|
2014-11-05 15:54:18 -06:00
|
|
|
char *line = new char[10000];
|
2021-03-17 09:24:14 -05:00
|
|
|
while ( std::fgets( line, 1000, fid ) != NULL ) {
|
|
|
|
if ( line[0] < 32 ) {
|
2014-09-09 13:42:13 -05:00
|
|
|
// Empty line
|
|
|
|
continue;
|
|
|
|
} else if ( line[0] != ' ' ) {
|
2021-03-17 09:24:14 -05:00
|
|
|
meshes.resize( meshes.size() + 1 );
|
|
|
|
std::string name( line );
|
|
|
|
name.resize( name.size() - 1 );
|
2014-09-09 13:42:13 -05:00
|
|
|
meshes.back().name = name;
|
2021-03-17 09:24:14 -05:00
|
|
|
} else if ( strncmp( line, " format:", 10 ) == 0 ) {
|
2021-03-18 08:41:39 -05:00
|
|
|
meshes.back().format = getFileFormat( &line[10] );
|
2021-03-17 09:24:14 -05:00
|
|
|
} else if ( strncmp( line, " type:", 8 ) == 0 ) {
|
2021-03-18 08:41:39 -05:00
|
|
|
meshes.back().type = getMeshType( &line[8] );
|
2021-03-17 09:24:14 -05:00
|
|
|
} else if ( strncmp( line, " meshClass:", 13 ) == 0 ) {
|
|
|
|
meshes.back().meshClass = deblank( std::string( &line[13] ) );
|
|
|
|
} else if ( strncmp( line, " domain:", 10 ) == 0 ) {
|
|
|
|
DatabaseEntry data( &line[10] );
|
|
|
|
meshes.back().domains.push_back( data );
|
|
|
|
} else if ( strncmp( line, " variables:", 13 ) == 0 ) {
|
|
|
|
MeshDatabase &mesh = meshes.back();
|
|
|
|
std::vector<std::string> variables = splitList( &line[13], ';' );
|
|
|
|
mesh.variables.resize( variables.size() );
|
|
|
|
for ( size_t i = 0; i < variables.size(); i++ ) {
|
|
|
|
std::vector<std::string> tmp = splitList( variables[i].c_str(), '|' );
|
|
|
|
ASSERT( tmp.size() == 3 );
|
2014-11-06 13:23:57 -06:00
|
|
|
mesh.variables[i].name = tmp[0];
|
2021-03-18 08:41:39 -05:00
|
|
|
mesh.variables[i].type = getVariableType( tmp[1] );
|
2021-03-17 09:24:14 -05:00
|
|
|
mesh.variables[i].dim = atoi( tmp[2].c_str() );
|
2014-11-06 13:23:57 -06:00
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
} else if ( strncmp( line, " variable(", 12 ) == 0 ) {
|
|
|
|
size_t i1 = find( line, ',' );
|
|
|
|
size_t i2 = find( line, ':' );
|
|
|
|
std::string domain = deblank( std::string( line, 12, i1 - 12 ) );
|
|
|
|
std::string variable = deblank( std::string( line, i1 + 1, i2 - i1 - 2 ) );
|
|
|
|
std::pair<std::string, std::string> key( domain, variable );
|
|
|
|
DatabaseEntry data( &line[i2 + 1] );
|
|
|
|
meshes.back().variable_data.insert(
|
|
|
|
std::pair<std::pair<std::string, std::string>, DatabaseEntry>( key, data ) );
|
2014-09-09 13:42:13 -05:00
|
|
|
} else {
|
2021-03-17 09:24:14 -05:00
|
|
|
ERROR( "Error reading line" );
|
2014-09-09 13:42:13 -05:00
|
|
|
}
|
|
|
|
}
|
2021-03-17 09:24:14 -05:00
|
|
|
fclose( fid );
|
|
|
|
delete[] line;
|
|
|
|
PROFILE_STOP( "read" );
|
2014-09-09 13:42:13 -05:00
|
|
|
return meshes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-04 20:58:20 -06:00
|
|
|
// Return the mesh type
|
2021-03-17 09:24:14 -05:00
|
|
|
IO::MeshType meshType( const IO::Mesh &mesh )
|
2014-11-04 20:58:20 -06:00
|
|
|
{
|
2021-03-17 09:24:14 -05:00
|
|
|
IO::MeshType type = IO::MeshType::Unknown;
|
2015-06-11 14:01:24 -05:00
|
|
|
const std::string meshClass = mesh.className();
|
2021-03-17 09:24:14 -05:00
|
|
|
if ( meshClass == "PointList" ) {
|
|
|
|
type = IO::MeshType::PointMesh;
|
|
|
|
} else if ( meshClass == "TriList" || meshClass == "TriMesh" ) {
|
|
|
|
type = IO::MeshType::SurfaceMesh;
|
|
|
|
} else if ( meshClass == "DomainMesh" ) {
|
|
|
|
type = IO::MeshType::VolumeMesh;
|
2014-11-04 20:58:20 -06:00
|
|
|
} else {
|
2021-03-17 09:24:14 -05:00
|
|
|
ERROR( "Unknown mesh" );
|
2014-11-04 20:58:20 -06:00
|
|
|
}
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2014-09-09 13:42:13 -05:00
|
|
|
|
2021-03-17 09:24:14 -05:00
|
|
|
} // namespace IO
|