MOAB: Mesh Oriented datABase
(version 5.4.1)
|
#include <iostream>
#include <string>
#include <sstream>
#include <ctime>
#include <vector>
#include <algorithm>
#include "moab/Core.hpp"
#include "moab/Range.hpp"
#include "moab/MeshTopoUtil.hpp"
#include "moab/NestedRefine.hpp"
#include "moab/DiscreteGeometry/DGMSolver.hpp"
#include "moab/DiscreteGeometry/HiReconstruction.hpp"
#include "TestUtil.hpp"
#include "geomObject.cpp"
#include <cmath>
#include <cstdlib>
Go to the source code of this file.
Defines | |
#define | nsamples 10 |
Functions | |
ErrorCode | test_closedsurface_mesh (const char *filename, int *level_degrees, int num_levels, int degree, bool interp, int dim, geomObject *obj) |
ErrorCode | closedsurface_uref_hirec_convergence_study (const char *filename, int *level_degrees, int num_levels, std::vector< int > °s2fit, bool interp, geomObject *obj) |
void | usage () |
int | main (int argc, char *argv[]) |
#define nsamples 10 |
Definition at line 36 of file uref_hirec_test.cpp.
Referenced by closedsurface_uref_hirec_convergence_study().
ErrorCode closedsurface_uref_hirec_convergence_study | ( | const char * | filename, |
int * | level_degrees, | ||
int | num_levels, | ||
std::vector< int > & | degs2fit, | ||
bool | interp, | ||
geomObject * | obj | ||
) |
Definition at line 141 of file uref_hirec_test.cpp.
References moab::Range::begin(), geomObject::compute_projecterror(), moab::Interface::create_meshset(), moab::Range::end(), moab::error(), ErrorCode, moab::NestedRefine::generate_mesh_hierarchy(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), moab::ParallelComm::get_pcomm(), moab::HiReconstruction::hiproj_walf_in_element(), moab::Interface::load_file(), MB_CHK_ERR, MBQUAD, MBTRI, mesh, MESHSET_SET, MPI_COMM_WORLD, nsamples, geomObject::project_points2geom(), read_options, moab::HiReconstruction::reconstruct3D_surf_geom(), moab::Interface::set_coords(), moab::Range::size(), moab::sum(), and moab::TYPE_FROM_HANDLE().
{ Core moab; Interface* mbImpl = &moab; ParallelComm* pc = NULL; EntityHandle fileset; ErrorCode error; error = mbImpl->create_meshset( moab::MESHSET_SET, fileset );MB_CHK_ERR( error ); // load mesh from file #ifdef MOAB_HAVE_MPI MPI_Comm comm = MPI_COMM_WORLD; EntityHandle partnset; error = mbImpl->create_meshset( moab::MESHSET_SET, partnset );MB_CHK_ERR( error ); pc = moab::ParallelComm::get_pcomm( mbImpl, partnset, &comm ); int procs = 1; MPI_Comm_size( comm, &procs ); if( procs > 1 ) { read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;"; error = mbImpl->load_file( filename, &fileset, read_options.c_str() );MB_CHK_ERR( error ); } else { error = mbImpl->load_file( filename, &fileset );MB_CHK_ERR( error ); } #else error = mbImpl->load_file( filename, &fileset );MB_CHK_ERR( error ); #endif // Generate hierarchy NestedRefine uref( &moab, pc, fileset ); std::vector< EntityHandle > meshes; std::vector< int > meshsizes; error = uref.generate_mesh_hierarchy( num_levels, level_degrees, meshes );MB_CHK_ERR( error ); std::vector< std::vector< double > > geoml1errs( 1 + degs2fit.size() ), geoml2errs( 1 + degs2fit.size() ), geomlinferrs( 1 + degs2fit.size() ); // Perform high order reconstruction on each level of mesh (projected onto exact geometry) and // estimate geometric error with various degrees of fitting for( size_t i = 0; i < meshes.size(); ++i ) { EntityHandle& mesh = meshes[i]; // project onto exact geometry since each level with uref has only linear coordinates Range verts; error = mbImpl->get_entities_by_dimension( mesh, 0, verts );MB_CHK_ERR( error ); for( Range::iterator ivert = verts.begin(); ivert != verts.end(); ++ivert ) { EntityHandle currvert = *ivert; double currcoords[3], exactcoords[3]; error = mbImpl->get_coords( &currvert, 1, currcoords ); obj->project_points2geom( 3, currcoords, exactcoords, NULL ); error = mbImpl->set_coords( &currvert, 1, exactcoords ); } // generate random points on each elements, assument 3D coordinates Range elems; error = mbImpl->get_entities_by_dimension( mesh, 2, elems );MB_CHK_ERR( error ); meshsizes.push_back( elems.size() ); int nvpe = TYPE_FROM_HANDLE( *elems.begin() ) == MBTRI ? 3 : 4; std::vector< double > testpnts, testnaturalcoords; testpnts.reserve( 3 * elems.size() * nsamples ); testnaturalcoords.reserve( nvpe * elems.size() * nsamples ); for( Range::iterator ielem = elems.begin(); ielem != elems.end(); ++ielem ) { EntityHandle currelem = *ielem; std::vector< EntityHandle > conn; error = mbImpl->get_connectivity( &currelem, 1, conn );MB_CHK_ERR( error ); nvpe = conn.size(); std::vector< double > elemcoords( 3 * conn.size() ); error = mbImpl->get_coords( &( conn[0] ), conn.size(), &( elemcoords[0] ) );MB_CHK_ERR( error ); EntityType type = TYPE_FROM_HANDLE( currelem ); for( int s = 0; s < nsamples; ++s ) { if( type == MBTRI ) { double a = (double)rand() / RAND_MAX, b = (double)rand() / RAND_MAX, c = (double)rand() / RAND_MAX, sum; sum = a + b + c; if( sum < 1e-12 ) { --s; continue; } else { a /= sum, b /= sum, c /= sum; } testpnts.push_back( a * elemcoords[0] + b * elemcoords[3] + c * elemcoords[6] ); testpnts.push_back( a * elemcoords[1] + b * elemcoords[4] + c * elemcoords[7] ); testpnts.push_back( a * elemcoords[2] + b * elemcoords[5] + c * elemcoords[8] ); testnaturalcoords.push_back( a ); testnaturalcoords.push_back( b ); testnaturalcoords.push_back( c ); } else if( type == MBQUAD ) { double xi = (double)rand() / RAND_MAX, eta = (double)rand() / RAND_MAX, N[4]; xi = 2 * xi - 1; eta = 2 * eta - 1; N[0] = ( 1 - xi ) * ( 1 - eta ) / 4, N[1] = ( 1 + xi ) * ( 1 - eta ) / 4, N[2] = ( 1 + xi ) * ( 1 + eta ) / 4, N[3] = ( 1 - xi ) * ( 1 + eta ) / 4; testpnts.push_back( N[0] * elemcoords[0] + N[1] * elemcoords[3] + N[2] * elemcoords[6] + N[3] * elemcoords[9] ); testpnts.push_back( N[0] * elemcoords[1] + N[1] * elemcoords[4] + N[2] * elemcoords[7] + N[3] * elemcoords[10] ); testpnts.push_back( N[0] * elemcoords[2] + N[1] * elemcoords[5] + N[2] * elemcoords[8] + N[3] * elemcoords[11] ); testnaturalcoords.push_back( N[0] ); testnaturalcoords.push_back( N[1] ); testnaturalcoords.push_back( N[2] ); testnaturalcoords.push_back( N[3] ); } else { throw std::invalid_argument( "NOT SUPPORTED ELEMENT TYPE" ); } } } // Compute error of linear interpolation double l1err, l2err, linferr; obj->compute_projecterror( 3, elems.size() * nsamples, &( testpnts[0] ), l1err, l2err, linferr ); geoml1errs[0].push_back( l1err ); geoml2errs[0].push_back( l2err ); geomlinferrs[0].push_back( linferr ); // Perform high order projection and compute error HiReconstruction hirec( &moab, pc, mesh ); for( size_t ideg = 0; ideg < degs2fit.size(); ++ideg ) { // High order reconstruction error = hirec.reconstruct3D_surf_geom( degs2fit[ideg], interp, false, true );MB_CHK_ERR( error ); int index = 0; for( Range::iterator ielem = elems.begin(); ielem != elems.end(); ++ielem, ++index ) { // Projection error = hirec.hiproj_walf_in_element( *ielem, nvpe, nsamples, &( testnaturalcoords[nvpe * nsamples * index] ), &( testpnts[3 * nsamples * index] ) );MB_CHK_ERR( error ); } // Estimate error obj->compute_projecterror( 3, elems.size() * nsamples, &( testpnts[0] ), l1err, l2err, linferr ); geoml1errs[ideg + 1].push_back( l1err ); geoml2errs[ideg + 1].push_back( l2err ); geomlinferrs[ideg + 1].push_back( linferr ); } } std::cout << "Mesh Size: "; for( size_t i = 0; i < meshsizes.size(); ++i ) { std::cout << meshsizes[i] << " "; } std::cout << std::endl; std::cout << "Degrees: 0 "; for( size_t ideg = 0; ideg < degs2fit.size(); ++ideg ) { std::cout << degs2fit[ideg] << " "; } std::cout << std::endl; std::cout << "L1-norm error: \n"; for( size_t i = 0; i < geoml1errs.size(); ++i ) { for( size_t j = 0; j < geoml1errs[i].size(); ++j ) { std::cout << geoml1errs[i][j] << " "; } std::cout << std::endl; } std::cout << "L2-norm error: \n"; for( size_t i = 0; i < geoml2errs.size(); ++i ) { for( size_t j = 0; j < geoml2errs[i].size(); ++j ) { std::cout << geoml2errs[i][j] << " "; } std::cout << std::endl; } std::cout << "Linf-norm error: \n"; for( size_t i = 0; i < geomlinferrs.size(); ++i ) { for( size_t j = 0; j < geomlinferrs[i].size(); ++j ) { std::cout << geomlinferrs[i][j] << " "; } std::cout << std::endl; } return error; }
int main | ( | int | argc, |
char * | argv[] | ||
) |
Definition at line 367 of file uref_hirec_test.cpp.
References closedsurface_uref_hirec_convergence_study(), dim, moab::error(), ErrorCode, geom, MB_CHK_ERR, MPI_COMM_WORLD, rank, test_closedsurface_mesh(), and usage.
{ #ifdef MOAB_HAVE_MPI MPI_Init( &argc, &argv ); int nprocs, rank; MPI_Comm_size( MPI_COMM_WORLD, &nprocs ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); #endif std::string infile = TestDir + "unittest/sphere_tris_5.vtk"; int degree = 2, dim = 2, geom = 0; bool interp = false; ErrorCode error; if( argc == 10 ) { infile = std::string( argv[1] ); bool hasdim = false; for( int i = 2; i < argc; ++i ) { if( i + 1 != argc ) { if( std::string( argv[i] ) == "-degree" ) { degree = atoi( argv[++i] ); } else if( std::string( argv[i] ) == "-interp" ) { interp = atoi( argv[++i] ); } else if( std::string( argv[i] ) == "-dim" ) { dim = atoi( argv[++i] ); hasdim = true; } else if( std::string( argv[i] ) == "-geom" ) { geom = std::string( argv[++i] ) == "s" ? 0 : 1; } else { #ifdef MOAB_HAVE_MPI if( 0 == rank ) { usage(); } MPI_Finalize(); #else usage(); #endif return -1; } } } if( !hasdim ) { #ifdef MOAB_HAVE_MPI if( 0 == rank ) { std::cout << "Dimension of input mesh should be provided, positive and less than 3" << std::endl; } #else std::cout << "Dimension of input mesh should be provided, positive and less than 3" << std::endl; #endif return -1; } if( degree <= 0 || dim > 2 || dim <= 0 ) { #ifdef MOAB_HAVE_MPI if( 0 == rank ) { std::cout << "Input degree should be positive number;\n"; std::cout << "Input dimesion should be positive and less than 3;" << std::endl; } #else std::cout << "Input degree should be positive number;\n"; std::cout << "Input dimesion should be positive and less than 3;" << std::endl; #endif return -1; } #ifdef MOAB_HAVE_MPI if( 0 == rank ) { std::cout << "Testing on " << infile << " with dimension " << dim << "\n"; std::string opts = interp ? "interpolation" : "least square fitting"; std::cout << "High order reconstruction with degree " << degree << " " << opts << std::endl; } #else std::cout << "Testing on " << infile << " with dimension " << dim << "\n"; std::string opts = interp ? "interpolation" : "least square fitting"; std::cout << "High order reconstruction with degree " << degree << " " << opts << std::endl; #endif } else { if( argc > 1 ) { usage(); return -1; } } { int level_degrees[3] = { 2, 2, 2 }; int num_levels = 3; // create the geometry object geomObject* obj; if( geom ) obj = new torus(); else obj = new sphere(); error = test_closedsurface_mesh( infile.c_str(), level_degrees, num_levels, degree, interp, dim, obj );MB_CHK_ERR( error ); std::vector< int > degs2fit( 6 ); for( int d = 1; d <= 6; ++d ) { degs2fit[d - 1] = d; } // Call the higher order reconstruction routines and compute error convergence error = closedsurface_uref_hirec_convergence_study( infile.c_str(), level_degrees, num_levels, degs2fit, interp, obj );MB_CHK_ERR( error ); // cleanup memory delete obj; } #ifdef MOAB_HAVE_MPI MPI_Finalize(); #endif return 0; }
ErrorCode test_closedsurface_mesh | ( | const char * | filename, |
int * | level_degrees, | ||
int | num_levels, | ||
int | degree, | ||
bool | interp, | ||
int | dim, | ||
geomObject * | obj | ||
) |
Definition at line 42 of file uref_hirec_test.cpp.
References moab::Range::begin(), moab::NestedRefine::child_to_parent(), geomObject::compute_projecterror(), moab::Interface::create_meshset(), moab::Range::end(), moab::error(), ErrorCode, moab::NestedRefine::generate_mesh_hierarchy(), moab::NestedRefine::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), moab::ParallelComm::get_pcomm(), moab::DGMSolver::get_tri_natural_coords(), moab::HiReconstruction::hiproj_walf_in_element(), moab::Interface::load_file(), MB_CHK_ERR, MBTRI, MESHSET_SET, MPI_COMM_WORLD, read_options, moab::HiReconstruction::reconstruct3D_surf_geom(), moab::Range::size(), and moab::TYPE_FROM_HANDLE().
Referenced by main().
{ Core moab; Interface* mbImpl = &moab; ParallelComm* pc = NULL; EntityHandle fileset; ErrorCode error; error = mbImpl->create_meshset( moab::MESHSET_SET, fileset );MB_CHK_ERR( error ); // load mesh from file #ifdef MOAB_HAVE_MPI MPI_Comm comm = MPI_COMM_WORLD; EntityHandle partnset; error = mbImpl->create_meshset( moab::MESHSET_SET, partnset );MB_CHK_ERR( error ); pc = moab::ParallelComm::get_pcomm( mbImpl, partnset, &comm ); int procs = 1; MPI_Comm_size( comm, &procs ); if( procs > 1 ) { read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;"; error = mbImpl->load_file( filename, &fileset, read_options.c_str() );MB_CHK_ERR( error ); } else { error = mbImpl->load_file( filename, &fileset );MB_CHK_ERR( error ); } #else error = mbImpl->load_file( filename, &fileset );MB_CHK_ERR( error ); #endif // Generate hierarchy // error = refine_entities(&moab, pc, fileset, level_degrees, num_levels, true); // CHECK_ERR(error); NestedRefine uref( &moab, pc, fileset ); std::vector< EntityHandle > meshes; error = uref.generate_mesh_hierarchy( num_levels, level_degrees, meshes );MB_CHK_ERR( error ); // Perform high order reconstruction on level 0 mesh HiReconstruction hirec( &moab, pc, fileset ); assert( dim == 2 ); error = hirec.reconstruct3D_surf_geom( degree, interp, false );MB_CHK_ERR( error ); // High order projection Range verts, vorig; error = mbImpl->get_entities_by_dimension( meshes.back(), 0, verts );MB_CHK_ERR( error ); error = mbImpl->get_entities_by_dimension( meshes.front(), 0, vorig );MB_CHK_ERR( error ); int nvorig = vorig.size(); double l1err = 0, l2err = 0, linferr = 0; for( Range::iterator ivert = verts.begin() + nvorig; ivert != verts.end(); ++ivert ) { // locate the element in level 0 mesh, on which *ivert is lying EntityHandle currvert = *ivert; std::vector< EntityHandle > parentEntities; error = uref.get_adjacencies( *ivert, 2, parentEntities );MB_CHK_ERR( error ); assert( parentEntities.size() ); EntityHandle rootelem; error = uref.child_to_parent( parentEntities[0], num_levels, 0, &rootelem );MB_CHK_ERR( error ); // compute the natural coordinates of *ivert in this element assert( TYPE_FROM_HANDLE( rootelem ) == MBTRI ); const EntityHandle* conn; int nvpe = 3; error = mbImpl->get_connectivity( rootelem, conn, nvpe );MB_CHK_ERR( error ); std::vector< double > cornercoords( 3 * nvpe ), currcoords( 3 ); error = mbImpl->get_coords( conn, nvpe, &( cornercoords[0] ) );MB_CHK_ERR( error ); error = mbImpl->get_coords( &currvert, 1, &( currcoords[0] ) );MB_CHK_ERR( error ); std::vector< double > naturalcoords2fit( 3 ); DGMSolver::get_tri_natural_coords( 3, &( cornercoords[0] ), 1, &( currcoords[0] ), &( naturalcoords2fit[0] ) ); // project onto the estimated geometry double hicoords[3]; error = hirec.hiproj_walf_in_element( rootelem, nvpe, 1, &( naturalcoords2fit[0] ), hicoords );MB_CHK_ERR( error ); // estimate error double err = obj->compute_projecterror( 3, hicoords ); l1err += err; l2err += err * err; linferr = std::max( linferr, err ); } l1err /= verts.size() - nvorig; l2err = sqrt( l2err / ( verts.size() - nvorig ) ); std::cout << "L1 error " << l1err << " L2 error " << l2err << " Linf error " << linferr << std::endl; return error; }
void usage | ( | ) |
Definition at line 357 of file uref_hirec_test.cpp.
{ std::cout << "usage: ./uref_hirec_test <mesh file> -degree <degree> -interp <0=least square, " "1=interpolation> -dim <mesh dimension> -geom <s=sphere,t=torus>" << std::endl; std::cout << "Example: ./uref_hirec_test $MOAB_SOURCE_DIR/MeshFiles/unittest/sphere_tris_5.vtk " "-degree 2 -interp 0 -dim 2 -geom s" << std::endl; }