moab
mcnpmit.cpp
Go to the documentation of this file.
00001 #include <iostream>
00002 #include <fstream>
00003 #include <cstdlib>
00004 #include "mcnpmit.hpp"
00005 #include "moab/CartVect.hpp"
00006 #include "math.h"
00007 
00008 moab::Interface* mb_instance();
00009 
00010 // Parameters
00011 const double pi   = 3.141592653589793;
00012 const double c2pi = 0.1591549430918954;
00013 const double cpi  = 0.3183098861837907;
00014 
00015 MCNPError next_number(std::string, double&, int&);
00016 int how_many_numbers(std::string);
00017 MCNPError read_numbers(std::string, int, std::vector<double>&);
00018 
00019 // Constructor
00020 McnpData::McnpData() {
00021 
00022       // Default value for coordinate system
00023       coord_system = 0;
00024 
00025       // Default rotation matrix is identity matrix
00026       for (int i = 0; i < 4; i++) {
00027             for (int j = 0; j < 4; j++) {
00028                   if (i == j)
00029                         rotation_matrix[4*i + j] = 1;
00030                   else
00031                         rotation_matrix[4*i + j] = 0;
00032             }
00033       }
00034 
00035 }
00036 
00037 // Destructor
00038 McnpData::~McnpData() {
00039 
00040       // Vertices and elements
00041       MCNP_vertices.clear();
00042 
00043 }
00044 
00045 
00046 // Setting and retrieving coordinate sysem
00047 MCNPError McnpData::set_coord_system(int k) {
00048       coord_system = k;
00049       return MCNP_SUCCESS;
00050 }
00051 int McnpData::get_coord_system() {
00052       return coord_system;
00053 }
00054 
00055 // Setting and retrieving roation matrix
00056 MCNPError McnpData::set_rotation_matrix(double r[16]) {
00057       for (int i = 0; i < 16; i++) {
00058             rotation_matrix[i] = r[i];
00059       }
00060       return MCNP_SUCCESS;
00061 }
00062 double* McnpData::get_rotation_matrix() {
00063       return rotation_matrix;
00064 }
00065 
00066 
00067 // Set the filename
00068 MCNPError McnpData::set_filename(std::string fname) {
00069       MCNP_filename = fname;
00070       return MCNP_SUCCESS;
00071 }
00072 std::string McnpData::get_filename() {
00073       return MCNP_filename;
00074 }
00075 
00076 
00077 // Reading the MCNP file
00078 MCNPError McnpData::read_mcnpfile(bool skip_mesh) {
00079 
00080       MCNPError result;
00081       moab::ErrorCode MBresult;
00082       moab::CartVect tvect;
00083 
00084       std::vector<double> xvec[3];
00085 
00086       // Open the file
00087       std::ifstream mcnpfile;
00088       mcnpfile.open( MCNP_filename.c_str() );
00089       if (!mcnpfile) {
00090             std::cout << "Unable to open MCNP data file." << std::endl;
00091             return MCNP_FAILURE;
00092       }
00093       std::cout << std::endl;
00094       std::cout << "Reading MCNP input file..." << std::endl;
00095 
00096       // Prepare for file reading ...
00097       char line[10000];  
00098       int mode = 0;         // Set the file reading mode to read proper data
00099       int nv[3];
00100 
00101       // Read in the file ...
00102       while (! mcnpfile.eof() ) {
00103 
00104             mcnpfile.getline(line, 10000);
00105             // std::cout << line << std::endl;
00106 
00107             switch(mode) {
00108             case 0:           // First line is a title
00109                   mode++;
00110             break;
00111             case 1:           // Coordinate system
00112                   mode++;
00113                   result = read_coord_system(line);
00114                   if (result == MCNP_FAILURE)
00115                         return MCNP_FAILURE;
00116             break;
00117             case 2:           // Rotation matrix
00118                   mode++;
00119                   for (int i = 0; i < 4; i++) {
00120                         mcnpfile.getline(line, 10000);
00121                         result = read_rotation_matrix(line, i);
00122                         if (result == MCNP_FAILURE)
00123                               return MCNP_FAILURE;
00124                   }
00125                   if (skip_mesh) return MCNP_SUCCESS;
00126             break;
00127             case 3:           // Read in vertices and build elements
00128                   mode++;
00129 
00130                   for (int i = 0; i < 3; i++) {
00131                         // How many points in the x[i]-direction
00132                         nv[i] = how_many_numbers(line);
00133                         if (nv[i] <= 0) return MCNP_FAILURE;
00134 
00135                         // Get space and read in these points
00136                         result = read_numbers(line , nv[i], xvec[i]);
00137                         if (result == MCNP_FAILURE) return MCNP_FAILURE;
00138 
00139                         // Update to the next line
00140                         mcnpfile.getline(line, 10000);
00141                   }
00142 
00143                   // Make the elements and vertices
00144                   result = make_elements(xvec, nv);
00145                   if (result == MCNP_FAILURE) return MCNP_FAILURE;
00146             break;
00147             case 4:           // Read in tally data, make, and tag elements
00148                   mode++;
00149                   moab::EntityHandle elemhandle;
00150 
00151                   moab::EntityHandle vstart, vijk;
00152                   moab::EntityHandle connect[8];
00153                   // double d[3];
00154 
00155                   // vstart = MCNP_vertices.front();
00156                   vstart = *(vert_handles.begin());
00157 
00158                       for (int i=0; i < nv[0]-1; i++) {
00159                     for (int j=0; j < nv[1]-1; j++) {
00160                   for (int k=0; k < nv[2]-1; k++) {
00161                         vijk = vstart + (i + j*nv[0] + k*nv[0]*nv[1]);
00162 
00163                         //std::cout << vijk << std::endl;                        
00164 
00165                         connect[0] = vijk;
00166                         connect[1] = vijk + 1;
00167                         connect[2] = vijk + 1 + nv[0];
00168                         connect[3] = vijk + nv[0];
00169                         connect[4] = vijk + nv[0]*nv[1];
00170                         connect[5] = vijk + 1 + nv[0]*nv[1];
00171                         connect[6] = vijk + 1 + nv[0] + nv[0]*nv[1];
00172                         connect[7] = vijk + nv[0] + nv[0]*nv[1];
00173 
00174                         MBresult = MBI->create_element(moab::MBHEX, connect, 8, elemhandle);
00175                         if (MBresult != moab::MB_SUCCESS) return MCNP_FAILURE;
00176                         elem_handles.insert(elemhandle);
00177 
00178                         mcnpfile.getline(line, 10000);
00179                         result = extract_tally_data(line, elemhandle);
00180                         if (result == MCNP_FAILURE) return MCNP_FAILURE;
00181 
00182                     }
00183                   }
00184                 }
00185 
00186 /*
00187                   for (MBRange::iterator rit=vert_handles.begin(); rit != vert_handles.end(); rit++) {
00188                         std::cout << *rit << std::endl; 
00189                   }
00190 
00191 
00192                   for (int i=0; i < nv[0]-1; i++) {
00193                     for (int j=0; j < nv[1]-1; j++) {
00194                       for (int k=0; k < nv[2]-1; k++) {
00195                         vijk = vstart + (i + j*nv[0] + k*nv[0]*nv[1]);
00196                         connect[0] = vijk;
00197                         connect[1] = vijk + 1;
00198                         connect[2] = vijk + 1 + nv[0];
00199                         connect[3] = vijk + nv[0];
00200                         connect[4] = vijk + nv[0]*nv[1];
00201                         connect[5] = vijk + 1 + nv[0]*nv[1];
00202                         connect[6] = vijk + 1 + nv[0] + nv[0]*nv[1];
00203                         connect[7] = vijk + nv[0] + nv[0]*nv[1];
00204 
00205                         MBresult = MBI->create_element(MBHEX, connect, 8, elemhandle);
00206                         if (MBresult != MB_SUCCESS) return MCNP_FAILURE;
00207                         elem_handles.insert(elemhandle);
00208 
00209                         mcnpfile.getline(line, 10000);
00210                         result = extract_tally_data(line, elemhandle);
00211                         if (result == MCNP_FAILURE) return MCNP_FAILURE;
00212 
00213                     }
00214                   }
00215                 }
00216 */
00217             break;
00218             case 5:           // Ckeck for weirdness at end of file
00219                   if (! mcnpfile.eof() ) return MCNP_FAILURE;
00220             break;
00221             }
00222 
00223       }
00224 
00225       std::cout <<  "SUCCESS! Read in " << elem_handles.size() 
00226                 << " elements!" << std::endl << std::endl;
00227       // MCNP_vertices.clear();
00228       vert_handles.clear();
00229       MCNP_elems.clear();
00230       return MCNP_SUCCESS;
00231 
00232 }
00233 
00234 MCNPError McnpData::read_coord_system(std::string s) {
00235 
00236       if ((s.find("Box") < 100) || (s.find("xyz") < 100))
00237             coord_system = CARTESIAN;     
00238       else if (s.find("Cyl") < 100)
00239             coord_system = CYLINDRICAL; 
00240       else if (s.find("Sph") < 100)
00241             coord_system = SPHERICAL; 
00242       else
00243             return MCNP_FAILURE;
00244 
00245       return MCNP_SUCCESS;
00246 }
00247 
00248 MCNPError McnpData::read_rotation_matrix(std::string s, int i) {
00249 
00250       int fpos = 0;
00251       MCNPError result;
00252 
00253       for (int j = 0; j < 4; j++) {
00254             result = next_number(s, rotation_matrix[4*i+j], fpos);
00255             if (result == MCNP_FAILURE) 
00256                   return MCNP_FAILURE;
00257       }
00258 
00259       return MCNP_SUCCESS;
00260 }
00261 
00262 MCNPError McnpData::make_elements(std::vector<double> x[3], int* n) {
00263 
00264       // double v[3];
00265       // MBEntityHandle dumhandle;
00266       // MBEntityHandle vstart, vijk;
00267       unsigned int num_verts = n[0]*n[1]*n[2];
00268       double       *coords;
00269       coords = new double [ 3 * num_verts ]; 
00270 
00271 /*
00272       // Enter the vertices ...
00273       for (int k=0; k < n[2]; k++) {
00274             v[2] = x[2].at(k);
00275             for (int j=0; j < n[1]; j++) {
00276                   v[1] = x[1].at(j);
00277                   for (int i=0; i < n[0]; i++) {
00278                         v[0] = x[0].at(i);
00279                         MBresult = MBI->create_vertex(v, dumhandle);
00280                         if (MBresult != MB_SUCCESS) return MCNP_FAILURE;
00281                         MCNP_vertices.push_back(dumhandle);
00282 
00283                   }
00284             }
00285       }
00286 */
00287 
00288       // Enter the vertices ...
00289       for (int k=0; k < n[2]; k++) {
00290             for (int j=0; j < n[1]; j++) {
00291                   for (int i=0; i < n[0]; i++) {
00292                         unsigned int ijk = 3*(k*n[0]*n[1] + j*n[0] + i);
00293                         coords[ ijk   ] = x[0][i];
00294                         coords[ ijk+1 ] = x[1][j];
00295                         coords[ ijk+2 ] = x[2][k];
00296 
00297                         // std::cout << coords[ijk] << " " << coords[ijk+1] << " "
00298                         //          << coords[ijk+2] << std::endl;
00299 
00300                         // MCNP_vertices.push_back(dumhandle);
00301                   }
00302             }
00303       }
00304 
00305       MBI->create_vertices(coords, num_verts, vert_handles);
00306       
00307 
00308       delete coords;
00309       return MCNP_SUCCESS;
00310 }
00311 
00312 MCNPError McnpData::initialize_tags() {
00313 
00314       MBI->tag_get_handle(TALLY_TAG, 1, moab::MB_TYPE_DOUBLE, tally_tag, moab::MB_TAG_DENSE|moab::MB_TAG_CREAT);
00315       MBI->tag_get_handle(ERROR_TAG, 1, moab::MB_TYPE_DOUBLE, relerr_tag, moab::MB_TAG_DENSE|moab::MB_TAG_CREAT);
00316 
00317       return MCNP_SUCCESS;
00318 
00319 }
00320 
00321 MCNPError McnpData::extract_tally_data(std::string s, moab::EntityHandle handle) {
00322 
00323       int fpos = 0;
00324       double d = 0;
00325 
00326       MCNPError result;
00327       moab::ErrorCode MBresult;
00328 
00329       // Discard first three lines
00330       for (int i = 0; i < 3; i++) {
00331             result = next_number(s, d, fpos);
00332             if (result == MCNP_FAILURE) return MCNP_FAILURE;           
00333       }
00334       // Need to read in tally entry and tag ...
00335       result = next_number(s, d, fpos);
00336       if (result == MCNP_FAILURE) return MCNP_FAILURE;
00337       MBresult = MBI -> tag_set_data(tally_tag, &handle, 1, &d);
00338       if (MBresult != moab::MB_SUCCESS) return MCNP_FAILURE; 
00339 
00340       // Need to read in relative error entry and tag ...
00341       result = next_number(s, d, fpos);
00342       if (result == MCNP_FAILURE) return MCNP_FAILURE;
00343       MBresult = MBI -> tag_set_data(relerr_tag, &handle, 1, &d);
00344       if (MBresult != moab::MB_SUCCESS) return MCNP_FAILURE; 
00345 
00346       return MCNP_SUCCESS;
00347 }
00348 
00349 MCNPError next_number(std::string s, double &d, int &p) {
00350 
00351       unsigned int slen = s.length();
00352       unsigned int j;
00353       std::string sn;
00354 
00355       for (unsigned int i = p; i < slen; i++) {
00356             if ( ( (s[i] >= 48) && (s[i] <= 57) ) || (s[i] == 45) ) {
00357 
00358                   j = s.find(" ",i);
00359 
00360                   if (j > slen)
00361                         j = slen;
00362 
00363                   // Extract the number out of the string
00364                   d = std::atof(s.substr(i,j-i).c_str());
00365                   p = j+1;
00366 
00367                   return MCNP_SUCCESS;
00368             }
00369 
00370       }   
00371 
00372       return DONE;
00373 }
00374 
00375 int how_many_numbers(std::string s) {
00376 
00377       int n = -1;
00378       int fpos = 0;
00379       double d = 0;
00380       MCNPError result = MCNP_SUCCESS;
00381 
00382       while (result != DONE) {
00383             result = next_number(s, d, fpos);
00384             n++;
00385       }
00386 
00387       return n;
00388 
00389 }
00390 
00391 MCNPError read_numbers(std::string s, int n, std::vector<double> &x) {
00392 
00393       MCNPError result;
00394       int fpos = 0;
00395       double d;
00396 
00397       for (int i = 0; i < n; i++) {
00398             result = next_number(s, d, fpos);
00399             if (result == MCNP_FAILURE) return MCNP_FAILURE;
00400             x.push_back(d);
00401       }
00402 
00403       return MCNP_SUCCESS;
00404 }
00405 
00406 MCNPError McnpData::transform_point(double *p, double *r, int csys, double *rmat) {
00407 
00408       double q[3];
00409 
00410       // Apply the rotation matrix
00411       for (unsigned int i=0; i < 3; i++) {
00412         q[i] =  p[0] * rmat[4*i  ] + p[1] * rmat[4*i+1]
00413               + p[2] * rmat[4*i+2] +        rmat[4*i+3];
00414       }
00415 
00416       // Transform coordinate system
00417       switch( csys ) {
00418         case CARTESIAN :
00419           r[0] = q[0]; r[1] = q[1]; r[2] = q[2];  // x, y, z
00420         break;
00421         case CYLINDRICAL :
00422           r[0] = sqrt( q[0]*q[0] + q[1]*q[1] );   // r
00423           r[1] = q[2];                            // z
00424           r[2] = c2pi * ( atan2( q[1], q[0] ) );  // theta (in rotations)
00425         break;
00426         case SPHERICAL :
00427           return MCNP_FAILURE;
00428         break;
00429         default :
00430           return MCNP_FAILURE;
00431         break;
00432       }
00433 
00434       return MCNP_SUCCESS;
00435 
00436 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines