Mesh Oriented datABase  (version 5.5.1)
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 );MB_CHK_ERR( MBresult );
126  MBresult = MBI->tag_get_data( rotation_tag, &root, 1, &rmatrix );MB_CHK_ERR( MBresult );
127 
128  build_time = clock() - load_time;
129 
130  // Read the CAD mesh data and query the tree
131  std::ifstream cadfile;
132  std::ofstream outfile;
133 
134  outfile.open( output_filename.c_str() );
135 
136  int num_pts;
137  int n;
138  long int nl = 0;
139  char* ctmp;
140  int elems_read = 0;
141  int p = 0;
142  char line[10000];
143 
144  // Used only when reading a mesh file to get vertex info
145  double* cfd_coords = NULL;
146  moab::Range::iterator cfd_iter;
147  moab::EntityHandle meshset;
148 
149  if( read_qnv )
150  {
151  cadfile.open( CAD_filename.c_str() );
152  cadfile.getline( line, 10000 );
153  cadfile.getline( line, 10000 );
154  result = next_int( line, num_pts, p );
155  }
156  else
157  {
158 
159  meshset = 0;
160  MBresult = MBI->load_file( CAD_filename.c_str(), &meshset );MB_CHK_ERR( MBresult );
161  assert( 0 != meshset );
162 
163  moab::Range cfd_verts;
164  MBresult = MBI->get_entities_by_type( meshset, moab::MBVERTEX, cfd_verts, true );MB_CHK_ERR( MBresult );
165  num_pts = cfd_verts.size();
166 
167  cfd_coords = new double[3 * num_pts];
168  MBresult = MBI->get_coords( cfd_verts, cfd_coords );MB_CHK_ERR( MBresult );
169 
170  cfd_iter = cfd_verts.begin();
171  MBresult = MBI->tag_get_handle( "heating_tag", 1, moab::MB_TYPE_DOUBLE, cfd_heating_tag,
173  MBresult = MBI->tag_get_handle( "error_tag", 1, moab::MB_TYPE_DOUBLE, cfd_error_tag,
175 
176  std::cout << std::endl << "Read in mesh with query points." << std::endl << std::endl;
177  }
178 
179  double testpt[3];
180  double transformed_pt[3];
181  double taldata;
182  double errdata;
183 
184  moab::CartVect testvc;
185 
186  bool found = false;
187 
188  // MBRange verts;
189  std::vector< moab::EntityHandle > verts;
190  moab::Range range;
192 
193  moab::CartVect hexverts[8];
194  moab::CartVect tmp_cartvect;
195  std::vector< double > coords;
196 
197  double tal_sum = 0.0, err_sum = 0.0, tal_sum_sqr = 0.0, err_sum_sqr = 0.0;
198 
199  // double davg = 0.0;
200  // unsigned int nmax = 0, nmin = 1000000000 ;
201 
202  for( unsigned int i = 0; i < (unsigned int)num_pts; i++ )
203  {
204 
205  // if (i%status_freq == 0)
206  // std::cerr << "Completed " << i/status_freq << "%" << std::endl;
207 
208  // Grab the coordinates to query
209  if( read_qnv )
210  {
211  cadfile.getline( line, 10000 );
212 
213  nl = std::strtol( line, &ctmp, 10 );
214  n = (unsigned int)nl;
215  testpt[0] = std::strtod( ctmp + 1, &ctmp );
216  testpt[1] = std::strtod( ctmp + 1, &ctmp );
217  testpt[2] = std::strtod( ctmp + 1, NULL );
218  }
219  else
220  {
221  testpt[0] = cfd_coords[3 * i];
222  testpt[1] = cfd_coords[3 * i + 1];
223  testpt[2] = cfd_coords[3 * i + 2];
224  n = i + 1;
225  }
226 
227  result = MCNP->transform_point( testpt, transformed_pt, coord_sys, rmatrix );
228 
229  testvc[0] = transformed_pt[0];
230  testvc[1] = transformed_pt[1];
231  testvc[2] = transformed_pt[2];
232 
233  // Find the leaf containing the point
234  moab::EntityHandle tree_node;
235  MBresult = kdtree.point_search( transformed_pt, tree_node );
236  if( moab::MB_SUCCESS != MBresult )
237  {
238  double x = 0.0, y = 0.0, z = 0.0;
239  if( CARTESIAN == coord_sys )
240  {
241  x = testvc[0];
242  y = testvc[1];
243  z = testvc[2];
244  }
245  else if( CYLINDRICAL == coord_sys )
246  {
247  x = testvc[0] * cos( 2 * M_PI * testvc[2] );
248  y = testvc[0] * sin( 2 * M_PI * testvc[2] );
249  z = testvc[1];
250  }
251  else
252  {
253  std::cout << "MOAB WARNING: Unhandled error code during point search in KdTree, "
254  "ErrorCode = "
255  << MBresult << " and Coord xyz=" << x << " " << y << " " << z << std::endl;
256  }
257  std::cout << "No leaf found, MCNP coord xyz=" << x << " " << y << " " << z << std::endl;
258  ++cfd_iter;
259  continue;
260  }
261 
262  range.clear();
263  MBresult = MBI->get_entities_by_type( tree_node, moab::MBHEX, range );MB_CHK_ERR( MBresult );
264 
265  // davg += (double) range.size();
266  // if (range.size() > nmax) nmax = range.size();
267  // if (range.size() < nmin) nmin = range.size();
268 
269  for( moab::Range::iterator rit = range.begin(); rit != range.end(); ++rit )
270  {
271  verts.clear();
272  const moab::EntityHandle* connect;
273  int num_connect;
274  MBresult = MBI->get_connectivity( *rit, connect, num_connect, true );MB_CHK_ERR( MBresult );
275 
276  coords.resize( 3 * num_connect );
277  MBresult = MBI->get_coords( connect, num_connect, &coords[0] );MB_CHK_ERR( MBresult );
278 
279  for( unsigned int j = 0; j < (unsigned int)num_connect; j++ )
280  {
281  hexverts[j][0] = coords[3 * j];
282  hexverts[j][1] = coords[3 * j + 1];
283  hexverts[j][2] = coords[3 * j + 2];
284  }
285 
286  if( moab::ElemUtil::point_in_trilinear_hex( hexverts, testvc, 1.e-6 ) )
287  {
288  MBresult = MBI->tag_get_data( MCNP->tally_tag, &( *rit ), 1, &taldata );MB_CHK_ERR( MBresult );
289  MBresult = MBI->tag_get_data( MCNP->relerr_tag, &( *rit ), 1, &errdata );MB_CHK_ERR( MBresult );
290 
291  outfile << n << "," << testpt[0] << "," << testpt[1] << "," << testpt[2] << "," << taldata << ","
292  << errdata << std::endl;
293 
294  if( !read_qnv )
295  {
296  MBresult = MBI->tag_set_data( cfd_heating_tag, &( *cfd_iter ), 1, &taldata );MB_CHK_ERR( MBresult );
297  MBresult = MBI->tag_set_data( cfd_error_tag, &( *cfd_iter ), 1, &errdata );MB_CHK_ERR( MBresult );
298  }
299 
300  found = true;
301  elems_read++;
302 
303  tal_sum = tal_sum + taldata;
304  err_sum = err_sum + errdata;
305  tal_sum_sqr = tal_sum_sqr + taldata * taldata;
306  err_sum_sqr = err_sum_sqr + errdata * errdata;
307 
308  break;
309  }
310  }
311 
312  if( !read_qnv ) ++cfd_iter;
313 
314  if( !found )
315  {
316  std::cout << n << " " << testvc << std::endl;
317  }
318  found = false;
319  }
320 
321  cadfile.close();
322  outfile.close();
323 
324  if( result == MCNP_SUCCESS )
325  {
326  std::cout << "Success! " << elems_read << " elements interpolated." << std::endl << std::endl;
327  }
328  else
329  {
330  std::cout << "Failure during query! " << elems_read << " elements interpolated." << std::endl << std::endl;
331  }
332 
333  double tal_std_dev = sqrt( ( 1.0 / elems_read ) * ( tal_sum_sqr - ( 1.0 / elems_read ) * tal_sum * tal_sum ) );
334  double err_std_dev = sqrt( ( 1.0 / elems_read ) * ( err_sum_sqr - ( 1.0 / elems_read ) * err_sum * err_sum ) );
335 
336  std::cout << "Tally Mean: " << tal_sum / elems_read << std::endl;
337  std::cout << "Tally Standard Deviation: " << tal_std_dev << std::endl;
338  std::cout << "Error Mean: " << err_sum / elems_read << std::endl;
339  std::cout << "Error Standard Deviation: " << err_std_dev << std::endl;
340 
341  interp_time = clock() - build_time;
342 
343  if( !read_qnv )
344  {
345  std::string out_mesh_fname = output_filename;
346  MBresult = MBI->write_mesh( ( out_mesh_fname + ".h5m" ).c_str(), &meshset, 1 );
347  // MBresult = MBI->write_file( (cfd_mesh_fname + ".vtk").c_str(), "vtk", NULL, &meshset, 1,
348  // &cfd_heating_tag, 1);
349  }
350 
351  std::cout << "Time to read in file: " << (double)load_time / CLOCKS_PER_SEC << std::endl;
352  std::cout << "Time to build kd-tree: " << (double)build_time / CLOCKS_PER_SEC << std::endl;
353  std::cout << "Time to interpolate data: " << (double)interp_time / CLOCKS_PER_SEC << std::endl;
354 
355  return 0;
356 }
357 
358 MCNPError read_files( int argc, char** argv )
359 {
360  MCNPError result = MCNP_FAILURE;
361 
362  // Check to see if appropriate command lines specified
363  if( argc < 3 )
364  {
365  std::cout << "Source and Target mesh filenames NOT specified!";
366  std::cout << std::endl;
367  return MCNP_FAILURE;
368  }
369 
370  // Set the MCNP or H5M filename
371  std::string str;
372  str = argv[1];
373 
374  unsigned int itmp = str.find( ".h5m" );
375  if( ( itmp > 0 ) && ( itmp < str.length() ) )
376  {
377  skip_build = true;
378  h5m_filename = str;
379  }
380  else
381  {
382  result = MCNP->set_filename( str );
383  }
384 
385  // Set the CAD filename
386  str = argv[2];
387  CAD_filename = str;
388 
389  itmp = str.find( ".qnv" );
390  if( ( itmp > 0 ) && ( itmp < str.length() ) ) read_qnv = true;
391 
392  // Set the output filename
393  str = argv[3];
394  output_filename = str;
395 
396  return result;
397 }
398 
399 MCNPError next_double( std::string s, double& d, int& p )
400 {
401 
402  unsigned int slen = s.length();
403  unsigned int j;
404 
405  for( unsigned int i = p; i < slen; i++ )
406  {
407  if( ( ( s[i] >= 48 ) && ( s[i] <= 57 ) ) || ( s[i] == 45 ) )
408  {
409 
410  j = s.find( ",", i );
411  if( j > slen ) j = slen;
412 
413  d = std::atof( s.substr( i, j - i ).c_str() );
414  p = j + 1;
415 
416  return MCNP_SUCCESS;
417  }
418  }
419 
420  return DONE;
421 }
422 
423 MCNPError next_int( std::string s, int& k, int& p )
424 {
425 
426  unsigned int slen = s.length();
427  unsigned int j;
428 
429  for( unsigned int i = p; i < slen; i++ )
430  {
431  if( ( ( s[i] >= 48 ) && ( s[i] <= 57 ) ) || ( s[i] == 45 ) )
432  {
433 
434  j = s.find( ",", i );
435  if( j > slen ) j = slen;
436 
437  k = std::atoi( s.substr( i, j - i ).c_str() );
438  p = j + 1;
439 
440  return MCNP_SUCCESS;
441  }
442  }
443 
444  return DONE;
445 }
446 
448 {
449  static McnpData inst;
450  return &inst;
451 }
452 
454 {
455  static moab::Core inst;
456  return &inst;
457 }