Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #include <iostream> 00002 #include <sstream> 00003 #include <ctime> 00004 #include <cstdlib> 00005 #include <string> 00006 #include <cmath> 00007 #include "moab/Core.hpp" 00008 #include "moab/Interface.hpp" 00009 #include "moab/IntxMesh/Intx2MeshOnSphere.hpp" 00010 #include "moab/ParallelComm.hpp" 00011 #include "moab/ProgOptions.hpp" 00012 #include "MBParallelConventions.h" 00013 #include "moab/ReadUtilIface.hpp" 00014 #include "MBTagConventions.hpp" 00015 #include "IntxUtilsCSLAM.hpp" 00016 00017 #include "TestUtil.hpp" 00018 00019 // std::string file_name("./uniform_30.g"); 00020 // std::string file_name("./uniform_120.g"); 00021 // std::string file_name("./eulerHomme.vtk"); 00022 00023 using namespace moab; 00024 00025 moab::ErrorCode update_density( moab::Interface* mb, 00026 moab::EntityHandle euler_set, 00027 moab::EntityHandle lagr_set, 00028 moab::EntityHandle out_set, 00029 moab::Tag& rhoTag, 00030 moab::Tag& areaTag, 00031 moab::Tag& rhoCoefsTag, 00032 moab::Tag& weightsTag, 00033 moab::Tag& planeTag ); 00034 00035 moab::ErrorCode get_departure_grid( moab::Interface* mb, 00036 moab::EntityHandle euler_set, 00037 moab::EntityHandle lagr_set, 00038 moab::EntityHandle covering_set, 00039 int tStep, 00040 moab::Range& connecVerts ); 00041 00042 moab::ErrorCode get_barycenters( moab::Interface* mb, 00043 moab::EntityHandle set, 00044 moab::Tag& planeTag, 00045 moab::Tag& barycenterTag, 00046 moab::Tag& areaTag ); 00047 moab::ErrorCode get_gnomonic_plane( moab::Interface* mb, moab::EntityHandle set, moab::Tag& planeTag ); 00048 moab::ErrorCode get_linear_reconstruction( moab::Interface* mb, 00049 moab::EntityHandle set, 00050 moab::Tag& rhoTag, 00051 moab::Tag& planeTag, 00052 moab::Tag& barycenterTag, 00053 moab::Tag& linearCoefTag ); 00054 moab::ErrorCode get_intersection_weights( moab::Interface* mb, 00055 moab::EntityHandle euler_set, 00056 moab::EntityHandle lagr_set, 00057 moab::EntityHandle intx_set, 00058 moab::Tag& planeTag, 00059 moab::Tag& weightsTag ); 00060 00061 moab::ErrorCode set_density( moab::Interface* mb, 00062 moab::EntityHandle euler_set, 00063 moab::Tag& barycenterTag, 00064 moab::Tag& rhoTag, 00065 int field_type ); 00066 00067 moab::ErrorCode create_lagr_mesh( moab::Interface* mb, moab::EntityHandle euler_set, moab::EntityHandle lagr_set ); 00068 00069 // functions to compute departure point locations 00070 void departure_point_swirl( moab::CartVect& arrival_point, double t, double delta_t, moab::CartVect& departure_point ); 00071 void departure_point_swirl_rot( moab::CartVect& arrival_point, 00072 double t, 00073 double delta_t, 00074 moab::CartVect& departure_point ); 00075 00076 double gtol = 1.e-9; // this is for geometry tolerance 00077 00078 double radius = 1.; 00079 00080 bool writeFiles = true; 00081 bool parallelWrite = false; 00082 bool velocity = false; 00083 00084 int numSteps = 200; // number of times with velocity displayed at points 00085 double T = 5; 00086 00087 Intx2MeshOnSphere* pworker = NULL; 00088 00089 int main( int argc, char* argv[] ) 00090 { 00091 00092 MPI_Init( &argc, &argv ); 00093 00094 // set up MOAB interface and parallel communication 00095 moab::Core moab; 00096 moab::Interface& mb = moab; 00097 moab::ParallelComm mb_pcomm( &mb, MPI_COMM_WORLD ); 00098 00099 // int rank = mb_pcomm->proc_config().proc_rank(); 00100 int rank = mb_pcomm.proc_config().proc_rank(); 00101 00102 // create meshset 00103 moab::EntityHandle euler_set; 00104 moab::ErrorCode rval = mb.create_meshset( MESHSET_SET, euler_set );MB_CHK_ERR( rval ); 00105 00106 // std::stringstream opts; 00107 // opts << 00108 // "PARALLEL=READ_PART;PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;GATHER_SET=0;PARTITION_METHOD=TRIVIAL_PARTITION;VARIABLE="; 00109 // opts << "PARALLEL=READ_PART;PARTITION;PARALLEL_RESOLVE_SHARED_ENTS"; 00110 // rval = mb.load_file(file_name.c_str(), &euler_set, opts.str().c_str()); 00111 std::string fileN = TestDir + "unittest/mbcslam/fine4.h5m"; 00112 00113 rval = mb.load_file( fileN.c_str(), &euler_set );MB_CHK_ERR( rval ); 00114 00115 // Create tag for cell density 00116 moab::Tag rhoTag = 0; 00117 rval = mb.tag_get_handle( "Density", 1, moab::MB_TYPE_DOUBLE, rhoTag, moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );MB_CHK_ERR( rval ); 00118 00119 // Create tag for cell area 00120 moab::Tag areaTag = 0; 00121 rval = mb.tag_get_handle( "Area", 1, moab::MB_TYPE_DOUBLE, areaTag, moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );MB_CHK_ERR( rval ); 00122 // Create tag for cell barycenters in 3D Cartesian space 00123 moab::Tag barycenterTag = 0; 00124 rval = mb.tag_get_handle( "CellBarycenter", 3, moab::MB_TYPE_DOUBLE, barycenterTag, 00125 moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );MB_CHK_ERR( rval ); 00126 // Create tag for cell density reconstruction coefficients 00127 moab::Tag rhoCoefTag = 0; 00128 rval = mb.tag_get_handle( "LinearCoefRho", 3, moab::MB_TYPE_DOUBLE, rhoCoefTag, 00129 moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );MB_CHK_ERR( rval ); 00130 // Create tag for index of gnomonic plane for each cell 00131 moab::Tag planeTag = 0; 00132 rval = mb.tag_get_handle( "gnomonicPlane", 1, moab::MB_TYPE_INTEGER, planeTag, 00133 moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );MB_CHK_ERR( rval ); 00134 // Create tag for intersection weights 00135 moab::Tag weightsTag = 0; 00136 rval = mb.tag_get_handle( "Weights", 3, moab::MB_TYPE_DOUBLE, weightsTag, moab::MB_TAG_CREAT | moab::MB_TAG_DENSE );MB_CHK_ERR( rval ); 00137 00138 // get cell plane 00139 rval = get_gnomonic_plane( &mb, euler_set, planeTag );MB_CHK_ERR( rval ); 00140 00141 // get cell barycenters (and cell area) 00142 rval = get_barycenters( &mb, euler_set, planeTag, areaTag, barycenterTag );MB_CHK_ERR( rval ); 00143 00144 // Set density distributions 00145 rval = set_density( &mb, euler_set, barycenterTag, rhoTag, 1 );MB_CHK_ERR( rval ); 00146 00147 // Get initial values for use in error computation 00148 moab::Range redEls; 00149 rval = mb.get_entities_by_dimension( euler_set, 2, redEls );MB_CHK_ERR( rval ); 00150 std::vector< double > iniValsRho( redEls.size() ); 00151 rval = mb.tag_get_data( rhoTag, redEls, &iniValsRho[0] );MB_CHK_ERR( rval ); 00152 00153 // Get Lagrangian set 00154 moab::EntityHandle out_set, lagrange_set, covering_set; 00155 rval = mb.create_meshset( MESHSET_SET, out_set );MB_CHK_ERR( rval ); 00156 rval = mb.create_meshset( MESHSET_SET, lagrange_set );MB_CHK_ERR( rval ); 00157 rval = mb.create_meshset( MESHSET_SET, covering_set );MB_CHK_ERR( rval ); 00158 // rval = create_lagr_mesh(&mb, euler_set, lagrange_set); 00159 rval = IntxUtilsCSLAM::deep_copy_set( &mb, euler_set, lagrange_set );MB_CHK_ERR( rval ); 00160 moab::EntityHandle dum = 0; 00161 moab::Tag corrTag; 00162 rval = mb.tag_get_handle( CORRTAGNAME, 1, MB_TYPE_HANDLE, corrTag, MB_TAG_DENSE | MB_TAG_CREAT, &dum );MB_CHK_ERR( rval ); 00163 // Set up intersection of two meshes 00164 00165 /* 00166 moab::Intx2MeshOnSphere worker(&mb); 00167 worker.SetRadius(radius); 00168 worker.SetErrorTolerance(gtol); 00169 */ 00170 00171 pworker = new Intx2MeshOnSphere( &mb ); 00172 pworker->set_error_tolerance( gtol ); 00173 pworker->set_radius_source_mesh( radius ); 00174 pworker->set_radius_destination_mesh( radius ); 00175 pworker->set_box_error( 100 * gtol ); 00176 00177 rval = pworker->FindMaxEdges( euler_set, euler_set );MB_CHK_ERR( rval ); 00178 00179 // these stay fixed for one run 00180 moab::Range local_verts; 00181 rval = pworker->build_processor_euler_boxes( euler_set, 00182 local_verts ); // output also the local_verts 00183 MB_CHK_ERR( rval ); 00184 // rval = worker.build_processor_euler_boxes(euler_set, local_verts);// output also the 00185 // local_verts 00186 00187 // loop over time to update density 00188 for( int ts = 1; ts < numSteps + 1; ts++ ) 00189 { 00190 00191 if( ts == 1 ) // output initial condition 00192 { 00193 std::stringstream newDensity; 00194 newDensity << "Density" << rank << "_" << ts - 1 << ".vtk"; 00195 rval = mb.write_file( newDensity.str().c_str(), 0, 0, &euler_set, 1 ); 00196 } 00197 00198 // get linear reconstruction coefficients 00199 get_linear_reconstruction( &mb, euler_set, rhoTag, planeTag, barycenterTag, rhoCoefTag ); 00200 00201 // get depature grid 00202 rval = get_departure_grid( &mb, euler_set, lagrange_set, covering_set, ts, local_verts );MB_CHK_ERR( rval ); 00203 00204 // intersect the meshes 00205 rval = pworker->intersect_meshes( lagrange_set, euler_set, out_set );MB_CHK_ERR( rval ); 00206 00207 // intersection weights (i.e. area, x integral, and y integral over cell intersections) 00208 get_intersection_weights( &mb, euler_set, lagrange_set, out_set, planeTag, weightsTag ); 00209 00210 // update the density 00211 rval = 00212 update_density( &mb, euler_set, lagrange_set, out_set, rhoTag, areaTag, rhoCoefTag, weightsTag, planeTag );MB_CHK_ERR( rval ); 00213 00214 if( writeFiles && ( ts % 5 == 0 ) ) // so if write 00215 { 00216 std::stringstream newDensity; 00217 newDensity << "Density" << rank << "_" << ts << ".vtk"; 00218 rval = mb.write_file( newDensity.str().c_str(), 0, 0, &euler_set, 1 );MB_CHK_ERR( rval ); 00219 } 00220 00221 // delete the polygons and elements of out_set 00222 moab::Range allVerts; 00223 rval = mb.get_entities_by_dimension( 0, 0, allVerts );MB_CHK_ERR( rval ); 00224 00225 moab::Range allElems; 00226 rval = mb.get_entities_by_dimension( 0, 2, allElems );MB_CHK_ERR( rval ); 00227 00228 // get Eulerian and lagrangian cells 00229 moab::Range polys; 00230 rval = mb.get_entities_by_dimension( euler_set, 2, polys );MB_CHK_ERR( rval ); 00231 rval = 00232 mb.get_entities_by_dimension( lagrange_set, 2, polys ); // do not delete lagr set either, with its vertices 00233 MB_CHK_ERR( rval ); 00234 00235 // add to the connecVerts range all verts, from all initial polys 00236 moab::Range vertsToStay; 00237 rval = mb.get_connectivity( polys, vertsToStay );MB_CHK_ERR( rval ); 00238 00239 moab::Range todeleteVerts = subtract( allVerts, vertsToStay ); 00240 00241 moab::Range todeleteElem = subtract( allElems, polys ); 00242 // empty the out mesh set 00243 rval = mb.clear_meshset( &out_set, 1 );MB_CHK_ERR( rval ); 00244 00245 rval = mb.delete_entities( todeleteElem );MB_CHK_ERR( rval ); 00246 rval = mb.delete_entities( todeleteVerts );MB_CHK_ERR( rval ); 00247 if( rank == 0 ) std::cout << " step: " << ts << "\n"; 00248 } 00249 00250 // final vals and errors 00251 moab::Range::iterator iter = redEls.begin(); 00252 double norm1 = 0.; 00253 double norm2 = 0.; 00254 double exact2 = 0.; 00255 double exact1 = 0.; 00256 int count = 0; 00257 void* data; 00258 int j = 0; // index in iniVals 00259 while( iter != redEls.end() ) 00260 { 00261 rval = mb.tag_iterate( rhoTag, iter, redEls.end(), count, data );MB_CHK_ERR( rval ); 00262 double* ptrTracer = (double*)data; 00263 00264 rval = mb.tag_iterate( areaTag, iter, redEls.end(), count, data );MB_CHK_ERR( rval ); 00265 double* ptrArea = (double*)data; 00266 for( int i = 0; i < count; i++, ++iter, ptrTracer++, ptrArea++, j++ ) 00267 { 00268 // double area = *ptrArea; 00269 norm1 += fabs( *ptrTracer - iniValsRho[j] ) * ( *ptrArea ); 00270 norm2 += ( *ptrTracer - iniValsRho[j] ) * ( *ptrTracer - iniValsRho[j] ) * ( *ptrArea ); 00271 exact1 += ( iniValsRho[j] ) * ( *ptrArea ); 00272 exact2 += ( iniValsRho[j] ) * ( iniValsRho[j] ) * ( *ptrArea ); 00273 } 00274 } 00275 00276 double total_norm1 = 0; 00277 double total_norm2 = 0; 00278 double total_exact1 = 0; 00279 double total_exact2 = 0; 00280 int mpi_err = MPI_Reduce( &norm1, &total_norm1, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD ); 00281 if( mpi_err ) std::cout << " error in MPI_reduce:" << mpi_err << "\n"; 00282 mpi_err = MPI_Reduce( &norm2, &total_norm2, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD ); 00283 if( mpi_err ) std::cout << " error in MPI_reduce:" << mpi_err << "\n"; 00284 mpi_err = MPI_Reduce( &exact1, &total_exact1, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD ); 00285 if( mpi_err ) std::cout << " error in MPI_reduce:" << mpi_err << "\n"; 00286 mpi_err = MPI_Reduce( &exact2, &total_exact2, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD ); 00287 if( mpi_err ) std::cout << " error in MPI_reduce:" << mpi_err << "\n"; 00288 if( 0 == rank ) 00289 std::cout << " numSteps:" << numSteps << " 1-norm:" << total_norm1 / total_exact1 00290 << " 2-norm:" << total_norm2 / total_exact2 << "\n"; 00291 00292 MPI_Finalize(); 00293 return 0; 00294 } 00295 00296 moab::ErrorCode get_gnomonic_plane( moab::Interface* mb, moab::EntityHandle set, moab::Tag& planeTag ) 00297 { 00298 // get all entities of dimension 2 00299 moab::Range cells; 00300 ErrorCode rval = mb->get_entities_by_dimension( set, 2, cells );MB_CHK_ERR( rval ); 00301 00302 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 00303 { 00304 moab::EntityHandle icell = *it; 00305 00306 // get the nodes 00307 const moab::EntityHandle* verts; 00308 int num_nodes; 00309 rval = mb->get_connectivity( icell, verts, num_nodes );MB_CHK_ERR( rval ); 00310 00311 // get coordinates 00312 std::vector< double > coords( 3 * num_nodes ); 00313 rval = mb->get_coords( verts, num_nodes, &coords[0] );MB_CHK_ERR( rval ); 00314 00315 // get cell center 00316 double centerx = 0; 00317 double centery = 0; 00318 double centerz = 0; 00319 for( int inode = 0; inode < num_nodes; inode++ ) 00320 { 00321 centerx += coords[inode * 3] / num_nodes; 00322 centery += coords[inode * 3 + 1] / num_nodes; 00323 centerz += coords[inode * 3 + 2] / num_nodes; 00324 } 00325 double rad = std::sqrt( centerx * centerx + centery * centery + centerz * centerz ); 00326 centerx = centerx / rad; 00327 centery = centery / rad; 00328 centerz = centerz / rad; 00329 moab::CartVect center( centerx, centery, centerz ); 00330 00331 // define gnomonic plane based on cell center coordinates 00332 int plane = 0; 00333 moab::IntxUtils::decide_gnomonic_plane( center, plane ); 00334 00335 rval = mb->tag_set_data( planeTag, &icell, 1, &plane );MB_CHK_ERR( rval ); 00336 } 00337 00338 return moab::MB_SUCCESS; 00339 } 00340 00341 moab::ErrorCode get_barycenters( moab::Interface* mb, 00342 moab::EntityHandle set, 00343 moab::Tag& planeTag, 00344 moab::Tag& areaTag, 00345 moab::Tag& barycenterTag ) 00346 { 00347 00348 // get all entities of dimension 2 00349 moab::Range cells; 00350 ErrorCode rval = mb->get_entities_by_dimension( set, 2, cells );MB_CHK_ERR( rval ); 00351 00352 // set sphere radius to 1 00353 double R = 1.0; 00354 00355 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 00356 { 00357 moab::EntityHandle icell = *it; 00358 00359 // get the nodes 00360 const moab::EntityHandle* verts; 00361 int num_nodes; 00362 rval = mb->get_connectivity( icell, verts, num_nodes );MB_CHK_ERR( rval ); 00363 00364 // get coordinates 00365 std::vector< double > coords( 3 * num_nodes ); 00366 rval = mb->get_coords( verts, num_nodes, &coords[0] );MB_CHK_ERR( rval ); 00367 00368 // get gnomonic plane 00369 int plane = 0; 00370 rval = mb->tag_get_data( planeTag, &icell, 1, &plane );MB_CHK_ERR( rval ); 00371 00372 // get vertex coordinates and project onto gnomonic plane 00373 std::vector< double > x( num_nodes ); 00374 std::vector< double > y( num_nodes ); 00375 double area = 0; 00376 double bary_x = 0; 00377 double bary_y = 0; 00378 for( int inode = 0; inode < num_nodes; inode++ ) 00379 { 00380 double rad = sqrt( coords[inode * 3] * coords[inode * 3] + coords[inode * 3 + 1] * coords[inode * 3 + 1] + 00381 coords[inode * 3 + 2] * coords[inode * 3 + 2] ); 00382 CartVect xyzcoord( coords[inode * 3] / rad, coords[inode * 3 + 1] / rad, coords[inode * 3 + 2] / rad ); 00383 moab::IntxUtils::gnomonic_projection( xyzcoord, R, plane, x[inode], y[inode] ); 00384 } 00385 00386 // integrate over cell to get barycenter in gnomonic coordinates 00387 for( int inode = 0; inode < num_nodes; inode++ ) 00388 { 00389 int inode2 = inode + 1; 00390 if( inode2 >= num_nodes ) inode2 = 0; 00391 double xmid = 0.5 * ( x[inode] + x[inode2] ); 00392 double ymid = 0.5 * ( y[inode] + y[inode2] ); 00393 double r1 = sqrt( 1 + x[inode] * x[inode] + y[inode] * y[inode] ); 00394 double rm = sqrt( 1 + xmid * xmid + ymid * ymid ); 00395 double r2 = sqrt( 1 + x[inode2] * x[inode2] + y[inode2] * y[inode2] ); 00396 double hx = x[inode2] - x[inode]; 00397 00398 area += -hx * 00399 ( y[inode] / ( r1 * ( 1 + x[inode] * x[inode] ) ) + 4.0 * ymid / ( rm * ( 1 + xmid * xmid ) ) + 00400 y[inode2] / ( r2 * ( 1 + x[inode2] * x[inode2] ) ) ) / 00401 6.0; 00402 00403 bary_x += -hx * 00404 ( x[inode] * y[inode] / ( r1 * ( 1 + x[inode] * x[inode] ) ) + 00405 4.0 * xmid * ymid / ( rm * ( 1 + xmid * xmid ) ) + 00406 x[inode2] * y[inode2] / ( r2 * ( 1 + x[inode2] * x[inode2] ) ) ) / 00407 6.0; 00408 00409 bary_y += hx * ( 1.0 / r1 + 4.0 / rm + 1.0 / r2 ) / 6.0; 00410 } 00411 bary_x = bary_x / area; 00412 bary_y = bary_y / area; 00413 00414 // barycenter in Cartesian X,Y,Z coordinates 00415 moab::CartVect barycent; 00416 moab::IntxUtils::reverse_gnomonic_projection( bary_x, bary_y, R, plane, barycent ); 00417 00418 // set barycenter 00419 std::vector< double > barycenter( 3 ); 00420 barycenter[0] = barycent[0]; 00421 barycenter[1] = barycent[1]; 00422 barycenter[2] = barycent[2]; 00423 rval = mb->tag_set_data( barycenterTag, &icell, 1, &barycenter[0] );MB_CHK_ERR( rval ); 00424 00425 // set area 00426 rval = mb->tag_set_data( areaTag, &icell, 1, &area );MB_CHK_ERR( rval ); 00427 } 00428 00429 return moab::MB_SUCCESS; 00430 } 00431 00432 moab::ErrorCode set_density( moab::Interface* mb, 00433 moab::EntityHandle euler_set, 00434 moab::Tag& barycenterTag, 00435 moab::Tag& rhoTag, 00436 int field_type ) 00437 { 00438 // get cells 00439 moab::Range cells; 00440 moab::ErrorCode rval = mb->get_entities_by_dimension( euler_set, 2, cells );MB_CHK_ERR( rval ); 00441 00442 // get barycenters 00443 std::vector< double > cell_barys( 3 * cells.size() ); 00444 rval = mb->tag_get_data( barycenterTag, cells, &cell_barys[0] );MB_CHK_ERR( rval ); 00445 00446 // loop over cells 00447 int cell_ind = 0; 00448 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 00449 { 00450 moab::EntityHandle icell = *it; 00451 00452 // convert barycenter from 3-D Cartesian to lat/lon 00453 moab::CartVect bary_xyz( cell_barys[cell_ind * 3], cell_barys[cell_ind * 3 + 1], cell_barys[cell_ind * 3 + 2] ); 00454 moab::IntxUtils::SphereCoords sphCoord = moab::IntxUtils::cart_to_spherical( bary_xyz ); 00455 00456 if( field_type == 1 ) // cosine bells 00457 { 00458 // lon1, lat1 lon2 lat2 b c hmax r 00459 double params[] = { 5 * M_PI / 6.0, 0.0, 7 * M_PI / 6, 0.0, 0.1, 0.9, 1., 0.5 }; 00460 00461 double rho_barycent = IntxUtilsCSLAM::quasi_smooth_field( sphCoord.lon, sphCoord.lat, params ); 00462 rval = mb->tag_set_data( rhoTag, &icell, 1, &rho_barycent );MB_CHK_ERR( rval ); 00463 } 00464 00465 if( field_type == 2 ) // Gaussian hills 00466 { 00467 moab::CartVect p1, p2; 00468 moab::IntxUtils::SphereCoords spr; 00469 spr.R = 1; 00470 spr.lat = M_PI / 3; 00471 spr.lon = M_PI; 00472 p1 = moab::IntxUtils::spherical_to_cart( spr ); 00473 spr.lat = -M_PI / 3; 00474 p2 = moab::IntxUtils::spherical_to_cart( spr ); 00475 // X1, Y1, Z1, X2, Y2, Z2, ?, ? 00476 double params[] = { p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], 1, 5. }; 00477 00478 double rho_barycent = IntxUtilsCSLAM::smooth_field( sphCoord.lon, sphCoord.lat, params ); 00479 rval = mb->tag_set_data( rhoTag, &icell, 1, &rho_barycent );MB_CHK_ERR( rval ); 00480 } 00481 00482 if( field_type == 3 ) // Zalesak cylinders 00483 { 00484 // lon1, lat1, lon2, lat2, b, c, r 00485 double params[] = { 5 * M_PI / 6.0, 0.0, 7 * M_PI / 6.0, 0.0, 0.1, 0.9, 0.5 }; 00486 00487 double rho_barycent = IntxUtilsCSLAM::slotted_cylinder_field( sphCoord.lon, sphCoord.lat, params ); 00488 rval = mb->tag_set_data( rhoTag, &icell, 1, &rho_barycent );MB_CHK_ERR( rval ); 00489 } 00490 00491 if( field_type == 4 ) // constant 00492 { 00493 double rho_barycent = 1.0; 00494 rval = mb->tag_set_data( rhoTag, &icell, 1, &rho_barycent );MB_CHK_ERR( rval ); 00495 } 00496 00497 cell_ind++; 00498 } 00499 00500 return moab::MB_SUCCESS; 00501 } 00502 00503 moab::ErrorCode get_linear_reconstruction( moab::Interface* mb, 00504 moab::EntityHandle set, 00505 moab::Tag& rhoTag, 00506 moab::Tag& planeTag, 00507 moab::Tag& barycenterTag, 00508 moab::Tag& linearCoefTag ) 00509 { 00510 // get all entities of dimension 2 00511 Range cells; 00512 ErrorCode rval = mb->get_entities_by_dimension( set, 2, cells );MB_CHK_ERR( rval ); 00513 00514 // Get coefficients for reconstruction (in cubed-sphere coordinates) 00515 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 00516 { 00517 moab::EntityHandle icell = *it; 00518 00519 // get the nodes, then the coordinates 00520 const moab::EntityHandle* verts; 00521 int num_nodes; 00522 rval = mb->get_connectivity( icell, verts, num_nodes );MB_CHK_ERR( rval ); 00523 00524 moab::Range adjacentEdges; 00525 rval = mb->get_adjacencies( &icell, 1, 1, true, adjacentEdges );MB_CHK_ERR( rval ); 00526 00527 // get adjacent cells from edges 00528 moab::Range adjacentCells; 00529 rval = mb->get_adjacencies( adjacentEdges, 2, true, adjacentCells, Interface::UNION );MB_CHK_ERR( rval ); 00530 00531 // get gnomonic plane 00532 int plane = 0; 00533 rval = mb->tag_get_data( planeTag, &icell, 1, &plane );MB_CHK_ERR( rval ); 00534 00535 std::vector< double > dx( adjacentCells.size() - 1 ); 00536 std::vector< double > dy( adjacentCells.size() - 1 ); 00537 std::vector< double > dr( adjacentCells.size() - 1 ); 00538 double bary_x; 00539 double bary_y; 00540 00541 // get barycenter of cell where reconstruction occurs 00542 double rad = 1; 00543 std::vector< double > barycent( 3 ); 00544 rval = mb->tag_get_data( barycenterTag, &icell, 1, &barycent[0] );MB_CHK_ERR( rval ); 00545 CartVect barycenter( barycent[0], barycent[1], barycent[2] ); 00546 double cellbaryx = 0; 00547 double cellbaryy = 0; 00548 moab::IntxUtils::gnomonic_projection( barycenter, rad, plane, cellbaryx, cellbaryy ); 00549 00550 // get density value 00551 double rhocell = 0; 00552 rval = mb->tag_get_data( rhoTag, &icell, 1, &rhocell );MB_CHK_ERR( rval ); 00553 00554 // get barycenters of surrounding cells 00555 std::vector< double > cell_barys( 3 * adjacentCells.size() ); 00556 rval = mb->tag_get_data( barycenterTag, adjacentCells, &cell_barys[0] );MB_CHK_ERR( rval ); 00557 00558 // get density of surrounding cells 00559 std::vector< double > rho_vals( adjacentCells.size() ); 00560 rval = mb->tag_get_data( rhoTag, adjacentCells, &rho_vals[0] );MB_CHK_ERR( rval ); 00561 00562 std::size_t jind = 0; 00563 for( std::size_t i = 0; i < adjacentCells.size(); i++ ) 00564 { 00565 00566 if( adjacentCells[i] != icell ) 00567 { 00568 00569 CartVect bary_xyz( cell_barys[i * 3], cell_barys[i * 3 + 1], cell_barys[i * 3 + 2] ); 00570 moab::IntxUtils::gnomonic_projection( bary_xyz, rad, plane, bary_x, bary_y ); 00571 00572 dx[jind] = bary_x - cellbaryx; 00573 dy[jind] = bary_y - cellbaryy; 00574 dr[jind] = rho_vals[i] - rhocell; 00575 00576 jind++; 00577 } 00578 } 00579 00580 std::vector< double > linearCoef( 3 ); 00581 if( adjacentCells.size() == 5 ) 00582 { 00583 00584 // compute normal equations matrix 00585 double N11 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2] + dx[3] * dx[3]; 00586 double N22 = dy[0] * dy[0] + dy[1] * dy[1] + dy[2] * dy[2] + dy[3] * dy[3]; 00587 double N12 = dx[0] * dy[0] + dx[1] * dy[1] + dx[2] * dy[2] + dx[3] * dy[3]; 00588 00589 // rhs 00590 double Rx = dx[0] * dr[0] + dx[1] * dr[1] + dx[2] * dr[2] + dx[3] * dr[3]; 00591 double Ry = dy[0] * dr[0] + dy[1] * dr[1] + dy[2] * dr[2] + dy[3] * dr[3]; 00592 00593 // determinant 00594 double Det = N11 * N22 - N12 * N12; 00595 00596 // solution 00597 linearCoef[0] = ( Rx * N22 - Ry * N12 ) / Det; 00598 linearCoef[1] = ( Ry * N11 - Rx * N12 ) / Det; 00599 linearCoef[2] = rhocell - linearCoef[0] * cellbaryx - linearCoef[1] * cellbaryy; 00600 } 00601 else 00602 { 00603 // default to first order 00604 linearCoef[0] = 0.0; 00605 linearCoef[1] = 0.0; 00606 linearCoef[2] = rhocell; 00607 std::cout << "Need 4 adjacent cells for linear reconstruction! \n"; 00608 } 00609 00610 rval = mb->tag_set_data( linearCoefTag, &icell, 1, &linearCoef[0] );MB_CHK_ERR( rval ); 00611 } 00612 00613 return moab::MB_SUCCESS; 00614 } 00615 00616 moab::ErrorCode get_departure_grid( moab::Interface* mb, 00617 moab::EntityHandle euler_set, 00618 moab::EntityHandle lagr_set, 00619 moab::EntityHandle covering_set, 00620 int tStep, 00621 Range& connecVerts ) 00622 { 00623 EntityHandle dum = 0; 00624 Tag corrTag; 00625 mb->tag_get_handle( CORRTAGNAME, 1, MB_TYPE_HANDLE, corrTag, MB_TAG_DENSE, &dum ); 00626 00627 double t = tStep * T / numSteps; // numSteps is global; so is T 00628 double delta_t = T / numSteps; // this is global too, actually 00629 // double delta_t = 0.0001; 00630 // double t = delta_t; 00631 00632 Range polys; 00633 ErrorCode rval = mb->get_entities_by_dimension( euler_set, 2, polys );MB_CHK_ERR( rval ); 00634 00635 // change coordinates of lagr mesh vertices 00636 for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit ) 00637 { 00638 moab::EntityHandle oldV = *vit; 00639 CartVect posi; 00640 rval = mb->get_coords( &oldV, 1, &( posi[0] ) );MB_CHK_ERR( rval ); 00641 00642 // Intx utils, case 1 00643 CartVect newPos; 00644 departure_point_swirl_rot( posi, t, delta_t, newPos ); 00645 newPos = radius * newPos; // do we need this? the radius should be 1 00646 moab::EntityHandle new_vert; 00647 rval = mb->tag_get_data( corrTag, &oldV, 1, &new_vert );MB_CHK_ERR( rval ); 00648 00649 // set the new position for the new vertex 00650 rval = mb->set_coords( &new_vert, 1, &( newPos[0] ) );MB_CHK_ERR( rval ); 00651 } 00652 00653 // if in parallel, we have to move some elements to another proc, and receive other cells 00654 // from other procs 00655 rval = pworker->create_departure_mesh_3rd_alg( lagr_set, covering_set );MB_CHK_ERR( rval ); 00656 00657 return rval; 00658 } 00659 00660 // !!! For now serial !!! 00661 moab::ErrorCode update_density( moab::Interface* mb, 00662 moab::EntityHandle euler_set, 00663 moab::EntityHandle lagr_set, 00664 moab::EntityHandle out_set, 00665 moab::Tag& rhoTag, 00666 moab::Tag& areaTag, 00667 moab::Tag& rhoCoefsTag, 00668 moab::Tag& weightsTag, 00669 moab::Tag& planeTag ) 00670 { 00671 // moab::ParallelComm * parcomm = ParallelComm::get_pcomm(mb, 0); 00672 ErrorCode rval; 00673 double R = 1.0; 00674 moab::EntityHandle dum = 0; 00675 Tag corrTag; 00676 00677 rval = mb->tag_get_handle( CORRTAGNAME, 1, MB_TYPE_HANDLE, corrTag, MB_TAG_DENSE, &dum );MB_CHK_ERR( rval ); 00678 00679 // get all polygons out of out_set; then see where are they coming from 00680 moab::Range polys; 00681 rval = mb->get_entities_by_dimension( out_set, 2, polys );MB_CHK_ERR( rval ); 00682 00683 // get all Lagrangian cells 00684 moab::Range rs1; 00685 rval = mb->get_entities_by_dimension( lagr_set, 2, rs1 );MB_CHK_ERR( rval ); 00686 00687 // get all Eulerian cells 00688 moab::Range rs2; 00689 rval = mb->get_entities_by_dimension( euler_set, 2, rs2 );MB_CHK_ERR( rval ); 00690 00691 // get gnomonic plane for Eulerian cells 00692 std::vector< int > plane( rs2.size() ); 00693 rval = mb->tag_get_data( planeTag, rs2, &plane[0] );MB_CHK_ERR( rval ); 00694 00695 // get Eulerian cell reconstruction coefficients 00696 std::vector< double > rhoCoefs( 3 * rs2.size() ); 00697 rval = mb->tag_get_data( rhoCoefsTag, rs2, &rhoCoefs[0] );MB_CHK_ERR( rval ); 00698 00699 // get intersection weights 00700 std::vector< double > weights( 3 * polys.size() ); 00701 rval = mb->tag_get_data( weightsTag, polys, &weights[0] );MB_CHK_ERR( rval ); 00702 00703 // Initialize the new values 00704 std::vector< double > newValues( rs2.size(), 0. ); // initialize with 0 all of them 00705 00706 // For each polygon get red/blue parent 00707 moab::Tag tgtParentTag; 00708 moab::Tag srcParentTag; 00709 rval = mb->tag_get_handle( "TargetParent", 1, MB_TYPE_INTEGER, tgtParentTag, MB_TAG_DENSE );MB_CHK_ERR( rval ); 00710 rval = mb->tag_get_handle( "SourceParent", 1, MB_TYPE_INTEGER, srcParentTag, MB_TAG_DENSE );MB_CHK_ERR( rval ); 00711 00712 // mass_lagr = (\sum_intx \int rho^h(x,y) dV) 00713 // rho_eul^n+1 = mass_lagr/area_eul 00714 double check_intx_area = 0.; 00715 int polyIndex = 0; 00716 for( Range::iterator it = polys.begin(); it != polys.end(); ++it ) 00717 { 00718 moab::EntityHandle poly = *it; 00719 int blueIndex, redIndex; 00720 rval = mb->tag_get_data( srcParentTag, &poly, 1, &blueIndex );MB_CHK_ERR( rval ); 00721 00722 moab::EntityHandle blue = rs1[blueIndex]; 00723 rval = mb->tag_get_data( tgtParentTag, &poly, 1, &redIndex );MB_CHK_ERR( rval ); 00724 00725 moab::EntityHandle redArr; 00726 rval = mb->tag_get_data( corrTag, &blue, 1, &redArr );MB_CHK_ERR( rval ); 00727 int arrRedIndex = rs2.index( redArr ); 00728 00729 // sum into new density values 00730 newValues[arrRedIndex] += rhoCoefs[redIndex * 3] * weights[polyIndex * 3] + 00731 rhoCoefs[redIndex * 3 + 1] * weights[polyIndex * 3 + 1] + 00732 rhoCoefs[redIndex * 3 + 2] * weights[polyIndex * 3 + 2]; 00733 00734 check_intx_area += weights[polyIndex * 3 + 2]; 00735 00736 polyIndex++; 00737 } 00738 00739 // now divide by red area (current) 00740 int j = 0; 00741 Range::iterator iter = rs2.begin(); 00742 void* data = NULL; // used for stored area 00743 int count = 0; 00744 double total_mass_local = 0.; 00745 while( iter != rs2.end() ) 00746 { 00747 rval = mb->tag_iterate( areaTag, iter, rs2.end(), count, data );MB_CHK_ERR( rval ); 00748 00749 double* ptrArea = (double*)data; 00750 for( int i = 0; i < count; i++, ++iter, j++, ptrArea++ ) 00751 { 00752 total_mass_local += newValues[j]; 00753 newValues[j] /= ( *ptrArea ); 00754 } 00755 } 00756 00757 rval = mb->tag_set_data( rhoTag, rs2, &newValues[0] );MB_CHK_ERR( rval ); 00758 00759 std::cout << "total mass now:" << total_mass_local << "\n"; 00760 std::cout << "check: total intersection area: (4 * M_PI * R^2): " << 4 * M_PI * R * R << " " << check_intx_area 00761 << "\n"; 00762 00763 return MB_SUCCESS; 00764 } 00765 00766 /* 00767 * Deformational flow 00768 */ 00769 void departure_point_swirl( moab::CartVect& arrival_point, double t, double delta_t, moab::CartVect& departure_point ) 00770 { 00771 00772 // always assume radius is 1 here? 00773 moab::IntxUtils::SphereCoords sph = moab::IntxUtils::cart_to_spherical( arrival_point ); 00774 double k = 2.4; // flow parameter 00775 /* radius needs to be within some range */ 00776 double sl2 = sin( sph.lon / 2 ); 00777 double pit = M_PI * t / T; 00778 double omega = M_PI / T; 00779 double costheta = cos( sph.lat ); 00780 // double u = k * sl2*sl2 * sin(2*sph.lat) * cos(pit); 00781 double v = k * sin( sph.lon ) * costheta * cos( pit ); 00782 // double psi = k * sl2 * sl2 *costheta * costheta * cos(pit); 00783 double u_tilda = 2 * k * sl2 * sl2 * sin( sph.lat ) * cos( pit ); 00784 00785 // formula 35, page 8 00786 // this will approximate dep point using a Taylor series with up to second derivative 00787 // this will be O(delta_t^3) exact. 00788 double lon_dep = 00789 sph.lon - delta_t * u_tilda - 00790 delta_t * delta_t * k * sl2 * 00791 ( sl2 * sin( sph.lat ) * sin( pit ) * omega - u_tilda * sin( sph.lat ) * cos( pit ) * cos( sph.lon / 2 ) - 00792 v * sl2 * costheta * cos( pit ) ); 00793 // formula 36, page 8 again 00794 double lat_dep = sph.lat - delta_t * v - 00795 delta_t * delta_t / 4 * k * 00796 ( sin( sph.lon ) * cos( sph.lat ) * sin( pit ) * omega - 00797 u_tilda * cos( sph.lon ) * cos( sph.lat ) * cos( pit ) + 00798 v * sin( sph.lon ) * sin( sph.lat ) * cos( pit ) ); 00799 moab::IntxUtils::SphereCoords sph_dep; 00800 sph_dep.R = 1.; // radius 00801 sph_dep.lat = lat_dep; 00802 sph_dep.lon = lon_dep; 00803 00804 departure_point = moab::IntxUtils::spherical_to_cart( sph_dep ); 00805 return; 00806 } 00807 00808 /* 00809 * Deformational flow with rotation 00810 */ 00811 void departure_point_swirl_rot( moab::CartVect& arrival_point, 00812 double t, 00813 double delta_t, 00814 moab::CartVect& departure_point ) 00815 { 00816 00817 moab::IntxUtils::SphereCoords sph = moab::IntxUtils::cart_to_spherical( arrival_point ); 00818 double omega = M_PI / T; 00819 double gt = cos( M_PI * t / T ); 00820 00821 double lambda = sph.lon - 2.0 * omega * t; 00822 double u_tilda = 4.0 * sin( lambda ) * sin( lambda ) * sin( sph.lat ) * gt + 2.0 * omega; 00823 double v = 2.0 * sin( 2.0 * lambda ) * cos( sph.lat ) * gt; 00824 00825 double lon_dep = sph.lon - delta_t * u_tilda - 00826 delta_t * delta_t * 2.0 * sin( lambda ) * 00827 ( sin( lambda ) * sin( sph.lat ) * sin( omega * t ) * omega - 00828 sin( lambda ) * cos( sph.lat ) * cos( omega * t ) * v - 00829 2.0 * cos( lambda ) * sin( sph.lat ) * cos( omega * t ) * u_tilda ); 00830 00831 double lat_dep = sph.lat - delta_t * v - 00832 delta_t * delta_t * 2.0 * 00833 ( cos( sph.lat ) * sin( omega * t ) * omega * sin( lambda ) * cos( lambda ) - 00834 2.0 * u_tilda * cos( sph.lat ) * cos( omega * t ) * cos( lambda ) * cos( lambda ) + 00835 u_tilda * cos( sph.lat ) * cos( omega * t ) + 00836 v * sin( sph.lat ) * cos( omega * t ) * sin( lambda ) * cos( lambda ) ); 00837 00838 moab::IntxUtils::SphereCoords sph_dep; 00839 sph_dep.R = 1.; // radius 00840 sph_dep.lat = lat_dep; 00841 sph_dep.lon = lon_dep; 00842 00843 departure_point = moab::IntxUtils::spherical_to_cart( sph_dep ); 00844 return; 00845 } 00846 00847 /* 00848 * Zonal flow 00849 */ 00850 moab::ErrorCode get_intersection_weights( moab::Interface* mb, 00851 moab::EntityHandle euler_set, 00852 moab::EntityHandle lagr_set, 00853 moab::EntityHandle intx_set, 00854 moab::Tag& planeTag, 00855 moab::Tag& weightsTag ) 00856 { 00857 // get all intersection polygons 00858 moab::Range polys; 00859 ErrorCode rval = mb->get_entities_by_dimension( intx_set, 2, polys );MB_CHK_ERR( rval ); 00860 00861 // get all Eulerian cells 00862 moab::Range eul_cells; 00863 rval = mb->get_entities_by_dimension( euler_set, 2, eul_cells );MB_CHK_ERR( rval ); 00864 00865 // get all Lagrangian cells 00866 moab::Range lagr_cells; 00867 rval = mb->get_entities_by_dimension( lagr_set, 2, lagr_cells );MB_CHK_ERR( rval ); 00868 00869 // get tag for Eulerian parent cell of intersection polygon 00870 moab::Tag tgtParentTag; 00871 rval = mb->tag_get_handle( "TargetParent", 1, MB_TYPE_INTEGER, tgtParentTag, MB_TAG_DENSE ); 00872 00873 // get tag for Lagrangian parent cell of intersection polygon 00874 moab::Tag srcParentTag; 00875 rval = mb->tag_get_handle( "SourceParent", 1, MB_TYPE_INTEGER, srcParentTag, MB_TAG_DENSE );MB_CHK_ERR( rval ); 00876 00877 // get gnomonic plane for Eulerian cells 00878 std::vector< int > plane( eul_cells.size() ); 00879 rval = mb->tag_get_data( planeTag, eul_cells, &plane[0] );MB_CHK_ERR( rval ); 00880 00881 double total_area = 0.; 00882 for( moab::Range::iterator it = polys.begin(); it != polys.end(); ++it ) 00883 { 00884 moab::EntityHandle poly = *it; 00885 00886 // get the nodes 00887 const moab::EntityHandle* verts; 00888 int num_nodes; 00889 rval = mb->get_connectivity( poly, verts, num_nodes );MB_CHK_ERR( rval ); 00890 00891 // get coordinates 00892 std::vector< double > coords( 3 * num_nodes ); 00893 rval = mb->get_coords( verts, num_nodes, &coords[0] );MB_CHK_ERR( rval ); 00894 00895 // get index of Eulerian parent cell for polygon 00896 int redIndex; 00897 rval = mb->tag_get_data( tgtParentTag, &poly, 1, &redIndex );MB_CHK_ERR( rval ); 00898 00899 // get index of Lagrangian parent cell for polygon 00900 int blueIndex; 00901 rval = mb->tag_get_data( srcParentTag, &poly, 1, &blueIndex );MB_CHK_ERR( rval ); 00902 00903 std::vector< double > x( num_nodes ); 00904 std::vector< double > y( num_nodes ); 00905 double poly_area = 0; 00906 double poly_intx = 0; 00907 double poly_inty = 0; 00908 double R = 1.0; 00909 for( int inode = 0; inode < num_nodes; inode++ ) 00910 { 00911 double rad = sqrt( coords[inode * 3] * coords[inode * 3] + coords[inode * 3 + 1] * coords[inode * 3 + 1] + 00912 coords[inode * 3 + 2] * coords[inode * 3 + 2] ); 00913 moab::CartVect xyzcoord( coords[inode * 3] / rad, coords[inode * 3 + 1] / rad, 00914 coords[inode * 3 + 2] / rad ); 00915 moab::IntxUtils::gnomonic_projection( xyzcoord, R, plane[redIndex], x[inode], y[inode] ); 00916 } 00917 00918 std::vector< double > weights( 3 ); 00919 for( int inode = 0; inode < num_nodes; inode++ ) 00920 { 00921 int inode2 = inode + 1; 00922 if( inode2 >= num_nodes ) inode2 = 0; 00923 double xmid = 0.5 * ( x[inode] + x[inode2] ); 00924 double ymid = 0.5 * ( y[inode] + y[inode2] ); 00925 double r1 = sqrt( 1 + x[inode] * x[inode] + y[inode] * y[inode] ); 00926 double rm = sqrt( 1 + xmid * xmid + ymid * ymid ); 00927 double r2 = sqrt( 1 + x[inode2] * x[inode2] + y[inode2] * y[inode2] ); 00928 double hx = x[inode2] - x[inode]; 00929 00930 poly_area += -hx * 00931 ( y[inode] / ( r1 * ( 1 + x[inode] * x[inode] ) ) + 4.0 * ymid / ( rm * ( 1 + xmid * xmid ) ) + 00932 y[inode2] / ( r2 * ( 1 + x[inode2] * x[inode2] ) ) ) / 00933 6.0; 00934 00935 poly_intx += -hx * 00936 ( x[inode] * y[inode] / ( r1 * ( 1 + x[inode] * x[inode] ) ) + 00937 4.0 * xmid * ymid / ( rm * ( 1 + xmid * xmid ) ) + 00938 x[inode2] * y[inode2] / ( r2 * ( 1 + x[inode2] * x[inode2] ) ) ) / 00939 6.0; 00940 00941 poly_inty += hx * ( 1.0 / r1 + 4.0 / rm + 1.0 / r2 ) / 6.0; 00942 } 00943 weights[0] = poly_intx; 00944 weights[1] = poly_inty; 00945 weights[2] = poly_area; 00946 00947 total_area += poly_area; 00948 00949 rval = mb->tag_set_data( weightsTag, &poly, 1, &weights[0] );MB_CHK_ERR( rval ); 00950 } 00951 00952 std::cout << "polygon area = " << total_area << "\n"; 00953 00954 return moab::MB_SUCCESS; 00955 } 00956 00957 ErrorCode create_lagr_mesh( moab::Interface* mb, moab::EntityHandle euler_set, moab::EntityHandle lagr_set ) 00958 { 00959 // create the handle tag for the corresponding element / vertex 00960 00961 moab::EntityHandle dum = 0; 00962 00963 moab::Tag corrTag; 00964 ErrorCode rval = mb->tag_get_handle( CORRTAGNAME, 1, MB_TYPE_HANDLE, corrTag, MB_TAG_DENSE | MB_TAG_CREAT, &dum ); 00965 00966 MB_CHK_ERR( rval ); 00967 // give the same global id to new verts and cells created in the lagr(departure) mesh 00968 moab::Tag gid = mb->globalId_tag(); 00969 00970 moab::Range polys; 00971 rval = mb->get_entities_by_dimension( euler_set, 2, polys );MB_CHK_ERR( rval ); 00972 00973 moab::Range connecVerts; 00974 rval = mb->get_connectivity( polys, connecVerts );MB_CHK_ERR( rval ); 00975 00976 std::map< moab::EntityHandle, moab::EntityHandle > newNodes; 00977 for( Range::iterator vit = connecVerts.begin(); vit != connecVerts.end(); ++vit ) 00978 { 00979 moab::EntityHandle oldV = *vit; 00980 moab::CartVect posi; 00981 rval = mb->get_coords( &oldV, 1, &( posi[0] ) );MB_CHK_ERR( rval ); 00982 int global_id; 00983 rval = mb->tag_get_data( gid, &oldV, 1, &global_id );MB_CHK_ERR( rval ); 00984 moab::EntityHandle new_vert; 00985 // duplicate the position 00986 rval = mb->create_vertex( &( posi[0] ), new_vert );MB_CHK_ERR( rval ); 00987 newNodes[oldV] = new_vert; 00988 // set also the correspondent tag :) 00989 rval = mb->tag_set_data( corrTag, &oldV, 1, &new_vert );MB_CHK_ERR( rval ); 00990 00991 // also the other side 00992 // need to check if we really need this; the new vertex will never need the old vertex 00993 // we have the global id which is the same 00994 /*rval = mb->tag_set_data(corrTag, &new_vert, 1, &oldV);MB_CHK_ERR(rval);*/ 00995 // set the global id on the corresponding vertex the same as the initial vertex 00996 rval = mb->tag_set_data( gid, &new_vert, 1, &global_id );MB_CHK_ERR( rval ); 00997 } 00998 00999 for( Range::iterator it = polys.begin(); it != polys.end(); ++it ) 01000 { 01001 moab::EntityHandle q = *it; 01002 int global_id; 01003 int nnodes; 01004 const moab::EntityHandle* conn; 01005 01006 rval = mb->get_connectivity( q, conn, nnodes );MB_CHK_ERR( rval ); 01007 rval = mb->tag_get_data( gid, &q, 1, &global_id );MB_CHK_ERR( rval ); 01008 01009 EntityType typeElem = mb->type_from_handle( q ); 01010 std::vector< moab::EntityHandle > new_conn( nnodes ); 01011 for( int i = 0; i < nnodes; i++ ) 01012 { 01013 moab::EntityHandle v1 = conn[i]; 01014 new_conn[i] = newNodes[v1]; 01015 } 01016 01017 moab::EntityHandle newElement; 01018 rval = mb->create_element( typeElem, &new_conn[0], nnodes, newElement );MB_CHK_ERR( rval ); 01019 // set the corresponding tag; not sure we need this one, from old to new 01020 /*rval = mb->tag_set_data(corrTag, &q, 1, &newElement);MB_CHK_ERR(rval);*/ 01021 rval = mb->tag_set_data( corrTag, &newElement, 1, &q );MB_CHK_ERR( rval ); 01022 // set the global id 01023 rval = mb->tag_set_data( gid, &newElement, 1, &global_id );MB_CHK_ERR( rval ); 01024 01025 rval = mb->add_entities( lagr_set, &newElement, 1 );MB_CHK_ERR( rval ); 01026 } 01027 01028 return MB_SUCCESS; 01029 }