Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
main.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <fstream>
3 #include <cmath>
4 #include <ctime>
5 #include <cstdlib>
6 #include <cassert>
7 
8 #include "mcnpmit.hpp"
9 
10 #include "moab/CartVect.hpp"
11 #include "moab/Core.hpp"
12 #include "MBTagConventions.hpp"
13 #include "moab/AdaptiveKDTree.hpp"
14 #include "moab/GeomUtil.hpp"
15 #include "moab/FileOptions.hpp"
16 #include "../tools/mbcoupler/ElemUtil.hpp"
17 
18 #define MBI mb_instance()
19 
22 MCNPError read_files( int, char** );
23 MCNPError next_double( std::string, double&, int& );
24 MCNPError next_int( std::string, int&, int& );
25 
27 
28 std::string h5m_filename;
29 std::string CAD_filename;
30 std::string output_filename;
31 
32 bool skip_build = false;
33 bool read_qnv = false;
34 
36 
37 int main( int argc, char** argv )
38 {
39  MCNPError result;
40 
41  start_time = clock();
42 
43  // Read in file names from command line
44  result = read_files( argc, argv );
45  if( result == MCNP_FAILURE ) return 1;
46 
47  result = MCNP->initialize_tags();
48 
49  // Parse the MCNP input file
50  if( !skip_build )
51  {
52 
53  result = MCNP->read_mcnpfile( skip_build );
54  if( result == MCNP_FAILURE )
55  {
56  std::cout << "Failure reading MCNP file!" << std::endl;
57  return 1;
58  }
59  }
60 
61  load_time = clock() - start_time;
62 
63  // Make the KD-Tree
64  moab::ErrorCode MBresult;
65  moab::AdaptiveKDTree kdtree( MBI );
66  moab::EntityHandle root;
67 
68  MBI->tag_get_handle( "CoordTag", 1, moab::MB_TYPE_INTEGER, coord_tag, moab::MB_TAG_DENSE | moab::MB_TAG_CREAT );
69  MBI->tag_get_handle( "RotationTag", 16, moab::MB_TYPE_DOUBLE, rotation_tag,
71 
72  if( skip_build )
73  {
74  MBresult = MBI->load_mesh( h5m_filename.c_str() );
75 
76  if( moab::MB_SUCCESS == MBresult )
77  {
78  std::cout << std::endl << "Read in mesh from h5m file." << std::endl << std::endl;
79  std::cout << "Querying mesh file..." << std::endl;
80  }
81  else
82  {
83  std::cout << "Failure reading h5m file!" << std::endl;
84  std::cerr << "Error code: " << MBI->get_error_string( MBresult ) << " (" << MBresult << ")" << std::endl;
85  std::string message;
86  if( moab::MB_SUCCESS == MBI->get_last_error( message ) && !message.empty() )
87  std::cerr << "Error message: " << message << std::endl;
88  return 1;
89  }
90 
91  moab::Range tmprange;
92  kdtree.find_all_trees( tmprange );
93  root = tmprange[0];
94  }
95  else
96  {
97  std::cout << "Building KD-Tree..." << std::endl;
98  moab::FileOptions opts( "CANDIDATE_PLANE_SET=SUBDIVISION" );
99  MBresult = kdtree.build_tree( MCNP->elem_handles, &root, &opts );
100  if( MBresult == moab::MB_SUCCESS )
101  {
102 
103  MBI->tag_set_data( coord_tag, &root, 1, &( MCNP->coord_system ) );
104  MBI->tag_set_data( rotation_tag, &root, 1, &( MCNP->rotation_matrix ) );
105 
106  std::cout << "KD-Tree has been built successfully!" << std::endl << std::endl;
107  MBresult = MBI->write_mesh( ( MCNP->MCNP_filename + ".h5m" ).c_str() );
108 
109  std::cout << "Querying mesh file..." << std::endl;
110  }
111  else
112  {
113  std::cout << "Error building KD-Tree!" << std::endl << std::endl;
114  std::cerr << "Error code: " << MBI->get_error_string( MBresult ) << " (" << MBresult << ")" << std::endl;
115  std::string message;
116  if( moab::MB_SUCCESS == MBI->get_last_error( message ) && !message.empty() )
117  std::cerr << "Error message: " << message << std::endl;
118  return 1;
119  }
120  }
121 
122  int coord_sys;
123  double rmatrix[16];
124 
125  MBresult = MBI->tag_get_data( coord_tag, &root, 1, &coord_sys );
126  MB_CHK_ERR( MBresult );
127  MBresult = MBI->tag_get_data( rotation_tag, &root, 1, &rmatrix );
128  MB_CHK_ERR( MBresult );
129 
130  build_time = clock() - load_time;
131 
132  // Read the CAD mesh data and query the tree
133  std::ifstream cadfile;
134  std::ofstream outfile;
135 
136  outfile.open( output_filename.c_str() );
137 
138  int num_pts;
139  int n;
140  long int nl = 0;
141  char* ctmp;
142  int elems_read = 0;
143  int p = 0;
144  char line[10000];
145 
146  // Used only when reading a mesh file to get vertex info
147  double* cfd_coords = NULL;
148  moab::Range::iterator cfd_iter;
149  moab::EntityHandle meshset;
150 
151  if( read_qnv )
152  {
153  cadfile.open( CAD_filename.c_str() );
154  cadfile.getline( line, 10000 );
155  cadfile.getline( line, 10000 );
156  result = next_int( line, num_pts, p );
157  }
158  else
159  {
160 
161  meshset = 0;
162  MBresult = MBI->load_file( CAD_filename.c_str(), &meshset );
163  MB_CHK_ERR( MBresult );
164  assert( 0 != meshset );
165 
166  moab::Range cfd_verts;
167  MBresult = MBI->get_entities_by_type( meshset, moab::MBVERTEX, cfd_verts, true );
168  MB_CHK_ERR( MBresult );
169  num_pts = cfd_verts.size();
170 
171  cfd_coords = new double[3 * num_pts];
172  MBresult = MBI->get_coords( cfd_verts, cfd_coords );
173  MB_CHK_ERR( MBresult );
174 
175  cfd_iter = cfd_verts.begin();
176  MBresult = MBI->tag_get_handle( "heating_tag", 1, moab::MB_TYPE_DOUBLE, cfd_heating_tag,
178  MB_CHK_ERR( MBresult );
179  MBresult = MBI->tag_get_handle( "error_tag", 1, moab::MB_TYPE_DOUBLE, cfd_error_tag,
181  MB_CHK_ERR( MBresult );
182 
183  std::cout << std::endl << "Read in mesh with query points." << std::endl << std::endl;
184  }
185 
186  double testpt[3];
187  double transformed_pt[3];
188  double taldata;
189  double errdata;
190 
191  moab::CartVect testvc;
192 
193  bool found = false;
194 
195  // MBRange verts;
196  std::vector< moab::EntityHandle > verts;
197  moab::Range range;
199 
200  moab::CartVect hexverts[8];
201  moab::CartVect tmp_cartvect;
202  std::vector< double > coords;
203 
204  double tal_sum = 0.0, err_sum = 0.0, tal_sum_sqr = 0.0, err_sum_sqr = 0.0;
205 
206  // double davg = 0.0;
207  // unsigned int nmax = 0, nmin = 1000000000 ;
208 
209  for( unsigned int i = 0; i < (unsigned int)num_pts; i++ )
210  {
211 
212  // if (i%status_freq == 0)
213  // std::cerr << "Completed " << i/status_freq << "%" << std::endl;
214 
215  // Grab the coordinates to query
216  if( read_qnv )
217  {
218  cadfile.getline( line, 10000 );
219 
220  nl = std::strtol( line, &ctmp, 10 );
221  n = (unsigned int)nl;
222  testpt[0] = std::strtod( ctmp + 1, &ctmp );
223  testpt[1] = std::strtod( ctmp + 1, &ctmp );
224  testpt[2] = std::strtod( ctmp + 1, NULL );
225  }
226  else
227  {
228  testpt[0] = cfd_coords[3 * i];
229  testpt[1] = cfd_coords[3 * i + 1];
230  testpt[2] = cfd_coords[3 * i + 2];
231  n = i + 1;
232  }
233 
234  result = MCNP->transform_point( testpt, transformed_pt, coord_sys, rmatrix );
235 
236  testvc[0] = transformed_pt[0];
237  testvc[1] = transformed_pt[1];
238  testvc[2] = transformed_pt[2];
239 
240  // Find the leaf containing the point
241  moab::EntityHandle tree_node;
242  MBresult = kdtree.point_search( transformed_pt, tree_node );
243  if( moab::MB_SUCCESS != MBresult )
244  {
245  double x = 0.0, y = 0.0, z = 0.0;
246  if( CARTESIAN == coord_sys )
247  {
248  x = testvc[0];
249  y = testvc[1];
250  z = testvc[2];
251  }
252  else if( CYLINDRICAL == coord_sys )
253  {
254  x = testvc[0] * cos( 2 * M_PI * testvc[2] );
255  y = testvc[0] * sin( 2 * M_PI * testvc[2] );
256  z = testvc[1];
257  }
258  else
259  {
260  std::cout << "MOAB WARNING: Unhandled error code during point search in KdTree, "
261  "ErrorCode = "
262  << MBresult << " and Coord xyz=" << x << " " << y << " " << z << std::endl;
263  }
264  std::cout << "No leaf found, MCNP coord xyz=" << x << " " << y << " " << z << std::endl;
265  ++cfd_iter;
266  continue;
267  }
268 
269  range.clear();
270  MBresult = MBI->get_entities_by_type( tree_node, moab::MBHEX, range );
271  MB_CHK_ERR( MBresult );
272 
273  // davg += (double) range.size();
274  // if (range.size() > nmax) nmax = range.size();
275  // if (range.size() < nmin) nmin = range.size();
276 
277  for( moab::Range::iterator rit = range.begin(); rit != range.end(); ++rit )
278  {
279  verts.clear();
280  const moab::EntityHandle* connect;
281  int num_connect;
282  MBresult = MBI->get_connectivity( *rit, connect, num_connect, true );
283  MB_CHK_ERR( MBresult );
284 
285  coords.resize( 3 * num_connect );
286  MBresult = MBI->get_coords( connect, num_connect, &coords[0] );
287  MB_CHK_ERR( MBresult );
288 
289  for( unsigned int j = 0; j < (unsigned int)num_connect; j++ )
290  {
291  hexverts[j][0] = coords[3 * j];
292  hexverts[j][1] = coords[3 * j + 1];
293  hexverts[j][2] = coords[3 * j + 2];
294  }
295 
296  if( moab::ElemUtil::point_in_trilinear_hex( hexverts, testvc, 1.e-6 ) )
297  {
298  MBresult = MBI->tag_get_data( MCNP->tally_tag, &( *rit ), 1, &taldata );
299  MB_CHK_ERR( MBresult );
300  MBresult = MBI->tag_get_data( MCNP->relerr_tag, &( *rit ), 1, &errdata );
301  MB_CHK_ERR( MBresult );
302 
303  outfile << n << "," << testpt[0] << "," << testpt[1] << "," << testpt[2] << "," << taldata << ","
304  << errdata << std::endl;
305 
306  if( !read_qnv )
307  {
308  MBresult = MBI->tag_set_data( cfd_heating_tag, &( *cfd_iter ), 1, &taldata );
309  MB_CHK_ERR( MBresult );
310  MBresult = MBI->tag_set_data( cfd_error_tag, &( *cfd_iter ), 1, &errdata );
311  MB_CHK_ERR( MBresult );
312  }
313 
314  found = true;
315  elems_read++;
316 
317  tal_sum = tal_sum + taldata;
318  err_sum = err_sum + errdata;
319  tal_sum_sqr = tal_sum_sqr + taldata * taldata;
320  err_sum_sqr = err_sum_sqr + errdata * errdata;
321 
322  break;
323  }
324  }
325 
326  if( !read_qnv ) ++cfd_iter;
327 
328  if( !found )
329  {
330  std::cout << n << " " << testvc << std::endl;
331  }
332  found = false;
333  }
334 
335  cadfile.close();
336  outfile.close();
337 
338  if( result == MCNP_SUCCESS )
339  {
340  std::cout << "Success! " << elems_read << " elements interpolated." << std::endl << std::endl;
341  }
342  else
343  {
344  std::cout << "Failure during query! " << elems_read << " elements interpolated." << std::endl << std::endl;
345  }
346 
347  double tal_std_dev = sqrt( ( 1.0 / elems_read ) * ( tal_sum_sqr - ( 1.0 / elems_read ) * tal_sum * tal_sum ) );
348  double err_std_dev = sqrt( ( 1.0 / elems_read ) * ( err_sum_sqr - ( 1.0 / elems_read ) * err_sum * err_sum ) );
349 
350  std::cout << "Tally Mean: " << tal_sum / elems_read << std::endl;
351  std::cout << "Tally Standard Deviation: " << tal_std_dev << std::endl;
352  std::cout << "Error Mean: " << err_sum / elems_read << std::endl;
353  std::cout << "Error Standard Deviation: " << err_std_dev << std::endl;
354 
355  interp_time = clock() - build_time;
356 
357  if( !read_qnv )
358  {
359  std::string out_mesh_fname = output_filename;
360  MBresult = MBI->write_mesh( ( out_mesh_fname + ".h5m" ).c_str(), &meshset, 1 );
361  // MBresult = MBI->write_file( (cfd_mesh_fname + ".vtk").c_str(), "vtk", NULL, &meshset, 1,
362  // &cfd_heating_tag, 1);
363  }
364 
365  std::cout << "Time to read in file: " << (double)load_time / CLOCKS_PER_SEC << std::endl;
366  std::cout << "Time to build kd-tree: " << (double)build_time / CLOCKS_PER_SEC << std::endl;
367  std::cout << "Time to interpolate data: " << (double)interp_time / CLOCKS_PER_SEC << std::endl;
368 
369  return 0;
370 }
371 
372 MCNPError read_files( int argc, char** argv )
373 {
374  MCNPError result = MCNP_FAILURE;
375 
376  // Check to see if appropriate command lines specified
377  if( argc < 3 )
378  {
379  std::cout << "Source and Target mesh filenames NOT specified!";
380  std::cout << std::endl;
381  return MCNP_FAILURE;
382  }
383 
384  // Set the MCNP or H5M filename
385  std::string str;
386  str = argv[1];
387 
388  unsigned int itmp = str.find( ".h5m" );
389  if( ( itmp > 0 ) && ( itmp < str.length() ) )
390  {
391  skip_build = true;
392  h5m_filename = str;
393  }
394  else
395  {
396  result = MCNP->set_filename( str );
397  }
398 
399  // Set the CAD filename
400  str = argv[2];
401  CAD_filename = str;
402 
403  itmp = str.find( ".qnv" );
404  if( ( itmp > 0 ) && ( itmp < str.length() ) ) read_qnv = true;
405 
406  // Set the output filename
407  str = argv[3];
408  output_filename = str;
409 
410  return result;
411 }
412 
413 MCNPError next_double( std::string s, double& d, int& p )
414 {
415 
416  unsigned int slen = s.length();
417  unsigned int j;
418 
419  for( unsigned int i = p; i < slen; i++ )
420  {
421  if( ( ( s[i] >= 48 ) && ( s[i] <= 57 ) ) || ( s[i] == 45 ) )
422  {
423 
424  j = s.find( ",", i );
425  if( j > slen ) j = slen;
426 
427  d = std::atof( s.substr( i, j - i ).c_str() );
428  p = j + 1;
429 
430  return MCNP_SUCCESS;
431  }
432  }
433 
434  return DONE;
435 }
436 
437 MCNPError next_int( std::string s, int& k, int& p )
438 {
439 
440  unsigned int slen = s.length();
441  unsigned int j;
442 
443  for( unsigned int i = p; i < slen; i++ )
444  {
445  if( ( ( s[i] >= 48 ) && ( s[i] <= 57 ) ) || ( s[i] == 45 ) )
446  {
447 
448  j = s.find( ",", i );
449  if( j > slen ) j = slen;
450 
451  k = std::atoi( s.substr( i, j - i ).c_str() );
452  p = j + 1;
453 
454  return MCNP_SUCCESS;
455  }
456  }
457 
458  return DONE;
459 }
460 
462 {
463  static McnpData inst;
464  return &inst;
465 }
466 
468 {
469  static moab::Core inst;
470  return &inst;
471 }