Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
ExtractClose.cpp
Go to the documentation of this file.
1 /**
2  * @file ExtractClose.cpp
3  * @brief Example demonstrating extraction of mesh elements based on distance from a point
4  *
5  * This example shows how to:
6  * - Load a large mesh file
7  * - Extract elements within a specified distance from a point
8  * - Handle both Cartesian and spherical coordinate systems
9  * - Compute element centroids for distance calculations
10  * - Create mesh sets for extracted elements
11  * - Write extracted mesh subsets to new files
12  *
13  * This is particularly useful for debugging large mesh files where
14  * you need to examine elements near a specific location without
15  * loading the entire mesh into memory.
16  *
17  * @author MOAB Development Team
18  * @date 2024
19  *
20 
21  * \brief This test shows how to extract mesh from a model, based on distance.
22  *
23  * MOAB's It is needed to extract from large mesh files cells close to some point, where we suspect
24  * errors It would be useful for 9Gb input file that we cannot visualize, but we have overlapped
25  * elements.
26  *
27  * @param argc Number of command line arguments
28  * @param argv Command line arguments array
29  * @return 0 on success, 1 on failure
30  */
31 
32 #include <iostream>
33 #include <cstdlib>
34 #include <cstdio>
35 
36 #include "moab/Core.hpp"
37 #include "moab/Interface.hpp"
38 #include "moab/Range.hpp"
39 #include "moab/ProgOptions.hpp"
40 #include "moab/CartVect.hpp"
42 
43 #ifdef MOAB_HAVE_MPI
44 #include "moab_mpi.h"
45 #include "moab/ParallelComm.hpp"
46 #endif
47 
48 using namespace moab;
49 using namespace std;
50 
51 #ifdef MOAB_HAVE_HDF5
52 string test_file_name = string( MESH_DIR ) + string( "/64bricks_512hex_256part.h5m" );
53 #endif
54 int main( int argc, char** argv )
55 {
56  ProgOptions opts;
57 
58  // vertex 25 in filt out (-0.784768, 0.594952, -0.173698)
59  double x = -0.784768, y = 0.594952, z = -0.173698;
60  double lat = 28.6551, lon = 61.0204; // from Charlie Zender's page
61  // https://acme-climate.atlassian.net/wiki/spaces/ED/pages/1347092547/Assessing+and+Addressing+Regridding+Weights+in+Map-Files
62 
63  string inputFile = test_file_name;
64  opts.addOpt< string >( "inFile,i", "Specify the input file name string ", &inputFile );
65 
66  string outFile = "out.h5m";
67  opts.addOpt< string >( "outFile,o", "Specify the output file name string ", &outFile );
68 
69  opts.addOpt< double >( string( "xpos,x" ), string( "x position" ), &x );
70  opts.addOpt< double >( string( "ypos,y" ), string( "y position" ), &y );
71  opts.addOpt< double >( string( "zpos,z" ), string( "z position" ), &z );
72 
73  opts.addOpt< double >( string( "latitude,t" ), string( "north latitude in degrees" ), &lat );
74  opts.addOpt< double >( string( "longitude,w" ), string( "east longitude in degrees" ), &lon );
75 
76  bool spherical = false;
77  opts.addOpt< void >( "spherical,s", "use spherical coords input (default false) ", &spherical );
78 
79  double distance = 0.01;
80  opts.addOpt< double >( string( "distance,d" ), string( "distance " ), &distance );
81 
82  opts.parseCommandLine( argc, argv );
83 
84  int rank = 0;
85  int numProcesses = 1;
86  std::string readopts;
87 
88  // Instantiate
89  Core mb;
90 
91  // Load the file into a new file set
92  EntityHandle fileSet;
93  MB_CHK_SET_ERR( mb.create_meshset( MESHSET_SET, fileSet ), "Error creating file set" );
94  MB_CHK_SET_ERR( mb.load_file( inputFile.c_str(), &fileSet, readopts.c_str() ), "Error loading file" );
95 
96  if( !rank )
97  {
98  cout << " reading file " << inputFile << " on " << numProcesses << " task";
99  if( numProcesses > 1 ) cout << "s";
100  cout << "\n";
101  }
102  // Get all 2d elements in the file set
103  Range elems;
104  MB_CHK_SET_ERR( mb.get_entities_by_dimension( fileSet, 2, elems ), "Error getting 2d elements" );
105 
106  // create a meshset with close elements
107  EntityHandle outSet;
108 
109  // create meshset
110  MB_CHK_ERR( mb.create_meshset( MESHSET_SET, outSet ) );
111 
112  // double sphere radius is 1
113  CartVect point( x, y, z );
114  if( spherical )
115  {
116  std::cout << " use spherical coordinates on the sphere of radius 1.\n";
118  pos.R = 1; // always on the
119  pos.lat = lat * M_PI / 180; // defined in math.h
120  pos.lon = lon * M_PI / 180;
121  point = IntxUtils::spherical_to_cart( pos );
122  }
123 
124  Range closeByCells;
125  for( Range::iterator it = elems.begin(); it != elems.end(); it++ )
126  {
127  EntityHandle cell = *it;
129  MB_CHK_SET_ERR( mb.get_coords( &cell, 1, &( center[0] ) ), "Can't get cell center coords" );
130  double dist = ( center - point ).length();
131  if( dist <= distance )
132  {
133  closeByCells.insert( cell );
134  }
135  }
136 
137  MB_CHK_SET_ERR( mb.add_entities( outSet, closeByCells ), "Can't add to entity set" );
138 
139  int numCells = (int)closeByCells.size();
140 
141  if( numCells == 0 )
142  {
143  if( !rank )
144  std::cout << " no close cells to the point " << point << " at distance less than " << distance << "\n";
145  }
146  else
147  {
148  if( !rank )
149  std::cout << " write file " << outFile << " with cells closer than " << distance << " from " << point
150  << "\n";
151  string writeOpts;
152  if( numProcesses > 1 ) writeOpts = string( "PARALLEL=WRITE_PART;" );
153  MB_CHK_SET_ERR( mb.write_file( outFile.c_str(), 0, writeOpts.c_str(), &outSet, 1 ), "Can't write file" );
154  }
155 
156  return 0;
157 }