#include #include #include #include #include #include #include "shared_ptr.h" #include "common/UnitTest.h" #include "common/Utilities.h" #include "common/MPI_Helpers.h" #include "IO/MeshDatabase.h" #include "IO/Reader.h" #include "IO/Writer.h" inline bool approx_equal( const Point& A, const Point& B ) { double tol = 1e-8*sqrt(A.x*A.x+A.y*A.y+A.z*A.z); return fabs(A.x-B.x)<=tol && fabs(A.y-B.y)<=tol && fabs(A.z-B.z)<=tol; } inline bool approx_equal( const double& A, const double& B ) { return fabs(A-B)<=1e-8*fabs(A+B); } inline double distance( const Point& p ) { return sqrt(p.x*p.x+p.y*p.y+p.z*p.z); } // Test writing and reading the given format void testWriter( const std::string& format, const std::vector& meshData, UnitTest& ut ) { int rank, nprocs; MPI_Comm comm = MPI_COMM_WORLD; MPI_Comm_rank(comm,&rank); MPI_Comm_size(comm,&nprocs); MPI_Barrier(comm); // Write the data PROFILE_START(format+"-write"); IO::initialize( "test_"+format, format, false ); IO::writeData( 0, meshData, comm ); IO::writeData( 3, meshData, comm ); MPI_Barrier(comm); PROFILE_STOP(format+"-write"); // Get the summary name for reading std::string summary_name; if ( format=="old" || format=="new" ) summary_name = "test_" + format + "/summary.LBM"; else if ( format == "silo" ) summary_name = "test_" + format + "/LBM.visit"; else ERROR("Unknown format"); // Get direct access to the meshes used to test the reader const auto pointmesh = dynamic_cast( meshData[0].mesh.get() ); const auto trimesh = dynamic_cast( meshData[1].mesh.get() ); const auto trilist = dynamic_cast( meshData[2].mesh.get() ); const auto domain = dynamic_cast( meshData[3].mesh.get() ); const size_t N_tri = trimesh->A.size(); // Get a list of the timesteps PROFILE_START(format+"-read-timesteps"); std::vector timesteps = IO::readTimesteps(summary_name); PROFILE_STOP(format+"-read-timesteps"); if ( timesteps.size()==2 ) ut.passes("Corrent number of timesteps"); else ut.failure("Incorrent number of timesteps"); // Check the mesh lists for (size_t i=0; i list = IO::getMeshList(".",timesteps[i]); PROFILE_STOP(format+"-read-getMeshList"); if ( list.size()==meshData.size() ) ut.passes("Corrent number of meshes found"); else ut.failure("Incorrent number of meshes found"); // Check the number of domains for each mesh bool pass = true; for (size_t j=0; j mesh = IO::getMesh(".",timesteps[i],list[j],k); PROFILE_STOP(format+"-read-getMesh"); if ( mesh.get()==NULL ) { printf("Failed to load %s\n",list[j].name.c_str()); pass = false; break; } if ( list[j].name=="pointmesh" ) { // Check the pointmesh std::shared_ptr pmesh = IO::getPointList(mesh); if ( pmesh.get()==NULL ) { pass = false; break; } if ( pmesh->points.size() != pointmesh->points.size() ) { pass = false; break; } } if ( list[j].name=="trimesh" || list[j].name=="trilist" ) { // Check the trimesh/trilist std::shared_ptr mesh1 = IO::getTriMesh(mesh); std::shared_ptr mesh2 = IO::getTriList(mesh); if ( mesh1.get()==NULL || mesh2.get()==NULL ) { pass = false; break; } if ( mesh1->A.size()!=N_tri || mesh1->B.size()!=N_tri || mesh1->C.size()!=N_tri || mesh2->A.size()!=N_tri || mesh2->B.size()!=N_tri || mesh2->C.size()!=N_tri ) { pass = false; break; } const std::vector& P1 = mesh1->vertices->points; const std::vector& A1 = mesh1->A; const std::vector& B1 = mesh1->B; const std::vector& C1 = mesh1->C; const std::vector& A2 = mesh2->A; const std::vector& B2 = mesh2->B; const std::vector& C2 = mesh2->C; const std::vector& A = trilist->A; const std::vector& B = trilist->B; const std::vector& C = trilist->C; for (size_t i=0; i(mesh); if ( mesh1.nprocx!=domain->nprocx || mesh1.nprocy!=domain->nprocy || mesh1.nprocz!=domain->nprocz ) pass = false; if ( mesh1.nx!=domain->nx || mesh1.ny!=domain->ny || mesh1.nz!=domain->nz ) pass = false; if ( mesh1.Lx!=domain->Lx || mesh1.Ly!=domain->Ly || mesh1.Lz!=domain->Lz ) pass = false; } } } if ( pass ) { ut.passes("Meshes loaded correctly"); } else { ut.failure("Meshes did not load correctly"); continue; } // For each domain, load the variables and check their data if ( format=="old" ) continue; // Old format does not support variables for (size_t j=0; j variable = IO::getVariable(".",timesteps[i],list[j],k,list[j].variables[v].name); PROFILE_STOP(format+"-read-getVariable"); const IO::Variable& var1 = *mesh0->vars[v]; const IO::Variable& var2 = *variable; pass = var1.name == var2.name; pass = pass && var1.dim == var2.dim; pass = pass && var1.type == var2.type; pass = pass && var1.data.length() == var2.data.length(); if ( pass ) { for (size_t m=0; m set1( new IO::PointList(N_points) ); for (int i=0; ipoints[i].x = x[i]; set1->points[i].y = y[i]; set1->points[i].z = z[i]; } std::shared_ptr trimesh( new IO::TriMesh(N_tri,set1) ); for (int i=0; iA[i] = tri[i][0]; trimesh->B[i] = tri[i][1]; trimesh->C[i] = tri[i][2]; } std::shared_ptr trilist( new IO::TriList(*trimesh) ); for (int i=0; iA[i],A) || !approx_equal(trilist->B[i],B) || !approx_equal(trilist->C[i],C) ) { printf("Failed to create trilist\n"); return -1; } } RankInfoStruct rank_data( rank, nprocs, 1, 1 ); std::shared_ptr domain( new IO::DomainMesh(rank_data,6,7,8,1.0,1.0,1.0) ); // Create the variables std::shared_ptr dist_set1( new IO::Variable() ); std::shared_ptr dist_list( new IO::Variable() ); std::shared_ptr domain_var( new IO::Variable() ); dist_set1->dim = 1; dist_list->dim = 1; domain_var->dim = 1; dist_set1->name = "Distance"; dist_list->name = "Distance"; domain_var->name = "Distance"; dist_set1->type = IO::NodeVariable; dist_list->type = IO::NodeVariable; domain_var->type = IO::VolumeVariable; dist_set1->data.resize( N_points ); for (int i=0; idata(i) = distance(set1->points[i]); dist_list->data.resize( 3, N_tri ); for (int i=0; idata(0,i) = distance(trilist->A[i]); dist_list->data(1,i) = distance(trilist->B[i]); dist_list->data(2,i) = distance(trilist->C[i]); } domain_var->data.resize(domain->nx,domain->ny,domain->nz); for (int i=0; inx; i++) { for (int j=0; jny; j++) { for (int k=0; knz; k++) { domain_var->data(i,j,k) = distance(Point(i,j,k)); } } } // Create the MeshDataStruct std::vector meshData(4); meshData[0].meshName = "pointmesh"; meshData[0].mesh = set1; meshData[0].vars.push_back(dist_set1); meshData[1].meshName = "trimesh"; meshData[1].mesh = trimesh; meshData[1].vars.push_back(dist_set1); meshData[2].meshName = "trilist"; meshData[2].mesh = trilist; meshData[2].vars.push_back(dist_list); meshData[3].meshName = "domain"; meshData[3].mesh = domain; meshData[3].vars.push_back(domain_var); // Run the tests testWriter( "old", meshData, ut ); testWriter( "new", meshData, ut ); //testWriter( "silo", meshData, ut ); // Finished ut.report(); PROFILE_SAVE("TestWriter",true); int N_errors = ut.NumFailGlobal(); MPI_Barrier(comm); MPI_Finalize(); return N_errors; }