1
15
16 #include "ReadMCNP5.hpp"
17 #include "moab/Interface.hpp"
18 #include "moab/ReadUtilIface.hpp"
19 #include "Internals.hpp"
20 #include "moab/Range.hpp"
21 #include "moab/FileOptions.hpp"
22 #include "moab/Util.hpp"
23
24 #include <iostream>
25 #include <sstream>
26 #include <fstream>
27 #include <vector>
28 #include <cstdlib>
29 #include <cmath>
30 #include <cassert>
31
32 namespace moab
33 {
34
35
36 const double ReadMCNP5::PI = 3.141592653589793;
37 const double ReadMCNP5::C2PI = 0.1591549430918954;
38 const double ReadMCNP5::CPI = 0.3183098861837907;
39
40 ReaderIface* ReadMCNP5::factory( Interface* iface )
41 {
42 return new ReadMCNP5( iface );
43 }
44
45
46 ReadMCNP5::ReadMCNP5( Interface* impl ) : MBI( impl ), fileIDTag( NULL ), nodeId( 0 ), elemId( 0 )
47 {
48 assert( NULL != impl );
49 MBI->query_interface( readMeshIface );
50 assert( NULL != readMeshIface );
51 }
52
53
54 ReadMCNP5::~ReadMCNP5()
55 {
56 if( readMeshIface )
57 {
58 MBI->release_interface( readMeshIface );
59 readMeshIface = 0;
60 }
61 }
62
63 ErrorCode ReadMCNP5::read_tag_values( const char* ,
64 const char* ,
65 const FileOptions& ,
66 std::vector< int >& ,
67 const SubsetList* )
68 {
69 return MB_NOT_IMPLEMENTED;
70 }
71
72
73 ErrorCode ReadMCNP5::load_file( const char* filename,
74 const EntityHandle* input_meshset,
75 const FileOptions& options,
76 const ReaderIface::SubsetList* subset_list,
77 const Tag* file_id_tag )
78 {
79
80 if( subset_list )
81 {
82 MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for meshtal" );
83 }
84
85 nodeId = elemId = 0;
86 fileIDTag = file_id_tag;
87
88
89
90
91
92
93 int n_files;
94 bool average = false;
95 ErrorCode result;
96 if( MB_SUCCESS == options.get_int_option( "AVERAGE_TALLY", n_files ) )
97 {
98
99 result = load_one_file( filename, input_meshset, options, average );
100 if( MB_SUCCESS != result ) return result;
101
102
103 std::string root_filename( filename );
104 int length = root_filename.length();
105 root_filename.erase( length - sizeof( ".meshtal" ) );
106
107
108 average = true;
109 for( int i = 2; i <= n_files; i++ )
110 {
111 std::stringstream index;
112 index << i;
113 std::string subsequent_filename = root_filename + index.str() + ".meshtal";
114 result = load_one_file( subsequent_filename.c_str(), input_meshset, options, average );
115 if( MB_SUCCESS != result ) return result;
116 }
117
118
119 }
120 else
121 {
122 result = load_one_file( filename, input_meshset, options, average );
123 if( MB_SUCCESS != result ) return result;
124 }
125
126 return MB_SUCCESS;
127 }
128
129
130
131 ErrorCode ReadMCNP5::load_one_file( const char* fname,
132 const EntityHandle* input_meshset,
133 const FileOptions& options,
134 const bool average )
135 {
136 bool debug = false;
137 if( debug ) std::cout << "begin ReadMCNP5::load_one_file" << std::endl;
138
139 ErrorCode result;
140 std::fstream file;
141 file.open( fname, std::fstream::in );
142 char line[10000];
143
144
145 Tag date_and_time_tag, title_tag, nps_tag, tally_number_tag, tally_comment_tag, tally_particle_tag,
146 tally_coord_sys_tag, tally_tag, error_tag;
147
148 result = create_tags( date_and_time_tag, title_tag, nps_tag, tally_number_tag, tally_comment_tag,
149 tally_particle_tag, tally_coord_sys_tag, tally_tag, error_tag );
150 if( MB_SUCCESS != result ) return result;
151
152
153
154
155
156
157 char date_and_time[100] = "";
158 char title[100] = "";
159
160 unsigned long int nps;
161
162 unsigned long int new_nps;
163
164
165 result = read_file_header( file, debug, date_and_time, title, nps );
166 if( MB_SUCCESS != result ) return result;
167
168
169 file.getline( line, 10000 );
170
171
172
173 if( !average && 0 != input_meshset )
174 {
175 result = set_header_tags( *input_meshset, date_and_time, title, nps, date_and_time_tag, title_tag, nps_tag );
176 if( MB_SUCCESS != result ) return result;
177 }
178
179
180
181
182
183
184 while( !file.eof() )
185 {
186
187 unsigned int tally_number;
188 char tally_comment[100] = "";
189 particle tally_particle;
190 coordinate_system tally_coord_sys;
191 std::vector< double > planes[3];
192 unsigned int n_chopped_x0_planes;
193 unsigned int n_chopped_x2_planes;
194
195
196 result = read_tally_header( file, debug, tally_number, tally_comment, tally_particle );
197 if( MB_SUCCESS != result ) return result;
198
199
200 file.getline( line, 10000 );
201 std::string l = line;
202
203 if( std::string::npos != l.find( "This mesh tally is modified by a dose response function." ) )
204 {
205 file.getline( line, 10000 );
206 }
207
208
209 result = read_mesh_planes( file, debug, planes, tally_coord_sys );
210 if( MB_SUCCESS != result ) return result;
211
212
213 file.getline( line, 10000 );
214 std::string a = line;
215 if( debug ) std::cout << "Energy bin boundaries:=| " << a << std::endl;
216
217
218 file.getline( line, 10000 );
219
220
221 file.getline( line, 10000 );
222
223
224
225
226
227
228
229 if( CYLINDRICAL == tally_coord_sys && MB_SUCCESS == options.get_null_option( "REMOVE_LAST_AZIMUTHAL_PLANE" ) )
230 {
231 planes[2].pop_back();
232 n_chopped_x2_planes = 1;
233 if( debug ) std::cout << "remove last cylindrical plane option found" << std::endl;
234 }
235 else
236 {
237 n_chopped_x2_planes = 0;
238 }
239
240
241
242
243
244 if( CYLINDRICAL == tally_coord_sys && MB_SUCCESS == options.get_null_option( "REMOVE_FIRST_RADIAL_PLANE" ) )
245 {
246 std::vector< double >::iterator front = planes[0].begin();
247 planes[0].erase( front );
248 n_chopped_x0_planes = 1;
249 if( debug ) std::cout << "remove first radial plane option found" << std::endl;
250 }
251 else
252 {
253 n_chopped_x0_planes = 0;
254 }
255
256
257
258 unsigned int n_elements = ( planes[0].size() - 1 ) * ( planes[1].size() - 1 ) * ( planes[2].size() - 1 );
259 double* values = new double[n_elements];
260 double* errors = new double[n_elements];
261 result = read_element_values_and_errors( file, debug, planes, n_chopped_x0_planes, n_chopped_x2_planes,
262 tally_particle, values, errors );
263 if( MB_SUCCESS != result ) return result;
264
265
266 file.getline( line, 10000 );
267
268
269
270
271
272
273 if( !average )
274 {
275 EntityHandle tally_meshset;
276 result = MBI->create_meshset( MESHSET_SET, tally_meshset );
277 if( MB_SUCCESS != result ) return result;
278
279
280 result = set_tally_tags( tally_meshset, tally_number, tally_comment, tally_particle, tally_coord_sys,
281 tally_number_tag, tally_comment_tag, tally_particle_tag, tally_coord_sys_tag );
282 if( MB_SUCCESS != result ) return result;
283
284
285
286 EntityHandle start_vert = 0;
287 result = create_vertices( planes, debug, start_vert, tally_coord_sys, tally_meshset );
288 if( MB_SUCCESS != result ) return result;
289
290
291
292 result = create_elements( debug, planes, n_chopped_x0_planes, n_chopped_x2_planes, start_vert, values,
293 errors, tally_tag, error_tag, tally_meshset, tally_coord_sys );
294 if( MB_SUCCESS != result ) return result;
295
296
297 if( debug ) std::cout << "not averaging tally" << std::endl;
298
299
300 }
301 else
302 {
303 if( debug ) std::cout << "averaging tally" << std::endl;
304 result = average_with_existing_tally( debug, new_nps, nps, tally_number, tally_number_tag, nps_tag,
305 tally_tag, error_tag, values, errors, n_elements );
306 if( MB_SUCCESS != result ) return result;
307 }
308
309
310 delete[] values;
311 delete[] errors;
312 }
313
314
315
316
317 if( average )
318 {
319 Range matching_nps_sets;
320 result = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &nps_tag, 0, 1, matching_nps_sets );
321 if( MB_SUCCESS != result ) return result;
322 if( debug ) std::cout << "number of matching nps meshsets=" << matching_nps_sets.size() << std::endl;
323 assert( 1 == matching_nps_sets.size() );
324 result = MBI->tag_set_data( nps_tag, matching_nps_sets, &new_nps );
325 if( MB_SUCCESS != result ) return result;
326
327
328 }
329
330 file.close();
331 return MB_SUCCESS;
332 }
333
334
335 ErrorCode ReadMCNP5::create_tags( Tag& date_and_time_tag,
336 Tag& title_tag,
337 Tag& nps_tag,
338 Tag& tally_number_tag,
339 Tag& tally_comment_tag,
340 Tag& tally_particle_tag,
341 Tag& tally_coord_sys_tag,
342 Tag& tally_tag,
343 Tag& error_tag )
344 {
345 ErrorCode result;
346 result = MBI->tag_get_handle( "DATE_AND_TIME_TAG", 100, MB_TYPE_OPAQUE, date_and_time_tag,
347 MB_TAG_SPARSE | MB_TAG_CREAT );
348 if( MB_SUCCESS != result ) return result;
349 result = MBI->tag_get_handle( "TITLE_TAG", 100, MB_TYPE_OPAQUE, title_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
350 if( MB_SUCCESS != result ) return result;
351 result = MBI->tag_get_handle( "NPS_TAG", sizeof( unsigned long int ), MB_TYPE_OPAQUE, nps_tag,
352 MB_TAG_SPARSE | MB_TAG_CREAT );
353 if( MB_SUCCESS != result ) return result;
354 result =
355 MBI->tag_get_handle( "TALLY_NUMBER_TAG", 1, MB_TYPE_INTEGER, tally_number_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
356 if( MB_SUCCESS != result ) return result;
357 result = MBI->tag_get_handle( "TALLY_COMMENT_TAG", 100, MB_TYPE_OPAQUE, tally_comment_tag,
358 MB_TAG_SPARSE | MB_TAG_CREAT );
359 if( MB_SUCCESS != result ) return result;
360 result = MBI->tag_get_handle( "TALLY_PARTICLE_TAG", sizeof( particle ), MB_TYPE_OPAQUE, tally_particle_tag,
361 MB_TAG_SPARSE | MB_TAG_CREAT );
362 if( MB_SUCCESS != result ) return result;
363 result = MBI->tag_get_handle( "TALLY_COORD_SYS_TAG", sizeof( coordinate_system ), MB_TYPE_OPAQUE,
364 tally_coord_sys_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
365 if( MB_SUCCESS != result ) return result;
366 result = MBI->tag_get_handle( "TALLY_TAG", 1, MB_TYPE_DOUBLE, tally_tag, MB_TAG_DENSE | MB_TAG_CREAT );
367 if( MB_SUCCESS != result ) return result;
368 result = MBI->tag_get_handle( "ERROR_TAG", 1, MB_TYPE_DOUBLE, error_tag, MB_TAG_DENSE | MB_TAG_CREAT );
369 if( MB_SUCCESS != result ) return result;
370
371 return MB_SUCCESS;
372 }
373
374 ErrorCode ReadMCNP5::read_file_header( std::fstream& file,
375 bool debug,
376 char date_and_time[100],
377 char title[100],
378 unsigned long int& nps )
379 {
380
381
382 char line[100];
383 file.getline( line, 100 );
384 date_and_time = line;
385 if( debug ) std::cout << "date_and_time=| " << date_and_time << std::endl;
386
387
388
389 file.getline( line, 100 );
390 title = line;
391 if( debug ) std::cout << "title=| " << title << std::endl;
392
393
394
395 file.getline( line, 100 );
396 std::string a = line;
397 std::string::size_type b = a.find( "Number of histories used for normalizing tallies =" );
398 if( std::string::npos != b )
399 {
400 std::istringstream nps_ss(
401 a.substr( b + sizeof( "Number of histories used for normalizing tallies =" ), 100 ) );
402 nps_ss >> nps;
403 if( debug ) std::cout << "nps=| " << nps << std::endl;
404 }
405 else
406 return MB_FAILURE;
407
408 return MB_SUCCESS;
409 }
410
411 ErrorCode ReadMCNP5::set_header_tags( EntityHandle output_meshset,
412 char date_and_time[100],
413 char title[100],
414 unsigned long int nps,
415 Tag data_and_time_tag,
416 Tag title_tag,
417 Tag nps_tag )
418 {
419 ErrorCode result;
420 result = MBI->tag_set_data( data_and_time_tag, &output_meshset, 1, &date_and_time );
421 if( MB_SUCCESS != result ) return result;
422 result = MBI->tag_set_data( title_tag, &output_meshset, 1, &title );
423 if( MB_SUCCESS != result ) return result;
424 result = MBI->tag_set_data( nps_tag, &output_meshset, 1, &nps );
425 if( MB_SUCCESS != result ) return result;
426
427 return MB_SUCCESS;
428 }
429
430 ErrorCode ReadMCNP5::read_tally_header( std::fstream& file,
431 bool debug,
432 unsigned int& tally_number,
433 char tally_comment[100],
434 particle& tally_particle )
435 {
436
437
438 ErrorCode result;
439 char line[100];
440 file.getline( line, 100 );
441 std::string a = line;
442 std::string::size_type b = a.find( "Mesh Tally Number" );
443 if( std::string::npos != b )
444 {
445 std::istringstream tally_number_ss( a.substr( b + sizeof( "Mesh Tally Number" ), 100 ) );
446 tally_number_ss >> tally_number;
447 if( debug ) std::cout << "tally_number=| " << tally_number << std::endl;
448 }
449 else
450 {
451 std::cout << "tally number not found" << std::endl;
452 return MB_FAILURE;
453 }
454
455
456
457
458
459
460
461 file.getline( line, 100 );
462 a = line;
463 result = get_tally_particle( a, debug, tally_particle );
464 if( MB_FAILURE == result )
465 {
466
467
468 tally_comment = line;
469 file.getline( line, 100 );
470 a = line;
471 result = get_tally_particle( a, debug, tally_particle );
472 if( MB_SUCCESS != result ) return result;
473 }
474 if( debug ) std::cout << "tally_comment=| " << tally_comment << std::endl;
475
476 return MB_SUCCESS;
477 }
478
479 ErrorCode ReadMCNP5::get_tally_particle( std::string a, bool debug, particle& tally_particle )
480 {
481 if( std::string::npos != a.find( "This is a neutron mesh tally." ) )
482 {
483 tally_particle = NEUTRON;
484 }
485 else if( std::string::npos != a.find( "This is a photon mesh tally." ) )
486 {
487 tally_particle = PHOTON;
488 }
489 else if( std::string::npos != a.find( "This is an electron mesh tally." ) )
490 {
491 tally_particle = ELECTRON;
492 }
493 else
494 return MB_FAILURE;
495
496 if( debug ) std::cout << "tally_particle=| " << tally_particle << std::endl;
497
498 return MB_SUCCESS;
499 }
500
501 ErrorCode ReadMCNP5::read_mesh_planes( std::fstream& file,
502 bool debug,
503 std::vector< double > planes[3],
504 coordinate_system& coord_sys )
505 {
506
507 ErrorCode result;
508 char line[10000];
509 file.getline( line, 10000 );
510 std::string a = line;
511 if( std::string::npos == a.find( "Tally bin boundaries:" ) ) return MB_FAILURE;
512
513
514
515 file.getline( line, 10000 );
516 a = line;
517 std::string::size_type b = a.find( "Cylinder origin at" );
518 if( std::string::npos != b )
519 {
520 coord_sys = CYLINDRICAL;
521 if( debug ) std::cout << "origin, axis, direction=| " << a << std::endl;
522 std::istringstream ss( a.substr( b + sizeof( "Cylinder origin at" ), 10000 ) );
523
524
525
526
527
528
529 double origin[3];
530 if( debug ) std::cout << "origin=| ";
531 for( int i = 0; i < 3; i++ )
532 {
533 ss >> origin[i];
534 if( debug ) std::cout << origin[i] << " ";
535 }
536 if( debug ) std::cout << std::endl;
537 int length_of_string = 10;
538 ss.ignore( length_of_string, ' ' );
539 ss.ignore( length_of_string, ' ' );
540 ss.ignore( length_of_string, ' ' );
541
542 double axis[3];
543 if( debug ) std::cout << "axis=| ";
544 for( int i = 0; i < 3; i++ )
545 {
546 ss >> axis[i];
547 if( debug ) std::cout << axis[i] << " ";
548 }
549 if( debug ) std::cout << std::endl;
550 file.getline( line, 10000 );
551 a = line;
552
553
554 if( debug ) std::cout << "R direction:=| ";
555 b = a.find( "R direction:" );
556 if( std::string::npos != b )
557 {
558 std::istringstream ss2( a.substr( b + sizeof( "R direction" ), 10000 ) );
559 result = get_mesh_plane( ss2, debug, planes[0] );
560 if( MB_SUCCESS != result ) return result;
561 }
562 else
563 return MB_FAILURE;
564
565
566 file.getline( line, 10000 );
567 a = line;
568 if( debug ) std::cout << "Z direction:=| ";
569 b = a.find( "Z direction:" );
570 if( std::string::npos != b )
571 {
572 std::istringstream ss2( a.substr( b + sizeof( "Z direction" ), 10000 ) );
573 result = get_mesh_plane( ss2, debug, planes[1] );
574 if( MB_SUCCESS != result ) return result;
575 }
576 else
577 return MB_FAILURE;
578
579
580 file.getline( line, 10000 );
581 a = line;
582 if( debug ) std::cout << "Theta direction:=| ";
583 b = a.find( "Theta direction (revolutions):" );
584 if( std::string::npos != b )
585 {
586 std::istringstream ss2( a.substr( b + sizeof( "Theta direction (revolutions):" ), 10000 ) );
587 result = get_mesh_plane( ss2, debug, planes[2] );
588 if( MB_SUCCESS != result ) return result;
589 }
590 else
591 return MB_FAILURE;
592
593
594 }
595 else if( std::string::npos != a.find( "X direction:" ) )
596 {
597 coord_sys = CARTESIAN;
598
599 if( debug ) std::cout << "X direction:=| ";
600 b = a.find( "X direction:" );
601 if( std::string::npos != b )
602 {
603 std::istringstream ss2( a.substr( b + sizeof( "X direction" ), 10000 ) );
604 result = get_mesh_plane( ss2, debug, planes[0] );
605 if( MB_SUCCESS != result ) return result;
606 }
607 else
608 return MB_FAILURE;
609
610
611 file.getline( line, 10000 );
612 a = line;
613 if( debug ) std::cout << "Y direction:=| ";
614 b = a.find( "Y direction:" );
615 if( std::string::npos != b )
616 {
617 std::istringstream ss2( a.substr( b + sizeof( "Y direction" ), 10000 ) );
618 result = get_mesh_plane( ss2, debug, planes[1] );
619 if( MB_SUCCESS != result ) return result;
620 }
621 else
622 return MB_FAILURE;
623
624
625 file.getline( line, 10000 );
626 a = line;
627 if( debug ) std::cout << "Z direction:=| ";
628 b = a.find( "Z direction:" );
629 if( std::string::npos != b )
630 {
631 std::istringstream ss2( a.substr( b + sizeof( "Z direction" ), 10000 ) );
632 result = get_mesh_plane( ss2, debug, planes[2] );
633 if( MB_SUCCESS != result ) return result;
634 }
635 else
636 return MB_FAILURE;
637
638
639 }
640 else
641 return MB_FAILURE;
642
643 return MB_SUCCESS;
644 }
645
646
647 ErrorCode ReadMCNP5::get_mesh_plane( std::istringstream& ss, bool debug, std::vector< double >& plane )
648 {
649 double value;
650 plane.clear();
651 while( !ss.eof() )
652 {
653 ss >> value;
654 plane.push_back( value );
655 if( debug ) std::cout << value << " ";
656 }
657 if( debug ) std::cout << std::endl;
658
659 return MB_SUCCESS;
660 }
661
662 ErrorCode ReadMCNP5::read_element_values_and_errors( std::fstream& file,
663 bool ,
664 std::vector< double > planes[3],
665 unsigned int n_chopped_x0_planes,
666 unsigned int n_chopped_x2_planes,
667 particle tally_particle,
668 double values[],
669 double errors[] )
670 {
671 unsigned int index = 0;
672
673 for( unsigned int i = 0; i < planes[0].size() - 1 + n_chopped_x0_planes; i++ )
674 {
675 for( unsigned int j = 0; j < planes[1].size() - 1; j++ )
676 {
677 for( unsigned int k = 0; k < planes[2].size() - 1 + n_chopped_x2_planes; k++ )
678 {
679 char line[100];
680 file.getline( line, 100 );
681
682 if( i < n_chopped_x0_planes ) continue;
683 if( k >= planes[2].size() - 1 && k < planes[2].size() - 1 + n_chopped_x2_planes ) continue;
684 std::string a = line;
685 std::stringstream ss( a );
686 double centroid[3];
687 double energy;
688
689 if( PHOTON == tally_particle ) ss >> energy;
690
691 ss >> centroid[0];
692 ss >> centroid[1];
693 ss >> centroid[2];
694
695 ss >> values[index];
696 ss >> errors[index];
697
698
699 if( !Util::is_finite( errors[index] ) )
700 {
701 std::cerr << "found nan error while reading file" << std::endl;
702 errors[index] = 1.0;
703 }
704 if( !Util::is_finite( values[index] ) )
705 {
706 std::cerr << "found nan value while reading file" << std::endl;
707 values[index] = 0.0;
708 }
709
710 index++;
711 }
712 }
713 }
714
715 return MB_SUCCESS;
716 }
717
718 ErrorCode ReadMCNP5::set_tally_tags( EntityHandle tally_meshset,
719 unsigned int tally_number,
720 char tally_comment[100],
721 particle tally_particle,
722 coordinate_system tally_coord_sys,
723 Tag tally_number_tag,
724 Tag tally_comment_tag,
725 Tag tally_particle_tag,
726 Tag tally_coord_sys_tag )
727 {
728 ErrorCode result;
729 result = MBI->tag_set_data( tally_number_tag, &tally_meshset, 1, &tally_number );
730 if( MB_SUCCESS != result ) return result;
731 result = MBI->tag_set_data( tally_comment_tag, &tally_meshset, 1, &tally_comment );
732 if( MB_SUCCESS != result ) return result;
733 result = MBI->tag_set_data( tally_particle_tag, &tally_meshset, 1, &tally_particle );
734 if( MB_SUCCESS != result ) return result;
735 result = MBI->tag_set_data( tally_coord_sys_tag, &tally_meshset, 1, &tally_coord_sys );
736 if( MB_SUCCESS != result ) return result;
737
738 return MB_SUCCESS;
739 }
740
741 ErrorCode ReadMCNP5::create_vertices( std::vector< double > planes[3],
742 bool debug,
743 EntityHandle& start_vert,
744 coordinate_system coord_sys,
745 EntityHandle tally_meshset )
746 {
747
748 ErrorCode result;
749 int n_verts = planes[0].size() * planes[1].size() * planes[2].size();
750 if( debug ) std::cout << "n_verts=" << n_verts << std::endl;
751 std::vector< double* > coord_arrays( 3 );
752 result = readMeshIface->get_node_coords( 3, n_verts, MB_START_ID, start_vert, coord_arrays );
753 if( MB_SUCCESS != result ) return result;
754 assert( 0 != start_vert );
755
756 for( unsigned int k = 0; k < planes[2].size(); k++ )
757 {
758 for( unsigned int j = 0; j < planes[1].size(); j++ )
759 {
760 for( unsigned int i = 0; i < planes[0].size(); i++ )
761 {
762 unsigned int idx = ( k * planes[0].size() * planes[1].size() + j * planes[0].size() + i );
763 double in[3], out[3];
764
765 in[0] = planes[0][i];
766 in[1] = planes[1][j];
767 in[2] = planes[2][k];
768 result = transform_point_to_cartesian( in, out, coord_sys );
769 if( MB_SUCCESS != result ) return result;
770
771
772
773 coord_arrays[0][idx] = out[0];
774 coord_arrays[1][idx] = out[1];
775 coord_arrays[2][idx] = out[2];
776 }
777 }
778 }
779 Range vert_range( start_vert, start_vert + n_verts - 1 );
780 result = MBI->add_entities( tally_meshset, vert_range );
781 if( MB_SUCCESS != result ) return result;
782
783 if( fileIDTag )
784 {
785 result = readMeshIface->assign_ids( *fileIDTag, vert_range, nodeId );
786 if( MB_SUCCESS != result ) return result;
787 nodeId += vert_range.size();
788 }
789
790 return MB_SUCCESS;
791 }
792
793 ErrorCode ReadMCNP5::create_elements( bool debug,
794 std::vector< double > planes[3],
795 unsigned int ,
796 unsigned int ,
797 EntityHandle start_vert,
798 double* values,
799 double* errors,
800 Tag tally_tag,
801 Tag error_tag,
802 EntityHandle tally_meshset,
803 coordinate_system tally_coord_sys )
804 {
805 ErrorCode result;
806 unsigned int index;
807 EntityHandle start_element = 0;
808 unsigned int n_elements = ( planes[0].size() - 1 ) * ( planes[1].size() - 1 ) * ( planes[2].size() - 1 );
809 EntityHandle* connect;
810 result = readMeshIface->get_element_connect( n_elements, 8, MBHEX, MB_START_ID, start_element, connect );
811 if( MB_SUCCESS != result ) return result;
812 assert( 0 != start_element );
813
814 unsigned int counter = 0;
815 for( unsigned int i = 0; i < planes[0].size() - 1; i++ )
816 {
817 for( unsigned int j = 0; j < planes[1].size() - 1; j++ )
818 {
819 for( unsigned int k = 0; k < planes[2].size() - 1; k++ )
820 {
821 index = start_vert + i + j * planes[0].size() + k * planes[0].size() * planes[1].size();
822
823
824
825
826 if( CARTESIAN == tally_coord_sys )
827 {
828 connect[0] = index;
829 connect[1] = index + 1;
830 connect[2] = index + 1 + planes[0].size();
831 connect[3] = index + planes[0].size();
832 connect[4] = index + planes[0].size() * planes[1].size();
833 connect[5] = index + 1 + planes[0].size() * planes[1].size();
834 connect[6] = index + 1 + planes[0].size() + planes[0].size() * planes[1].size();
835 connect[7] = index + planes[0].size() + planes[0].size() * planes[1].size();
836
837
838 }
839 else if( CYLINDRICAL == tally_coord_sys )
840 {
841 connect[0] = index;
842 connect[1] = index + 1;
843 connect[2] = index + 1 + planes[0].size() * planes[1].size();
844 connect[3] = index + planes[0].size() * planes[1].size();
845 connect[4] = index + planes[0].size();
846 connect[5] = index + 1 + planes[0].size();
847 connect[6] = index + 1 + planes[0].size() + planes[0].size() * planes[1].size();
848 connect[7] = index + planes[0].size() + planes[0].size() * planes[1].size();
849 }
850 else
851 return MB_NOT_IMPLEMENTED;
852
853 connect += 8;
854 counter++;
855 }
856 }
857 }
858 if( counter != n_elements ) std::cout << "counter=" << counter << " n_elements=" << n_elements << std::endl;
859
860 Range element_range( start_element, start_element + n_elements - 1 );
861 result = MBI->tag_set_data( tally_tag, element_range, values );
862 if( MB_SUCCESS != result ) return result;
863 result = MBI->tag_set_data( error_tag, element_range, errors );
864 if( MB_SUCCESS != result ) return result;
865
866
867 result = MBI->add_entities( tally_meshset, element_range );
868 if( MB_SUCCESS != result ) return result;
869 if( debug ) std::cout << "Read " << n_elements << " elements from tally." << std::endl;
870
871 if( fileIDTag )
872 {
873 result = readMeshIface->assign_ids( *fileIDTag, element_range, elemId );
874 if( MB_SUCCESS != result ) return result;
875 elemId += element_range.size();
876 }
877
878 return MB_SUCCESS;
879 }
880
881
882
883 ErrorCode ReadMCNP5::average_with_existing_tally( bool debug,
884 unsigned long int& new_nps,
885 unsigned long int nps1,
886 unsigned int tally_number,
887 Tag tally_number_tag,
888 Tag nps_tag,
889 Tag tally_tag,
890 Tag error_tag,
891 double* values1,
892 double* errors1,
893 unsigned int n_elements )
894 {
895
896 ErrorCode result;
897
898
899 Range matching_tally_number_sets;
900 const void* const tally_number_val[] = { &tally_number };
901 result = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &tally_number_tag, tally_number_val, 1,
902 matching_tally_number_sets );
903 if( MB_SUCCESS != result ) return result;
904 if( debug ) std::cout << "number of matching meshsets=" << matching_tally_number_sets.size() << std::endl;
905 assert( 1 == matching_tally_number_sets.size() );
906
907
908 EntityHandle existing_meshset;
909 existing_meshset = matching_tally_number_sets.front();
910
911
912 Range existing_elements;
913 result = MBI->get_entities_by_type( existing_meshset, MBHEX, existing_elements );
914 if( MB_SUCCESS != result ) return result;
915 assert( existing_elements.size() == n_elements );
916
917
918 unsigned long int nps0;
919 Range sets_with_this_tag;
920 result = MBI->get_entities_by_type_and_tag( 0, MBENTITYSET, &nps_tag, 0, 1, sets_with_this_tag );
921 if( MB_SUCCESS != result ) return result;
922 if( debug ) std::cout << "number of nps sets=" << sets_with_this_tag.size() << std::endl;
923 assert( 1 == sets_with_this_tag.size() );
924 result = MBI->tag_get_data( nps_tag, &sets_with_this_tag.front(), 1, &nps0 );
925 if( MB_SUCCESS != result ) return result;
926 if( debug ) std::cout << "nps0=" << nps0 << " nps1=" << nps1 << std::endl;
927 new_nps = nps0 + nps1;
928
929
930 double* values0 = new double[existing_elements.size()];
931 double* errors0 = new double[existing_elements.size()];
932 result = MBI->tag_get_data( tally_tag, existing_elements, values0 );
933 if( MB_SUCCESS != result )
934 {
935 delete[] values0;
936 delete[] errors0;
937 return result;
938 }
939 result = MBI->tag_get_data( error_tag, existing_elements, errors0 );
940 if( MB_SUCCESS != result )
941 {
942 delete[] values0;
943 delete[] errors0;
944 return result;
945 }
946
947
948 result = average_tally_values( nps0, nps1, values0, values1, errors0, errors1, n_elements );
949 if( MB_SUCCESS != result )
950 {
951 delete[] values0;
952 delete[] errors0;
953 return result;
954 }
955
956
957 result = MBI->tag_set_data( tally_tag, existing_elements, values0 );
958 if( MB_SUCCESS != result )
959 {
960 delete[] values0;
961 delete[] errors0;
962 return result;
963 }
964 result = MBI->tag_set_data( error_tag, existing_elements, errors0 );
965 if( MB_SUCCESS != result )
966 {
967 delete[] values0;
968 delete[] errors0;
969 return result;
970 }
971
972
973 delete[] values0;
974 delete[] errors0;
975
976 return MB_SUCCESS;
977 }
978
979 ErrorCode ReadMCNP5::transform_point_to_cartesian( double* in, double* out, coordinate_system coord_sys )
980 {
981
982 switch( coord_sys )
983 {
984 case CARTESIAN:
985 out[0] = in[0];
986 out[1] = in[1];
987 out[2] = in[2];
988 break;
989
990 case CYLINDRICAL:
991 out[0] = in[0] * cos( 2 * PI * in[2] );
992 out[1] = in[0] * sin( 2 * PI * in[2] );
993 out[2] = in[1];
994 break;
995 case SPHERICAL:
996 return MB_NOT_IMPLEMENTED;
997 default:
998 return MB_NOT_IMPLEMENTED;
999 }
1000
1001 return MB_SUCCESS;
1002 }
1003
1004
1005
1006 ErrorCode ReadMCNP5::average_tally_values( const unsigned long int nps0,
1007 const unsigned long int nps1,
1008 double* values0,
1009 const double* values1,
1010 double* errors0,
1011 const double* errors1,
1012 const unsigned long int n_values )
1013 {
1014 for( unsigned long int i = 0; i < n_values; i++ )
1015 {
1016
1017
1018
1019 errors0[i] = sqrt( pow( values0[i] * errors0[i] * nps0, 2 ) + pow( values1[i] * errors1[i] * nps1, 2 ) ) /
1020 ( values0[i] * nps0 + values1[i] * nps1 );
1021
1022
1023 if( !Util::is_finite( errors0[i] ) ) errors0[i] = 1.0;
1024
1025 values0[i] = ( values0[i] * nps0 + values1[i] * nps1 ) / ( nps0 + nps1 );
1026
1027
1028 }
1029
1030
1031 return MB_SUCCESS;
1032 }
1033
1034 }