Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
BoundaryContinents.cpp File Reference

Example demonstrating creation of continent boundary edge meshes. More...

#include "moab/Core.hpp"
#include "moab/ReadUtilIface.hpp"
#include "moab/CartVect.hpp"
#include <iostream>
#include <fstream>
+ Include dependency graph for BoundaryContinents.cpp:

Go to the source code of this file.

Functions

double getLat (CartVect p)
 
double getLon (CartVect p)
 
int main (int argc, char **argv)
 

Variables

string bd_name = string( MESH_DIR ) + string( "/../examples/earth/boundary_points.dat" )
 
string loops = string( MESH_DIR ) + string( "/../examples/earth/SaveLoopCounts" )
 

Detailed Description

Example demonstrating creation of continent boundary edge meshes.

This example shows how to:

  • Load continent boundary point data and loop information
  • Create edge meshes from boundary point sequences
  • Convert 3D spherical coordinates to 2D lat-lon coordinates
  • Handle periodic boundary conditions for longitude wrapping
  • Remove long edges that cross the date line
  • Create mesh sets for boundary visualization
  • Write boundary meshes in VTK format

This tool is useful for creating continent boundary meshes for climate and geophysical applications.

Author
MOAB Development Team
Date
2024

Definition in file BoundaryContinents.cpp.

Function Documentation

◆ getLat()

double getLat ( CartVect  p)
Examples
BoundaryContinents.cpp.

Definition at line 44 of file BoundaryContinents.cpp.

45 {
46  p.normalize();
47  return asin( p[2] );
48 }

References moab::CartVect::normalize().

Referenced by main().

◆ getLon()

double getLon ( CartVect  p)
Examples
BoundaryContinents.cpp.

Definition at line 49 of file BoundaryContinents.cpp.

50 {
51  p.normalize();
52  double lon;
53 
54  lon = atan2( p[1], p[0] );
55  if( lon < -2.95 )
56  { // this is Behring Strait :)
57  return 2.0 * M_PI + lon;
58  }
59  else
60  {
61  return lon;
62  }
63 }

References moab::CartVect::normalize().

Referenced by main().

◆ main()

int main ( int  argc,
char **  argv 
)

get loops for boundaries

Examples
BoundaryContinents.cpp.

Definition at line 65 of file BoundaryContinents.cpp.

66 {
67  // Get MOAB instance
68  Interface* mb = new( std::nothrow ) Core;
69  if( NULL == mb ) return 1;
70 
71  if( argc > 1 )
72  {
73  // User has input file for boundary describing continents
74  bd_name = argv[1];
75  }
76  if( argc > 2 )
77  {
78  // User has input file for loops for continents/islands
79  loops = argv[2];
80  }
81 
82  std::vector< double > coords;
83  ifstream bdFile( bd_name.c_str() );
84  if( !bdFile )
85  {
86  cout << endl << "Failed to open file " << bd_name << endl;
87  ;
88  return 1;
89  }
90  coords.resize( 0 );
91  while( !bdFile.eof() )
92  {
93  double co;
94  bdFile >> co;
95  coords.push_back( co );
96  }
97  cout << " number of boundary points:" << coords.size() / 3 << "\n";
98  /// get loops for boundaries
99  vector< int > loopsindx;
100  ifstream loopFile( loops.c_str() );
101  while( !loopFile.eof() )
102  {
103  int indx;
104  loopFile >> indx;
105  loopsindx.push_back( indx );
106  }
107  cout << "number of loops: " << loopsindx.size() / 2 << "\n";
108  ReadUtilIface* readMeshIface;
109  mb->query_interface( readMeshIface );
110  Range verts;
111 
112  MB_CHK_SET_ERR( mb->create_vertices( &coords[0], coords.size() / 3, verts ), "do not create boundary vertices" );
113 
114  Tag gid = mb->globalId_tag();
115 
116  int num_edges = 0;
117  for( size_t i = 0; i < loopsindx.size() / 2; i++ )
118  {
119  num_edges += ( loopsindx[2 * i + 1] - loopsindx[2 * i] + 1 );
120  }
121  EntityHandle handle;
122  EntityHandle* conn_array;
123  MB_CHK_SET_ERR( readMeshIface->get_element_connect( num_edges, 2, MBEDGE, 1, handle, conn_array ), "do not elems" );
124  int i1 = 0; // index in edge connectivity
125  for( size_t i = 0; i < loopsindx.size() / 2; i++ )
126  {
127  for( int j = loopsindx[2 * i]; j <= loopsindx[2 * i + 1]; j++ )
128  {
129  int j2;
130  j2 = j;
131  if( j == loopsindx[2 * i + 1] ) j2 = loopsindx[2 * i] - 1; // close the loop
132  conn_array[2 * i1] = verts[j - 1]; // vertices for sure start at 1
133  conn_array[2 * i1 + 1] = verts[j2]; // vertices for sure start at 1
134  i1++;
135  }
136  // the last vertex is first one in the loop
137  }
138 
139  Range bedges( handle, handle + num_edges - 1 );
140  EntityHandle bound_set;
141  MB_CHK_SET_ERR( mb->create_meshset( MESHSET_SET, bound_set ), "Can't create boundary edges set" );
142 
143  MB_CHK_SET_ERR( mb->add_entities( bound_set, bedges ), "Can't add edges to boundary set" );
144 
145  // set global ids for vertices and edges
146  vector< int > gids;
147  gids.resize( verts.size() );
148  for( int j = 0; j < (int)verts.size(); j++ )
149  {
150  gids[j] = j + 1;
151  }
152  MB_CHK_SET_ERR( mb->tag_set_data( gid, verts, &gids[0] ), "Can't set global ids on verts" );
153  // we have less edges than vertices, we can reuse the array for edges too
154  MB_CHK_SET_ERR( mb->tag_set_data( gid, bedges, &gids[0] ), "Can't set global ids on edges" );
155 
156  mb->write_file( "bound.vtk", 0, 0, &bound_set, 1 );
157 
158  // now project the mesh in 2d plane
159  // get all the vertices coordinates
160  std::vector< CartVect > co3;
161  co3.resize( verts.size() );
162  MB_CHK_SET_ERR( mb->get_coords( verts, &( co3[0][0] ) ), "Can't get vertex coords" );
163  for( size_t i = 0; i < verts.size(); i++ )
164  {
165  CartVect p = co3[i];
166  double lat1 = getLat( p );
167  double lon1 = getLon( p );
168  co3[i] = CartVect( lon1, lat1, 0. );
169  }
170  MB_CHK_SET_ERR( mb->set_coords( verts, &( co3[0][0] ) ), "Can't set new vertex coords" );
171  // remove edges in 2d that are too long (longer than 6; they are on the other side..., periodic)
172 
173  Range longEdges;
174  for( Range::iterator eit = bedges.begin(); eit != bedges.end(); ++eit )
175  {
176  EntityHandle eh = *eit;
177  const EntityHandle* conn;
178  int nconn;
179  MB_CHK_ERR( mb->get_connectivity( eh, conn, nconn ) );
180  // get coordinates of nodes
181  CartVect c2[2];
182  MB_CHK_ERR( mb->get_coords( conn, 2, &( c2[0][0] ) ) );
183  double dist = ( c2[1] - c2[0] ).length_squared();
184  if( dist > 36. ) // too long edge in 2d, remove it
185  longEdges.insert( eh );
186  }
187  MB_CHK_ERR( mb->delete_entities( longEdges ) );
188 
189  mb->write_file( "bound2d.vtk" );
190  delete mb;
191 
192  return 0;
193 }

References moab::Core::add_entities(), bd_name, moab::Range::begin(), moab::Core::create_meshset(), moab::Core::create_vertices(), moab::Core::delete_entities(), moab::Range::end(), moab::Core::get_connectivity(), moab::Core::get_coords(), moab::ReadUtilIface::get_element_connect(), getLat(), getLon(), moab::Core::globalId_tag(), moab::Range::insert(), length_squared(), loops, mb, MB_CHK_ERR, MB_CHK_SET_ERR, MBEDGE, MESHSET_SET, moab::Interface::query_interface(), moab::Core::set_coords(), moab::Range::size(), moab::Core::tag_set_data(), and moab::Core::write_file().

Variable Documentation

◆ bd_name

string bd_name = string( MESH_DIR ) + string( "/../examples/earth/boundary_points.dat" )
Examples
BoundaryContinents.cpp.

Definition at line 41 of file BoundaryContinents.cpp.

Referenced by main().

◆ loops

string loops = string( MESH_DIR ) + string( "/../examples/earth/SaveLoopCounts" )
Examples
BoundaryContinents.cpp.

Definition at line 42 of file BoundaryContinents.cpp.

Referenced by main().