Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
copyPartition.cpp
Go to the documentation of this file.
1 /**
2  * @file copyPartition.cpp
3  * @brief Example demonstrating partition information copying between mesh files
4  *
5  * This example shows how to:
6  * - Load partition information from point cloud files
7  * - Copy partition data to PG2 mesh files
8  * - Match entities between different mesh files using global IDs
9  * - Create parallel partition sets for visualization
10  * - Handle partition mapping for E3SM climate model meshes
11  * - Write partition-enhanced mesh files for VisIt visualization
12  *
13  * This tool is useful for climate model visualization where
14  * partition information needs to be transferred between different
15  * mesh representations (point cloud to structured mesh).
16  *
17  * @author MOAB Development Team
18  * @date 2024
19  *
20 
21  * this tool will take an existing h5m phys grid partition file (point cloud) and copy the
22  * partition information on a pg2 mesh file, for better viewing with VisIt
23  *
24  * example of usage:
25  * ./copyPartition -p AtmPhys.h5m -g wholeATM_PG2.h5m -o atm_PG2_part.h5m
26  *
27  * the *PG2" style atm mesh is available in E3SM only for pg2 runs, something like
28  * --res ne30pg2_r05_oECv3_ICG --compset A_WCYCL1850S_CMIP6
29  * or
30  * --res ne4pg2_ne4pg2 --compset FC5AV1C-L
31  *
32  * @param argc Number of command line arguments
33  * @param argv Command line arguments array
34  * @return 0 on success, 1 on failure
35  */
36 #include "moab/ProgOptions.hpp"
37 #include "moab/Core.hpp"
38 
39 #include <cmath>
40 #include <sstream>
41 
42 using namespace moab;
43 
44 int main( int argc, char* argv[] )
45 {
46 
47  ProgOptions opts;
48 
49  std::string physfile, pg2file, outfile;
50 
51  opts.addOpt< std::string >( "physgridfile,p", "phys grid filename", &physfile );
52  opts.addOpt< std::string >( "pg2file,g", "pg2 mesh file", &pg2file );
53  opts.addOpt< std::string >( "output,o", "output mesh filename", &outfile );
54 
55  opts.parseCommandLine( argc, argv );
56 
57  std::cout << "phys grid cloud file: " << physfile << "\n";
58  std::cout << "pg2 mesh file: " << pg2file << "\n";
59  std::cout << "output file: " << outfile << "\n";
60 
61  if( physfile.empty() )
62  {
63  opts.printHelp();
64  return 0;
65  }
66  ErrorCode rval;
67  Core* mb = new Core();
68 
69  MB_CHK_SET_ERR( mb->load_file( physfile.c_str() ), "can't load phys grid file" );
70 
71  Core* mb2 = new Core();
72  MB_CHK_SET_ERR( mb2->load_file( pg2file.c_str() ), "can't load pg2 mesh file" );
73 
74  Tag globalIDTag1 = mb->globalId_tag();
75  Tag parti;
76  MB_CHK_SET_ERR( mb->tag_get_handle( "partition", parti ), "can't get partition tag phys grid mesh " );
77 
78  Tag globalIDTag2 = mb2->globalId_tag();
79 
80  Range verts1;
81  MB_CHK_SET_ERR( mb->get_entities_by_dimension( 0, 0, verts1 ), "can't get vertices " );
82 
83  std::vector< int > partValues;
84  partValues.resize( verts1.size() );
85  MB_CHK_SET_ERR( mb->tag_get_data( parti, verts1, &partValues[0] ), "can't get parts values on vertices " );
86 
87  Range cells;
88  MB_CHK_SET_ERR( mb2->get_entities_by_dimension( 0, 2, cells ), "can't get 2d cells " );
89  std::vector< int > globalIdsCells;
90  globalIdsCells.resize( cells.size() );
91  MB_CHK_SET_ERR( mb2->tag_get_data( globalIDTag2, cells, &globalIdsCells[0] ), "can't get global ids cells " );
92 
93  std::vector< int > globalIdsVerts;
94  globalIdsVerts.resize( verts1.size() );
95  MB_CHK_SET_ERR( mb->tag_get_data( globalIDTag1, verts1, &globalIdsVerts[0] ), "can't get global ids cells " );
96 
97  Tag partTag;
98  MB_CHK_SET_ERR( mb2->tag_get_handle( "PARALLEL_PARTITION", partTag ), "can't partition tag " );
99 
100  Range sets;
101  MB_CHK_ERR( mb2->get_entities_by_type_and_tag( 0, MBENTITYSET, &partTag, NULL, 1, sets ) );
102 
103  std::vector< int > setValues;
104  setValues.resize( sets.size() );
105  MB_CHK_ERR( mb2->tag_get_data( partTag, sets, &setValues[0] ) );
106 
107  std::map< int, EntityHandle > valToSet;
108  int i = 0;
109  for( Range::iterator st = sets.begin(); st != sets.end(); ++st, i++ )
110  {
111  valToSet[setValues[i]] = *st;
112  }
113  // now, every cell will be put into one set, by looking at the global id of cell
114 
115  std::map< int, EntityHandle > gidToCell;
116  i = 0;
117  for( Range::iterator it = cells.begin(); it != cells.end(); ++it, i++ )
118  {
119  gidToCell[globalIdsCells[i]] = *it;
120  }
121  // empty all sets
122  MB_CHK_ERR( mb2->clear_meshset( sets ) );
123 
124  // look now at parti values for vertices, and their global ids
125  for( i = 0; i < (int)verts1.size(); i++ )
126  {
127  int part = partValues[i];
128  int gid = globalIdsVerts[i];
129  EntityHandle set1 = valToSet[part];
130  EntityHandle cell = gidToCell[gid];
131  MB_CHK_ERR( mb2->add_entities( set1, &cell, 1 ) );
132  }
133 
134  MB_CHK_SET_ERR( mb2->write_file( outfile.c_str() ), "can't write file" );
135 
136  delete mb;
137  delete mb2;
138 
139  return 0;
140 }