![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #include "TestUtil.hpp"
00002 #include "ElemUtil.hpp"
00003 #include "moab/Core.hpp"
00004 #include "moab/Range.hpp"
00005 #include
00006
00007 #ifndef MESHDIR
00008 #error Specify MESHDIR to compile test
00009 #endif
00010
00011 using namespace moab;
00012
00013 void test_tet();
00014 void test_hex();
00015 void test_spectral_hex();
00016 void test_spectral_quad();
00017 void test_spherical_quad();
00018 void test_linear_tri();
00019 void test_spherical_tri();
00020
00021 int main()
00022 {
00023 int rval = 0;
00024 rval += RUN_TEST( test_tet );
00025 rval += RUN_TEST( test_hex );
00026 rval += RUN_TEST( test_spectral_hex );
00027 rval += RUN_TEST( test_spectral_quad );
00028 rval += RUN_TEST( test_spherical_quad );
00029 rval += RUN_TEST( test_linear_tri );
00030 rval += RUN_TEST( test_spherical_tri );
00031 return rval;
00032 }
00033
00034 void test_tet()
00035 {
00036 moab::Element::LinearTet tet;
00037 } // test_tet()
00038
00039 void test_hex()
00040 {
00041 double positions[] = { 236.80706050970281, -139.55422526228017, 193.27999999999997,
00042 236.47511729348639, -141.33020962638582, 193.27999999999997,
00043 237.8457938295229, -142.57076074835663, 193.27999999999997,
00044 239.12702305519684, -139.96608933577852, 193.27999999999997,
00045 236.80841321361444, -139.55341321335499, 202.654,
00046 236.47655014713746, -141.32980272396816, 202.654,
00047 237.8477913707564, -142.57047282187165, 202.654,
00048 239.12865103844533, -139.96531051891105, 202.654 };
00049 CartVect x( 235.96518686964933, -142.43503000077749, 188.19999999999987 );
00050 std::vector< CartVect > vertices;
00051 for( int i = 0; i < 8; i++ )
00052 vertices.push_back( CartVect( positions + 3 * i ) );
00053
00054 moab::Element::LinearHex hex( vertices );
00055 double tol( 0.0001 );
00056 if( hex.inside_box( x, tol ) )
00057 {
00058 CartVect nat_par = hex.ievaluate( x, 0.0001 );
00059 std::cout << nat_par << "\n";
00060 }
00061
00062 double positions2[] = { 49.890500000000024, -20.376134375374882, 312.72000000000003,
00063 52.015875000000044, -19.149048546996006, 312.72000000000003,
00064 48.430375821458099, -18.548796774572125, 312.72000000000003,
00065 47.717616239031223, -21.191360829777231, 312.72000000000003,
00066 49.890500000000024, -20.376134375374882, 322.88,
00067 52.015875000000044, -19.149048546996006, 322.88,
00068 48.429930354643275, -18.52828610485021, 322.88,
00069 47.720552036968819, -21.167591146685712, 322.88 };
00070
00071 CartVect x2( 51.469000000000015, -20.145482942833631, 317.80000000000001 );
00072
00073 vertices.clear();
00074 for( int i = 0; i < 8; i++ )
00075 vertices.push_back( CartVect( positions2 + 3 * i ) );
00076 moab::Element::LinearHex hex2( vertices );
00077 if( hex2.inside_box( x2, tol ) )
00078 {
00079 try
00080 {
00081 CartVect nat_par = hex.ievaluate( x, 0.0001 );
00082 std::cout << nat_par << "\n";
00083 }
00084 catch( Element::Map::EvaluationError )
00085 {
00086 // nothing
00087 }
00088 }
00089
00090 } // test_hex()
00091
00092 void test_spectral_hex()
00093 {
00094 // first load a model that has spectral elements
00095 moab::Core* mb = new moab::Core();
00096 std::string meshFile = STRINGIFY( MESHDIR ) "/spectral.h5m";
00097 moab::ErrorCode rval = mb->load_mesh( meshFile.c_str() );
00098 if( moab::MB_SUCCESS != rval )
00099 {
00100 std::cout << "Problems reading file " << meshFile << "." << std::endl;
00101 delete mb;
00102 return;
00103 }
00104
00105 // get the ent set with SEM_DIMS tag
00106 moab::Range spectral_sets;
00107 moab::Tag sem_tag;
00108 rval = mb->tag_get_handle( "SEM_DIMS", 3, moab::MB_TYPE_INTEGER, sem_tag );
00109 if( moab::MB_SUCCESS != rval )
00110 {
00111 std::cout << "can't find tag, no spectral set\n";
00112 delete mb;
00113 return;
00114 }
00115 rval = mb->get_entities_by_type_and_tag( 0, moab::MBENTITYSET, &sem_tag, NULL, 1, spectral_sets );
00116 if( moab::MB_SUCCESS != rval || spectral_sets.empty() )
00117 {
00118 std::cout << "can't get sem set\n";
00119 delete mb;
00120 return;
00121 }
00122
00123 moab::Range ents;
00124
00125 int sem_dims[3];
00126 moab::EntityHandle firstSemSet = spectral_sets[0];
00127 rval = mb->tag_get_data( sem_tag, &firstSemSet, 1, (void*)sem_dims );
00128 if( moab::MB_SUCCESS != rval )
00129 {
00130 delete mb;
00131 return;
00132 }
00133
00134 rval = mb->get_entities_by_dimension( firstSemSet, 3, ents );
00135 if( moab::MB_SUCCESS != rval )
00136 {
00137 delete mb;
00138 return;
00139 }
00140 std::cout << "Found " << ents.size() << " " << 3 << "-dimensional entities:" << std::endl;
00141
00142 if( sem_dims[0] != sem_dims[1] || sem_dims[0] != sem_dims[2] )
00143 {
00144 std::cout << " dimensions are different. bail out\n";
00145 delete mb;
00146 return;
00147 }
00148
00149 // get the SEM_X ...tags
00150 moab::Tag xm1Tag, ym1Tag, zm1Tag;
00151 int ntot = sem_dims[0] * sem_dims[1] * sem_dims[2];
00152 rval = mb->tag_get_handle( "SEM_X", ntot, moab::MB_TYPE_DOUBLE, xm1Tag );
00153 if( moab::MB_SUCCESS != rval )
00154 {
00155 std::cout << "can't get xm1tag \n";
00156 delete mb;
00157 return;
00158 }
00159 rval = mb->tag_get_handle( "SEM_Y", ntot, moab::MB_TYPE_DOUBLE, ym1Tag );
00160 if( moab::MB_SUCCESS != rval )
00161 {
00162 std::cout << "can't get ym1tag \n";
00163 delete mb;
00164 return;
00165 }
00166 rval = mb->tag_get_handle( "SEM_Z", ntot, moab::MB_TYPE_DOUBLE, zm1Tag );
00167 if( moab::MB_SUCCESS != rval )
00168 {
00169 std::cout << "can't get zm1tag \n";
00170 delete mb;
00171 return;
00172 }
00173 moab::Tag velTag;
00174
00175 rval = mb->tag_get_handle( "VX", ntot, moab::MB_TYPE_DOUBLE, velTag );
00176 if( moab::MB_SUCCESS != rval )
00177 {
00178 std::cout << "can't get veltag \n";
00179 delete mb;
00180 return;
00181 }
00182 moab::Element::SpectralHex specHex( sem_dims[0] );
00183
00184 // compute the data for some elements
00185 for( moab::Range::iterator rit = ents.begin(); rit != ents.end(); ++rit )
00186 {
00187 // get the tag pointers to the internal storage for xm1, to not copy the values
00188 moab::EntityHandle eh = *rit;
00189 const double* xval;
00190 const double* yval;
00191 const double* zval;
00192 rval = mb->tag_get_by_ptr( xm1Tag, &eh, 1, (const void**)&xval );
00193 if( moab::MB_SUCCESS != rval )
00194 {
00195 std::cout << "can't get xm1 values \n";
00196 delete mb;
00197 return;
00198 }
00199 rval = mb->tag_get_by_ptr( ym1Tag, &eh, 1, (const void**)&yval );
00200 if( moab::MB_SUCCESS != rval )
00201 {
00202 std::cout << "can't get ym1 values \n";
00203 delete mb;
00204 return;
00205 }
00206 rval = mb->tag_get_by_ptr( zm1Tag, &eh, 1, (const void**)&zval );
00207 if( moab::MB_SUCCESS != rval )
00208 {
00209 std::cout << "can't get zm1 values \n";
00210 delete mb;
00211 return;
00212 }
00213 if( rit == ents.begin() )
00214 {
00215 std::cout << " xm1 for first element: \n";
00216 for( int i = 0; i < ntot; i++ )
00217 std::cout << " " << xval[i];
00218 std::cout << "\n";
00219 }
00220 specHex.set_gl_points( (double*)xval, (double*)yval, (double*)zval );
00221 // first evaluate a point, then inverse it to see if we get the same thing
00222 moab::CartVect rst( 0.1, -0.1, 0.5 );
00223 moab::CartVect pos = specHex.evaluate( rst );
00224 moab::CartVect inverse = specHex.ievaluate( pos, 0.0001 );
00225 std::cout << "difference" << rst - inverse << "\n";
00226 Matrix3 jac = specHex.jacobian( rst );
00227 std::cout << "jacobian: \n" << jac << " \n determinant: " << jac.determinant() << "\n";
00228 // evaluate vx at some point
00229 const double* vx;
00230 rval = mb->tag_get_by_ptr( velTag, &eh, 1, (const void**)&vx );
00231 if( moab::MB_SUCCESS != rval )
00232 {
00233 std::cout << "can't get vel values \n";
00234 delete mb;
00235 return;
00236 }
00237 double vel1 = specHex.evaluate_scalar_field( rst, vx );
00238 std::cout << "velocity: " << vel1 << "\n";
00239 // compute integral over vx:
00240 double integral = specHex.integrate_scalar_field( vx );
00241 std::cout << "integral over vx: " << integral << "\n";
00242 }
00243 std::cout << "success...\n";
00244
00245 delete mb;
00246 }
00247
00248 void test_spectral_quad()
00249 {
00250 // first load a model that has spectral elements
00251 moab::Core* mb = new moab::Core();
00252 // use the grid on Sphere from mbcslam folder
00253 std::string meshFile = STRINGIFY( MESHDIR ) "/mbcslam/eulerHomme.vtk";
00254 moab::ErrorCode rval = mb->load_mesh( meshFile.c_str() );
00255 if( moab::MB_SUCCESS != rval )
00256 {
00257 std::cout << "Problems reading file " << meshFile << "." << std::endl;
00258 delete mb;
00259 return;
00260 }
00261
00262 // for each element, compute the gl points and project them on sphere
00263 // the radius is the same as the one from intersection test on sphere
00264 // double R = 6. * sqrt(3.) / 2; // input
00265
00266 moab::Range ents;
00267
00268 rval = mb->get_entities_by_type( 0, moab::MBQUAD, ents ); // get all quads
00269 if( moab::MB_SUCCESS != rval )
00270 {
00271 delete mb;
00272 return;
00273 }
00274 std::cout << "Found " << ents.size() << " " << 2 << "-dimensional entities:" << std::endl;
00275
00276 //
00277 int NP = 4; // test this....
00278 moab::Element::SpectralQuad specQuad( NP );
00279
00280 // compute the gl points for some elements
00281 for( moab::Range::iterator rit = ents.begin(); rit != ents.end(); ++rit )
00282 {
00283
00284 const moab::EntityHandle* conn4 = NULL;
00285 int num_nodes = 0;
00286 rval = mb->get_connectivity( *rit, conn4, num_nodes );
00287 if( moab::MB_SUCCESS != rval )
00288 {
00289 std::cout << "can't get connectivity for quad \n";
00290 delete mb;
00291 return;
00292 }
00293 assert( num_nodes == 4 );
00294
00295 std::vector< CartVect > verts( 4 );
00296 rval = mb->get_coords( conn4, num_nodes, &( verts[0][0] ) );
00297 if( moab::MB_SUCCESS != rval )
00298 {
00299 std::cout << "can't get coords for quad \n";
00300 delete mb;
00301 return;
00302 }
00303
00304 specQuad.set_vertices( verts );
00305 specQuad.compute_gl_positions();
00306 // do something with the gl positions, project them on a sphere, and create another mesh?
00307 if( rit == ents.begin() )
00308 {
00309 std::cout << " gl points for first element: \n";
00310 int size;
00311 double* xyz[3];
00312 specQuad.get_gl_points( xyz[0], xyz[1], xyz[2], size );
00313 for( int i = 0; i < size; i++ )
00314 std::cout << xyz[0][i] << " " << xyz[1][i] << " " << xyz[2][i] << "\n";
00315 }
00316
00317 // project them on a sphere, and create another mesh with it?
00318 }
00319 std::cout << "success...\n";
00320
00321 delete mb;
00322 }
00323 void test_spherical_quad()
00324 {
00325 // example from one coupler test, run like this
00326 // ./mbcoupler_test -meshes sphere_16p.h5m mpas_p8.h5m -itag vertex_field -meth 4 -outfile
00327 // dd.h5m method 4 is spherical
00328 double positions[] = { -0.88882388032987436, -0.069951956448441419, 0.45287838714646161, -0.88226455385461389,
00329 -0.13973697758043971, 0.4495362433757738, -0.84497006020160348, -0.13383011007602069,
00330 0.51779831884618843, -0.85072691325794214, -0.066953660115039074, 0.52132612293631853 };
00331 CartVect x( -0.85408569769999998, -0.12391301439999999, 0.50515659540000002 );
00332 std::vector< CartVect > vertices;
00333 for( int i = 0; i < 4; i++ )
00334 vertices.push_back( CartVect( positions + 3 * i ) );
00335
00336 moab::Element::SphericalQuad squad( vertices );
00337 double tol( 0.0001 );
00338 if( squad.inside_box( x, tol ) )
00339 {
00340 CartVect nat_par = squad.ievaluate( x, 0.000001 );
00341 std::cout << nat_par << "\n";
00342 }
00343 std::cout << "success...\n";
00344 }
00345
00346 void test_linear_tri()
00347 {
00348 double positions[] = { 0, 0, 0, 2, 0, 0, 0, 3, 0 };
00349 CartVect x( 1, 0.5, 0 );
00350 std::vector< CartVect > vertices;
00351 for( int i = 0; i < 3; i++ )
00352 vertices.push_back( CartVect( positions + 3 * i ) );
00353
00354 moab::Element::LinearTri tri( vertices );
00355 double tol( 0.0001 );
00356 if( tri.inside_box( x, tol ) )
00357 {
00358 CartVect nat_par = tri.ievaluate( x );
00359 std::cout << x << " :" << nat_par << "\n";
00360 }
00361
00362 x = CartVect( 0, 2, 0 );
00363 if( tri.inside_box( x, tol ) )
00364 {
00365 CartVect nat_par = tri.ievaluate( x );
00366 std::cout << x << " :" << nat_par << "\n";
00367 }
00368
00369 x = CartVect( 1, 0, 0.5 );
00370 if( tri.inside_box( x, tol ) )
00371 {
00372 CartVect nat_par = tri.ievaluate( x );
00373 std::cout << x << " :" << nat_par << "\n";
00374 }
00375
00376 double positions2[] = { -0.866026, -0.500001, 0., 0.866026, -0.500001, 0., 0.000000, 100.000000, 0. };
00377 x = CartVect( 0, 0, 0 );
00378 std::vector< CartVect > vertices2;
00379 for( int i = 0; i < 3; i++ )
00380 vertices2.push_back( CartVect( positions2 + 3 * i ) );
00381
00382 moab::Element::LinearTri tri2( vertices2 );
00383
00384 if( tri2.inside_box( x, tol ) )
00385 {
00386 CartVect nat_par = tri2.ievaluate( x );
00387 std::cout << x << " :" << nat_par << "\n";
00388 }
00389
00390 std::cout << "vertices2 " << vertices2[0] << " " << vertices2[1] << " " << vertices2[2] << "\n";
00391
00392 x = CartVect( -0.866026, -0.500001, 0. );
00393 std::cout << x << " :" << tri2.ievaluate( x ) << "\n";
00394
00395 x = CartVect( +0.866026, -0.500001, 0. );
00396 std::cout << x << " :" << tri2.ievaluate( x ) << "\n";
00397 x = CartVect( 0.000000, 100.000000, 0. );
00398 std::cout << x << " :" << tri2.ievaluate( x ) << "\n";
00399
00400 std::cout << "success...\n";
00401 }
00402
00403 void test_spherical_tri()
00404 {
00405 // example from one coupler test, run like this
00406 // ./mbcoupler_test -meshes tri_fl_8p.h5m mpas_p8.h5m -itag vertex_field -meth 4 -outfile
00407 // oo.h5m -eps 1.e-9 method 4 is spherical
00408 double positions[] = { -0.86339258282987197, -0.17004443185241255, 0.47501383044112816,
00409 -0.80777478326268271, -0.15172299908552511, 0.5696314870803928,
00410 -0.8655618847392077, -0.061613422011313854, 0.49699739427361828 };
00411 CartVect x( -0.85408569769999998, -0.12391301439999999, 0.50515659540000002 );
00412 std::vector< CartVect > vertices;
00413 for( int i = 0; i < 3; i++ )
00414 vertices.push_back( CartVect( positions + 3 * i ) );
00415
00416 moab::Element::SphericalTri sphtri( vertices );
00417 double tol( 0.000001 );
00418 if( sphtri.inside_box( x, tol ) )
00419 {
00420 CartVect nat_par = sphtri.ievaluate( x, 0.000001 );
00421 std::cout << nat_par << "\n";
00422 }
00423 std::cout << "success...\n";
00424 }