MOAB: Mesh Oriented datABase  (version 5.5.0)
hireconst_test_parallel.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/CartVect.hpp"
#include "moab/MeshTopoUtil.hpp"
#include "moab/NestedRefine.hpp"
#include "moab/DiscreteGeometry/HiReconstruction.hpp"
#include "TestUtil.hpp"
#include <cmath>
+ Include dependency graph for hireconst_test_parallel.cpp:

Go to the source code of this file.

Functions

ErrorCode load_meshset_hirec (const char *infile, Interface *mbimpl, EntityHandle &meshset, ParallelComm *&pc, const int degree=0, const int dim=2)
 
ErrorCode test_mesh (const char *infile, const int degree, const bool interp, const int dim)
 
void compute_linear_coords (const int nvpe, double *elemcoords, double *naturals, double *linearcoords)
 
void usage ()
 
int main (int argc, char *argv[])
 

Function Documentation

◆ compute_linear_coords()

void compute_linear_coords ( const int  nvpe,
double *  elemcoords,
double *  naturals,
double *  linearcoords 
)

Definition at line 338 of file hireconst_test_parallel.cpp.

339 {
340  assert( elemcoords && linearcoords );
341 
342  for( int i = 0; i < 3; ++i )
343  {
344  linearcoords[i] = 0;
345 
346  for( int j = 0; j < nvpe; ++j )
347  {
348  linearcoords[i] += naturals[j] * elemcoords[3 * j + i];
349  }
350  }
351 }

Referenced by test_mesh().

◆ load_meshset_hirec()

ErrorCode load_meshset_hirec ( const char *  infile,
Interface mbimpl,
EntityHandle meshset,
ParallelComm *&  pc,
const int  degree = 0,
const int  dim = 2 
)

Definition at line 177 of file hireconst_test_parallel.cpp.

183 {
185  error = mbimpl->create_meshset( moab::MESHSET_SET, meshset );MB_CHK_ERR( error );
186 #ifdef MOAB_HAVE_MPI
187  int nprocs, rank;
188  MPI_Comm comm = MPI_COMM_WORLD;
189  MPI_Comm_size( comm, &nprocs );
190  MPI_Comm_rank( comm, &rank );
191  EntityHandle partnset;
192  error = mbimpl->create_meshset( moab::MESHSET_SET, partnset );MB_CHK_ERR( error );
193 
194  if( nprocs > 1 )
195  {
196  pc = moab::ParallelComm::get_pcomm( mbimpl, partnset, &comm );
197  }
198 
199  if( nprocs > 1 )
200  {
201  int nghlayers = degree > 0 ? HiReconstruction::estimate_num_ghost_layers( degree, true ) : 0;
202  std::string part_method = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;";
203 #ifndef MOAB_HAVE_HDF5
204  part_method = "PARALLEL=BCAST_DELETE;PARTITION=TRIVIAL;";
205 #endif
206 
207  if( nghlayers )
208  {
209  // get ghost layers
210  if( dim == 2 )
211  {
212  read_options = part_method + ";PARALLEL_RESOLVE_SHARED_ENTS;PARALLEL_GHOSTS=2.0.";
213  }
214  else if( dim == 1 )
215  {
216  read_options = part_method + ";PARALLEL_RESOLVE_SHARED_ENTS;PARALLEL_GHOSTS=1.0.";
217  }
218  else
219  {
220  MB_SET_ERR( MB_FAILURE, "unsupported dimension" );
221  }
222 
223  read_options += (char)( '0' + nghlayers );
224  }
225  else
226  {
227  read_options = part_method + ";PARALLEL_RESOLVE_SHARED_ENTS;";
228  }
229 
230  error = mbimpl->load_file( infile, &meshset, read_options.c_str() );MB_CHK_ERR( error );
231  }
232  else
233  {
234  error = mbimpl->load_file( infile, &meshset );MB_CHK_ERR( error );
235  }
236 
237 #else
238  assert( !pc && degree && dim );
239  error = mbimpl->load_file( infile, &meshset );MB_CHK_ERR( error );
240 #endif
241  return error;
242 }

References moab::Interface::create_meshset(), dim, moab::error(), ErrorCode, moab::HiReconstruction::estimate_num_ghost_layers(), moab::ParallelComm::get_pcomm(), moab::Interface::load_file(), MB_CHK_ERR, MB_SET_ERR, MESHSET_SET, MPI_COMM_WORLD, rank, and read_options.

Referenced by test_mesh().

◆ main()

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

Definition at line 58 of file hireconst_test_parallel.cpp.

59 {
60 #ifdef MOAB_HAVE_MPI
61  MPI_Init( &argc, &argv );
62  int nprocs, rank;
63  MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
64  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
65 #endif
66  int degree = 3, dim = 2;
67  bool interp = false;
69 
70 #ifdef MOAB_HAVE_HDF5
71  std::string infile = TestDir + "unittest/mbcslam/fine4.h5m";
72 #else
73  std::string infile = TestDir + "unittest/sphere_quads_20.vtk";
74 #endif
75 
76  if( argc == 1 )
77  {
78  usage();
79  std::cout << "Using default arguments: ./hireconst_test_parallel " << infile << " -degree 3 -interp 0 -dim 2"
80  << std::endl;
81  }
82  else
83  {
84  infile = argv[1];
85  bool hasdim = false;
86 
87  for( int i = 2; i < argc; ++i )
88  {
89  if( i + 1 != argc )
90  {
91  if( std::string( argv[i] ) == "-degree" )
92  {
93  degree = atoi( argv[++i] );
94  }
95  else if( std::string( argv[i] ) == "-interp" )
96  {
97  interp = atoi( argv[++i] );
98  }
99  else if( std::string( argv[i] ) == "-dim" )
100  {
101  dim = atoi( argv[++i] );
102  hasdim = true;
103  }
104  else
105  {
106 #ifdef MOAB_HAVE_MPI
107 
108  if( 0 == rank )
109  {
110  usage();
111  }
112 
113  MPI_Finalize();
114 #else
115  usage();
116 #endif
117  return 0;
118  }
119  }
120  }
121 
122  if( !hasdim )
123  {
124 #ifdef MOAB_HAVE_MPI
125 
126  if( 0 == rank )
127  {
128  std::cout << "Dimension of input mesh should be provided, positive and less than 3" << std::endl;
129  }
130 
131 #else
132  std::cout << "Dimension of input mesh should be provided, positive and less than 3" << std::endl;
133 #endif
134  return 0;
135  }
136 
137  if( degree <= 0 || dim > 2 || dim <= 0 )
138  {
139 #ifdef MOAB_HAVE_MPI
140 
141  if( 0 == rank )
142  {
143  std::cout << "Input degree should be positive number;\n";
144  std::cout << "Input dimesion should be positive and less than 3;" << std::endl;
145  }
146 
147 #else
148  std::cout << "Input degree should be positive number;\n";
149  std::cout << "Input dimesion should be positive and less than 3;" << std::endl;
150 #endif
151  return 0;
152  }
153 
154 #ifdef MOAB_HAVE_MPI
155 
156  if( 0 == rank )
157  {
158  std::cout << "Testing on " << infile << " with dimension " << dim << "\n";
159  std::string opts = interp ? "interpolation" : "least square fitting";
160  std::cout << "High order reconstruction with degree " << degree << " " << opts << std::endl;
161  }
162 
163 #else
164  std::cout << "Testing on " << infile << " with dimension " << dim << "\n";
165  std::string opts = interp ? "interpolation" : "least square fitting";
166  std::cout << "High order reconstruction with degree " << degree << " " << opts << std::endl;
167 #endif
168  }
169 
170  error = test_mesh( infile.c_str(), degree, interp, dim );MB_CHK_ERR( error );
171 
172 #ifdef MOAB_HAVE_MPI
173  MPI_Finalize();
174 #endif
175 }

References dim, moab::error(), ErrorCode, MB_CHK_ERR, MPI_COMM_WORLD, rank, test_mesh(), and usage().

◆ test_mesh()

ErrorCode test_mesh ( const char *  infile,
const int  degree,
const bool  interp,
const int  dim 
)

Definition at line 244 of file hireconst_test_parallel.cpp.

245 {
246  Core moab;
247  Interface* mbimpl = &moab;
248  ParallelComm* pc = NULL;
249  EntityHandle meshset;
250 #ifdef MOAB_HAVE_MPI
251  int nprocs, rank;
252  MPI_Comm comm = MPI_COMM_WORLD;
253  MPI_Comm_size( comm, &nprocs );
254  MPI_Comm_rank( comm, &rank );
255 #endif
256 
258  // mesh will be loaded and communicator pc will be updated
259  error = load_meshset_hirec( infile, mbimpl, meshset, pc, degree, dim );MB_CHK_ERR( error );
260  // initialize
261  HiReconstruction hirec( dynamic_cast< Core* >( mbimpl ), pc, meshset );
262  Range elems, elems_owned;
263  error = mbimpl->get_entities_by_dimension( meshset, dim, elems );MB_CHK_ERR( error );
264  int nelems = elems.size();
265 
266 #ifdef MOAB_HAVE_MPI
267 
268  if( pc )
269  {
270  error = pc->filter_pstatus( elems, PSTATUS_GHOST, PSTATUS_NOT, -1, &elems_owned );MB_CHK_ERR( error );
271  }
272  else
273  {
274  elems_owned = elems;
275  }
276 
277 #endif
278 
279 #ifdef MOAB_HAVE_MPI
280  std::cout << "Mesh has " << nelems << " elements on Processor " << rank << " in total;";
281  std::cout << elems_owned.size() << " of which are locally owned elements" << std::endl;
282 #else
283  std::cout << "Mesh has " << nelems << " elements" << std::endl;
284 #endif
285 
286  // reconstruction
287  if( dim == 2 )
288  {
289  error = hirec.reconstruct3D_surf_geom( degree, interp, false );MB_CHK_ERR( error );
290  }
291  else if( dim == 1 )
292  {
293  error = hirec.reconstruct3D_curve_geom( degree, interp, false );MB_CHK_ERR( error );
294  }
295 
296 #ifdef MOAB_HAVE_MPI
297  std::cout << "HiRec has been done on Processor " << rank << std::endl;
298 #else
299  std::cout << "HiRec has been done " << std::endl;
300 #endif
301  // fitting
302  double mxdist = 0;
303 
304  for( Range::iterator ielem = elems_owned.begin(); ielem != elems_owned.end(); ++ielem )
305  {
306  int nvpe;
307  const EntityHandle* conn;
308  error = mbimpl->get_connectivity( *ielem, conn, nvpe );MB_CHK_ERR( error );
309  double w = 1.0 / (double)nvpe;
310  std::vector< double > naturalcoords2fit( nvpe, w );
311  CartVect newcoords, linearcoords;
312  error = hirec.hiproj_walf_in_element( *ielem, nvpe, 1, &( naturalcoords2fit[0] ), newcoords.array() );
313 
314  if( MB_FAILURE == error )
315  {
316  continue;
317  }
318 
319  std::vector< double > coords( 3 * nvpe );
320  error = mbimpl->get_coords( conn, nvpe, &( coords[0] ) );MB_CHK_ERR( error );
321  compute_linear_coords( nvpe, &( coords[0] ), &( naturalcoords2fit[0] ), linearcoords.array() );
322  CartVect nlcoords = newcoords - linearcoords;
323  mxdist = std::max( mxdist, nlcoords.length() );
324  /*#ifdef MOAB_HAVE_MPI
325  std::cout << "Error on element " << *ielem << " is " << nlcoords.length() << "on
326  Processor " << rank << std::endl; #else std::cout << "Error on element " << *ielem << " is "
327  << nlcoords.length() << std::endl; #endif*/
328  }
329 
330 #ifdef MOAB_HAVE_MPI
331  std::cout << "Maximum projection lift is " << mxdist << " on Processor " << rank << std::endl;
332 #else
333  std::cout << "Maximum projection lift is " << mxdist << std::endl;
334 #endif
335  return error;
336 }

References moab::CartVect::array(), moab::Range::begin(), compute_linear_coords(), dim, moab::Range::end(), moab::error(), ErrorCode, moab::ParallelComm::filter_pstatus(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), moab::HiReconstruction::hiproj_walf_in_element(), moab::CartVect::length(), load_meshset_hirec(), MB_CHK_ERR, MPI_COMM_WORLD, PSTATUS_GHOST, PSTATUS_NOT, rank, moab::HiReconstruction::reconstruct3D_curve_geom(), moab::HiReconstruction::reconstruct3D_surf_geom(), and moab::Range::size().

Referenced by main().

◆ usage()

void usage ( )

Definition at line 51 of file hireconst_test_parallel.cpp.

52 {
53  std::cout << "usage: mpirun -np <number of processors> ./hireconst_test_parallel <mesh file> "
54  "-degree <degree> -interp <0=least square, 1=interpolation> -dim <mesh dimension>"
55  << std::endl;
56 }

Referenced by main().