MOAB: Mesh Oriented datABase  (version 5.5.0)
uref_hirec_test.cpp File Reference
#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>
+ Include dependency graph for uref_hirec_test.cpp:

Go to the source code of this file.

Macros

#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 > &degs2fit, bool interp, geomObject *obj)
 
void usage ()
 
int main (int argc, char *argv[])
 

Macro Definition Documentation

◆ nsamples

#define nsamples   10

Definition at line 36 of file uref_hirec_test.cpp.

Function Documentation

◆ 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.

147 {
148  Core moab;
149  Interface* mbImpl = &moab;
150  ParallelComm* pc = NULL;
151  EntityHandle fileset;
153  error = mbImpl->create_meshset( moab::MESHSET_SET, fileset );MB_CHK_ERR( error );
154  // load mesh from file
155 #ifdef MOAB_HAVE_MPI
156  MPI_Comm comm = MPI_COMM_WORLD;
157  EntityHandle partnset;
158  error = mbImpl->create_meshset( moab::MESHSET_SET, partnset );MB_CHK_ERR( error );
159  pc = moab::ParallelComm::get_pcomm( mbImpl, partnset, &comm );
160  int procs = 1;
161  MPI_Comm_size( comm, &procs );
162 
163  if( procs > 1 )
164  {
165  read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;";
166  error = mbImpl->load_file( filename, &fileset, read_options.c_str() );MB_CHK_ERR( error );
167  }
168  else
169  {
170  error = mbImpl->load_file( filename, &fileset );MB_CHK_ERR( error );
171  }
172 
173 #else
174  error = mbImpl->load_file( filename, &fileset );MB_CHK_ERR( error );
175 #endif
176  // Generate hierarchy
177  NestedRefine uref( &moab, pc, fileset );
178  std::vector< EntityHandle > meshes;
179  std::vector< int > meshsizes;
180  error = uref.generate_mesh_hierarchy( num_levels, level_degrees, meshes );MB_CHK_ERR( error );
181  std::vector< std::vector< double > > geoml1errs( 1 + degs2fit.size() ), geoml2errs( 1 + degs2fit.size() ),
182  geomlinferrs( 1 + degs2fit.size() );
183 
184  // Perform high order reconstruction on each level of mesh (projected onto exact geometry) and
185  // estimate geometric error with various degrees of fitting
186  for( size_t i = 0; i < meshes.size(); ++i )
187  {
188  EntityHandle& mesh = meshes[i];
189  // project onto exact geometry since each level with uref has only linear coordinates
190  Range verts;
191  error = mbImpl->get_entities_by_dimension( mesh, 0, verts );MB_CHK_ERR( error );
192 
193  for( Range::iterator ivert = verts.begin(); ivert != verts.end(); ++ivert )
194  {
195  EntityHandle currvert = *ivert;
196  double currcoords[3], exactcoords[3];
197  error = mbImpl->get_coords( &currvert, 1, currcoords );
198  obj->project_points2geom( 3, currcoords, exactcoords, NULL );
199  error = mbImpl->set_coords( &currvert, 1, exactcoords );
200  }
201 
202  // generate random points on each elements, assument 3D coordinates
203  Range elems;
204  error = mbImpl->get_entities_by_dimension( mesh, 2, elems );MB_CHK_ERR( error );
205  meshsizes.push_back( elems.size() );
206  int nvpe = TYPE_FROM_HANDLE( *elems.begin() ) == MBTRI ? 3 : 4;
207  std::vector< double > testpnts, testnaturalcoords;
208  testpnts.reserve( 3 * elems.size() * nsamples );
209  testnaturalcoords.reserve( nvpe * elems.size() * nsamples );
210 
211  for( Range::iterator ielem = elems.begin(); ielem != elems.end(); ++ielem )
212  {
213  EntityHandle currelem = *ielem;
214  std::vector< EntityHandle > conn;
215  error = mbImpl->get_connectivity( &currelem, 1, conn );MB_CHK_ERR( error );
216  nvpe = conn.size();
217  std::vector< double > elemcoords( 3 * conn.size() );
218  error = mbImpl->get_coords( &( conn[0] ), conn.size(), &( elemcoords[0] ) );MB_CHK_ERR( error );
219  EntityType type = TYPE_FROM_HANDLE( currelem );
220 
221  for( int s = 0; s < nsamples; ++s )
222  {
223  if( type == MBTRI )
224  {
225  double a = (double)rand() / RAND_MAX, b = (double)rand() / RAND_MAX, c = (double)rand() / RAND_MAX,
226  sum;
227  sum = a + b + c;
228 
229  if( sum < 1e-12 )
230  {
231  --s;
232  continue;
233  }
234  else
235  {
236  a /= sum, b /= sum, c /= sum;
237  }
238 
239  testpnts.push_back( a * elemcoords[0] + b * elemcoords[3] + c * elemcoords[6] );
240  testpnts.push_back( a * elemcoords[1] + b * elemcoords[4] + c * elemcoords[7] );
241  testpnts.push_back( a * elemcoords[2] + b * elemcoords[5] + c * elemcoords[8] );
242  testnaturalcoords.push_back( a );
243  testnaturalcoords.push_back( b );
244  testnaturalcoords.push_back( c );
245  }
246  else if( type == MBQUAD )
247  {
248  double xi = (double)rand() / RAND_MAX, eta = (double)rand() / RAND_MAX, N[4];
249  xi = 2 * xi - 1;
250  eta = 2 * eta - 1;
251  N[0] = ( 1 - xi ) * ( 1 - eta ) / 4, N[1] = ( 1 + xi ) * ( 1 - eta ) / 4,
252  N[2] = ( 1 + xi ) * ( 1 + eta ) / 4, N[3] = ( 1 - xi ) * ( 1 + eta ) / 4;
253  testpnts.push_back( N[0] * elemcoords[0] + N[1] * elemcoords[3] + N[2] * elemcoords[6] +
254  N[3] * elemcoords[9] );
255  testpnts.push_back( N[0] * elemcoords[1] + N[1] * elemcoords[4] + N[2] * elemcoords[7] +
256  N[3] * elemcoords[10] );
257  testpnts.push_back( N[0] * elemcoords[2] + N[1] * elemcoords[5] + N[2] * elemcoords[8] +
258  N[3] * elemcoords[11] );
259  testnaturalcoords.push_back( N[0] );
260  testnaturalcoords.push_back( N[1] );
261  testnaturalcoords.push_back( N[2] );
262  testnaturalcoords.push_back( N[3] );
263  }
264  else
265  {
266  throw std::invalid_argument( "NOT SUPPORTED ELEMENT TYPE" );
267  }
268  }
269  }
270 
271  // Compute error of linear interpolation
272  double l1err, l2err, linferr;
273  obj->compute_projecterror( 3, elems.size() * nsamples, &( testpnts[0] ), l1err, l2err, linferr );
274  geoml1errs[0].push_back( l1err );
275  geoml2errs[0].push_back( l2err );
276  geomlinferrs[0].push_back( linferr );
277  // Perform high order projection and compute error
278  HiReconstruction hirec( &moab, pc, mesh );
279 
280  for( size_t ideg = 0; ideg < degs2fit.size(); ++ideg )
281  {
282  // High order reconstruction
283  error = hirec.reconstruct3D_surf_geom( degs2fit[ideg], interp, false, true );MB_CHK_ERR( error );
284  int index = 0;
285 
286  for( Range::iterator ielem = elems.begin(); ielem != elems.end(); ++ielem, ++index )
287  {
288  // Projection
289  error = hirec.hiproj_walf_in_element( *ielem, nvpe, nsamples,
290  &( testnaturalcoords[nvpe * nsamples * index] ),
291  &( testpnts[3 * nsamples * index] ) );MB_CHK_ERR( error );
292  }
293 
294  // Estimate error
295  obj->compute_projecterror( 3, elems.size() * nsamples, &( testpnts[0] ), l1err, l2err, linferr );
296  geoml1errs[ideg + 1].push_back( l1err );
297  geoml2errs[ideg + 1].push_back( l2err );
298  geomlinferrs[ideg + 1].push_back( linferr );
299  }
300  }
301 
302  std::cout << "Mesh Size: ";
303 
304  for( size_t i = 0; i < meshsizes.size(); ++i )
305  {
306  std::cout << meshsizes[i] << " ";
307  }
308 
309  std::cout << std::endl;
310  std::cout << "Degrees: 0 ";
311 
312  for( size_t ideg = 0; ideg < degs2fit.size(); ++ideg )
313  {
314  std::cout << degs2fit[ideg] << " ";
315  }
316 
317  std::cout << std::endl;
318  std::cout << "L1-norm error: \n";
319 
320  for( size_t i = 0; i < geoml1errs.size(); ++i )
321  {
322  for( size_t j = 0; j < geoml1errs[i].size(); ++j )
323  {
324  std::cout << geoml1errs[i][j] << " ";
325  }
326 
327  std::cout << std::endl;
328  }
329 
330  std::cout << "L2-norm error: \n";
331 
332  for( size_t i = 0; i < geoml2errs.size(); ++i )
333  {
334  for( size_t j = 0; j < geoml2errs[i].size(); ++j )
335  {
336  std::cout << geoml2errs[i][j] << " ";
337  }
338 
339  std::cout << std::endl;
340  }
341 
342  std::cout << "Linf-norm error: \n";
343 
344  for( size_t i = 0; i < geomlinferrs.size(); ++i )
345  {
346  for( size_t j = 0; j < geomlinferrs[i].size(); ++j )
347  {
348  std::cout << geomlinferrs[i][j] << " ";
349  }
350 
351  std::cout << std::endl;
352  }
353 
354  return error;
355 }

References moab::Range::begin(), geomObject::compute_projecterror(), moab::Interface::create_meshset(), moab::Range::end(), moab::error(), ErrorCode, filename, 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().

Referenced by main().

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 367 of file uref_hirec_test.cpp.

368 {
369 #ifdef MOAB_HAVE_MPI
370  MPI_Init( &argc, &argv );
371  int nprocs, rank;
372  MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
373  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
374 #endif
375 
376  std::string infile = TestDir + "unittest/sphere_tris_5.vtk";
377 
378  int degree = 2, dim = 2, geom = 0;
379  bool interp = false;
381 
382  if( argc == 10 )
383  {
384  infile = std::string( argv[1] );
385  bool hasdim = false;
386 
387  for( int i = 2; i < argc; ++i )
388  {
389  if( i + 1 != argc )
390  {
391  if( std::string( argv[i] ) == "-degree" )
392  {
393  degree = atoi( argv[++i] );
394  }
395  else if( std::string( argv[i] ) == "-interp" )
396  {
397  interp = atoi( argv[++i] );
398  }
399  else if( std::string( argv[i] ) == "-dim" )
400  {
401  dim = atoi( argv[++i] );
402  hasdim = true;
403  }
404  else if( std::string( argv[i] ) == "-geom" )
405  {
406  geom = std::string( argv[++i] ) == "s" ? 0 : 1;
407  }
408  else
409  {
410 #ifdef MOAB_HAVE_MPI
411 
412  if( 0 == rank )
413  {
414  usage();
415  }
416  MPI_Finalize();
417 
418 #else
419  usage();
420 #endif
421  return -1;
422  }
423  }
424  }
425 
426  if( !hasdim )
427  {
428 #ifdef MOAB_HAVE_MPI
429 
430  if( 0 == rank )
431  {
432  std::cout << "Dimension of input mesh should be provided, positive and less than 3" << std::endl;
433  }
434 
435 #else
436  std::cout << "Dimension of input mesh should be provided, positive and less than 3" << std::endl;
437 #endif
438  return -1;
439  }
440 
441  if( degree <= 0 || dim > 2 || dim <= 0 )
442  {
443 #ifdef MOAB_HAVE_MPI
444 
445  if( 0 == rank )
446  {
447  std::cout << "Input degree should be positive number;\n";
448  std::cout << "Input dimesion should be positive and less than 3;" << std::endl;
449  }
450 
451 #else
452  std::cout << "Input degree should be positive number;\n";
453  std::cout << "Input dimesion should be positive and less than 3;" << std::endl;
454 #endif
455  return -1;
456  }
457 
458 #ifdef MOAB_HAVE_MPI
459 
460  if( 0 == rank )
461  {
462  std::cout << "Testing on " << infile << " with dimension " << dim << "\n";
463  std::string opts = interp ? "interpolation" : "least square fitting";
464  std::cout << "High order reconstruction with degree " << degree << " " << opts << std::endl;
465  }
466 
467 #else
468  std::cout << "Testing on " << infile << " with dimension " << dim << "\n";
469  std::string opts = interp ? "interpolation" : "least square fitting";
470  std::cout << "High order reconstruction with degree " << degree << " " << opts << std::endl;
471 #endif
472  }
473  else
474  {
475  if( argc > 1 )
476  {
477  usage();
478  return -1;
479  }
480  }
481 
482  {
483  int level_degrees[3] = { 2, 2, 2 };
484  int num_levels = 3;
485 
486  // create the geometry object
487  geomObject* obj;
488  if( geom )
489  obj = new torus();
490  else
491  obj = new sphere();
492 
493  error = test_closedsurface_mesh( infile.c_str(), level_degrees, num_levels, degree, interp, dim, obj );MB_CHK_ERR( error );
494 
495  std::vector< int > degs2fit( 6 );
496  for( int d = 1; d <= 6; ++d )
497  {
498  degs2fit[d - 1] = d;
499  }
500 
501  // Call the higher order reconstruction routines and compute error convergence
502  error = closedsurface_uref_hirec_convergence_study( infile.c_str(), level_degrees, num_levels, degs2fit, interp,
503  obj );MB_CHK_ERR( error );
504  // cleanup memory
505  delete obj;
506  }
507 
508 #ifdef MOAB_HAVE_MPI
509  MPI_Finalize();
510 #endif
511  return 0;
512 }

References closedsurface_uref_hirec_convergence_study(), dim, moab::error(), ErrorCode, geom, MB_CHK_ERR, MPI_COMM_WORLD, rank, test_closedsurface_mesh(), and usage().

◆ test_closedsurface_mesh()

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.

49 {
50  Core moab;
51  Interface* mbImpl = &moab;
52  ParallelComm* pc = NULL;
53  EntityHandle fileset;
55  error = mbImpl->create_meshset( moab::MESHSET_SET, fileset );MB_CHK_ERR( error );
56  // load mesh from file
57 #ifdef MOAB_HAVE_MPI
58  MPI_Comm comm = MPI_COMM_WORLD;
59  EntityHandle partnset;
60  error = mbImpl->create_meshset( moab::MESHSET_SET, partnset );MB_CHK_ERR( error );
61  pc = moab::ParallelComm::get_pcomm( mbImpl, partnset, &comm );
62  int procs = 1;
63  MPI_Comm_size( comm, &procs );
64 
65  if( procs > 1 )
66  {
67  read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;";
68  error = mbImpl->load_file( filename, &fileset, read_options.c_str() );MB_CHK_ERR( error );
69  }
70  else
71  {
72  error = mbImpl->load_file( filename, &fileset );MB_CHK_ERR( error );
73  }
74 
75 #else
76  error = mbImpl->load_file( filename, &fileset );MB_CHK_ERR( error );
77 #endif
78 
79  // Generate hierarchy
80  // error = refine_entities(&moab, pc, fileset, level_degrees, num_levels, true);
81  // CHECK_ERR(error);
82  NestedRefine uref( &moab, pc, fileset );
83  std::vector< EntityHandle > meshes;
84  error = uref.generate_mesh_hierarchy( num_levels, level_degrees, meshes );MB_CHK_ERR( error );
85 
86  // Perform high order reconstruction on level 0 mesh
87  HiReconstruction hirec( &moab, pc, fileset );
88  assert( dim == 2 );
89  error = hirec.reconstruct3D_surf_geom( degree, interp, false );MB_CHK_ERR( error );
90 
91  // High order projection
92  Range verts, vorig;
93  error = mbImpl->get_entities_by_dimension( meshes.back(), 0, verts );MB_CHK_ERR( error );
94  error = mbImpl->get_entities_by_dimension( meshes.front(), 0, vorig );MB_CHK_ERR( error );
95  int nvorig = vorig.size();
96  double l1err = 0, l2err = 0, linferr = 0;
97 
98  for( Range::iterator ivert = verts.begin() + nvorig; ivert != verts.end(); ++ivert )
99  {
100  // locate the element in level 0 mesh, on which *ivert is lying
101  EntityHandle currvert = *ivert;
102 
103  std::vector< EntityHandle > parentEntities;
104  error = uref.get_adjacencies( *ivert, 2, parentEntities );MB_CHK_ERR( error );
105  assert( parentEntities.size() );
106 
107  EntityHandle rootelem;
108  error = uref.child_to_parent( parentEntities[0], num_levels, 0, &rootelem );MB_CHK_ERR( error );
109 
110  // compute the natural coordinates of *ivert in this element
111  assert( TYPE_FROM_HANDLE( rootelem ) == MBTRI );
112 
113  const EntityHandle* conn;
114  int nvpe = 3;
115  error = mbImpl->get_connectivity( rootelem, conn, nvpe );MB_CHK_ERR( error );
116 
117  std::vector< double > cornercoords( 3 * nvpe ), currcoords( 3 );
118  error = mbImpl->get_coords( conn, nvpe, &( cornercoords[0] ) );MB_CHK_ERR( error );
119  error = mbImpl->get_coords( &currvert, 1, &( currcoords[0] ) );MB_CHK_ERR( error );
120 
121  std::vector< double > naturalcoords2fit( 3 );
122  DGMSolver::get_tri_natural_coords( 3, &( cornercoords[0] ), 1, &( currcoords[0] ), &( naturalcoords2fit[0] ) );
123 
124  // project onto the estimated geometry
125  double hicoords[3];
126  error = hirec.hiproj_walf_in_element( rootelem, nvpe, 1, &( naturalcoords2fit[0] ), hicoords );MB_CHK_ERR( error );
127 
128  // estimate error
129  double err = obj->compute_projecterror( 3, hicoords );
130  l1err += err;
131  l2err += err * err;
132  linferr = std::max( linferr, err );
133  }
134 
135  l1err /= verts.size() - nvorig;
136  l2err = sqrt( l2err / ( verts.size() - nvorig ) );
137  std::cout << "L1 error " << l1err << " L2 error " << l2err << " Linf error " << linferr << std::endl;
138  return error;
139 }

References moab::Range::begin(), moab::NestedRefine::child_to_parent(), geomObject::compute_projecterror(), moab::Interface::create_meshset(), dim, moab::Range::end(), moab::error(), ErrorCode, filename, 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().

◆ usage()

void usage ( )

Definition at line 357 of file uref_hirec_test.cpp.

358 {
359  std::cout << "usage: ./uref_hirec_test <mesh file> -degree <degree> -interp <0=least square, "
360  "1=interpolation> -dim <mesh dimension> -geom <s=sphere,t=torus>"
361  << std::endl;
362  std::cout << "Example: ./uref_hirec_test $MOAB_SOURCE_DIR/MeshFiles/unittest/sphere_tris_5.vtk "
363  "-degree 2 -interp 0 -dim 2 -geom s"
364  << std::endl;
365 }

Referenced by main().