![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
#include <cassert>
#include "moab/Core.hpp"
#include "moab/IntxMesh/IntxUtils.hpp"
#include "moab/ProgOptions.hpp"
#include "moab/CpuTimer.hpp"
#include "DebugOutput.hpp"
Go to the source code of this file.
Functions | |
int | main (int argc, char *argv[]) |
int main | ( | int | argc, |
char * | argv[] | ||
) |
Definition at line 34 of file mbIntxCheck.cpp.
References moab::Interface::add_entities(), ProgOptions::addOpt(), moab::IntxAreaUtils::area_spherical_polygon(), moab::Range::begin(), moab::Range::clear(), moab::Interface::create_meshset(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), moab::Interface::get_entities_by_handle(), moab::Interface::globalId_tag(), moab::Range::insert(), moab::IntxAreaUtils::lHuiller, moab::Interface::load_file(), mb, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, MESHSET_SET, ProgOptions::parseCommandLine(), moab::R, moab::IntxUtils::ScaleToRadius(), size, moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and moab::Interface::write_file().
{
std::stringstream sstr;
// Default area_method = lHuiller; Options: Girard, GaussQuadrature (if TR is available)
const IntxAreaUtils::AreaMethod areaMethod = IntxAreaUtils::lHuiller;
int rank = 0, size = 1;
#ifdef MOAB_HAVE_MPI
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
#endif
std::string sourceFile, targetFile, intxFile;
std::string source_verif( "outS.h5m" ), target_verif( "outt.h5m" );
int sphere = 1;
int oldNamesParents = 1;
double areaErrSource = -1;
double areaErrTarget = -1;
ProgOptions opts;
opts.addOpt< std::string >( "source,s", "source file ", &sourceFile );
opts.addOpt< std::string >( "target,t", "target file ", &targetFile );
opts.addOpt< std::string >( "intersection,i", "intersection file ", &intxFile );
opts.addOpt< std::string >( "verif_source,v", "output source verification ", &source_verif );
opts.addOpt< std::string >( "verif_target,w", "output target verification ", &target_verif );
opts.addOpt< double >( "threshold_source,m", "error source threshold ", &areaErrSource );
opts.addOpt< double >( "threshold_target,q", "error target threshold ", &areaErrTarget );
opts.addOpt< int >( "sphere,p", "mesh on a sphere", &sphere );
opts.addOpt< int >( "old_convention,n", "old names for parent tags", &oldNamesParents );
opts.parseCommandLine( argc, argv );
// load meshes in parallel if needed
std::string opts_read = ( size == 1 ? ""
: std::string( "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION" ) +
std::string( ";PARALLEL_RESOLVE_SHARED_ENTS" ) );
// read meshes in 3 file sets
ErrorCode rval;
Core moab;
Interface* mb = &moab; // global
EntityHandle sset, tset, ixset;
// create meshsets and load files
rval = mb->create_meshset( MESHSET_SET, sset );MB_CHK_ERR( rval );
rval = mb->create_meshset( MESHSET_SET, tset );MB_CHK_ERR( rval );
rval = mb->create_meshset( MESHSET_SET, ixset );MB_CHK_ERR( rval );
if( 0 == rank ) std::cout << "Loading source file " << sourceFile << "\n";
rval = mb->load_file( sourceFile.c_str(), &sset, opts_read.c_str() );MB_CHK_SET_ERR( rval, "failed reading source file" );
if( 0 == rank ) std::cout << "Loading target file " << targetFile << "\n";
rval = mb->load_file( targetFile.c_str(), &tset, opts_read.c_str() );MB_CHK_SET_ERR( rval, "failed reading target file" );
if( 0 == rank ) std::cout << "Loading intersection file " << intxFile << "\n";
rval = mb->load_file( intxFile.c_str(), &ixset, opts_read.c_str() );MB_CHK_SET_ERR( rval, "failed reading intersection file" );
double R = 1.;
if( sphere )
{
// fix radius of both meshes, to be consistent with radius 1
rval = moab::IntxUtils::ScaleToRadius( mb, sset, R );MB_CHK_ERR( rval );
rval = moab::IntxUtils::ScaleToRadius( mb, tset, R );MB_CHK_ERR( rval );
}
Range intxCells;
rval = mb->get_entities_by_dimension( ixset, 2, intxCells );MB_CHK_ERR( rval );
Range sourceCells;
rval = mb->get_entities_by_dimension( sset, 2, sourceCells );MB_CHK_ERR( rval );
Range targetCells;
rval = mb->get_entities_by_dimension( tset, 2, targetCells );MB_CHK_ERR( rval );
Tag sourceParentTag;
Tag targetParentTag;
if( oldNamesParents )
{
rval = mb->tag_get_handle( "RedParent", targetParentTag );MB_CHK_SET_ERR( rval, "can't find target parent tag" );
rval = mb->tag_get_handle( "BlueParent", sourceParentTag );MB_CHK_SET_ERR( rval, "can't find source parent tag" );
}
else
{
rval = mb->tag_get_handle( "TargetParent", targetParentTag );MB_CHK_SET_ERR( rval, "can't find target parent tag" );
rval = mb->tag_get_handle( "SourceParent", sourceParentTag );MB_CHK_SET_ERR( rval, "can't find source parent tag" );
}
// error sets, for better visualization
EntityHandle errorSourceSet;
rval = mb->create_meshset( MESHSET_SET, errorSourceSet );MB_CHK_ERR( rval );
EntityHandle errorTargetSet;
rval = mb->create_meshset( MESHSET_SET, errorTargetSet );MB_CHK_ERR( rval );
std::map< int, double > sourceAreas;
std::map< int, double > targetAreas;
std::map< int, double > sourceAreasIntx;
std::map< int, double > targetAreasIntx;
std::map< int, int > sourceNbIntx;
std::map< int, int > targetNbIntx;
std::map< int, EntityHandle > sourceMap;
std::map< int, EntityHandle > targetMap;
Tag gidTag = mb->globalId_tag();
Tag areaTag;
rval = mb->tag_get_handle( "OrigArea", 1, MB_TYPE_DOUBLE, areaTag, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_ERR( rval );
moab::IntxAreaUtils areaAdaptor( areaMethod );
Range non_convex_intx_cells;
for( Range::iterator eit = sourceCells.begin(); eit != sourceCells.end(); ++eit )
{
EntityHandle cell = *eit;
const EntityHandle* verts;
int num_nodes;
rval = mb->get_connectivity( cell, verts, num_nodes );MB_CHK_ERR( rval );
if( MB_SUCCESS != rval ) return -1;
std::vector< double > coords( 3 * num_nodes );
// get coordinates
rval = mb->get_coords( verts, num_nodes, &coords[0] );
if( MB_SUCCESS != rval ) return -1;
double area = areaAdaptor.area_spherical_polygon( &coords[0], num_nodes, R );
int sourceID;
rval = mb->tag_get_data( gidTag, &cell, 1, &sourceID );MB_CHK_ERR( rval );
sourceAreas[sourceID] = area;
rval = mb->tag_set_data( areaTag, &cell, 1, &area );MB_CHK_ERR( rval );
sourceMap[sourceID] = cell;
}
for( Range::iterator eit = targetCells.begin(); eit != targetCells.end(); ++eit )
{
EntityHandle cell = *eit;
const EntityHandle* verts;
int num_nodes;
rval = mb->get_connectivity( cell, verts, num_nodes );MB_CHK_ERR( rval );
if( MB_SUCCESS != rval ) return -1;
std::vector< double > coords( 3 * num_nodes );
// get coordinates
rval = mb->get_coords( verts, num_nodes, &coords[0] );
if( MB_SUCCESS != rval ) return -1;
double area = areaAdaptor.area_spherical_polygon( &coords[0], num_nodes, R );
int targetID;
rval = mb->tag_get_data( gidTag, &cell, 1, &targetID );MB_CHK_ERR( rval );
targetAreas[targetID] = area;
rval = mb->tag_set_data( areaTag, &cell, 1, &area );MB_CHK_ERR( rval );
targetMap[targetID] = cell;
}
for( Range::iterator eit = intxCells.begin(); eit != intxCells.end(); ++eit )
{
EntityHandle cell = *eit;
const EntityHandle* verts;
int num_nodes;
rval = mb->get_connectivity( cell, verts, num_nodes );MB_CHK_ERR( rval );
if( MB_SUCCESS != rval ) return -1;
std::vector< double > coords( 3 * num_nodes );
// get coordinates
rval = mb->get_coords( verts, num_nodes, &coords[0] );
if( MB_SUCCESS != rval ) return -1;
int check_sign = 1;
double intx_area = areaAdaptor.area_spherical_polygon( &coords[0], num_nodes, R, &check_sign );
rval = mb->tag_set_data( areaTag, &cell, 1, &intx_area );
;MB_CHK_ERR( rval );
int sourceID, targetID;
rval = mb->tag_get_data( sourceParentTag, &cell, 1, &sourceID );MB_CHK_ERR( rval );
rval = mb->tag_get_data( targetParentTag, &cell, 1, &targetID );MB_CHK_ERR( rval );
std::map< int, double >::iterator sit = sourceAreasIntx.find( sourceID );
if( sit == sourceAreasIntx.end() )
{
sourceAreasIntx[sourceID] = intx_area;
sourceNbIntx[sourceID] = 1;
}
else
{
sourceAreasIntx[sourceID] += intx_area;
sourceNbIntx[sourceID]++;
}
std::map< int, double >::iterator tit = targetAreasIntx.find( targetID );
if( tit == targetAreasIntx.end() )
{
targetAreasIntx[targetID] = intx_area;
targetNbIntx[targetID] = 1;
}
else
{
targetAreasIntx[targetID] += intx_area;
targetNbIntx[targetID]++;
}
if( intx_area < 0 )
{
std::cout << "negative intx area: " << intx_area << " n:" << num_nodes << " parents: " << sourceID << " "
<< targetID << "\n";
}
if( check_sign < 0 )
{
non_convex_intx_cells.insert( cell );
std::cout << " non-convex polygon: " << intx_area << " n:" << num_nodes << " parents: " << sourceID << " "
<< targetID << "\n";
}
}
Tag diffTag;
rval = mb->tag_get_handle( "AreaDiff", 1, MB_TYPE_DOUBLE, diffTag, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_ERR( rval );
Tag countIntxCellsTag;
rval = mb->tag_get_handle( "CountIntx", 1, MB_TYPE_INTEGER, countIntxCellsTag, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_ERR( rval );
for( Range::iterator eit = sourceCells.begin(); eit != sourceCells.end(); ++eit )
{
EntityHandle cell = *eit;
int sourceID;
rval = mb->tag_get_data( gidTag, &cell, 1, &sourceID );MB_CHK_ERR( rval );
double areaDiff = sourceAreas[sourceID];
std::map< int, double >::iterator sit = sourceAreasIntx.find( sourceID );
int countIntxCells = 0;
if( sit != sourceAreasIntx.end() )
{
areaDiff -= sourceAreasIntx[sourceID];
countIntxCells = sourceNbIntx[sourceID];
}
rval = mb->tag_set_data( diffTag, &cell, 1, &areaDiff );
rval = mb->tag_set_data( countIntxCellsTag, &cell, 1, &countIntxCells );
// add to errorSourceSet set if needed
if( ( areaErrSource > 0 ) && ( fabs( areaDiff ) > areaErrSource ) )
{
rval = mb->add_entities( errorSourceSet, &cell, 1 );MB_CHK_ERR( rval );
}
}
if( 0 == rank ) std::cout << "write source verification file " << source_verif << "\n";
rval = mb->write_file( source_verif.c_str(), 0, 0, &sset, 1 );MB_CHK_ERR( rval );
if( areaErrSource > 0 )
{
Range sourceErrorCells;
rval = mb->get_entities_by_handle( errorSourceSet, sourceErrorCells );MB_CHK_ERR( rval );
EntityHandle errorSourceIntxSet;
rval = mb->create_meshset( MESHSET_SET, errorSourceIntxSet );MB_CHK_ERR( rval );
if( !sourceErrorCells.empty() )
{
// add the intx cells that have these as source parent
std::vector< int > sourceIDs;
sourceIDs.resize( sourceErrorCells.size() );
rval = mb->tag_get_data( gidTag, sourceErrorCells, &sourceIDs[0] );MB_CHK_SET_ERR( rval, "can't get source IDs" );
std::sort( sourceIDs.begin(), sourceIDs.end() );
for( Range::iterator eit = intxCells.begin(); eit != intxCells.end(); ++eit )
{
EntityHandle cell = *eit;
int sourceID;
rval = mb->tag_get_data( sourceParentTag, &cell, 1, &sourceID );MB_CHK_ERR( rval );
std::vector< int >::iterator j = std::lower_bound( sourceIDs.begin(), sourceIDs.end(), sourceID );
if( ( j != sourceIDs.end() ) && ( *j == sourceID ) )
{
rval = mb->add_entities( errorSourceIntxSet, &cell, 1 );
;MB_CHK_ERR( rval );
}
}
std::string filtersource = std::string( "filt_" ) + source_verif;
rval = mb->write_file( filtersource.c_str(), 0, 0, &errorSourceSet, 1 );
std::string filterIntxsource = std::string( "filtIntx_" ) + source_verif;
rval = mb->write_file( filterIntxsource.c_str(), 0, 0, &errorSourceIntxSet, 1 );
}
}
for( Range::iterator eit = targetCells.begin(); eit != targetCells.end(); ++eit )
{
EntityHandle cell = *eit;
int targetID;
rval = mb->tag_get_data( gidTag, &cell, 1, &targetID );MB_CHK_ERR( rval );
double areaDiff = targetAreas[targetID];
int countIntxCells = 0;
std::map< int, double >::iterator sit = targetAreasIntx.find( targetID );
if( sit != targetAreasIntx.end() )
{
areaDiff -= targetAreasIntx[targetID];
countIntxCells = targetNbIntx[targetID];
}
rval = mb->tag_set_data( diffTag, &cell, 1, &areaDiff );
rval = mb->tag_set_data( countIntxCellsTag, &cell, 1, &countIntxCells );
// add to errorTargetSet set if needed
if( ( areaErrTarget > 0 ) && ( fabs( areaDiff ) > areaErrTarget ) )
{
rval = mb->add_entities( errorTargetSet, &cell, 1 );MB_CHK_ERR( rval );
}
}
if( 0 == rank ) std::cout << "write target verification file " << target_verif << "\n";
rval = mb->write_file( target_verif.c_str(), 0, 0, &tset, 1 );MB_CHK_ERR( rval );
if( areaErrTarget > 0 )
{
Range targetErrorCells;
rval = mb->get_entities_by_handle( errorTargetSet, targetErrorCells );MB_CHK_ERR( rval );
if( !targetErrorCells.empty() )
{
EntityHandle errorTargetIntxSet;
rval = mb->create_meshset( MESHSET_SET, errorTargetIntxSet );MB_CHK_ERR( rval );
// add the intx cells that have these as target parent
std::vector< int > targetIDs;
targetIDs.resize( targetErrorCells.size() );
rval = mb->tag_get_data( gidTag, targetErrorCells, &targetIDs[0] );MB_CHK_SET_ERR( rval, "can't get target IDs" );
std::sort( targetIDs.begin(), targetIDs.end() );
for( Range::iterator eit = intxCells.begin(); eit != intxCells.end(); ++eit )
{
EntityHandle cell = *eit;
int targetID;
rval = mb->tag_get_data( targetParentTag, &cell, 1, &targetID );MB_CHK_ERR( rval );
std::vector< int >::iterator j = std::lower_bound( targetIDs.begin(), targetIDs.end(), targetID );
if( ( j != targetIDs.end() ) && ( *j == targetID ) )
{
rval = mb->add_entities( errorTargetIntxSet, &cell, 1 );
;MB_CHK_ERR( rval );
}
}
std::string filterTarget = std::string( "filt_" ) + target_verif;
rval = mb->write_file( filterTarget.c_str(), 0, 0, &errorTargetSet, 1 );
std::string filterIntxtarget = std::string( "filtIntx_" ) + target_verif;
rval = mb->write_file( filterIntxtarget.c_str(), 0, 0, &errorTargetIntxSet, 1 );
}
}
if( !non_convex_intx_cells.empty() )
{
sourceCells.clear();
targetCells.clear();
for( Range::iterator it = non_convex_intx_cells.begin(); it != non_convex_intx_cells.end(); it++ )
{
EntityHandle cellIntx = *it;
int sourceID, targetID;
rval = mb->tag_get_data( sourceParentTag, &cellIntx, 1, &sourceID );MB_CHK_ERR( rval );
rval = mb->tag_get_data( targetParentTag, &cellIntx, 1, &targetID );MB_CHK_ERR( rval );
sourceCells.insert( sourceMap[sourceID] );
targetCells.insert( targetMap[targetID] );
}
EntityHandle nonConvexSet;
rval = mb->create_meshset( MESHSET_SET, nonConvexSet );MB_CHK_ERR( rval );
rval = mb->add_entities( nonConvexSet, non_convex_intx_cells );
rval = mb->write_file( "nonConvex.h5m", 0, 0, &nonConvexSet, 1 );MB_CHK_ERR( rval );
EntityHandle sSet;
rval = mb->create_meshset( MESHSET_SET, sSet );MB_CHK_ERR( rval );
rval = mb->add_entities( sSet, sourceCells );
rval = mb->write_file( "nonConvexSource.h5m", 0, 0, &sSet, 1 );MB_CHK_ERR( rval );
EntityHandle tSet;
rval = mb->create_meshset( MESHSET_SET, tSet );MB_CHK_ERR( rval );
rval = mb->add_entities( tSet, targetCells );
rval = mb->write_file( "nonConvexTarget.h5m", 0, 0, &tSet, 1 );MB_CHK_ERR( rval );
rval = mb->add_entities( nonConvexSet, sourceCells );
rval = mb->add_entities( nonConvexSet, targetCells );
rval = mb->write_file( "nonConvexAll.h5m", 0, 0, &nonConvexSet, 1 );MB_CHK_ERR( rval );
}
return 0;
}