moab
|
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 }