This example creates a 1d row of quad elements, with a user-specified number of "holes" (missing quads) in the row:
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.
#include <map>
#include <iostream>
#include <cassert>
using namespace std;
{
double* avg_ptr;
int* nv_ptr;
};
int main(
int argc,
char** argv )
{
Interface* mbImpl = new( std::nothrow ) Core;
if( NULL == mbImpl ) return 1;
int nquads = 1000, nholes = 1;
opts.
addOpt<
int >( string(
"nquads,n" ), string(
"Number of quads in the mesh (default = 1000" ), &nquads );
opts.
addOpt<
int >( string(
"holes,H" ), string(
"Number of holes in the element handle space (default = 1" ),
&nholes );
if( nholes >= nquads )
{
cerr << "Number of holes needs to be < number of elements." << endl;
return 1;
}
Range verts, elems;
rval = mbImpl->get_entities_by_handle( 0, elems );
MB_CHK_SET_ERR( rval,
"Trouble getting all entities" );
verts = elems.subset_by_dimension( 0 );
elems -= verts;
double def_val[3] = { 0.0, 0.0, 0.0 };
int def_val_int = 0;
double *x_ptr, *y_ptr, *z_ptr, *tag1_ptr, *tag2_ptr;
int* tag3_ptr;
int vpere, count;
rval = mbImpl->coords_iterate( verts.begin(), verts.end(), x_ptr, y_ptr, z_ptr, count );
MB_CHK_SET_ERR( rval,
"Error in coords_iterate" );
assert( count == (int)verts.size() );
while( e_it != elems.end() )
{
rval = mbImpl->connect_iterate( e_it, elems.end(), conn_ptr, vpere, count );
MB_CHK_SET_ERR( rval,
"Error in connect_iterate" );
rval = mbImpl->tag_iterate( tag1, e_it, elems.end(), count, (
void*&)tag1_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag1_iterate" );
for( int i = 0; i < count; i++ )
{
tag1_ptr[0] = tag1_ptr[1] = tag1_ptr[2] = 0.0;
for( int j = 0; j < vpere; j++ )
{
int v_index = conn_ptr[j] - first_vert;
tag1_ptr[0] += x_ptr[v_index];
tag1_ptr[1] += y_ptr[v_index];
tag1_ptr[2] += z_ptr[v_index];
}
tag1_ptr[0] /= vpere;
tag1_ptr[1] /= vpere;
tag1_ptr[2] /= vpere;
conn_ptr += vpere;
tag1_ptr += 3;
}
e_it += count;
}
map< EntityHandle, tag_struct > elem_map;
e_it = elems.begin();
while( e_it != elems.end() )
{
rval = mbImpl->tag_iterate( tag2, e_it, elems.end(), count, (
void*&)ts.
avg_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag2_iterate" );
rval = mbImpl->tag_iterate( tag3, e_it, elems.end(), count, (
void*&)ts.
nv_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag3_iterate" );
elem_map[*e_it] = ts;
e_it += count;
}
Range dum_range;
rval = mbImpl->get_adjacencies( &( *v_it ), 1, 2,
false, dum_range );
MB_CHK_SET_ERR( rval,
"Error in get_adjacencies" );
const vector< EntityHandle >** adjs_ptr;
while( v_it != verts.end() )
{
rval = mbImpl->coords_iterate( v_it, verts.end(), x_ptr, y_ptr, z_ptr, count );
MB_CHK_SET_ERR( rval,
"Error in coords_iterate" );
rval = mbImpl->adjacencies_iterate( v_it, verts.end(), adjs_ptr, count );
MB_CHK_SET_ERR( rval,
"Error in adjacencies_iterate" );
for( int v = 0; v < count; v++ )
{
const vector< EntityHandle >* avec = *( adjs_ptr + v );
for( vector< EntityHandle >::const_iterator ait = avec->begin(); ait != avec->end(); ++ait )
{
map< EntityHandle, tag_struct >::iterator mit = elem_map.upper_bound( *ait );
--mit;
int a_ind = *ait - ( *mit ).first;
ts.
avg_ptr[3 * a_ind + 0] += x_ptr[v];
ts.
avg_ptr[3 * a_ind + 1] += y_ptr[v];
ts.
avg_ptr[3 * a_ind + 2] += z_ptr[v];
}
}
v_it += count;
}
e_it = elems.begin();
while( e_it != elems.end() )
{
rval = mbImpl->tag_iterate( tag1, e_it, elems.end(), count, (
void*&)tag1_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag1_iterate" );
rval = mbImpl->tag_iterate( tag2, e_it, elems.end(), count, (
void*&)tag2_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag2_iterate" );
rval = mbImpl->tag_iterate( tag3, e_it, elems.end(), count, (
void*&)tag3_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag3_iterate" );
for( int i = 0; i < count; i++ )
{
for( int j = 0; j < 3; j++ )
tag2_ptr[3 * i + j] /= (double)tag3_ptr[i];
if( tag1_ptr[3 * i] != tag2_ptr[3 * i] || tag1_ptr[3 * i + 1] != tag2_ptr[3 * i + 1] ||
tag1_ptr[3 * i + 2] != tag2_ptr[3 * i + 2] )
cout << "Tag1, tag2 disagree for element " << *e_it + i << endl;
}
e_it += count;
}
delete mbImpl;
return 0;
}
{
ReadUtilIface* read_iface;
vector< double* > coords;
rval = read_iface->get_node_coords( 3, 2 * ( nquads + 1 ), 0, start_vert, coords );
MB_CHK_SET_ERR( rval,
"Error in get_node_arrays" );
rval = read_iface->get_element_connect( nquads, 4,
MBQUAD, 0, start_elem, connect );
MB_CHK_SET_ERR( rval,
"Error in get_element_connect" );
for( int i = 0; i < nquads; i++ )
{
coords[0][2 * i] = coords[0][2 * i + 1] = (double)i;
coords[1][2 * i] = 0.0;
coords[1][2 * i + 1] = 1.0;
coords[2][2 * i] = coords[2][2 * i + 1] = (double)0.0;
for( int j = 0; j < 4; j++ )
connect[4 * i + j] = quad_v + j;
}
coords[0][2 * nquads] = coords[0][2 * nquads + 1] = (double)nquads;
coords[1][2 * nquads] = 0.0;
coords[1][2 * nquads + 1] = 1.0;
coords[2][2 * nquads] = coords[2][2 * nquads + 1] = (double)0.0;
int de = nquads / ( nholes + 1 );
for( int i = 0; i < nholes; i++ )
{
start_elem += de;
rval = mbImpl->delete_entities( &start_elem, 1 );
MB_CHK_SET_ERR( rval,
"Error in delete_entities" );
}
}