Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #include <iostream> 00002 #include <cmath> 00003 00004 #include "moab/Core.hpp" 00005 #include "moab/Interface.hpp" 00006 #include "moab/IntxMesh/Intx2MeshOnSphere.hpp" 00007 #include "moab/ParallelComm.hpp" 00008 #include "moab/ProgOptions.hpp" 00009 #include "MBParallelConventions.h" 00010 #include "moab/ReadUtilIface.hpp" 00011 #include "MBTagConventions.hpp" 00012 00013 #include "moab/IntxMesh/IntxUtils.hpp" 00014 #include "IntxUtilsCSLAM.hpp" 00015 00016 #include "TestUtil.hpp" 00017 00018 // std::string file_name("./uniform_15.g"); 00019 // std::string file_name("./eulerHomme.vtk"); 00020 00021 using namespace moab; 00022 00023 // computes cell barycenters in Cartesian X,Y,Z coordinates 00024 void get_barycenters( moab::Interface* mb, moab::EntityHandle set, moab::Tag& planeTag, moab::Tag& barycenterTag ); 00025 00026 // computes gnomonic plane for each cell of the Eulerian mesh 00027 void get_gnomonic_plane( moab::Interface* mb, moab::EntityHandle set, moab::Tag& planeTag ); 00028 00029 // computes coefficients (A,B,C) for linear reconstruction in gnomonic coordinates: rho(x,y) = Ax + 00030 // By + C 00031 void get_linear_reconstruction( moab::Interface* mb, 00032 moab::EntityHandle set, 00033 moab::Tag& rhoTag, 00034 moab::Tag& planeTag, 00035 moab::Tag& barycenterTag, 00036 moab::Tag& linearCoefTag ); 00037 00038 // evaluates the integral of rho(x,y) over cell, should be equal to cell average rho 00039 void test_linear_reconstruction( moab::Interface* mb, 00040 moab::EntityHandle set, 00041 moab::Tag& rhoTag, 00042 moab::Tag& planeTag, 00043 moab::Tag& barycenterTag, 00044 moab::Tag& linearCoefTag ); 00045 00046 // set density function 00047 moab::ErrorCode add_field_value( moab::Interface* mb, 00048 moab::EntityHandle euler_set, 00049 int rank, 00050 moab::Tag& tagTracer, 00051 moab::Tag& tagElem, 00052 moab::Tag& tagArea, 00053 int field_type ); 00054 00055 // functions that implement gnomonic projection as in Homme (different from Moab implementation) 00056 int gnomonic_projection_test( const moab::CartVect& pos, double R, int plane, double& c1, double& c2 ); 00057 int reverse_gnomonic_projection_test( const double& c1, const double& c2, double R, int plane, moab::CartVect& pos ); 00058 void decide_gnomonic_plane_test( const CartVect& pos, int& plane ); 00059 00060 double radius = 1.; // in m: 6371220. 00061 00062 int main( int argc, char* argv[] ) 00063 { 00064 00065 // set up MOAB interface and parallel communication 00066 MPI_Init( &argc, &argv ); 00067 moab::Core moab; 00068 moab::Interface& mb = moab; 00069 moab::ParallelComm mb_pcomm( &mb, MPI_COMM_WORLD ); 00070 00071 // int rank = mb_pcomm->proc_config().proc_rank(); 00072 int rank = mb_pcomm.proc_config().proc_rank(); 00073 00074 // create meshset 00075 moab::EntityHandle euler_set; 00076 moab::ErrorCode rval = mb.create_meshset( MESHSET_SET, euler_set );CHECK_ERR( rval ); 00077 00078 // std::stringstream opts; 00079 // opts << 00080 // "PARALLEL=READ_PART;PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;GATHER_SET=0;PARTITION_METHOD=TRIVIAL_PARTITION;VARIABLE="; 00081 // opts << "PARALLEL=READ_PART;PARTITION;PARALLEL_RESOLVE_SHARED_ENTS"; 00082 std::string fileN = TestDir + "unittest/mbcslam/fine4.h5m"; 00083 00084 rval = mb.load_file( fileN.c_str(), &euler_set );CHECK_ERR( rval ); 00085 00086 // Create tag for cell density 00087 moab::Tag rhoTag = 0; 00088 rval = mb.tag_get_handle( "Density", 1, moab::MB_TYPE_DOUBLE, rhoTag, moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );CHECK_ERR( rval ); 00089 moab::Tag rhoNodeTag = 0; 00090 rval = mb.tag_get_handle( "DensityNode", 1, moab::MB_TYPE_DOUBLE, rhoNodeTag, 00091 moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );CHECK_ERR( rval ); 00092 // Create tag for cell area 00093 moab::Tag areaTag = 0; 00094 rval = mb.tag_get_handle( "Area", 1, moab::MB_TYPE_DOUBLE, areaTag, moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );CHECK_ERR( rval ); 00095 // Create tag for cell barycenters in 3D Cartesian space 00096 moab::Tag barycenterTag = 0; 00097 rval = mb.tag_get_handle( "CellBarycenter", 3, moab::MB_TYPE_DOUBLE, barycenterTag, 00098 moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );CHECK_ERR( rval ); 00099 // Create tag for cell density reconstruction coefficients 00100 moab::Tag coefRhoTag = 0; 00101 rval = mb.tag_get_handle( "LinearCoefRho", 3, moab::MB_TYPE_DOUBLE, coefRhoTag, 00102 moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );CHECK_ERR( rval ); 00103 // Create tag for index of gnomonic plane for each cell 00104 moab::Tag planeTag = 0; 00105 rval = mb.tag_get_handle( "gnomonicPlane", 1, moab::MB_TYPE_INTEGER, planeTag, 00106 moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );CHECK_ERR( rval ); 00107 // Set density distributions 00108 rval = add_field_value( &mb, euler_set, rank, rhoNodeTag, rhoTag, areaTag, 2 );CHECK_ERR( rval ); 00109 // get cell plane 00110 get_gnomonic_plane( &mb, euler_set, planeTag ); 00111 00112 // get cell barycenters 00113 get_barycenters( &mb, euler_set, planeTag, barycenterTag ); 00114 00115 // get linear reconstruction 00116 get_linear_reconstruction( &mb, euler_set, rhoTag, planeTag, barycenterTag, coefRhoTag ); 00117 00118 // test linear reconstruction 00119 test_linear_reconstruction( &mb, euler_set, rhoTag, planeTag, barycenterTag, coefRhoTag ); 00120 00121 MPI_Finalize(); 00122 return 0; 00123 } 00124 00125 void get_gnomonic_plane( moab::Interface* mb, moab::EntityHandle set, moab::Tag& planeTag ) 00126 { 00127 // get all entities of dimension 2 00128 // then get the connectivity, etc 00129 moab::Range cells; 00130 ErrorCode rval = mb->get_entities_by_dimension( set, 2, cells ); 00131 if( MB_SUCCESS != rval ) return; 00132 00133 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 00134 { 00135 moab::EntityHandle icell = *it; 00136 // get the nodes, then the coordinates 00137 const moab::EntityHandle* verts; 00138 int num_nodes; 00139 rval = mb->get_connectivity( icell, verts, num_nodes ); 00140 if( MB_SUCCESS != rval ) return; 00141 00142 std::vector< double > coords( 3 * num_nodes ); 00143 // get coordinates 00144 rval = mb->get_coords( verts, num_nodes, &coords[0] ); 00145 if( MB_SUCCESS != rval ) return; 00146 00147 double centerx = 0; 00148 double centery = 0; 00149 double centerz = 0; 00150 for( int inode = 0; inode < num_nodes; inode++ ) 00151 { 00152 centerx += coords[inode * 3] / num_nodes; 00153 centery += coords[inode * 3 + 1] / num_nodes; 00154 centerz += coords[inode * 3 + 2] / num_nodes; 00155 } 00156 double R = std::sqrt( centerx * centerx + centery * centery + centerz * centerz ); 00157 centerx = centerx / R; 00158 centery = centery / R; 00159 centerz = centerz / R; 00160 moab::CartVect center( centerx, centery, centerz ); 00161 R = 1.0; 00162 00163 int plane = 0; 00164 moab::IntxUtils::decide_gnomonic_plane( center, plane ); 00165 // decide_gnomonic_plane_test(center,plane); 00166 00167 rval = mb->tag_set_data( planeTag, &icell, 1, &plane );CHECK_ERR( rval ); 00168 } 00169 return; 00170 } 00171 00172 void get_barycenters( moab::Interface* mb, moab::EntityHandle set, moab::Tag& planeTag, moab::Tag& barycenterTag ) 00173 { 00174 // get all entities of dimension 2 00175 moab::Range cells; 00176 ErrorCode rval = mb->get_entities_by_dimension( set, 2, cells ); 00177 if( MB_SUCCESS != rval ) return; 00178 00179 // set sphere radius to 1 00180 double R = 1.0; 00181 00182 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 00183 { 00184 moab::EntityHandle icell = *it; 00185 00186 // get the nodes 00187 const moab::EntityHandle* verts; 00188 int num_nodes; 00189 rval = mb->get_connectivity( icell, verts, num_nodes ); 00190 if( MB_SUCCESS != rval ) return; 00191 00192 // get coordinates 00193 std::vector< double > coords( 3 * num_nodes ); 00194 rval = mb->get_coords( verts, num_nodes, &coords[0] ); 00195 if( MB_SUCCESS != rval ) return; 00196 00197 // get plane for cell 00198 int plane = 0; 00199 rval = mb->tag_get_data( planeTag, &icell, 1, &plane ); 00200 if( MB_SUCCESS != rval ) return; 00201 std::vector< double > x( num_nodes ); 00202 std::vector< double > y( num_nodes ); 00203 double area = 0; 00204 double bary_x = 0; 00205 double bary_y = 0; 00206 for( int inode = 0; inode < num_nodes; inode++ ) 00207 { 00208 // radius should be 1.0, but divide by it just in case for now 00209 double rad = sqrt( coords[inode * 3] * coords[inode * 3] + coords[inode * 3 + 1] * coords[inode * 3 + 1] + 00210 coords[inode * 3 + 2] * coords[inode * 3 + 2] ); 00211 CartVect xyzcoord( coords[inode * 3] / rad, coords[inode * 3 + 1] / rad, coords[inode * 3 + 2] / rad ); 00212 moab::IntxUtils::gnomonic_projection( xyzcoord, R, plane, x[inode], y[inode] ); 00213 // int dum = gnomonic_projection_test(xyzcoord, R, plane, x[inode],y[inode]); 00214 } 00215 00216 for( int inode = 0; inode < num_nodes; inode++ ) 00217 { 00218 int inode2 = inode + 1; 00219 if( inode2 >= num_nodes ) inode2 = 0; 00220 double xmid = 0.5 * ( x[inode] + x[inode2] ); 00221 double ymid = 0.5 * ( y[inode] + y[inode2] ); 00222 double r1 = sqrt( 1 + x[inode] * x[inode] + y[inode] * y[inode] ); 00223 double rm = sqrt( 1 + xmid * xmid + ymid * ymid ); 00224 double r2 = sqrt( 1 + x[inode2] * x[inode2] + y[inode2] * y[inode2] ); 00225 double hx = x[inode2] - x[inode]; 00226 00227 area += hx * 00228 ( y[inode] / ( r1 * ( 1 + x[inode] * x[inode] ) ) + 4.0 * ymid / ( rm * ( 1 + xmid * xmid ) ) + 00229 y[inode2] / ( r2 * ( 1 + x[inode2] * x[inode2] ) ) ) / 00230 6.0; 00231 00232 bary_x += hx * 00233 ( x[inode] * y[inode] / ( r1 * ( 1 + x[inode] * x[inode] ) ) + 00234 4.0 * xmid * ymid / ( rm * ( 1 + xmid * xmid ) ) + 00235 x[inode2] * y[inode2] / ( r2 * ( 1 + x[inode2] * x[inode2] ) ) ) / 00236 6.0; 00237 00238 bary_y += -hx * ( 1.0 / r1 + 4.0 / rm + 1.0 / r2 ) / 6.0; 00239 } 00240 00241 bary_x = bary_x / area; 00242 bary_y = bary_y / area; 00243 00244 moab::CartVect barycent; 00245 moab::IntxUtils::reverse_gnomonic_projection( bary_x, bary_y, R, plane, barycent ); 00246 // reverse_gnomonic_projection_test(bary_x, bary_y, R, plane, barycent); 00247 std::vector< double > barycenter( 3 ); 00248 barycenter[0] = barycent[0]; 00249 barycenter[1] = barycent[1]; 00250 barycenter[2] = barycent[2]; 00251 00252 rval = mb->tag_set_data( barycenterTag, &icell, 1, &barycenter[0] );CHECK_ERR( rval ); 00253 } 00254 return; 00255 } 00256 00257 void get_linear_reconstruction( moab::Interface* mb, 00258 moab::EntityHandle set, 00259 moab::Tag& rhoTag, 00260 moab::Tag& planeTag, 00261 moab::Tag& barycenterTag, 00262 moab::Tag& linearCoefTag ) 00263 { 00264 // get all entities of dimension 2 00265 Range cells; 00266 ErrorCode rval = mb->get_entities_by_dimension( set, 2, cells ); 00267 if( MB_SUCCESS != rval ) return; 00268 00269 // set sphere radius to 1 00270 double R = 1; 00271 00272 // Get coefficients of reconstruction (in cubed-sphere coordinates) 00273 // rho(x,y) = Ax + By + C 00274 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 00275 { 00276 moab::EntityHandle icell = *it; 00277 00278 // get the nodes, then the coordinates 00279 const moab::EntityHandle* verts; 00280 int num_nodes; 00281 rval = mb->get_connectivity( icell, verts, num_nodes ); 00282 if( MB_SUCCESS != rval ) return; 00283 00284 moab::Range adjacentEdges; 00285 rval = mb->get_adjacencies( &icell, 1, 1, true, adjacentEdges );CHECK_ERR( rval ); 00286 // int num_edges = adjacentEdges.size(); 00287 00288 // get adjacent cells from edges 00289 moab::Range adjacentCells; 00290 rval = mb->get_adjacencies( adjacentEdges, 2, true, adjacentCells, Interface::UNION ); 00291 if( MB_SUCCESS != rval ) return; 00292 // get plane for cell 00293 int plane = 0; 00294 rval = mb->tag_get_data( planeTag, &icell, 1, &plane );CHECK_ERR( rval ); 00295 00296 std::vector< double > dx( adjacentCells.size() - 1 ); 00297 std::vector< double > dy( adjacentCells.size() - 1 ); 00298 std::vector< double > dr( adjacentCells.size() - 1 ); 00299 double bary_x; 00300 double bary_y; 00301 00302 // get barycenter of cell where reconstruction occurs 00303 std::vector< double > barycent( 3 ); 00304 rval = mb->tag_get_data( barycenterTag, &icell, 1, &barycent[0] );CHECK_ERR( rval ); 00305 CartVect barycenter( barycent[0], barycent[1], barycent[2] ); 00306 double cellbaryx = 0; 00307 double cellbaryy = 0; 00308 moab::IntxUtils::gnomonic_projection( barycenter, R, plane, cellbaryx, cellbaryy ); 00309 // int rc = gnomonic_projection_test(barycenter, R, plane, cellbaryx, cellbaryy); 00310 00311 // get density value 00312 double rhocell = 0; 00313 rval = mb->tag_get_data( rhoTag, &icell, 1, &rhocell );CHECK_ERR( rval ); 00314 00315 // get barycenters of surrounding cells 00316 std::vector< double > cell_barys( 3 * adjacentCells.size() ); 00317 rval = mb->tag_get_data( barycenterTag, adjacentCells, &cell_barys[0] );CHECK_ERR( rval ); 00318 00319 // get density of surrounding cells 00320 std::vector< double > rho_vals( adjacentCells.size() ); 00321 rval = mb->tag_get_data( rhoTag, adjacentCells, &rho_vals[0] );CHECK_ERR( rval ); 00322 00323 std::size_t jind = 0; 00324 for( std::size_t i = 0; i < adjacentCells.size(); i++ ) 00325 { 00326 00327 if( adjacentCells[i] != icell ) 00328 { 00329 CartVect bary_xyz( cell_barys[i * 3], cell_barys[i * 3 + 1], cell_barys[i * 3 + 2] ); 00330 moab::IntxUtils::gnomonic_projection( bary_xyz, R, plane, bary_x, bary_y ); 00331 // rc = gnomonic_projection_test(bary_xyz, R, plane, bary_x, bary_y); 00332 00333 dx[jind] = bary_x - cellbaryx; 00334 dy[jind] = bary_y - cellbaryy; 00335 dr[jind] = rho_vals[i] - rhocell; 00336 00337 jind++; 00338 } 00339 } 00340 00341 std::vector< double > linearCoef( 3 ); 00342 if( adjacentCells.size() == 5 ) 00343 { 00344 00345 // compute normal equations matrix 00346 double N11 = dx[1] * dx[1] + dx[2] * dx[2] + dx[3] * dx[3] + dx[0] * dx[0]; 00347 double N22 = dy[1] * dy[1] + dy[2] * dy[2] + dy[3] * dy[3] + dy[0] * dy[0]; 00348 double N12 = dx[1] * dy[1] + dx[2] * dy[2] + dx[3] * dy[3] + dx[0] * dy[0]; 00349 00350 // rhs 00351 double Rx = dx[1] * dr[1] + dx[2] * dr[2] + dx[3] * dr[3] + dx[0] * dr[0]; 00352 double Ry = dy[1] * dr[1] + dy[2] * dr[2] + dy[3] * dr[3] + dy[0] * dr[0]; 00353 00354 // determinant 00355 double Det = N11 * N22 - N12 * N12; 00356 00357 // solution 00358 linearCoef[0] = ( Rx * N22 - Ry * N12 ) / Det; 00359 linearCoef[1] = ( Ry * N11 - Rx * N12 ) / Det; 00360 linearCoef[2] = rhocell - linearCoef[0] * cellbaryx - linearCoef[1] * cellbaryy; 00361 } 00362 else 00363 { 00364 // default to first order 00365 linearCoef[0] = 0.0; 00366 linearCoef[1] = 0.0; 00367 linearCoef[2] = rhocell; 00368 std::cout << "Need 4 adjacent cells for linear reconstruction! \n"; 00369 } 00370 00371 rval = mb->tag_set_data( linearCoefTag, &icell, 1, &linearCoef[0] );CHECK_ERR( rval ); 00372 } 00373 return; 00374 } 00375 00376 void test_linear_reconstruction( moab::Interface* mb, 00377 moab::EntityHandle set, 00378 moab::Tag& rhoTag, 00379 moab::Tag& planeTag, 00380 moab::Tag& barycenterTag, 00381 moab::Tag& linearCoefTag ) 00382 { 00383 // get all entities of dimension 2 00384 Range cells; 00385 ErrorCode rval = mb->get_entities_by_dimension( set, 2, cells ); 00386 if( MB_SUCCESS != rval ) return; 00387 00388 // set sphere radius to 1 00389 double R = 1; 00390 00391 // For get coefficients for reconstruction (in cubed-sphere coordinates) 00392 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 00393 { 00394 moab::EntityHandle icell = *it; 00395 00396 // get the nodes, then the coordinates 00397 const moab::EntityHandle* verts; 00398 int num_nodes; 00399 rval = mb->get_connectivity( icell, verts, num_nodes ); 00400 if( MB_SUCCESS != rval ) return; 00401 00402 // get coordinates 00403 std::vector< double > coords( 3 * num_nodes ); 00404 rval = mb->get_coords( verts, num_nodes, &coords[0] ); 00405 if( MB_SUCCESS != rval ) return; 00406 00407 // get plane for cell 00408 int plane = 0; 00409 rval = mb->tag_get_data( planeTag, &icell, 1, &plane );CHECK_ERR( rval ); 00410 00411 // get vertex coordinates projections 00412 std::vector< double > x( num_nodes ); 00413 std::vector< double > y( num_nodes ); 00414 for( int inode = 0; inode < num_nodes; inode++ ) 00415 { 00416 double rad = sqrt( coords[inode * 3] * coords[inode * 3] + coords[inode * 3 + 1] * coords[inode * 3 + 1] + 00417 coords[inode * 3 + 2] * coords[inode * 3 + 2] ); 00418 CartVect xyzcoord( coords[inode * 3] / rad, coords[inode * 3 + 1] / rad, coords[inode * 3 + 2] / rad ); 00419 moab::IntxUtils::gnomonic_projection( xyzcoord, R, plane, x[inode], y[inode] ); 00420 // int dum = gnomonic_projection_test(xyzcoord, R, plane, x[inode],y[inode]); 00421 } 00422 00423 double area = 0; 00424 double int_x = 0; 00425 double int_y = 0; 00426 for( int inode = 0; inode < num_nodes; inode++ ) 00427 { 00428 int inode2 = inode + 1; 00429 if( inode2 >= num_nodes ) inode2 = 0; 00430 double xmid = 0.5 * ( x[inode] + x[inode2] ); 00431 double ymid = 0.5 * ( y[inode] + y[inode2] ); 00432 double r1 = sqrt( 1 + x[inode] * x[inode] + y[inode] * y[inode] ); 00433 double rm = sqrt( 1 + xmid * xmid + ymid * ymid ); 00434 double r2 = sqrt( 1 + x[inode2] * x[inode2] + y[inode2] * y[inode2] ); 00435 double hx = x[inode2] - x[inode]; 00436 00437 area += hx * 00438 ( y[inode] / ( r1 * ( 1 + x[inode] * x[inode] ) ) + 4.0 * ymid / ( rm * ( 1 + xmid * xmid ) ) + 00439 y[inode2] / ( r2 * ( 1 + x[inode2] * x[inode2] ) ) ) / 00440 6.0; 00441 00442 int_x += hx * 00443 ( x[inode] * y[inode] / ( r1 * ( 1 + x[inode] * x[inode] ) ) + 00444 4.0 * xmid * ymid / ( rm * ( 1 + xmid * xmid ) ) + 00445 x[inode2] * y[inode2] / ( r2 * ( 1 + x[inode2] * x[inode2] ) ) ) / 00446 6.0; 00447 00448 int_y += -hx * ( 1.0 / r1 + 4.0 / rm + 1.0 / r2 ) / 6.0; 00449 } 00450 00451 // get linear coeficients 00452 std::vector< double > rho_coefs( 3 ); 00453 rval = mb->tag_get_data( linearCoefTag, &icell, 1, &rho_coefs[0] );CHECK_ERR( rval ); 00454 00455 // get barycenters 00456 std::vector< double > bary( 3 ); 00457 rval = mb->tag_get_data( barycenterTag, &icell, 1, &bary[0] );CHECK_ERR( rval ); 00458 double bary_x; 00459 double bary_y; 00460 CartVect bary_xyz( bary[0], bary[1], bary[2] ); 00461 moab::IntxUtils::gnomonic_projection( bary_xyz, R, plane, bary_x, bary_y ); 00462 // int rc = gnomonic_projection_test(bary_xyz, R, plane, bary_x, bary_y); 00463 00464 // get cell average density 00465 double cell_rho; 00466 rval = mb->tag_get_data( rhoTag, &icell, 1, &cell_rho );CHECK_ERR( rval ); 00467 00468 // ave rho = \int rho^h(x,y) dV / area = (\int (Ax + By + C) dV) / area 00469 double rho_test1 = ( rho_coefs[0] * int_x + rho_coefs[1] * int_y + rho_coefs[2] * area ) / area; 00470 00471 // ave rho = A*bary_x + B*bary_y + C 00472 double rho_test2 = rho_coefs[0] * bary_x + rho_coefs[1] * bary_y + rho_coefs[2]; 00473 00474 std::cout << cell_rho << " " << rho_test1 << " " << rho_test2 << " " << cell_rho - rho_test1 << "\n"; 00475 } 00476 return; 00477 } 00478 00479 int reverse_gnomonic_projection_test( const double& c1, const double& c2, double R, int plane, CartVect& pos ) 00480 { 00481 00482 double x = c1; 00483 double y = c2; 00484 double r = sqrt( 1.0 + x * x + y * y ); 00485 00486 switch( plane ) 00487 { 00488 00489 case 1: { 00490 pos[0] = R / r * R; 00491 pos[1] = R / r * x; 00492 pos[2] = R / r * y; 00493 break; 00494 } 00495 case 2: { 00496 pos[0] = -R / r * x; 00497 pos[1] = R / r * R; 00498 pos[2] = R / r * y; 00499 break; 00500 } 00501 case 3: { 00502 pos[0] = -R / r * R; 00503 pos[1] = -R / r * x; 00504 pos[2] = R / r * y; 00505 break; 00506 } 00507 case 4: { 00508 pos[0] = R / r * x; 00509 pos[1] = -R / r * R; 00510 pos[2] = R / r * y; 00511 break; 00512 } 00513 case 5: { 00514 pos[0] = R / r * y; 00515 pos[1] = R / r * x; 00516 pos[2] = -R / r * R; 00517 break; 00518 } 00519 case 6: { 00520 pos[0] = -R / r * y; 00521 pos[1] = R / r * x; 00522 pos[2] = R / r * R; 00523 break; 00524 } 00525 } 00526 00527 return 0; // no error 00528 } 00529 00530 void decide_gnomonic_plane_test( const CartVect& pos, int& plane ) 00531 { 00532 00533 // This is from early version of Homme vorticity calculation in parvis 00534 // Poles are reversed from Homme and Iulian version. 00535 00536 // Now has been changed for consistency 00537 00538 double X = pos[0]; 00539 double Y = pos[1]; 00540 double Z = pos[2]; 00541 double R = sqrt( X * X + Y * Y + Z * Z ); 00542 X = X / R; 00543 Y = Y / R; 00544 Z = Z / R; 00545 00546 if( ( Y < X ) & ( Y > -X ) ) 00547 { 00548 if( Z > X ) 00549 { 00550 plane = 6; 00551 } 00552 else if( Z < -X ) 00553 { 00554 plane = 5; 00555 } 00556 else 00557 { 00558 plane = 1; 00559 } 00560 } 00561 else if( ( Y > X ) & ( Y < -X ) ) 00562 { 00563 if( Z > -X ) 00564 { 00565 plane = 6; 00566 } 00567 else if( Z < X ) 00568 { 00569 plane = 5; 00570 } 00571 else 00572 { 00573 plane = 3; 00574 } 00575 } 00576 else if( ( Y > X ) & ( Y > -X ) ) 00577 { 00578 if( Z > Y ) 00579 { 00580 plane = 6; 00581 } 00582 else if( Z < -Y ) 00583 { 00584 plane = 5; 00585 } 00586 else 00587 { 00588 plane = 2; 00589 } 00590 } 00591 else if( ( Y < X ) & ( Y < -X ) ) 00592 { 00593 if( Z > -Y ) 00594 { 00595 plane = 6; 00596 } 00597 else if( Z < Y ) 00598 { 00599 plane = 5; 00600 } 00601 else 00602 { 00603 plane = 4; 00604 } 00605 } 00606 else 00607 { 00608 if( fabs( X ) < Z ) 00609 { 00610 plane = 6; 00611 } 00612 else if( Z < -fabs( X ) ) 00613 { 00614 plane = 5; 00615 } 00616 else if( ( X > 0 ) & ( Y > 0 ) ) 00617 { 00618 plane = 1; 00619 } 00620 else if( ( X < 0 ) & ( Y > 0 ) ) 00621 { 00622 plane = 2; 00623 } 00624 else if( ( X < 0 ) & ( Y < 0 ) ) 00625 { 00626 plane = 3; 00627 } 00628 else 00629 { 00630 plane = 4; 00631 } 00632 } 00633 00634 return; 00635 } 00636 00637 moab::ErrorCode add_field_value( moab::Interface* mb, 00638 moab::EntityHandle euler_set, 00639 int /*rank*/, 00640 moab::Tag& tagTracer, 00641 moab::Tag& tagElem, 00642 moab::Tag& tagArea, 00643 int field_type ) 00644 { 00645 00646 /* 00647 * get all plys first, then vertices, then move them on the surface of the sphere 00648 * radius is 1., most of the time 00649 * 00650 */ 00651 moab::Range polygons; 00652 moab::ErrorCode rval = mb->get_entities_by_dimension( euler_set, 2, polygons ); 00653 if( MB_SUCCESS != rval ) return rval; 00654 00655 moab::Range connecVerts; 00656 rval = mb->get_connectivity( polygons, connecVerts ); 00657 if( MB_SUCCESS != rval ) return rval; 00658 00659 void* data; // pointer to the LOC in memory, for each vertex 00660 int count; 00661 00662 rval = mb->tag_iterate( tagTracer, connecVerts.begin(), connecVerts.end(), count, data );CHECK_ERR( rval ); 00663 // here we are checking contiguity 00664 assert( count == (int)connecVerts.size() ); 00665 double* ptr_DP = (double*)data; 00666 // lambda is for longitude, theta for latitude 00667 // param will be: (la1, te1), (la2, te2), b, c; hmax=1, r=1/2 00668 // nondivergent flow, page 5, case 1, (la1, te1) = (M_PI, M_PI/3) 00669 // (la2, te2) = (M_PI, -M_PI/3) 00670 // la1, te1 la2 te2 b c hmax r 00671 if( field_type == 1 ) // quasi smooth 00672 { 00673 double params[] = { 5 * M_PI / 6.0, 0.0, 7 * M_PI / 6, 0.0, 0.1, 0.9, 1., 0.5 }; 00674 for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit ) 00675 { 00676 moab::EntityHandle oldV = *vit; 00677 moab::CartVect posi; 00678 rval = mb->get_coords( &oldV, 1, &( posi[0] ) );CHECK_ERR( rval ); 00679 00680 moab::IntxUtils::SphereCoords sphCoord = moab::IntxUtils::cart_to_spherical( posi ); 00681 00682 ptr_DP[0] = IntxUtilsCSLAM::quasi_smooth_field( sphCoord.lon, sphCoord.lat, params ); 00683 00684 ptr_DP++; // increment to the next node 00685 } 00686 } 00687 else if( 2 == field_type ) // smooth 00688 { 00689 moab::CartVect p1, p2; 00690 moab::IntxUtils::SphereCoords spr; 00691 spr.R = 1; 00692 spr.lat = M_PI / 3; 00693 spr.lon = M_PI; 00694 p1 = moab::IntxUtils::spherical_to_cart( spr ); 00695 spr.lat = -M_PI / 3; 00696 p2 = moab::IntxUtils::spherical_to_cart( spr ); 00697 // x1, y1, z1, x2, y2, z2, h_max, b0 00698 double params[] = { p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], 1, 5. }; 00699 for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit ) 00700 { 00701 moab::EntityHandle oldV = *vit; 00702 moab::CartVect posi; 00703 rval = mb->get_coords( &oldV, 1, &( posi[0] ) );CHECK_ERR( rval ); 00704 00705 moab::IntxUtils::SphereCoords sphCoord = moab::IntxUtils::cart_to_spherical( posi ); 00706 00707 ptr_DP[0] = IntxUtilsCSLAM::smooth_field( sphCoord.lon, sphCoord.lat, params ); 00708 00709 ptr_DP++; // increment to the next node 00710 } 00711 } 00712 else if( 3 == field_type ) // slotted 00713 { 00714 // la1, te1, la2, te2, b, c, r 00715 double params[] = { M_PI, M_PI / 3, M_PI, -M_PI / 3, 0.1, 0.9, 0.5 }; // no h_max 00716 for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit ) 00717 { 00718 moab::EntityHandle oldV = *vit; 00719 moab::CartVect posi; 00720 rval = mb->get_coords( &oldV, 1, &( posi[0] ) );CHECK_ERR( rval ); 00721 00722 moab::IntxUtils::SphereCoords sphCoord = moab::IntxUtils::cart_to_spherical( posi ); 00723 00724 ptr_DP[0] = IntxUtilsCSLAM::slotted_cylinder_field( sphCoord.lon, sphCoord.lat, params ); 00725 ; 00726 00727 ptr_DP++; // increment to the next node 00728 } 00729 } 00730 else if( 4 == field_type ) // constant = 1 00731 { 00732 for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit ) 00733 { 00734 /* moab::EntityHandle oldV = *vit; 00735 moab::CartVect posi; 00736 rval = mb->get_coords(&oldV, 1, &(posi[0])); 00737 00738 moab::IntxUtils::SphereCoords sphCoord = moab::IntxUtils::cart_to_spherical(posi);*/ 00739 00740 ptr_DP[0] = 1.0; 00741 00742 ptr_DP++; // increment to the next node 00743 } 00744 } 00745 // add average value for quad/polygon (average corners) 00746 // do some averages 00747 00748 Range::iterator iter = polygons.begin(); 00749 while( iter != polygons.end() ) 00750 { 00751 rval = mb->tag_iterate( tagElem, iter, polygons.end(), count, data );CHECK_ERR( rval ); 00752 double* ptr = (double*)data; 00753 00754 rval = mb->tag_iterate( tagArea, iter, polygons.end(), count, data );CHECK_ERR( rval ); 00755 double* ptrArea = (double*)data; 00756 for( int i = 0; i < count; i++, ++iter, ptr++, ptrArea++ ) 00757 { 00758 const moab::EntityHandle* conn = NULL; 00759 int num_nodes = 0; 00760 rval = mb->get_connectivity( *iter, conn, num_nodes );CHECK_ERR( rval ); 00761 if( num_nodes == 0 ) return MB_FAILURE; 00762 std::vector< double > nodeVals( num_nodes ); 00763 double average = 0.; 00764 rval = mb->tag_get_data( tagTracer, conn, num_nodes, &nodeVals[0] );CHECK_ERR( rval ); 00765 for( int j = 0; j < num_nodes; j++ ) 00766 average += nodeVals[j]; 00767 average /= num_nodes; 00768 *ptr = average; 00769 } 00770 } 00771 00772 return MB_SUCCESS; 00773 }