Example demonstrating direct access to MOAB data with holes in entity handle space.
More...
Example demonstrating direct access to MOAB data with holes in entity handle space.
This example shows how to:
- Create a structured mesh with holes in the entity handle space
- Use direct access iterators to avoid API overhead
- Handle non-contiguous entity handles efficiently
- Access vertex coordinates, element connectivity, and tag data directly
- Work with adjacency lists for vertex-to-element relationships
- Use maps to track data chunks for non-contiguous handles
The program creates a 1D row of quad elements with specified holes, then demonstrates direct access to MOAB's internal data structures even when entity handles are not contiguous.
- Author
- MOAB Development Team
- Date
- 2024
Use direct access to MOAB data to avoid calling through API
This example creates a 1d row of quad elements, with a user-specified number of "holes" (missing quads) in the row:
* ---------------------- ---------------------- --------
* | | | | | | | | | |
* | | | |(hole)| | | |(hole)| | ...
* | | | | | | | | | |
* ---------------------- ---------------------- --------
*
This makes (nholes+1) contiguous runs of quad handles in the handle space This example shows how to use the xxx_iterate functions in MOAB (xxx = coords, connect, tag, adjacencies) to get direct pointer access to MOAB internal storage, which can be used without calling through the MOAB API.
- Initialize MOAB
- Create a quad mesh with holes, as depicted above
- Create 2 dense tags (tag1, tag2) for avg position to assign to quads, and # verts per quad (tag3)
- Get connectivity, coordinate, tag1 iterators
- Iterate through quads, computing midpoint based on vertex positions, set on quad-based tag1
- Set up map from starting quad handle for a chunk to struct of (tag1_ptr, tag2_ptr, tag3_ptr), pointers to the dense tag storage for those tags for the chunk
- Iterate through vertices, summing positions into tag2 on connected quads and incrementing vertex count
- Iterate through quads, normalizing tag2 by vertex count and comparing values of tag1 and tag2
To compile:
make DirectAccessWithHoles
To run: ./DirectAccess [-nquads <# quads>] [-holes <# holes>]
- Parameters
-
| argc | Number of command line arguments |
| argv | Command line arguments array |
- Returns
- 0 on success, 1 on failure
Definition in file DirectAccessWithHoles.cpp.
| int main |
( |
int |
argc, |
|
|
char ** |
argv |
|
) |
| |
Definition at line 77 of file DirectAccessWithHoles.cpp.
81 if( NULL == mbImpl )
return 1;
83 int nquads = 1000, nholes = 1;
87 opts.
addOpt<
int >( string(
"nquads,n" ), string(
"Number of quads in the mesh (default = 1000" ), &nquads );
88 opts.
addOpt<
int >( string(
"holes,H" ), string(
"Number of holes in the element handle space (default = 1" ),
91 if( nholes >= nquads )
93 cerr <<
"Number of holes needs to be < number of elements." << endl;
107 Tag tag1, tag2, tag3;
109 "Trouble creating tag1" );
110 double def_val[3] = { 0.0, 0.0, 0.0 };
112 "Trouble creating tag2" );
116 "Trouble creating tag3" );
120 double *x_ptr, *y_ptr, *z_ptr, *tag1_ptr, *tag2_ptr;
134 "Error in coords_iterate" );
135 assert( count == (
int)verts.
size() );
141 while( e_it != elems.
end() )
146 "Error in connect_iterate" );
148 "Error in tag1_iterate" );
151 for(
int i = 0; i < count; i++ )
153 tag1_ptr[0] = tag1_ptr[1] = tag1_ptr[2] = 0.0;
154 for(
int j = 0; j < vpere; j++ )
156 int v_index = conn_ptr[j] - first_vert;
157 tag1_ptr[0] += x_ptr[v_index];
158 tag1_ptr[1] += y_ptr[v_index];
159 tag1_ptr[2] += z_ptr[v_index];
161 tag1_ptr[0] /= vpere;
162 tag1_ptr[1] /= vpere;
163 tag1_ptr[2] /= vpere;
183 map< EntityHandle, tag_struct > elem_map;
184 e_it = elems.
begin();
185 while( e_it != elems.
end() )
189 "Error in tag2_iterate" );
191 "Error in tag3_iterate" );
192 elem_map[*e_it] = ts;
200 const vector< EntityHandle >** adjs_ptr;
201 while( v_it != verts.
end() )
206 "Error in coords_iterate" );
208 "Error in adjacencies_iterate" );
210 for(
int v = 0; v < count; v++ )
212 const vector< EntityHandle >* avec = *( adjs_ptr + v );
213 for( vector< EntityHandle >::const_iterator ait = avec->begin(); ait != avec->end(); ++ait )
218 map< EntityHandle, tag_struct >::iterator mit = elem_map.upper_bound( *ait );
221 int a_ind = *ait - ( *mit ).first;
223 ts.
avg_ptr[3 * a_ind + 0] += x_ptr[v];
224 ts.
avg_ptr[3 * a_ind + 1] += y_ptr[v];
225 ts.
avg_ptr[3 * a_ind + 2] += z_ptr[v];
235 e_it = elems.
begin();
236 while( e_it != elems.
end() )
241 "Error in tag1_iterate" );
243 "Error in tag2_iterate" );
245 "Error in tag3_iterate" );
248 for(
int i = 0; i < count; i++ )
250 for(
int j = 0; j < 3; j++ )
251 tag2_ptr[3 * i + j] /= (
double)tag3_ptr[i];
252 if( tag1_ptr[3 * i] != tag2_ptr[3 * i] || tag1_ptr[3 * i + 1] != tag2_ptr[3 * i + 1] ||
253 tag1_ptr[3 * i + 2] != tag2_ptr[3 * i + 2] )
254 cout <<
"Tag1, tag2 disagree for element " << *e_it + i << endl;
References ProgOptions::addOpt(), moab::Interface::adjacencies_iterate(), tag_struct::avg_ptr, moab::Range::begin(), moab::Interface::connect_iterate(), moab::Interface::coords_iterate(), create_mesh_with_holes(), moab::Range::end(), moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_handle(), MB_CHK_SET_ERR, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, tag_struct::nv_ptr, ProgOptions::parseCommandLine(), moab::Range::size(), moab::Range::subset_by_dimension(), moab::Interface::tag_get_handle(), and moab::Interface::tag_iterate().