MOAB: Mesh Oriented datABase  (version 5.5.0)
imoab_ptest2.cpp
Go to the documentation of this file.
1 /*
2  * imoab_ptest_C.cpp
3  *
4  * push parallel mesh into moab, using iMoab API, C version
5  * This program shows how to push a mesh into MOAB in parallel using iMoab, with sufficient
6  * information to resolve boundary sharing and exchange a layer of ghost information.
7  *
8  * After resolving the sharing, mesh is saved to a file, then read back again, in parallel
9  * the mesh is a quad mesh, 2x2 on each task,
10  * by default, this test is run on 2 processors
11 
12  * Test is similar to itaps/iMeshP_unit_tests.cpp, and with imoab_ptest.F, fortran 77 version
13  *
14  *
15  * Create a mesh:
16  * Groups of four quads will be arranged into parts as follows:
17  * +------+------+------+------+------+-----
18  * | | |
19  * | | |
20  * + Part 0 + Part 2 + Part 4
21  * | | |
22  * | | |
23  * +------+------+------+------+------+-----
24  * | | |
25  * | | |
26  * + Part 1 + Part 3 + Part 5
27  * | | |
28  * | | |
29  * +------+------+------+------+------+-----
30  *
31  * Vertices will be enumerated as follows:
32  * 1------6-----11-----16-----21-----26----- > x x from 0, 1, 2
33  * | | |
34  * | | |
35  * 2 7 12 17 22 27
36  * | | |
37  * | | |
38  * 3------8-----13-----18-----23-----28-----
39  * | | |
40  * | | |
41  * 4 9 14 19 24 29
42  * | | |
43  * | | |
44  * 5-----10-----15-----20-----25-----30-----
45  * |
46  * y varies from 0 to 4
47  *
48  * Processor 0 will have vertices 1, 2, 3, 6, 7, 8, 11, 12, 13
49  * and 4 quads, with ids from 1 to 4, and connectivity
50  * 1, 2, 7, 6; 2, 3, 8, 7; 6 ,7, 12, 11; 7, 8, 13, 12
51  * Processor 1 will have vertices 3, 4, 5, 8, 9, 10, 13, 14, 15
52  * and 4 quads, with ids from 5 to 8, and connectivity
53  * 3, 4, 8, 9; 4, 5, 10, 9; 8, 9, 14, 13; 9, 10, 15, 14,
54  * and so on
55  *
56  * Vertex Global IDs will be used to resolve sharing
57  *
58  * Element IDs will be [4*rank+1,4*rank+5]
59  * */
60 
61 /*
62  * #define ERROR(rval) if (0 .ne. rval) call exit(1)
63  */
64 
65 #include "moab/MOABConfig.h"
66 #include "moab_mpi.h"
67 #include "moab/iMOAB.h"
68 #include <cstdio>
69 #include <cstring>
70 #include <vector>
71 
72 #define ERROR( rc, msg ) \
73  if( 0 != ( rc ) ) \
74  { \
75  printf( "error %s", msg ); \
76  return 1; \
77  }
78 
79 int main( int argc, char** argv )
80 {
81  int my_id, num_procs, ix, iy, numv, nume;
82  int dime, lco, mbtype, blockid, npe;
83  char appname[10] = "IMTEST";
84  /* coordinates for 9 vertices */
85  double coordinates[27], deltax, deltay;
86  int ids[9] = { 1, 2, 3, 6, 7, 8, 11, 12, 13 };
87  int connec[16] = { 1, 2, 5, 4, 2, 3, 6, 5, 4, 5, 8, 7, 5, 6, 9, 8 };
88  /* used for ghosting */
89  int dimgh, bridge, num_layers;
90  double coords_core[27] = { 0., 0., 0., 0., 1., 0., 0., 2., 0., 1., 0., 0., 1., 1.,
91  0., 1., 2., 0., 2., 0., 0., 2., 1., 0., 2., 2., 0. };
92  int appID, compid;
93  iMOAB_AppID pid = &appID;
94 
95  MPI_Init( &argc, &argv );
96  MPI_Comm comm = MPI_COMM_WORLD;
97 
98  MPI_Comm_size( comm, &num_procs );
99  MPI_Comm_rank( comm, &my_id );
100 
101  ErrCode rc = iMOAB_Initialize( argc, argv );
102  ERROR( rc, "can't initialize" );
103  if( !my_id ) printf( " I'm process %d out of %d\n", my_id, num_procs );
104 
105  appname[7] = 0; // make sure it is NULL
106  compid = 8; // given number, external application number
107  rc = iMOAB_RegisterApplication( appname, &comm, &compid, pid );
108  ERROR( rc, " can't register app" );
109  /* create first 9 vertices, in a square 3x3; */
110  deltax = ( my_id / 2 ) * 2.;
111  deltay = ( my_id % 2 ) * 2.;
112  ix = ( my_id / 2 ) * 10;
113  iy = my_id % 2 * 2;
114  for( int i = 0; i < 9; i++ )
115  {
116  coordinates[3 * i] = coords_core[3 * i] + deltax;
117  coordinates[3 * i + 1] = coords_core[3 * i + 1] + deltay;
118  coordinates[3 * i + 2] = coords_core[3 * i + 2];
119 
120  /* translate the ids too, by multiples of 10 or add 2, depending on my_id*/
121  ids[i] = ids[i] + ix + iy;
122  }
123  numv = 9;
124  nume = 4;
125  lco = numv * 3;
126  dime = 3;
127  rc = iMOAB_CreateVertices( pid, &lco, &dime, coordinates );
128  ERROR( rc, "can't create vertices" );
129  /* create now 4 quads with those 9 vertices*/
130  mbtype = 3;
131  blockid = 100;
132  npe = 4;
133  rc = iMOAB_CreateElements( pid, &nume, &mbtype, &npe, connec, &blockid );
134  ERROR( rc, "can't create elements" );
135 
136  rc = iMOAB_ResolveSharedEntities( pid, &numv, ids );
137  ERROR( rc, "can't resolve shared ents" );
138 
139  rc = iMOAB_UpdateMeshInfo( pid );
140  ERROR( rc, "can't update mesh info" );
141 
142  int num_global_verts, num_global_cells;
143  iMOAB_GetGlobalInfo( pid, &num_global_verts, &num_global_cells );
144 
145  // test iMOAB_ReduceTagsMax on a tag
146  int tagType = DENSE_DOUBLE;
147  int num_components = 1;
148  int tagIndex = 0; // output
149 
150  rc = iMOAB_DefineTagStorage( pid, "afrac:ifrac", &tagType, &num_components, &tagIndex );
151  ERROR( rc, "failed to create tags afrac:ifrac " );
152  double af[4] = { 1., 1., 1., 1. };
153  int entType = 1; // cells
154  rc = iMOAB_SetDoubleTagStorage( pid, "afrac", &nume, &entType, af );
155  ERROR( rc, "failed to set tag afrac " );
156  /* write out the mesh file to disk, in parallel, if h5m*/
157 #ifdef MOAB_HAVE_HDF5_PARALLEL
158  char wopts[100] = "PARALLEL=WRITE_PART";
159  char outfile[32] = "whole.h5m";
160  rc = iMOAB_WriteMesh( pid, outfile, wopts );
161  ERROR( rc, "can't write mesh" );
162 #endif
163 
164  // define repeat tags
165  rc = iMOAB_DefineTagStorage( pid, "ofrac:afrac:ofrad", &tagType, &num_components, &tagIndex );
166  ERROR( rc, "failed to create tags ofrac:afrac:ofrad " );
167 
168  // write again
169 #ifdef MOAB_HAVE_HDF5_PARALLEL
170  rc = iMOAB_WriteMesh( pid, outfile, wopts );
171  ERROR( rc, "can't write mesh 3\n" );
172 #endif
173 
174  tagType = DENSE_INTEGER;
175  rc = iMOAB_DefineTagStorage( pid, "INTFIELD", &tagType, &num_components, &tagIndex );
176  ERROR( rc, "failed to get tag INTFIELD " );
177  // set some values
178  std::vector< int > valstest( numv );
179  for( int k = 0; k < numv; k++ )
180  {
181  valstest[k] = my_id + k;
182  }
183  int num_tag_storage_length = numv * num_components;
184  entType = 0; // vertex
185  // create an integer tag
186 
187  rc = iMOAB_SetIntTagStorage( pid, "INTFIELD", &num_tag_storage_length, &entType, &valstest[0] );
188  ERROR( rc, "failed to set tag INTFIELD " );
189 
190  rc = iMOAB_ReduceTagsMax( pid, &tagIndex, &entType );
191  ERROR( rc, "failed reduce tags max " );
192 
193  /* see ghost elements */
194  dimgh = 2; /* will ghost quads, topological dim 2 */
195  bridge = 0; /* use vertex as bridge */
196  num_layers = 1; /* so far, one layer only */
197  rc = iMOAB_DetermineGhostEntities( pid, &dimgh, &num_layers, &bridge );
198  ERROR( rc, "can't determine ghosts" );
199 
200  /* write out the mesh file to disk, in parallel, if h5m*/
201 #ifdef MOAB_HAVE_HDF5_PARALLEL
202  rc = iMOAB_WriteMesh( pid, outfile, wopts );
203  ERROR( rc, "can't write mesh" );
204 #endif
205  /* all done. de-register and finalize */
206  rc = iMOAB_DeregisterApplication( pid );
207  ERROR( rc, "can't de-register app" );
208 
209  rc = iMOAB_Finalize();
210  ERROR( rc, "can't finalize" );
211 
212  MPI_Finalize();
213  return 0;
214 }