Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
moab::NestedRefine Class Reference

#include <NestedRefine.hpp>

+ Collaboration diagram for moab::NestedRefine:

Classes

struct  codeperf
 
struct  intFEdge
 Helper. More...
 
struct  level_memory
 
struct  pmat
 
struct  refPatterns
 refPatterns More...
 

Public Member Functions

 NestedRefine (Core *impl, ParallelComm *comm=0, EntityHandle rset=0)
 
 ~NestedRefine ()
 
ErrorCode initialize ()
 
ErrorCode generate_mesh_hierarchy (int num_level, int *level_degrees, std::vector< EntityHandle > &level_sets, bool optimize=false)
 Generate a mesh hierarchy. More...
 
ErrorCode get_connectivity (EntityHandle ent, int level, std::vector< EntityHandle > &conn)
 Given an entity and its level, return its connectivity. More...
 
ErrorCode get_coordinates (EntityHandle *verts, int num_verts, int level, double *coords)
 Given a vector of vertices and their level, return its coordinates. More...
 
ErrorCode get_adjacencies (const EntityHandle source_entity, const unsigned int target_dimension, std::vector< EntityHandle > &target_entities)
 Get the adjacencies associated with an entity. More...
 
ErrorCode child_to_parent (EntityHandle child, int child_level, int parent_level, EntityHandle *parent)
 
ErrorCode parent_to_child (EntityHandle parent, int parent_level, int child_level, std::vector< EntityHandle > &children)
 
ErrorCode vertex_to_entities_up (EntityHandle vertex, int vert_level, int parent_level, std::vector< EntityHandle > &incident_entities)
 
ErrorCode vertex_to_entities_down (EntityHandle vertex, int vert_level, int child_level, std::vector< EntityHandle > &incident_entities)
 
ErrorCode get_vertex_duplicates (EntityHandle vertex, int level, EntityHandle &dupvertex)
 
bool is_entity_on_boundary (const EntityHandle &entity)
 
ErrorCode exchange_ghosts (std::vector< EntityHandle > &lsets, int num_glayers)
 
ErrorCode update_special_tags (int level, EntityHandle &lset)
 

Public Attributes

codeperf timeall
 

Protected Member Functions

int get_index_from_degree (int degree)
 
ErrorCode estimate_hm_storage (EntityHandle set, int level_degree, int cur_level, int hmest[4])
 
ErrorCode create_hm_storage_single_level (EntityHandle *set, int cur_level, int estL[4])
 
ErrorCode generate_hm (int *level_degrees, int num_level, EntityHandle *hm_set, bool optimize)
 
ErrorCode construct_hm_entities (int cur_level, int deg)
 
ErrorCode construct_hm_1D (int cur_level, int deg)
 
ErrorCode construct_hm_1D (int cur_level, int deg, EntityType type, std::vector< EntityHandle > &trackverts)
 
ErrorCode construct_hm_2D (int cur_level, int deg)
 
ErrorCode construct_hm_2D (int cur_level, int deg, EntityType type, std::vector< EntityHandle > &trackvertsC_edg, std::vector< EntityHandle > &trackvertsF)
 
ErrorCode construct_hm_3D (int cur_level, int deg)
 
ErrorCode subdivide_cells (EntityType type, int cur_level, int deg)
 
ErrorCode subdivide_tets (int cur_level, int deg)
 
ErrorCode copy_vertices_from_prev_level (int cur_level)
 
ErrorCode count_subentities (EntityHandle set, int cur_level, int *nedges, int *nfaces)
 
ErrorCode get_octahedron_corner_coords (int cur_level, int deg, EntityHandle *vbuffer, double *ocoords)
 
int find_shortest_diagonal_octahedron (int cur_level, int deg, EntityHandle *vbuffer)
 
int get_local_vid (EntityHandle vid, EntityHandle ent, int level)
 
ErrorCode update_tracking_verts (EntityHandle cid, int cur_level, int deg, std::vector< EntityHandle > &trackvertsC_edg, std::vector< EntityHandle > &trackvertsC_face, EntityHandle *vbuffer)
 
ErrorCode reorder_indices (int cur_level, int deg, EntityHandle cell, int lfid, EntityHandle sib_cell, int sib_lfid, int index, int *id_sib)
 
ErrorCode reorder_indices (int deg, EntityHandle *face1_conn, EntityHandle *face2_conn, int nvF, std::vector< int > &lemap, std::vector< int > &vidx, int *leorient=NULL)
 
ErrorCode reorder_indices (int deg, int nvF, int comb, int *childfid_map)
 
ErrorCode reorder_indices (EntityHandle *face1_conn, EntityHandle *face2_conn, int nvF, int *conn_map, int &comb, int *orient=NULL)
 
ErrorCode get_lid_inci_child (EntityType type, int deg, int lfid, int leid, std::vector< int > &child_ids, std::vector< int > &child_lvids)
 
ErrorCode print_maps_1D (int level)
 
ErrorCode print_maps_2D (int level, EntityType type)
 
ErrorCode print_maps_3D (int level, EntityType type)
 
ErrorCode compute_coordinates (int cur_level, int deg, EntityType type, EntityHandle *vbuffer, int vtotal, double *corner_coords, std::vector< int > &vflag, int nverts_prev)
 
ErrorCode update_local_ahf (int deg, EntityType type, EntityHandle *vbuffer, EntityHandle *ent_buffer, int etotal)
 
ErrorCode update_local_ahf (int deg, EntityType type, int pat_id, EntityHandle *vbuffer, EntityHandle *ent_buffer, int etotal)
 
ErrorCode update_global_ahf (EntityType type, int cur_level, int deg, std::vector< int > *pattern_ids=NULL)
 
ErrorCode update_global_ahf_1D (int cur_level, int deg)
 
ErrorCode update_global_ahf_1D_sub (int cur_level, int deg)
 
ErrorCode update_ahf_1D (int cur_level)
 
ErrorCode update_global_ahf_2D (int cur_level, int deg)
 
ErrorCode update_global_ahf_2D_sub (int cur_level, int deg)
 
ErrorCode update_global_ahf_3D (int cur_level, int deg, std::vector< int > *pattern_ids=NULL)
 
bool is_vertex_on_boundary (const EntityHandle &entity)
 
bool is_edge_on_boundary (const EntityHandle &entity)
 
bool is_face_on_boundary (const EntityHandle &entity)
 
bool is_cell_on_boundary (const EntityHandle &entity)
 

Protected Attributes

CorembImpl
 
ParallelCommpcomm
 
HalfFacetRepahf
 
CpuTimertm
 
EntityHandle _rset
 
Range _inverts
 
Range _inedges
 
Range _infaces
 
Range _incells
 
EntityType elementype
 
int meshdim
 
int nlevels
 
int level_dsequence [MAX_LEVELS]
 
std::map< int, int > deg_index
 
bool hasghost
 
level_memory level_mesh [MAX_LEVELS]
 

Static Protected Attributes

static const refPatterns refTemplates [9][MAX_DEGREE]
 refPatterns More...
 
static const intFEdge intFacEdg [2][2]
 
static const pmat permutation [2]
 

Detailed Description

Examples
UniformRefinement.cpp.

Definition at line 34 of file NestedRefine.hpp.

Constructor & Destructor Documentation

◆ NestedRefine()

moab::NestedRefine::NestedRefine ( Core impl,
ParallelComm comm = 0,
EntityHandle  rset = 0 
)

Definition at line 24 of file NestedRefine.cpp.

25  : mbImpl( impl ), pcomm( comm ), _rset( rset )
26 {
28  assert( NULL != impl );
29 
30 #ifdef MOAB_HAVE_MPI
31  // Get the Parallel Comm instance to prepare all new sets to work in parallel
32  // in case the user did not provide any arguments
33  if( !comm ) pcomm = moab::ParallelComm::get_pcomm( mbImpl, 0 );
34 #endif
35  error = initialize();
36  if( error != MB_SUCCESS )
37  {
38  std::cout << "Error initializing NestedRefine\n" << std::endl;
39  exit( 1 );
40  }
41 }

References moab::error(), ErrorCode, moab::ParallelComm::get_pcomm(), initialize(), MB_SUCCESS, mbImpl, and pcomm.

◆ ~NestedRefine()

moab::NestedRefine::~NestedRefine ( )

Definition at line 43 of file NestedRefine.cpp.

44 {
45 #ifdef MOAB_HAVE_AHF
46  ahf = NULL;
47 #else
48  delete ahf;
49 #endif
50  delete tm;
51 }

References ahf, and tm.

Member Function Documentation

◆ child_to_parent()

ErrorCode moab::NestedRefine::child_to_parent ( EntityHandle  child,
int  child_level,
int  parent_level,
EntityHandle parent 
)

Given an entity from a certain level, it returns a pointer to its parent at the requested parent level. NOTE: This query does not support vertices.

Parameters
childEntityHandle of the entity whose parent is requested
child_levelMesh level where the child exists
parent_levelMesh level from which parent is requested
parentPointer to the parent in the requested parent_level

Definition at line 240 of file NestedRefine.cpp.

241 {
242  assert( ( child_level > 0 ) && ( child_level > parent_level ) );
243  EntityType type = mbImpl->type_from_handle( child );
244  assert( type != MBVERTEX );
245 
246  int child_index;
247  if( type == MBEDGE )
248  child_index = child - level_mesh[child_level - 1].start_edge;
249  else if( type == MBTRI || type == MBQUAD )
250  child_index = child - level_mesh[child_level - 1].start_face;
251  else if( type == MBTET || type == MBHEX )
252  child_index = child - level_mesh[child_level - 1].start_cell;
253  else
254  MB_SET_ERR( MB_FAILURE, "Requesting parent for unsupported entity type" );
255 
256  int parent_index;
257  int l = child_level - parent_level;
258  for( int i = 0; i < l; i++ )
259  {
260  int d = get_index_from_degree( level_dsequence[child_level - i - 1] );
261  int nch = refTemplates[type - 1][d].total_new_ents;
262  child_index = child_index / nch;
263  }
264  parent_index = child_index;
265 
266  if( type == MBEDGE )
267  {
268  if( parent_level > 0 )
269  *parent = level_mesh[parent_level - 1].start_edge + parent_index;
270  else
271  *parent = _inedges[parent_index];
272  }
273  else if( type == MBTRI || type == MBQUAD )
274  {
275  if( parent_level > 0 )
276  *parent = level_mesh[parent_level - 1].start_face + parent_index;
277  else
278  *parent = _infaces[parent_index];
279  }
280  else if( type == MBTET || type == MBHEX )
281  {
282  if( parent_level > 0 )
283  *parent = level_mesh[parent_level - 1].start_cell + parent_index;
284  else
285  *parent = _incells[parent_index];
286  }
287 
288  return MB_SUCCESS;
289 }

References _incells, _inedges, _infaces, get_index_from_degree(), level_dsequence, level_mesh, MB_SET_ERR, MB_SUCCESS, MBEDGE, MBHEX, mbImpl, MBQUAD, MBTET, MBTRI, MBVERTEX, refTemplates, moab::NestedRefine::level_memory::start_cell, moab::NestedRefine::level_memory::start_edge, moab::NestedRefine::level_memory::start_face, moab::NestedRefine::refPatterns::total_new_ents, and moab::Core::type_from_handle().

Referenced by vertex_to_entities_up().

◆ compute_coordinates()

ErrorCode moab::NestedRefine::compute_coordinates ( int  cur_level,
int  deg,
EntityType  type,
EntityHandle vbuffer,
int  vtotal,
double *  corner_coords,
std::vector< int > &  vflag,
int  nverts_prev 
)
protected

Definition at line 1830 of file NestedRefine.cpp.

1838 {
1839  EntityHandle vstart = level_mesh[cur_level].start_vertex;
1840  int d = get_index_from_degree( deg );
1841 
1842  if( type == MBTRI )
1843  {
1844  double xi, eta, N[3];
1845  int findex = mbImpl->type_from_handle( *( _infaces.begin() ) ) - 1;
1846 
1847  for( int i = 3; i < vtotal; i++ )
1848  {
1849  if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1850 
1851  xi = refTemplates[findex][d].vert_nat_coord[i - 3][0];
1852  eta = refTemplates[findex][d].vert_nat_coord[i - 3][1];
1853  N[0] = 1 - xi - eta;
1854  N[1] = xi;
1855  N[2] = eta;
1856 
1857  double x = 0, y = 0, z = 0;
1858  for( int j = 0; j < 3; j++ )
1859  {
1860  x += N[j] * corner_coords[3 * j];
1861  y += N[j] * corner_coords[3 * j + 1];
1862  z += N[j] * corner_coords[3 * j + 2];
1863  }
1864 
1865  level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1866  level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1867  level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1868  vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1869  }
1870  }
1871  else if( type == MBQUAD )
1872  {
1873  double xi, eta, N[4];
1874  int findex = mbImpl->type_from_handle( *( _infaces.begin() ) ) - 1;
1875 
1876  for( int i = 4; i < vtotal; i++ )
1877  {
1878  if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1879 
1880  xi = refTemplates[findex][d].vert_nat_coord[i - 4][0];
1881  eta = refTemplates[findex][d].vert_nat_coord[i - 4][1];
1882  N[0] = ( 1 - xi ) * ( 1 - eta ) / 4;
1883  N[1] = ( 1 + xi ) * ( 1 - eta ) / 4;
1884  N[2] = ( 1 + xi ) * ( 1 + eta ) / 4, N[3] = ( 1 - xi ) * ( 1 + eta ) / 4;
1885 
1886  double x = 0, y = 0, z = 0;
1887  for( int j = 0; j < 4; j++ )
1888  {
1889  x += N[j] * corner_coords[3 * j];
1890  y += N[j] * corner_coords[3 * j + 1];
1891  z += N[j] * corner_coords[3 * j + 2];
1892  }
1893 
1894  level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1895  level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1896  level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1897  vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1898  }
1899  }
1900  else if( type == MBTET )
1901  {
1902  double xi, eta, mu, N[4];
1903  int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1;
1904 
1905  for( int i = 4; i < vtotal; i++ )
1906  {
1907  if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1908 
1909  xi = refTemplates[cindex][d].vert_nat_coord[i - 4][0];
1910  eta = refTemplates[cindex][d].vert_nat_coord[i - 4][1];
1911  mu = refTemplates[cindex][d].vert_nat_coord[i - 4][2];
1912 
1913  N[0] = 1 - xi - eta - mu;
1914  N[1] = xi;
1915  N[2] = eta, N[3] = mu;
1916 
1917  double x = 0, y = 0, z = 0;
1918  for( int j = 0; j < 4; j++ )
1919  {
1920  x += N[j] * corner_coords[3 * j];
1921  y += N[j] * corner_coords[3 * j + 1];
1922  z += N[j] * corner_coords[3 * j + 2];
1923  }
1924 
1925  level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1926  level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1927  level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1928  vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1929  }
1930  }
1931  else if( type == MBPRISM )
1932  {
1933  double xi, eta, mu, N[6];
1934  int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1;
1935 
1936  for( int i = 6; i < vtotal; i++ )
1937  {
1938  if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1939 
1940  xi = refTemplates[cindex][d].vert_nat_coord[i - 6][0];
1941  eta = refTemplates[cindex][d].vert_nat_coord[i - 6][1];
1942  mu = refTemplates[cindex][d].vert_nat_coord[i - 6][2];
1943 
1944  N[0] = ( 1 - xi - eta ) * ( 1 - mu ), N[1] = xi * ( 1 - mu ), N[2] = eta * ( 1 - mu ),
1945  N[3] = ( 1 - xi - eta ) * ( 1 + mu ), N[4] = xi * ( 1 + mu ), N[5] = eta * ( 1 + mu );
1946 
1947  double x = 0, y = 0, z = 0;
1948  for( int j = 0; j < 6; j++ )
1949  {
1950  x += N[j] * corner_coords[3 * j];
1951  y += N[j] * corner_coords[3 * j + 1];
1952  z += N[j] * corner_coords[3 * j + 2];
1953  }
1954 
1955  level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
1956  level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
1957  level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
1958  vflag[vbuffer[i] - vstart - nverts_prev] = 1;
1959  }
1960  }
1961  else if( type == MBHEX )
1962  {
1963  double xi, eta, mu, N[8];
1964  double d1, d2, d3, s1, s2, s3;
1965  int cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1;
1966 
1967  for( int i = 8; i < vtotal; i++ )
1968  {
1969 
1970  if( vflag[vbuffer[i] - vstart - nverts_prev] ) continue;
1971 
1972  xi = refTemplates[cindex][d].vert_nat_coord[i - 8][0];
1973  eta = refTemplates[cindex][d].vert_nat_coord[i - 8][1];
1974  mu = refTemplates[cindex][d].vert_nat_coord[i - 8][2];
1975 
1976  d1 = 1 - xi;
1977  d2 = 1 - eta;
1978  d3 = 1 - mu;
1979  s1 = 1 + xi;
1980  s2 = 1 + eta;
1981  s3 = 1 + mu;
1982  N[0] = ( d1 * d2 * d3 ) / 8;
1983  N[1] = ( s1 * d2 * d3 ) / 8;
1984  N[2] = ( s1 * s2 * d3 ) / 8;
1985  N[3] = ( d1 * s2 * d3 ) / 8;
1986  N[4] = ( d1 * d2 * s3 ) / 8;
1987  N[5] = ( s1 * d2 * s3 ) / 8;
1988  N[6] = ( s1 * s2 * s3 ) / 8;
1989  N[7] = ( d1 * s2 * s3 ) / 8;
1990 
1991  double x = 0, y = 0, z = 0;
1992  for( int j = 0; j < 8; j++ )
1993  {
1994  x += N[j] * corner_coords[3 * j];
1995  y += N[j] * corner_coords[3 * j + 1];
1996  z += N[j] * corner_coords[3 * j + 2];
1997  }
1998 
1999  level_mesh[cur_level].coordinates[0][vbuffer[i] - vstart] = x;
2000  level_mesh[cur_level].coordinates[1][vbuffer[i] - vstart] = y;
2001  level_mesh[cur_level].coordinates[2][vbuffer[i] - vstart] = z;
2002 
2003  vflag[vbuffer[i] - vstart - nverts_prev] = 1;
2004  }
2005  }
2006  return MB_SUCCESS;
2007 }

References _incells, _infaces, moab::Range::begin(), moab::NestedRefine::level_memory::coordinates, get_index_from_degree(), level_mesh, MB_SUCCESS, MBHEX, mbImpl, MBPRISM, MBQUAD, MBTET, MBTRI, refTemplates, moab::NestedRefine::level_memory::start_vertex, moab::Core::type_from_handle(), and moab::NestedRefine::refPatterns::vert_nat_coord.

Referenced by construct_hm_2D(), subdivide_cells(), and subdivide_tets().

◆ construct_hm_1D() [1/2]

ErrorCode moab::NestedRefine::construct_hm_1D ( int  cur_level,
int  deg 
)
protected

Definition at line 863 of file NestedRefine.cpp.

864 {
866  int nverts_prev, nents_prev;
867  if( cur_level )
868  {
869  nverts_prev = level_mesh[cur_level - 1].num_verts;
870  nents_prev = level_mesh[cur_level - 1].num_edges;
871  }
872  else
873  {
874  nverts_prev = _inverts.size();
875  nents_prev = _inedges.size();
876  }
877 
878  int d = get_index_from_degree( deg );
879  int vtotal = 2 + refTemplates[0][d].total_new_verts;
880  std::vector< EntityHandle > vbuffer( vtotal );
881 
882  std::vector< EntityHandle > conn;
883  int count_nents = 0;
884  int count_verts = nverts_prev;
885 
886  // Step 1: Create the subentities via refinement of the previous mesh
887  for( int eid = 0; eid < nents_prev; eid++ )
888  {
889  conn.clear();
890 
891  // EntityHandle of the working edge
893  if( cur_level )
894  edge = level_mesh[cur_level - 1].start_edge + eid;
895  else
896  edge = _inedges[eid]; // Makes the assumption initial mesh is contiguous in memory
897 
898  error = get_connectivity( edge, cur_level, conn );
899  MB_CHK_ERR( error );
900 
901  // Add the vertex handles to vbuffer for the current level for the working edge
902 
903  // Since the old vertices are copied first, their local indices do not change as new levels
904  // are added. Clearly the local indices of the new vertices introduced in the current level
905  // is still the same when the old vertices are copied. Thus, there is no need to explicitly
906  // store another map between the old and duplicates in the subsequent levels. The second
907  // part in the following sum is the local index in the previous level.
908 
909  // Add the corners to the vbuffer first.
910 
911  for( int i = 0; i < (int)conn.size(); i++ )
912  {
913  if( cur_level )
914  vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex );
915  else
916  vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() );
917  }
918 
919  // Adding rest of the entityhandles to working buffer for vertices.
920  int num_new_verts = refTemplates[0][d].total_new_verts;
921 
922  for( int i = 0; i < num_new_verts; i++ )
923  {
924  vbuffer[i + 2] = level_mesh[cur_level].start_vertex + count_verts;
925  count_verts += 1;
926  }
927 
928  // Use the template to obtain the subentities
929  int id1, id2;
930  int etotal = refTemplates[0][d].total_new_ents;
931  std::vector< EntityHandle > ent_buffer( etotal );
932 
933  for( int i = 0; i < etotal; i++ )
934  {
935  id1 = refTemplates[0][d].ents_conn[i][0];
936  id2 = refTemplates[0][d].ents_conn[i][1];
937  level_mesh[cur_level].edge_conn[2 * ( count_nents )] = vbuffer[id1];
938  level_mesh[cur_level].edge_conn[2 * ( count_nents ) + 1] = vbuffer[id2];
939  ent_buffer[i] = level_mesh[cur_level].start_edge + count_nents;
940  count_nents += 1;
941  };
942 
943  error = update_local_ahf( deg, MBEDGE, &vbuffer[0], &ent_buffer[0], etotal );
944  MB_CHK_ERR( error );
945 
946  // Compute the coordinates of the new vertices: Linear interpolation
947  int idx;
948  double xi;
949  for( int i = 0; i < num_new_verts; i++ )
950  {
951  xi = refTemplates[0][d].vert_nat_coord[i][0];
952  idx = vbuffer[i + 2] - level_mesh[cur_level].start_vertex; // index of new vertex in current level
953  if( cur_level )
954  {
955  id1 = conn[0] - level_mesh[cur_level - 1].start_vertex; // index of old end vertices in current level
956  id2 = conn[1] - level_mesh[cur_level - 1].start_vertex;
957  }
958  else
959  {
960  id1 = _inverts.index( conn[0] );
961  id2 = _inverts.index( conn[1] );
962  }
963 
964  level_mesh[cur_level].coordinates[0][idx] =
965  ( 1 - xi ) * level_mesh[cur_level].coordinates[0][id1] + xi * level_mesh[cur_level].coordinates[0][id2];
966  level_mesh[cur_level].coordinates[1][idx] =
967  ( 1 - xi ) * level_mesh[cur_level].coordinates[1][id1] + xi * level_mesh[cur_level].coordinates[1][id2];
968  level_mesh[cur_level].coordinates[2][idx] =
969  ( 1 - xi ) * level_mesh[cur_level].coordinates[2][id1] + xi * level_mesh[cur_level].coordinates[2][id2];
970  }
971  }
972 
973  error = update_global_ahf( MBEDGE, cur_level, deg );
974  MB_CHK_ERR( error );
975 
976  return MB_SUCCESS;
977 }

References _inedges, _inverts, moab::Range::begin(), moab::NestedRefine::level_memory::coordinates, moab::NestedRefine::level_memory::edge_conn, moab::NestedRefine::refPatterns::ents_conn, moab::error(), ErrorCode, get_connectivity(), get_index_from_degree(), moab::Range::index(), level_mesh, MB_CHK_ERR, MB_SUCCESS, MBEDGE, moab::NestedRefine::level_memory::num_edges, moab::NestedRefine::level_memory::num_verts, refTemplates, moab::Range::size(), moab::NestedRefine::level_memory::start_edge, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::NestedRefine::refPatterns::total_new_verts, update_global_ahf(), update_local_ahf(), and moab::NestedRefine::refPatterns::vert_nat_coord.

Referenced by construct_hm_2D(), construct_hm_entities(), subdivide_cells(), and subdivide_tets().

◆ construct_hm_1D() [2/2]

ErrorCode moab::NestedRefine::construct_hm_1D ( int  cur_level,
int  deg,
EntityType  type,
std::vector< EntityHandle > &  trackverts 
)
protected

Definition at line 979 of file NestedRefine.cpp.

983 {
985 
986  int nedges_prev;
987  if( cur_level )
988  nedges_prev = level_mesh[cur_level - 1].num_edges;
989  else
990  nedges_prev = _inedges.size();
991 
992  int d = get_index_from_degree( deg );
993  int nve = refTemplates[0][d].nv_edge;
994  int vtotal = 2 + refTemplates[0][d].total_new_verts;
995  int etotal = refTemplates[0][d].total_new_ents;
996  int ne = 0, dim = 0, index = 0;
997  if( type == MBTRI || type == MBQUAD )
998  {
999  index = type - 2;
1001  dim = 2;
1002  }
1003  else if( type == MBTET || type == MBHEX )
1004  {
1005  index = ahf->get_index_in_lmap( *( _incells.begin() ) );
1007  dim = 3;
1008  }
1009 
1010  std::vector< EntityHandle > vbuffer( vtotal );
1011  std::vector< EntityHandle > ent_buffer( etotal );
1012 
1013  std::vector< EntityHandle > adjents, econn, fconn;
1014  std::vector< int > leids;
1015  int count_nents = 0;
1016 
1017  // Loop over all the edges and gather the vertices to be used for refinement
1018  for( int eid = 0; eid < nedges_prev; eid++ )
1019  {
1020  adjents.clear();
1021  leids.clear();
1022  econn.clear();
1023  fconn.clear();
1024  for( int i = 0; i < vtotal; i++ )
1025  vbuffer[i] = 0;
1026  for( int i = 0; i < etotal; i++ )
1027  ent_buffer[i] = 0;
1028 
1030  if( cur_level )
1031  edge = level_mesh[cur_level - 1].start_edge + eid;
1032  else
1033  edge = _inedges[eid];
1034 
1035  error = get_connectivity( edge, cur_level, econn );
1036  MB_CHK_ERR( error );
1037 
1038  for( int i = 0; i < (int)econn.size(); i++ )
1039  {
1040  if( cur_level )
1041  vbuffer[i] = level_mesh[cur_level].start_vertex + ( econn[i] - level_mesh[cur_level - 1].start_vertex );
1042  else
1043  vbuffer[i] = level_mesh[cur_level].start_vertex + ( econn[i] - *_inverts.begin() );
1044  }
1045 
1046  int fid = -1, lid = -1, idx1 = -1, idx2 = -1;
1047 
1048  if( dim == 2 )
1049  {
1050  error = ahf->get_up_adjacencies_2d( edge, adjents, &leids );
1051  MB_CHK_ERR( error );
1052  if( cur_level )
1053  fid = adjents[0] - level_mesh[cur_level - 1].start_face;
1054  else
1055  fid = _infaces.index( adjents[0] );
1056 
1057  lid = leids[0];
1058  idx1 = lid;
1059  idx2 = ahf->lConnMap2D[index].next[lid];
1060  }
1061  else if( dim == 3 )
1062  {
1063  error = ahf->get_up_adjacencies_edg_3d( edge, adjents, &leids );
1064  MB_CHK_ERR( error );
1065  if( cur_level )
1066  fid = adjents[0] - level_mesh[cur_level - 1].start_cell;
1067  else
1068  fid = _incells.index( adjents[0] );
1069 
1070  lid = leids[0];
1071  idx1 = ahf->lConnMap3D[index].e2v[lid][0];
1072  idx2 = ahf->lConnMap3D[index].e2v[lid][1];
1073  }
1074 
1075  error = get_connectivity( adjents[0], cur_level, fconn );
1076  MB_CHK_ERR( error );
1077 
1078  bool orient = false;
1079  if( ( fconn[idx1] == econn[0] ) && ( fconn[idx2] == econn[1] ) ) orient = true;
1080 
1081  if( orient )
1082  {
1083  for( int j = 0; j < nve; j++ )
1084  vbuffer[j + 2] = trackverts[fid * ne * nve + nve * lid + j];
1085  }
1086  else
1087  {
1088  for( int j = 0; j < nve; j++ )
1089  vbuffer[( nve - j - 1 ) + 2] = trackverts[fid * ne * nve + nve * lid + j];
1090  }
1091 
1092  // Use the template to obtain the subentities
1093  int id1, id2;
1094 
1095  for( int i = 0; i < etotal; i++ )
1096  {
1097  id1 = refTemplates[0][d].ents_conn[i][0];
1098  id2 = refTemplates[0][d].ents_conn[i][1];
1099  level_mesh[cur_level].edge_conn[2 * ( count_nents )] = vbuffer[id1];
1100  level_mesh[cur_level].edge_conn[2 * ( count_nents ) + 1] = vbuffer[id2];
1101  ent_buffer[i] = level_mesh[cur_level].start_edge + count_nents;
1102 
1103  count_nents += 1;
1104  };
1105 
1106  error = update_local_ahf( deg, MBEDGE, &vbuffer[0], &ent_buffer[0], etotal );
1107  MB_CHK_ERR( error );
1108  }
1109 
1110  error = update_global_ahf_1D_sub( cur_level, deg );
1111  MB_CHK_ERR( error );
1112 
1113  return MB_SUCCESS;
1114 }

References _incells, _inedges, _infaces, _inverts, ahf, moab::Range::begin(), moab::HalfFacetRep::LocalMaps3D::e2v, moab::NestedRefine::level_memory::edge_conn, moab::NestedRefine::refPatterns::ents_conn, moab::error(), ErrorCode, get_connectivity(), get_index_from_degree(), moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::get_up_adjacencies_2d(), moab::HalfFacetRep::get_up_adjacencies_edg_3d(), moab::index, moab::Range::index(), moab::HalfFacetRep::lConnMap2D, moab::HalfFacetRep::lConnMap3D, level_mesh, MB_CHK_ERR, MB_SUCCESS, MBEDGE, MBHEX, MBQUAD, MBTET, MBTRI, moab::HalfFacetRep::LocalMaps2D::next, moab::NestedRefine::level_memory::num_edges, moab::HalfFacetRep::LocalMaps3D::num_edges_in_cell, moab::HalfFacetRep::LocalMaps2D::num_verts_in_face, moab::NestedRefine::refPatterns::nv_edge, refTemplates, moab::Range::size(), moab::NestedRefine::level_memory::start_cell, moab::NestedRefine::level_memory::start_edge, moab::NestedRefine::level_memory::start_face, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::NestedRefine::refPatterns::total_new_verts, update_global_ahf_1D_sub(), and update_local_ahf().

◆ construct_hm_2D() [1/2]

ErrorCode moab::NestedRefine::construct_hm_2D ( int  cur_level,
int  deg 
)
protected

Definition at line 1116 of file NestedRefine.cpp.

1117 {
1118  ErrorCode error;
1119  int nverts_prev, nents_prev;
1120  if( cur_level )
1121  {
1122  nverts_prev = level_mesh[cur_level - 1].num_verts;
1123  nents_prev = level_mesh[cur_level - 1].num_faces;
1124  }
1125  else
1126  {
1127  nverts_prev = _inverts.size();
1128  nents_prev = _infaces.size();
1129  }
1130 
1131  // Create some book-keeping arrays over the old mesh to avoid introducing duplicate vertices and
1132  // calculating vertices more than once.
1133  EntityType ftype = mbImpl->type_from_handle( *_infaces.begin() );
1134  int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face;
1135  int findex = ftype - 1;
1136 
1137  int d = get_index_from_degree( deg );
1138  int tnv = refTemplates[findex][d].total_new_verts;
1139  int vtotal = nepf + tnv;
1140  std::vector< EntityHandle > vbuffer( vtotal );
1141  int etotal = refTemplates[findex][d].total_new_ents;
1142  std::vector< EntityHandle > ent_buffer( etotal );
1143 
1144  int nve = refTemplates[findex][d].nv_edge;
1145  std::vector< EntityHandle > trackvertsF( nents_prev * nepf * nve, 0 );
1146  int cur_nverts = level_mesh[cur_level].num_verts;
1147  std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 );
1148 
1149  int count_nverts = nverts_prev;
1150  int count_nents = 0;
1151  std::vector< EntityHandle > conn, cur_conn;
1152 
1153  // Step 1: Create the subentities via refinement of the previous mesh
1154  for( int fid = 0; fid < nents_prev; fid++ )
1155  {
1156  conn.clear();
1157  cur_conn.clear();
1158  for( int i = 0; i < vtotal; i++ )
1159  vbuffer[i] = 0;
1160  for( int i = 0; i < etotal; i++ )
1161  ent_buffer[i] = 0;
1162 
1163  // EntityHandle of the working face
1165  if( cur_level )
1166  face = level_mesh[cur_level - 1].start_face + fid;
1167  else
1168  face = _infaces[fid];
1169 
1170  error = get_connectivity( face, cur_level, conn );
1171  MB_CHK_ERR( error );
1172 
1173  // Step 1: Add vertices from the current level for the working face that will be used for
1174  // subdivision.
1175  // Add the corners to vbuffer
1176  for( int i = 0; i < (int)conn.size(); i++ )
1177  {
1178  if( cur_level )
1179  vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex );
1180  else
1181  vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() );
1182 
1183  cur_conn.push_back( vbuffer[i] );
1184  }
1185 
1186  // Gather vertices already added to tracking array due to refinement of the sibling faces
1187 
1188  for( int i = 0; i < nepf; i++ )
1189  {
1190  for( int j = 0; j < nve; j++ )
1191  {
1192  int id = refTemplates[findex][d].vert_on_edges[i][j];
1193  vbuffer[id] = trackvertsF[fid * nve * nepf + nve * i + j];
1194  }
1195  }
1196 
1197  // Add the remaining vertex handles to vbuffer for the current level for the working face
1198  for( int i = 0; i < tnv; i++ )
1199  {
1200  if( !vbuffer[i + nepf] )
1201  {
1202  vbuffer[i + nepf] = level_mesh[cur_level].start_vertex + count_nverts;
1203  count_nverts += 1;
1204  }
1205  }
1206 
1207  // Step 2: Create the subentities using the template and the vbuffer
1208  int idx;
1209  for( int i = 0; i < etotal; i++ )
1210  {
1211  for( int k = 0; k < nepf; k++ )
1212  {
1213  idx = refTemplates[findex][d].ents_conn[i][k];
1214  level_mesh[cur_level].face_conn[nepf * count_nents + k] = vbuffer[idx];
1215  }
1216  ent_buffer[i] = level_mesh[cur_level].start_face + count_nents;
1217  count_nents += 1;
1218  }
1219 
1220  // Step 3: Update the local AHF maps
1221  error = update_local_ahf( deg, ftype, &vbuffer[0], &ent_buffer[0], etotal );
1222  MB_CHK_ERR( error );
1223 
1224  // Step 4: Add the new vertices to the tracking array
1225  int id;
1226 
1227  for( int i = 0; i < nepf; i++ )
1228  {
1229  // Add the vertices to trackvertsF for fid
1230  for( int j = 0; j < nve; j++ )
1231  {
1232  id = refTemplates[findex][d].vert_on_edges[i][j];
1233  trackvertsF[fid * nepf * nve + nve * i + j] = vbuffer[id];
1234  }
1235 
1236  std::vector< EntityHandle > sibfids;
1237  std::vector< int > sibleids;
1238  std::vector< int > siborient;
1239 
1240  // Add the vertices to trackvertsF for siblings of fid, if any.
1241  error = ahf->get_up_adjacencies_2d( face, i, false, sibfids, &sibleids, &siborient );
1242  MB_CHK_ERR( error );
1243 
1244  if( !sibfids.size() ) continue;
1245 
1246  for( int s = 0; s < (int)sibfids.size(); s++ )
1247  {
1248  int sibid;
1249  if( cur_level )
1250  sibid = sibfids[s] - level_mesh[cur_level - 1].start_face;
1251  else
1252  sibid = sibfids[s] - *_infaces.begin();
1253 
1254  if( siborient[s] ) // Same half-edge direction as the current half-edge
1255  {
1256  for( int j = 0; j < nve; j++ )
1257  {
1258  id = refTemplates[findex][d].vert_on_edges[i][j];
1259  trackvertsF[sibid * nepf * nve + nve * sibleids[s] + j] = vbuffer[id];
1260  }
1261  }
1262  else
1263  {
1264  for( int j = 0; j < nve; j++ )
1265  {
1266  id = refTemplates[findex][d].vert_on_edges[i][nve - j - 1];
1267  trackvertsF[sibid * nepf * nve + nve * sibleids[s] + j] = vbuffer[id];
1268  }
1269  }
1270  }
1271  }
1272 
1273  // Step 5: Compute the coordinates of the new vertices, avoids computing more than once via
1274  // the flag_verts array.
1275  std::vector< double > corner_coords( nepf * 3 );
1276  error = get_coordinates( &cur_conn[0], nepf, cur_level + 1, &corner_coords[0] );
1277  MB_CHK_ERR( error );
1278 
1279  error = compute_coordinates( cur_level, deg, ftype, &vbuffer[0], vtotal, &corner_coords[0], flag_verts,
1280  nverts_prev );
1281  MB_CHK_ERR( error );
1282  }
1283 
1284  // Step 6: Update the global maps
1285  error = update_global_ahf( ftype, cur_level, deg );
1286  MB_CHK_ERR( error );
1287 
1288  // Step 7: If edges exists, refine them.
1289  if( !_inedges.empty() )
1290  {
1291  error = construct_hm_1D( cur_level, deg, ftype, trackvertsF );
1292  MB_CHK_ERR( error );
1293  }
1294 
1295  return MB_SUCCESS;
1296 }

References _inedges, _infaces, _inverts, ahf, moab::Range::begin(), compute_coordinates(), construct_hm_1D(), moab::Range::empty(), moab::NestedRefine::refPatterns::ents_conn, moab::error(), ErrorCode, moab::NestedRefine::level_memory::face_conn, get_connectivity(), get_coordinates(), get_index_from_degree(), moab::HalfFacetRep::get_up_adjacencies_2d(), moab::HalfFacetRep::lConnMap2D, level_mesh, MB_CHK_ERR, MB_SUCCESS, mbImpl, moab::NestedRefine::level_memory::num_faces, moab::NestedRefine::level_memory::num_verts, moab::HalfFacetRep::LocalMaps2D::num_verts_in_face, moab::NestedRefine::refPatterns::nv_edge, refTemplates, moab::Range::size(), moab::NestedRefine::level_memory::start_face, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::NestedRefine::refPatterns::total_new_verts, moab::Core::type_from_handle(), update_global_ahf(), update_local_ahf(), and moab::NestedRefine::refPatterns::vert_on_edges.

Referenced by construct_hm_entities(), subdivide_cells(), and subdivide_tets().

◆ construct_hm_2D() [2/2]

ErrorCode moab::NestedRefine::construct_hm_2D ( int  cur_level,
int  deg,
EntityType  type,
std::vector< EntityHandle > &  trackvertsC_edg,
std::vector< EntityHandle > &  trackvertsF 
)
protected

Definition at line 1298 of file NestedRefine.cpp.

1303 {
1304  ErrorCode error;
1305 
1306  EntityType ftype = MBTRI;
1307  if( type == MBHEX ) ftype = MBQUAD;
1308 
1309  int d = get_index_from_degree( deg );
1310  int findex = ftype - 1;
1311  int cidx = ahf->get_index_in_lmap( *( _incells.begin() ) );
1312 
1313  int nepf = ahf->lConnMap2D[ftype - 2].num_verts_in_face;
1314  int nepc = ahf->lConnMap3D[cidx].num_edges_in_cell;
1315  int nfpc = ahf->lConnMap3D[cidx].num_faces_in_cell;
1316 
1317  int tnv = refTemplates[findex][d].total_new_verts;
1318  int nve = refTemplates[findex][d].nv_edge;
1319  int nvf = refTemplates[findex][d].nv_face;
1320  int vtotal = nepf + tnv;
1321  int etotal = refTemplates[findex][d].total_new_ents;
1322 
1323  std::vector< EntityHandle > vbuffer( vtotal );
1324  std::vector< EntityHandle > ent_buffer( etotal );
1325 
1326  std::vector< EntityHandle > adjents, fconn, cconn;
1327  std::vector< int > leids;
1328  int count_nents = 0;
1329 
1330  int nents_prev, ecount;
1331  if( cur_level )
1332  {
1333  nents_prev = level_mesh[cur_level - 1].num_faces;
1334  ecount = level_mesh[cur_level - 1].num_edges * refTemplates[MBEDGE - 1][d].total_new_ents;
1335  ;
1336  }
1337  else
1338  {
1339  nents_prev = _infaces.size();
1340  ecount = _inedges.size() * refTemplates[MBEDGE - 1][d].total_new_ents;
1341  ;
1342  }
1343 
1344  // Step 1: Create the subentities via refinement of the previous mesh
1345  for( int it = 0; it < nents_prev; it++ )
1346  {
1347  fconn.clear();
1348  cconn.clear();
1349  adjents.clear();
1350  leids.clear();
1351  for( int i = 0; i < vtotal; i++ )
1352  vbuffer[i] = 0;
1353  for( int i = 0; i < etotal; i++ )
1354  ent_buffer[i] = 0;
1355 
1356  // EntityHandle of the working face
1358  if( cur_level )
1359  face = level_mesh[cur_level - 1].start_face + it;
1360  else
1361  face = _infaces[it];
1362 
1363  error = get_connectivity( face, cur_level, fconn );
1364  MB_CHK_ERR( error );
1365 
1366  // Add the new handles for old connectivity in the buffer
1367  for( int i = 0; i < (int)fconn.size(); i++ )
1368  {
1369  if( cur_level )
1370  vbuffer[i] = level_mesh[cur_level].start_vertex + ( fconn[i] - level_mesh[cur_level - 1].start_vertex );
1371  else
1372  vbuffer[i] = level_mesh[cur_level].start_vertex + ( fconn[i] - *_inverts.begin() );
1373  }
1374 
1375  // Add handles for vertices on edges and faces from the already refined cell
1376  int fid, lid;
1377  error = ahf->get_up_adjacencies_face_3d( face, adjents, &leids );
1378  MB_CHK_ERR( error );
1379 
1380  if( cur_level )
1381  fid = adjents[0] - level_mesh[cur_level - 1].start_cell;
1382  else
1383  fid = _incells.index( adjents[0] );
1384 
1385  lid = leids[0];
1386 
1387  error = get_connectivity( adjents[0], cur_level, cconn );
1388  MB_CHK_ERR( error );
1389 
1390  // Find the orientation w.r.t the half-face and then add vertices properly.
1391  std::vector< EntityHandle > fac_conn( nepf );
1392  std::vector< EntityHandle > lfac_conn( nepf );
1393  for( int j = 0; j < nepf; j++ )
1394  {
1395  fac_conn[j] = fconn[j];
1396  int id = ahf->lConnMap3D[cidx].hf2v[lid][j];
1397  lfac_conn[j] = cconn[id];
1398  }
1399 
1400  std::vector< int > le_idx, indices;
1401 
1402  error = reorder_indices( deg, &fac_conn[0], &lfac_conn[0], nepf, le_idx, indices );
1403  MB_CHK_ERR( error );
1404 
1405  // Add the existing vertices on edges of the already refined cell to the vbuffer
1406  for( int j = 0; j < nepf; j++ )
1407  {
1408  int id = le_idx[j]; // Corresponding local edge
1409  int idx = ahf->lConnMap3D[cidx].f2leid[lid][id]; // Local edge in the cell
1410 
1411  // Get the orientation of the local edge of the face wrt the corresponding local edge in
1412  // the cell
1413  bool eorient = false;
1414  int fnext = ahf->lConnMap2D[ftype - 2].next[j];
1415  int idx1 = ahf->lConnMap3D[cidx].e2v[idx][0];
1416  int idx2 = ahf->lConnMap3D[cidx].e2v[idx][1];
1417  if( ( fconn[j] == cconn[idx1] ) && ( fconn[fnext] == cconn[idx2] ) ) eorient = true;
1418 
1419  if( eorient )
1420  {
1421  for( int k = 0; k < nve; k++ )
1422  {
1423  int ind = refTemplates[findex][d].vert_on_edges[j][k];
1424  vbuffer[ind] = trackvertsE[fid * nepc * nve + nve * idx + k];
1425  }
1426  }
1427  else
1428  {
1429  for( int k = 0; k < nve; k++ )
1430  {
1431  int ind = refTemplates[findex][d].vert_on_edges[j][nve - k - 1];
1432  vbuffer[ind] = trackvertsE[fid * nepc * nve + nve * idx + k];
1433  }
1434  }
1435  }
1436 
1437  // Add the existing vertices on the face of the refine cell to vbuffer
1438  if( nvf )
1439  {
1440  for( int k = 0; k < nvf; k++ )
1441  {
1442  int ind = refTemplates[findex][d].vert_on_faces[0][k];
1443  vbuffer[ind] = trackvertsF[fid * nfpc * nvf + nvf * lid + indices[k] - 1];
1444  }
1445  }
1446 
1447  // Create the subentities using the template and the vbuffer
1448  for( int i = 0; i < etotal; i++ )
1449  {
1450  for( int k = 0; k < nepf; k++ )
1451  {
1452  int idx = refTemplates[findex][d].ents_conn[i][k];
1453  level_mesh[cur_level].face_conn[nepf * count_nents + k] = vbuffer[idx];
1454  }
1455  ent_buffer[i] = level_mesh[cur_level].start_face + count_nents;
1456  count_nents += 1;
1457  }
1458 
1459  error = update_local_ahf( deg, ftype, &vbuffer[0], &ent_buffer[0], etotal );
1460  MB_CHK_ERR( error );
1461 
1462  // Create the interior edges
1463  int id1, id2;
1464 
1465  int ne = intFacEdg[ftype - 2][d].nie;
1466  for( int i = 0; i < ne; i++ )
1467  {
1468  id1 = intFacEdg[ftype - 2][d].ieconn[i][0];
1469  id2 = intFacEdg[ftype - 2][d].ieconn[i][1];
1470  level_mesh[cur_level].edge_conn[2 * ( ecount )] = vbuffer[id1];
1471  level_mesh[cur_level].edge_conn[2 * ( ecount ) + 1] = vbuffer[id2];
1472  ecount += 1;
1473  }
1474  }
1475 
1476  // Step 6: Update the global maps
1477  error = update_global_ahf_2D_sub( cur_level, deg );
1478  MB_CHK_ERR( error );
1479 
1480  // Step 7: Update the hf-maps for the edges
1481  error = update_ahf_1D( cur_level );
1482  MB_CHK_ERR( error );
1483 
1484  return MB_SUCCESS;
1485 }

References _incells, _inedges, _infaces, _inverts, ahf, moab::Range::begin(), moab::HalfFacetRep::LocalMaps3D::e2v, moab::NestedRefine::level_memory::edge_conn, moab::NestedRefine::refPatterns::ents_conn, moab::error(), ErrorCode, moab::HalfFacetRep::LocalMaps3D::f2leid, moab::NestedRefine::level_memory::face_conn, get_connectivity(), get_index_from_degree(), moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::get_up_adjacencies_face_3d(), moab::HalfFacetRep::LocalMaps3D::hf2v, moab::NestedRefine::intFEdge::ieconn, moab::Range::index(), intFacEdg, moab::HalfFacetRep::lConnMap2D, moab::HalfFacetRep::lConnMap3D, level_mesh, MB_CHK_ERR, MB_SUCCESS, MBEDGE, MBHEX, MBQUAD, MBTRI, moab::HalfFacetRep::LocalMaps2D::next, moab::NestedRefine::intFEdge::nie, moab::NestedRefine::level_memory::num_edges, moab::HalfFacetRep::LocalMaps3D::num_edges_in_cell, moab::NestedRefine::level_memory::num_faces, moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell, moab::HalfFacetRep::LocalMaps2D::num_verts_in_face, moab::NestedRefine::refPatterns::nv_edge, moab::NestedRefine::refPatterns::nv_face, refTemplates, reorder_indices(), moab::Range::size(), moab::NestedRefine::level_memory::start_cell, moab::NestedRefine::level_memory::start_face, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::NestedRefine::refPatterns::total_new_verts, update_ahf_1D(), update_global_ahf_2D_sub(), update_local_ahf(), moab::NestedRefine::refPatterns::vert_on_edges, and moab::NestedRefine::refPatterns::vert_on_faces.

◆ construct_hm_3D()

ErrorCode moab::NestedRefine::construct_hm_3D ( int  cur_level,
int  deg 
)
protected

Definition at line 1487 of file NestedRefine.cpp.

1488 {
1489  ErrorCode error;
1490  EntityType type = mbImpl->type_from_handle( *( _incells.begin() ) );
1491  if( type == MBTET )
1492  {
1493  error = subdivide_tets( cur_level, deg );
1494  MB_CHK_ERR( error );
1495  }
1496  else
1497  {
1498  error = subdivide_cells( type, cur_level, deg );
1499  MB_CHK_ERR( error );
1500  }
1501 
1502  return MB_SUCCESS;
1503 }

References _incells, moab::Range::begin(), moab::error(), ErrorCode, MB_CHK_ERR, MB_SUCCESS, mbImpl, MBTET, subdivide_cells(), subdivide_tets(), and moab::Core::type_from_handle().

Referenced by construct_hm_entities().

◆ construct_hm_entities()

ErrorCode moab::NestedRefine::construct_hm_entities ( int  cur_level,
int  deg 
)
protected

Definition at line 839 of file NestedRefine.cpp.

840 {
842 
843  // Generate mesh for current level by refining previous level.
844  if( ahf->thismeshtype == CURVE )
845  {
846  error = construct_hm_1D( cur_level, deg );
847  MB_CHK_ERR( error );
848  }
849  else if( ahf->thismeshtype == SURFACE || ahf->thismeshtype == SURFACE_MIXED )
850  {
851  error = construct_hm_2D( cur_level, deg );
852  MB_CHK_ERR( error );
853  }
854  else
855  {
856  error = construct_hm_3D( cur_level, deg );
857  MB_CHK_ERR( error );
858  }
859 
860  return MB_SUCCESS;
861 }

References ahf, construct_hm_1D(), construct_hm_2D(), construct_hm_3D(), moab::CURVE, moab::error(), ErrorCode, MB_CHK_ERR, MB_SUCCESS, moab::SURFACE, moab::SURFACE_MIXED, and moab::HalfFacetRep::thismeshtype.

Referenced by generate_hm().

◆ copy_vertices_from_prev_level()

ErrorCode moab::NestedRefine::copy_vertices_from_prev_level ( int  cur_level)
protected

Definition at line 4396 of file NestedRefine.cpp.

4397 {
4398  ErrorCode error;
4399 
4400  if( cur_level )
4401  {
4402  int nverts_prev = level_mesh[cur_level - 1].num_verts;
4403  for( int i = 0; i < nverts_prev; i++ )
4404  {
4405  level_mesh[cur_level].coordinates[0][i] = level_mesh[cur_level - 1].coordinates[0][i];
4406  level_mesh[cur_level].coordinates[1][i] = level_mesh[cur_level - 1].coordinates[1][i];
4407  level_mesh[cur_level].coordinates[2][i] = level_mesh[cur_level - 1].coordinates[2][i];
4408  }
4409  }
4410  else // Copy the vertices from the input mesh
4411  {
4412  int nverts_in = _inverts.size();
4413  std::vector< double > vcoords( 3 * nverts_in );
4414  error = mbImpl->get_coords( _inverts, &vcoords[0] );
4415  MB_CHK_ERR( error );
4416 
4417  for( int i = 0; i < nverts_in; i++ )
4418  {
4419  level_mesh[cur_level].coordinates[0][i] = vcoords[3 * i];
4420  level_mesh[cur_level].coordinates[1][i] = vcoords[3 * i + 1];
4421  level_mesh[cur_level].coordinates[2][i] = vcoords[3 * i + 2];
4422  }
4423  }
4424  return MB_SUCCESS;
4425  // To add: Map from old vertices to new duplicates: NOT NEEDED
4426 }

References _inverts, moab::NestedRefine::level_memory::coordinates, moab::error(), ErrorCode, moab::Core::get_coords(), level_mesh, MB_CHK_ERR, MB_SUCCESS, mbImpl, moab::NestedRefine::level_memory::num_verts, and moab::Range::size().

Referenced by generate_hm().

◆ count_subentities()

ErrorCode moab::NestedRefine::count_subentities ( EntityHandle  set,
int  cur_level,
int *  nedges,
int *  nfaces 
)
protected

Definition at line 4757 of file NestedRefine.cpp.

4758 {
4759  ErrorCode error;
4760 
4761  if( cur_level >= 0 )
4762  {
4763  Range edges, faces, cells;
4764 
4765  error = mbImpl->get_entities_by_dimension( set, 1, edges );
4766  MB_CHK_ERR( error );
4767 
4768  error = mbImpl->get_entities_by_dimension( set, 2, faces );
4769  MB_CHK_ERR( error );
4770 
4771  error = mbImpl->get_entities_by_dimension( set, 3, cells );
4772  MB_CHK_ERR( error );
4773 
4774  error = ahf->count_subentities( edges, faces, cells, nedges, nfaces );
4775  MB_CHK_ERR( error );
4776  }
4777  else
4778  {
4779  error = ahf->count_subentities( _inedges, _infaces, _incells, nedges, nfaces );
4780  MB_CHK_ERR( error );
4781  }
4782 
4783  return MB_SUCCESS;
4784 }

References _incells, _inedges, _infaces, ahf, moab::HalfFacetRep::count_subentities(), moab::error(), ErrorCode, moab::Core::get_entities_by_dimension(), MB_CHK_ERR, MB_SUCCESS, and mbImpl.

Referenced by estimate_hm_storage().

◆ create_hm_storage_single_level()

ErrorCode moab::NestedRefine::create_hm_storage_single_level ( EntityHandle set,
int  cur_level,
int  estL[4] 
)
protected

Definition at line 658 of file NestedRefine.cpp.

659 {
660  // Obtain chunks of memory for the current level. Add them to a particular meshset.
661  EntityHandle set_handle;
662  ErrorCode error = mbImpl->create_meshset( MESHSET_SET, set_handle );
663  MB_CHK_SET_ERR( error, "Cannot create mesh for the current level" );
664  *set = set_handle;
665 
666  ReadUtilIface* read_iface;
667  error = mbImpl->query_interface( read_iface );
668  MB_CHK_ERR( error );
669 
670  // Vertices
671  error = read_iface->get_node_coords( 3, estL[0], 0, level_mesh[cur_level].start_vertex,
672  level_mesh[cur_level].coordinates );
673  MB_CHK_ERR( error );
674  level_mesh[cur_level].num_verts = estL[0];
675 
676  Range newverts( level_mesh[cur_level].start_vertex, level_mesh[cur_level].start_vertex + estL[0] - 1 );
677  error = mbImpl->add_entities( *set, newverts );
678  MB_CHK_ERR( error );
679  level_mesh[cur_level].verts = newverts;
680 
681  Tag gidtag;
683  MB_CHK_ERR( error );
684  error = read_iface->assign_ids( gidtag, newverts, level_mesh[cur_level].start_vertex );
685  MB_CHK_ERR( error );
686 
687  // Edges
688  if( estL[1] )
689  {
690  error = read_iface->get_element_connect( estL[1], 2, MBEDGE, 0, level_mesh[cur_level].start_edge,
691  level_mesh[cur_level].edge_conn );
692  MB_CHK_ERR( error );
693  level_mesh[cur_level].num_edges = estL[1];
694 
695  Range newedges( level_mesh[cur_level].start_edge, level_mesh[cur_level].start_edge + estL[1] - 1 );
696  error = mbImpl->add_entities( *set, newedges );
697  MB_CHK_ERR( error );
698  level_mesh[cur_level].edges = newedges;
699  }
700  else
701  level_mesh[cur_level].num_edges = 0;
702 
703  // Faces
704  if( estL[2] )
705  {
706  EntityType type = mbImpl->type_from_handle( *( _infaces.begin() ) );
707  int nvpf = ahf->lConnMap2D[type - 2].num_verts_in_face;
708  error = read_iface->get_element_connect( estL[2], nvpf, type, 0, level_mesh[cur_level].start_face,
709  level_mesh[cur_level].face_conn );
710  MB_CHK_ERR( error );
711  level_mesh[cur_level].num_faces = estL[2];
712 
713  Range newfaces( level_mesh[cur_level].start_face, level_mesh[cur_level].start_face + estL[2] - 1 );
714  error = mbImpl->add_entities( *set, newfaces );
715  MB_CHK_ERR( error );
716  level_mesh[cur_level].faces = newfaces;
717  }
718  else
719  level_mesh[cur_level].num_faces = 0;
720 
721  // Cells
722  if( estL[3] )
723  {
724  EntityType type = mbImpl->type_from_handle( *( _incells.begin() ) );
726  int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
727  error = read_iface->get_element_connect( estL[3], nvpc, type, 0, level_mesh[cur_level].start_cell,
728  level_mesh[cur_level].cell_conn );
729  MB_CHK_ERR( error );
730  level_mesh[cur_level].num_cells = estL[3];
731 
732  Range newcells( level_mesh[cur_level].start_cell, level_mesh[cur_level].start_cell + estL[3] - 1 );
733  error = mbImpl->add_entities( *set, newcells );
734  MB_CHK_ERR( error );
735  level_mesh[cur_level].cells = newcells;
736  }
737  else
738  level_mesh[cur_level].num_cells = 0;
739 
740  // Resize the ahf maps
741  error = ahf->resize_hf_maps( level_mesh[cur_level].start_vertex, level_mesh[cur_level].num_verts,
742  level_mesh[cur_level].start_edge, level_mesh[cur_level].num_edges,
743  level_mesh[cur_level].start_face, level_mesh[cur_level].num_faces,
744  level_mesh[cur_level].start_cell, level_mesh[cur_level].num_cells );
745  MB_CHK_ERR( error );
746 
747  error = ahf->update_entity_ranges( *set );
748  MB_CHK_ERR( error );
749 
750  // If the mesh type changes, then update the member variable in ahf to use the applicable
751  // adjacency matrix
752  MESHTYPE nwmesh = ahf->get_mesh_type( level_mesh[cur_level].num_verts, level_mesh[cur_level].num_edges,
753  level_mesh[cur_level].num_faces, level_mesh[cur_level].num_cells );
754  MB_CHK_ERR( error );
755  if( ahf->thismeshtype != nwmesh ) ahf->thismeshtype = nwmesh;
756 
757  return MB_SUCCESS;
758 }

References _incells, _infaces, moab::Core::add_entities(), ahf, moab::ReadUtilIface::assign_ids(), moab::Range::begin(), moab::NestedRefine::level_memory::cells, moab::Core::create_meshset(), moab::NestedRefine::level_memory::edges, moab::error(), ErrorCode, moab::NestedRefine::level_memory::faces, moab::ReadUtilIface::get_element_connect(), moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::get_mesh_type(), moab::ReadUtilIface::get_node_coords(), GLOBAL_ID_TAG_NAME, moab::index, moab::HalfFacetRep::lConnMap2D, moab::HalfFacetRep::lConnMap3D, level_mesh, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, MBEDGE, mbImpl, MESHSET_SET, moab::NestedRefine::level_memory::num_cells, moab::NestedRefine::level_memory::num_edges, moab::NestedRefine::level_memory::num_faces, moab::NestedRefine::level_memory::num_verts, moab::HalfFacetRep::LocalMaps3D::num_verts_in_cell, moab::HalfFacetRep::LocalMaps2D::num_verts_in_face, moab::Interface::query_interface(), moab::HalfFacetRep::resize_hf_maps(), moab::Core::tag_get_handle(), moab::HalfFacetRep::thismeshtype, moab::Core::type_from_handle(), moab::HalfFacetRep::update_entity_ranges(), and moab::NestedRefine::level_memory::verts.

Referenced by generate_hm().

◆ estimate_hm_storage()

ErrorCode moab::NestedRefine::estimate_hm_storage ( EntityHandle  set,
int  level_degree,
int  cur_level,
int  hmest[4] 
)
protected

Definition at line 597 of file NestedRefine.cpp.

598 {
600 
601  // Obtain the size of input mesh.
602  int nverts_prev, nedges_prev, nfaces_prev, ncells_prev;
603  if( cur_level )
604  {
605  nverts_prev = level_mesh[cur_level - 1].num_verts;
606  nedges_prev = level_mesh[cur_level - 1].num_edges;
607  nfaces_prev = level_mesh[cur_level - 1].num_faces;
608  ncells_prev = level_mesh[cur_level - 1].num_cells;
609  }
610  else
611  {
612  nverts_prev = _inverts.size();
613  nedges_prev = _inedges.size();
614  nfaces_prev = _infaces.size();
615  ncells_prev = _incells.size();
616  }
617 
618  // Estimate mesh size of current level mesh.
619  int nedges = 0, nfaces = 0;
620  error = count_subentities( set, cur_level - 1, &nedges, &nfaces );
621  MB_CHK_ERR( error );
622 
623  int d = get_index_from_degree( level_degree );
624  int nverts = refTemplates[MBEDGE - 1][d].nv_edge * nedges;
625  hmest[0] = nverts_prev + nverts;
626  hmest[1] = nedges_prev * refTemplates[MBEDGE - 1][d].total_new_ents;
627  hmest[2] = 0;
628  hmest[3] = 0;
629 
630  int findex, cindex;
631  if( nfaces_prev != 0 )
632  {
633  EntityHandle start_face;
634  if( cur_level )
635  start_face = level_mesh[cur_level - 1].start_face;
636  else
637  start_face = *_infaces.begin();
638  findex = mbImpl->type_from_handle( start_face ) - 1;
639  hmest[2] = nfaces_prev * refTemplates[findex][d].total_new_ents;
640 
641  if( meshdim == 2 ) hmest[0] += refTemplates[findex][d].nv_face * nfaces_prev;
642 
643  if( meshdim == 3 ) hmest[1] += nfaces_prev * intFacEdg[findex - 1][d].nie;
644  }
645 
646  if( ncells_prev != 0 )
647  {
648  cindex = mbImpl->type_from_handle( *( _incells.begin() ) ) - 1;
649  hmest[3] = ncells_prev * refTemplates[cindex][d].total_new_ents;
650 
651  hmest[0] += refTemplates[cindex][d].nv_face * nfaces;
652  hmest[0] += refTemplates[cindex][d].nv_cell * ncells_prev;
653  }
654 
655  return MB_SUCCESS;
656 }

References _incells, _inedges, _infaces, _inverts, moab::Range::begin(), count_subentities(), moab::error(), ErrorCode, get_index_from_degree(), intFacEdg, level_mesh, MB_CHK_ERR, MB_SUCCESS, MBEDGE, mbImpl, meshdim, moab::NestedRefine::intFEdge::nie, moab::NestedRefine::level_memory::num_cells, moab::NestedRefine::level_memory::num_edges, moab::NestedRefine::level_memory::num_faces, moab::NestedRefine::level_memory::num_verts, moab::NestedRefine::refPatterns::nv_cell, moab::NestedRefine::refPatterns::nv_edge, moab::NestedRefine::refPatterns::nv_face, refTemplates, moab::Range::size(), moab::NestedRefine::level_memory::start_face, moab::NestedRefine::refPatterns::total_new_ents, and moab::Core::type_from_handle().

Referenced by generate_hm().

◆ exchange_ghosts()

ErrorCode moab::NestedRefine::exchange_ghosts ( std::vector< EntityHandle > &  lsets,
int  num_glayers 
)

Definition at line 468 of file NestedRefine.cpp.

469 {
471 
472  if( hasghost ) return MB_SUCCESS;
473 
474  hasghost = true;
475 #ifdef MOAB_HAVE_MPI
476  error = pcomm->exchange_ghost_cells( meshdim, 0, num_glayers, 0, true, false );
477  MB_CHK_ERR( error );
478  {
479  Range empty_range;
480  error = pcomm->exchange_tags( GLOBAL_ID_TAG_NAME, empty_range );
481  MB_CHK_ERR( error );
482  // error = pcomm->assign_global_ids(lsets[i], 0, 1, false, true, false);MB_CHK_ERR(error);
483  }
484 #else
485  MB_SET_ERR( MB_FAILURE, "Requesting ghost layers for a serial mesh" );
486 #endif
487 
488  Range* lverts = new Range[lsets.size()];
489  Range* lents = new Range[lsets.size()];
490  for( size_t i = 0; i < lsets.size(); i++ )
491  {
492  error = mbImpl->get_entities_by_dimension( lsets[i], meshdim, lents[i] );
493  MB_CHK_ERR( error );
494  error = mbImpl->get_connectivity( lents[i], lverts[i] );
495  MB_CHK_ERR( error );
496 
497  for( int gl = 0; gl < num_glayers; gl++ )
498  {
499  error = mbImpl->get_adjacencies( lverts[i], meshdim, false, lents[i], Interface::UNION );
500  MB_CHK_ERR( error );
501  error = mbImpl->get_connectivity( lents[i], lverts[i] );
502  MB_CHK_ERR( error );
503  }
504  }
505  for( size_t i = 0; i < lsets.size(); i++ )
506  {
507  error = mbImpl->add_entities( lsets[i], lverts[i] );
508  MB_CHK_ERR( error );
509  error = mbImpl->add_entities( lsets[i], lents[i] );
510  MB_CHK_ERR( error );
511  }
512 
513  delete[] lverts;
514  delete[] lents;
515  return MB_SUCCESS;
516 }

References moab::Core::add_entities(), moab::error(), ErrorCode, moab::ParallelComm::exchange_ghost_cells(), moab::ParallelComm::exchange_tags(), moab::Core::get_adjacencies(), moab::Core::get_connectivity(), moab::Core::get_entities_by_dimension(), GLOBAL_ID_TAG_NAME, hasghost, MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, mbImpl, meshdim, pcomm, and moab::Interface::UNION.

Referenced by main().

◆ find_shortest_diagonal_octahedron()

int moab::NestedRefine::find_shortest_diagonal_octahedron ( int  cur_level,
int  deg,
EntityHandle vbuffer 
)
protected

Definition at line 4822 of file NestedRefine.cpp.

4823 {
4824  ErrorCode error;
4825  double coords[18];
4826  error = get_octahedron_corner_coords( cur_level, deg, vbuffer, coords );
4827  if( error != MB_SUCCESS ) MB_SET_ERR( MB_FAILURE, "Error in obtaining octahedron corner coordinates" );
4828 
4829  int diag_map[6] = { 1, 3, 2, 4, 5, 0 };
4830  double length = std::numeric_limits< double >::max();
4831 
4832  int diag = 0;
4833  double x, y, z;
4834  x = y = z = 0;
4835 
4836  for( int d = 0; d < 3; d++ )
4837  {
4838  int id1 = diag_map[2 * d];
4839  int id2 = diag_map[2 * d + 1];
4840  x = coords[3 * id1] - coords[3 * id2];
4841  y = coords[3 * id1 + 1] - coords[3 * id2 + 1];
4842  z = coords[3 * id1 + 2] - coords[3 * id2 + 2];
4843  double dlen = sqrt( x * x + y * y + z * z );
4844  if( dlen < length )
4845  {
4846  length = dlen;
4847  diag = d + 1;
4848  }
4849  }
4850 
4851  return diag;
4852 }

References moab::error(), ErrorCode, get_octahedron_corner_coords(), length(), MB_SET_ERR, and MB_SUCCESS.

Referenced by subdivide_tets().

◆ generate_hm()

ErrorCode moab::NestedRefine::generate_hm ( int *  level_degrees,
int  num_level,
EntityHandle hm_set,
bool  optimize 
)
protected

Definition at line 764 of file NestedRefine.cpp.

765 {
767 
768  Tag gidtag;
770  MB_CHK_ERR( error );
771 
772  nlevels = num_level;
773 
774  timeall.tm_total = 0;
775  timeall.tm_refine = 0;
776  timeall.tm_resolve = 0;
777 
778  for( int l = 0; l < num_level; l++ )
779  {
780  double tstart;
781  tstart = tm->time_elapsed();
782 
783  // Estimate storage
784  int hmest[4] = { 0, 0, 0, 0 };
785  EntityHandle set;
786  if( l )
787  set = hm_set[l - 1];
788  else
789  set = _rset;
790  error = estimate_hm_storage( set, level_degrees[l], l, hmest );
791  MB_CHK_ERR( error );
792 
793  // Create arrays for storing the current level
794  error = create_hm_storage_single_level( &hm_set[l], l, hmest );
795  MB_CHK_ERR( error );
796 
797  // Copy the old vertices along with their coordinates
799  MB_CHK_ERR( error );
800 
801  // Create the new entities and new vertices
802  error = construct_hm_entities( l, level_degrees[l] );
803  MB_CHK_ERR( error );
804 
805  timeall.tm_refine += tm->time_elapsed() - tstart;
806 
807  // Go into parallel communication
808  if( !optimize )
809  {
810 #ifdef MOAB_HAVE_MPI
811  if( pcomm && ( pcomm->size() > 1 ) )
812  {
813  double tpstart = tm->time_elapsed();
814  error = resolve_shared_ents_parmerge( l, hm_set[l] );
815  MB_CHK_ERR( error );
816  timeall.tm_resolve += tm->time_elapsed() - tpstart;
817  }
818 #endif
819  }
820  }
821 
822  if( optimize )
823  {
824 #ifdef MOAB_HAVE_MPI
825  if( pcomm && ( pcomm->size() > 1 ) )
826  {
827  double tpstart = tm->time_elapsed();
828  error = resolve_shared_ents_opt( hm_set, nlevels );
829  MB_CHK_ERR( error );
830  timeall.tm_resolve = tm->time_elapsed() - tpstart;
831  }
832 #endif
833  }
835 
836  return MB_SUCCESS;
837 }

References _rset, construct_hm_entities(), copy_vertices_from_prev_level(), create_hm_storage_single_level(), moab::error(), ErrorCode, estimate_hm_storage(), GLOBAL_ID_TAG_NAME, MB_CHK_ERR, MB_SUCCESS, mbImpl, nlevels, pcomm, moab::ParallelComm::size(), moab::Core::tag_get_handle(), moab::CpuTimer::time_elapsed(), timeall, tm, moab::NestedRefine::codeperf::tm_refine, moab::NestedRefine::codeperf::tm_resolve, and moab::NestedRefine::codeperf::tm_total.

Referenced by generate_mesh_hierarchy().

◆ generate_mesh_hierarchy()

ErrorCode moab::NestedRefine::generate_mesh_hierarchy ( int  num_level,
int *  level_degrees,
std::vector< EntityHandle > &  level_sets,
bool  optimize = false 
)

Generate a mesh hierarchy.

Given a mesh, generate a sequence of meshes via uniform refinement. The inputs are: a) an array(level_degrees) storing the degrees which will be used to refine the previous level mesh to generate a new level and b) the total number of levels(should be same length as that of the array in a). Each mesh level in the hierarchy are stored in different meshsets whose handles are returned after the hierarchy generation. These handles can be used to work with a specific mesh level.

Parameters
level_degreesInteger array storing the degrees used in each level.
num_levelThe total number of levels in the hierarchy.
hm_setEntityHandle STL vector that returns the handles of the sets created for each mesh level.

Definition at line 116 of file NestedRefine.cpp.

120 {
121  assert( num_level > 0 );
122  nlevels = num_level;
123 
125  std::vector< moab::EntityHandle > hmsets( num_level );
126 
127  if( meshdim <= 2 )
128  {
129  for( int i = 0; i < num_level; i++ )
130  {
131  assert( ( level_degrees[i] == 2 ) || ( level_degrees[i] == 3 ) || ( level_degrees[i] == 5 ) );
132  level_dsequence[i] = level_degrees[i];
133  }
134  }
135  else
136  {
137  for( int i = 0; i < num_level; i++ )
138  {
139  assert( ( level_degrees[i] == 2 ) || ( level_degrees[i] == 3 ) );
140  level_dsequence[i] = level_degrees[i];
141  }
142  }
143 
144  error = generate_hm( level_degrees, num_level, &hmsets[0], optimize );
145  MB_CHK_ERR( error );
146 
147  // copy the entity handles
148  level_sets.resize( num_level + 1 );
149  level_sets[0] = _rset;
150  for( int i = 0; i < num_level; i++ )
151  level_sets[i + 1] = hmsets[i];
152 
153  return MB_SUCCESS;
154 }

References _rset, moab::error(), ErrorCode, generate_hm(), level_dsequence, MB_CHK_ERR, MB_SUCCESS, meshdim, and nlevels.

Referenced by main().

◆ get_adjacencies()

ErrorCode moab::NestedRefine::get_adjacencies ( const EntityHandle  source_entity,
const unsigned int  target_dimension,
std::vector< EntityHandle > &  target_entities 
)

Get the adjacencies associated with an entity.

Given an entity of dimension d, gather all the adjacent D dimensional entities where D >, = , < d .

Parameters
source_entityEntityHandle to which adjacent entities have to be found.
target_dimensionInt Dimension of the desired adjacent entities.
target_entitiesVector in which the adjacent EntityHandle are returned.

Definition at line 228 of file NestedRefine.cpp.

232 {
234  error = ahf->get_adjacencies( source_entity, target_dimension, target_entities );
235  MB_CHK_ERR( error );
236 
237  return MB_SUCCESS;
238 }

References ahf, moab::error(), ErrorCode, moab::HalfFacetRep::get_adjacencies(), MB_CHK_ERR, and MB_SUCCESS.

◆ get_connectivity()

ErrorCode moab::NestedRefine::get_connectivity ( EntityHandle  ent,
int  level,
std::vector< EntityHandle > &  conn 
)

Given an entity and its level, return its connectivity.

Given an entity at a certain level, it finds the connectivity via direct access to a stored internal pointer to the memory to connectivity sequence for the given level.

Parameters
entEntityHandle of the entity
levelInteger level of the entity for which connectivity is requested
connstd::vector returning the connectivity of the entity

Definition at line 156 of file NestedRefine.cpp.

157 {
159  EntityType type = mbImpl->type_from_handle( ent );
160  EntityHandle start_ent;
161  if( !conn.empty() ) conn.clear();
162  if( level > 0 )
163  {
164  if( type == MBEDGE )
165  {
166  conn.reserve( 2 );
167  start_ent = level_mesh[level - 1].start_edge;
168  EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent );
169  conn.push_back( level_mesh[level - 1].edge_conn[2 * offset] );
170  conn.push_back( level_mesh[level - 1].edge_conn[2 * offset + 1] );
171  }
172  else if( type == MBTRI || type == MBQUAD )
173  {
174  int num_corners = ahf->lConnMap2D[type - 2].num_verts_in_face;
175  conn.reserve( num_corners );
176  start_ent = level_mesh[level - 1].start_face;
177  EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent );
178 
179  for( int i = 0; i < num_corners; i++ )
180  conn.push_back( level_mesh[level - 1].face_conn[num_corners * offset + i] );
181  }
182  else if( type == MBTET || type == MBHEX )
183  {
185  int num_corners = ahf->lConnMap3D[index].num_verts_in_cell;
186  conn.reserve( num_corners );
187  start_ent = level_mesh[level - 1].start_cell;
188  EntityID offset = ID_FROM_HANDLE( ent ) - ID_FROM_HANDLE( start_ent );
189  for( int i = 0; i < num_corners; i++ )
190  conn.push_back( level_mesh[level - 1].cell_conn[num_corners * offset + i] );
191  }
192  else
193  MB_SET_ERR( MB_FAILURE, "Requesting connectivity for an unsupported entity type" );
194  }
195  else
196  {
197  error = mbImpl->get_connectivity( &ent, 1, conn );
198  MB_CHK_ERR( error );
199  }
200 
201  return MB_SUCCESS;
202 }

References _incells, ahf, moab::Range::begin(), moab::NestedRefine::level_memory::cell_conn, moab::error(), ErrorCode, moab::NestedRefine::level_memory::face_conn, moab::Core::get_connectivity(), moab::HalfFacetRep::get_index_in_lmap(), moab::ID_FROM_HANDLE(), moab::index, moab::HalfFacetRep::lConnMap2D, moab::HalfFacetRep::lConnMap3D, level_mesh, MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, MBEDGE, MBHEX, mbImpl, MBQUAD, MBTET, MBTRI, moab::HalfFacetRep::LocalMaps3D::num_verts_in_cell, moab::HalfFacetRep::LocalMaps2D::num_verts_in_face, moab::NestedRefine::level_memory::start_cell, moab::NestedRefine::level_memory::start_edge, moab::NestedRefine::level_memory::start_face, and moab::Core::type_from_handle().

Referenced by construct_hm_1D(), construct_hm_2D(), get_local_vid(), reorder_indices(), subdivide_cells(), subdivide_tets(), update_global_ahf_1D_sub(), update_global_ahf_2D(), and update_global_ahf_2D_sub().

◆ get_coordinates()

ErrorCode moab::NestedRefine::get_coordinates ( EntityHandle verts,
int  num_verts,
int  level,
double *  coords 
)

Given a vector of vertices and their level, return its coordinates.

Given a vector of vertices at a certain level, it finds the coordinates via direct access to a stored internal pointer to the memory to coordinate sequence for the given level.

Parameters
vertsstd::vector of the entity handles of the vertices
num_vertsThe number of vertices
levelInteger level of the entity for which connectivity is requested
coordsdouble pointer returning the coordinates of the vertices

Definition at line 204 of file NestedRefine.cpp.

205 {
206  if( level > 0 )
207  {
208  EntityID vstart = ID_FROM_HANDLE( level_mesh[level - 1].start_vertex );
209  for( int i = 0; i < num_verts; i++ )
210  {
211  const EntityHandle& vid = verts[i];
212  EntityID offset = ID_FROM_HANDLE( vid ) - vstart;
213  coords[3 * i] = level_mesh[level - 1].coordinates[0][offset];
214  coords[3 * i + 1] = level_mesh[level - 1].coordinates[1][offset];
215  coords[3 * i + 2] = level_mesh[level - 1].coordinates[2][offset];
216  }
217  }
218  else
219  {
221  error = mbImpl->get_coords( verts, num_verts, coords );
222  MB_CHK_ERR( error );
223  }
224 
225  return MB_SUCCESS;
226 }

References moab::NestedRefine::level_memory::coordinates, moab::error(), ErrorCode, moab::Core::get_coords(), moab::ID_FROM_HANDLE(), level_mesh, MB_CHK_ERR, MB_SUCCESS, and mbImpl.

Referenced by construct_hm_2D(), subdivide_cells(), and subdivide_tets().

◆ get_index_from_degree()

◆ get_lid_inci_child()

ErrorCode moab::NestedRefine::get_lid_inci_child ( EntityType  type,
int  deg,
int  lfid,
int  leid,
std::vector< int > &  child_ids,
std::vector< int > &  child_lvids 
)
protected

Definition at line 4207 of file NestedRefine.cpp.

4213 {
4214  int index = ahf->get_index_in_lmap( *_incells.begin() );
4215  int d = get_index_from_degree( deg );
4216 
4217  // int lv0 = ahf->lConnMap3D[index].e2v[leid][0];
4218  // int lv1 = ahf->lConnMap3D[index].e2v[leid][1];
4219  int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
4220 
4221  int nv = refTemplates[type - 1][d].nv_edge;
4222  int nch = refTemplates[type - 1][d].ents_on_pent[lfid][0];
4223 
4224  for( int i = 0; i < nch; i++ )
4225  {
4226  int id = refTemplates[type - 1][d].ents_on_pent[lfid][i + 1] - 1;
4227  for( int j = 0; j < nvpc; j++ )
4228  {
4229  int lv = refTemplates[type - 1][d].ents_conn[id][j];
4230  for( int k = 0; k < nv; k++ )
4231  {
4232  if( lv == refTemplates[type - 1][d].vert_on_edges[leid][k] )
4233  {
4234  child_ids.push_back( id );
4235  child_lvids.push_back( j );
4236  }
4237  }
4238  }
4239  }
4240 
4241  return MB_SUCCESS;
4242 }

References _incells, ahf, moab::Range::begin(), moab::NestedRefine::refPatterns::ents_conn, moab::NestedRefine::refPatterns::ents_on_pent, get_index_from_degree(), moab::HalfFacetRep::get_index_in_lmap(), moab::index, moab::HalfFacetRep::lConnMap3D, MB_SUCCESS, moab::HalfFacetRep::LocalMaps3D::num_verts_in_cell, moab::NestedRefine::refPatterns::nv_edge, and refTemplates.

◆ get_local_vid()

int moab::NestedRefine::get_local_vid ( EntityHandle  vid,
EntityHandle  ent,
int  level 
)
protected

Definition at line 4854 of file NestedRefine.cpp.

4855 {
4856  ErrorCode error;
4857  // Given a vertex, find its local id in the given entity
4858  std::vector< EntityHandle > conn;
4859 
4860  error = get_connectivity( ent, level + 1, conn );
4861  if( error != MB_SUCCESS ) MB_SET_ERR( MB_FAILURE, "Error in getting connectivity of the requested entity" );
4862 
4863  int lid = -1;
4864  for( int i = 0; i < (int)conn.size(); i++ )
4865  {
4866  if( conn[i] == vid )
4867  {
4868  lid = i;
4869  break;
4870  }
4871  }
4872  if( lid < 0 ) MB_SET_ERR( MB_FAILURE, "Error in getting local vertex id in the given entity" );
4873  return lid;
4874 }

References moab::error(), ErrorCode, get_connectivity(), MB_SET_ERR, and MB_SUCCESS.

Referenced by update_global_ahf_1D(), update_global_ahf_1D_sub(), update_global_ahf_2D(), update_global_ahf_2D_sub(), and update_global_ahf_3D().

◆ get_octahedron_corner_coords()

ErrorCode moab::NestedRefine::get_octahedron_corner_coords ( int  cur_level,
int  deg,
EntityHandle vbuffer,
double *  ocoords 
)
protected

Definition at line 4786 of file NestedRefine.cpp.

4787 {
4788  int lid[6] = { 0, 0, 0, 0, 0, 0 };
4789 
4790  if( deg == 2 )
4791  {
4792  lid[0] = 5;
4793  lid[1] = 8;
4794  lid[2] = 9;
4795  lid[3] = 6;
4796  lid[4] = 4;
4797  lid[5] = 7;
4798  }
4799  else if( deg == 3 )
4800  {
4801  lid[0] = 19;
4802  lid[1] = 16;
4803  lid[2] = 18;
4804  lid[3] = 9;
4805  lid[4] = 4;
4806  lid[5] = 10;
4807  }
4808 
4809  EntityHandle vstart = level_mesh[cur_level].start_vertex;
4810 
4811  for( int i = 0; i < 6; i++ )
4812  {
4813  EntityHandle vid = vbuffer[lid[i]];
4814  ocoords[3 * i] = level_mesh[cur_level].coordinates[0][vid - vstart];
4815  ocoords[3 * i + 1] = level_mesh[cur_level].coordinates[1][vid - vstart];
4816  ocoords[3 * i + 2] = level_mesh[cur_level].coordinates[2][vid - vstart];
4817  }
4818 
4819  return MB_SUCCESS;
4820 }

References moab::NestedRefine::level_memory::coordinates, level_mesh, MB_SUCCESS, and moab::NestedRefine::level_memory::start_vertex.

Referenced by find_shortest_diagonal_octahedron().

◆ get_vertex_duplicates()

ErrorCode moab::NestedRefine::get_vertex_duplicates ( EntityHandle  vertex,
int  level,
EntityHandle dupvertex 
)

Definition at line 439 of file NestedRefine.cpp.

440 {
441  if( ( vertex - *_inverts.begin() ) > _inverts.size() )
442  MB_SET_ERR( MB_FAILURE, "Requesting duplicates for non-coarse vertices" );
443 
444  dupvertex = level_mesh[level - 1].start_vertex + ( vertex - *_inverts.begin() );
445 
446  return MB_SUCCESS;
447 }

References _inverts, moab::Range::begin(), level_mesh, MB_SET_ERR, MB_SUCCESS, moab::Range::size(), and moab::NestedRefine::level_memory::start_vertex.

◆ initialize()

ErrorCode moab::NestedRefine::initialize ( )

Definition at line 53 of file NestedRefine.cpp.

54 {
56 
57  tm = new CpuTimer();
58  if( !tm ) return MB_MEMORY_ALLOCATION_FAILED;
59 
60 #ifdef MOAB_HAVE_AHF
61  ahf = mbImpl->a_half_facet_rep();
62 #else
63  ahf = new HalfFacetRep( mbImpl, pcomm, _rset, true );
64  if( !ahf ) return MB_MEMORY_ALLOCATION_FAILED;
65 #endif
66 
67  // Check for mixed entity type
68  bool chk_mixed = ahf->check_mixed_entity_type();
69  if( chk_mixed ) MB_SET_ERR( MB_NOT_IMPLEMENTED, "Encountered a mesh with mixed entity types" );
70 
71  error = ahf->initialize();
72  MB_CHK_ERR( error );
74  MB_CHK_ERR( error );
75 
76  // Check for supported entity type
77  if( !_incells.empty() )
78  {
79  EntityType type = mbImpl->type_from_handle( _incells[0] );
80  if( type != MBTET && type != MBHEX )
81  MB_SET_ERR( MB_FAILURE, "Not supported 3D entity types: MBPRISM, MBPYRAMID, MBKNIFE, MBPOLYHEDRON" );
82 
83  meshdim = 3;
84  elementype = type;
85  }
86  else if( !_infaces.empty() )
87  {
88  EntityType type = mbImpl->type_from_handle( _infaces[0] );
89  if( type == MBPOLYGON ) MB_SET_ERR( MB_FAILURE, "Not supported 2D entity type: POLYGON" );
90 
91  meshdim = 2;
92  elementype = type;
93  }
94  else if( !_inedges.empty() )
95  {
96  meshdim = 1;
98  }
99  else
100  MB_SET_ERR( MB_NOT_IMPLEMENTED, "Encountered a mixed-dimensional or invalid mesh" );
101 
102  // Initialize std::map to get indices of degrees.
103  deg_index[2] = 0;
104  deg_index[3] = 1;
105  deg_index[5] = 2;
106 
107  // Set ghost flag to false
108  hasghost = false;
109  return MB_SUCCESS;
110 }

References _incells, _inedges, _infaces, _inverts, _rset, ahf, moab::HalfFacetRep::check_mixed_entity_type(), deg_index, elementype, moab::Range::empty(), moab::error(), ErrorCode, moab::HalfFacetRep::get_entity_ranges(), hasghost, moab::HalfFacetRep::initialize(), MB_CHK_ERR, MB_MEMORY_ALLOCATION_FAILED, MB_NOT_IMPLEMENTED, MB_SET_ERR, MB_SUCCESS, MBEDGE, MBHEX, mbImpl, MBPOLYGON, MBTET, meshdim, pcomm, tm, and moab::Core::type_from_handle().

Referenced by NestedRefine().

◆ is_cell_on_boundary()

bool moab::NestedRefine::is_cell_on_boundary ( const EntityHandle entity)
protected

Definition at line 4368 of file NestedRefine.cpp.

4369 {
4370  if( meshdim != 3 )
4371  MB_SET_ERR( MB_FAILURE, "Requesting boundary information for a cell entity type on a curve or surface mesh" );
4372 
4373  bool is_border = false;
4374  int index = ahf->get_index_in_lmap( *_incells.begin() );
4375  int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
4376  EntityHandle sibents[6];
4377  int siblids[6];
4378 
4379  ErrorCode error = ahf->get_sibling_map( elementype, entity, &sibents[0], &siblids[0], nfpc );
4380  MB_CHK_ERR( error );
4381 
4382  for( int i = 0; i < nfpc; i++ )
4383  {
4384  if( sibents[i] == 0 )
4385  {
4386  is_border = true;
4387  break;
4388  }
4389  }
4390  return is_border;
4391 }

References _incells, ahf, moab::Range::begin(), elementype, moab::error(), ErrorCode, moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::get_sibling_map(), moab::index, moab::HalfFacetRep::lConnMap3D, MB_CHK_ERR, MB_SET_ERR, meshdim, and moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell.

Referenced by is_entity_on_boundary().

◆ is_edge_on_boundary()

bool moab::NestedRefine::is_edge_on_boundary ( const EntityHandle entity)
protected

Definition at line 4277 of file NestedRefine.cpp.

4278 {
4279  ErrorCode error;
4280  bool is_border = false;
4281  if( meshdim == 1 ) // The edge has a vertex on the boundary in the curve mesh
4282  {
4283  EntityHandle sibents[2];
4284  int siblids[2];
4285  error = ahf->get_sibling_map( MBEDGE, entity, &sibents[0], &siblids[0], 2 );
4286  MB_CHK_ERR( error );
4287  for( int i = 0; i < 2; i++ )
4288  {
4289  if( sibents[i] == 0 )
4290  {
4291  is_border = true;
4292  break;
4293  }
4294  }
4295  }
4296  else if( meshdim == 2 ) // The edge is on the boundary of the 2d mesh
4297  {
4298  std::vector< EntityHandle > adjents;
4299  error = ahf->get_up_adjacencies_2d( entity, adjents );
4300  MB_CHK_ERR( error );
4301  if( adjents.size() == 1 ) is_border = true;
4302  }
4303  else if( meshdim == 3 ) // The edge is part of a face on the boundary of the 3d mesh
4304  {
4305  std::vector< EntityHandle > adjents;
4306  std::vector< int > leids;
4307  error = ahf->get_up_adjacencies_edg_3d( entity, adjents, &leids );
4308  MB_CHK_ERR( error );
4309  assert( !adjents.empty() );
4310 
4311  int index = ahf->get_index_in_lmap( adjents[0] );
4312  int nhf = ahf->lConnMap3D[index].num_faces_in_cell;
4313 
4314  for( int i = 0; i < (int)adjents.size(); i++ )
4315  {
4316  EntityHandle sibents[6];
4317  int siblids[6];
4318  error = ahf->get_sibling_map( elementype, adjents[0], &sibents[0], &siblids[0], nhf );
4319  MB_CHK_ERR( error );
4320  for( int k = 0; k < 2; k++ )
4321  {
4322  int hf = ahf->lConnMap3D[index].e2hf[leids[0]][k];
4323  if( sibents[hf] == 0 )
4324  {
4325  is_border = true;
4326  break;
4327  }
4328  }
4329  }
4330  }
4331  return is_border;
4332 }

References ahf, moab::HalfFacetRep::LocalMaps3D::e2hf, elementype, moab::error(), ErrorCode, moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::get_sibling_map(), moab::HalfFacetRep::get_up_adjacencies_2d(), moab::HalfFacetRep::get_up_adjacencies_edg_3d(), moab::index, moab::HalfFacetRep::lConnMap3D, MB_CHK_ERR, MBEDGE, meshdim, and moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell.

Referenced by is_entity_on_boundary().

◆ is_entity_on_boundary()

bool moab::NestedRefine::is_entity_on_boundary ( const EntityHandle entity)

Given an entity at a certain level, it returns a boolean value true if it lies on the domain boundary.

Parameters
entity

Definition at line 449 of file NestedRefine.cpp.

450 {
451  bool is_border = false;
452  EntityType type = mbImpl->type_from_handle( entity );
453 
454  if( type == MBVERTEX )
455  is_border = is_vertex_on_boundary( entity );
456  else if( type == MBEDGE )
457  is_border = is_edge_on_boundary( entity );
458  else if( type == MBTRI || type == MBQUAD )
459  is_border = is_face_on_boundary( entity );
460  else if( type == MBTET || type == MBHEX )
461  is_border = is_cell_on_boundary( entity );
462  else
463  MB_SET_ERR( MB_FAILURE, "Requesting boundary information for unsupported entity type" );
464 
465  return is_border;
466 }

References is_cell_on_boundary(), is_edge_on_boundary(), is_face_on_boundary(), is_vertex_on_boundary(), MB_SET_ERR, MBEDGE, MBHEX, mbImpl, MBQUAD, MBTET, MBTRI, MBVERTEX, and moab::Core::type_from_handle().

◆ is_face_on_boundary()

bool moab::NestedRefine::is_face_on_boundary ( const EntityHandle entity)
protected

Definition at line 4334 of file NestedRefine.cpp.

4335 {
4336  ErrorCode error;
4337  bool is_border = false;
4338 
4339  if( meshdim == 1 )
4340  MB_SET_ERR( MB_FAILURE, "Requesting boundary information for a face entity type on a curve mesh" );
4341  else if( meshdim == 2 ) // The face has a local edge on the boundary of the 2d mesh
4342  {
4343  EntityHandle sibents[4];
4344  int siblids[4];
4345  int nepf = ahf->lConnMap2D[elementype - 2].num_verts_in_face;
4346  error = ahf->get_sibling_map( elementype, entity, &sibents[0], &siblids[0], nepf );
4347  MB_CHK_ERR( error );
4348 
4349  for( int i = 0; i < nepf; i++ )
4350  {
4351  if( sibents[i] == 0 )
4352  {
4353  is_border = true;
4354  break;
4355  }
4356  }
4357  }
4358  else if( meshdim == 3 ) // The face lies on the boundary of the 3d mesh
4359  {
4360  std::vector< EntityHandle > adjents;
4361  error = ahf->get_up_adjacencies_face_3d( entity, adjents );
4362  MB_CHK_ERR( error );
4363  if( adjents.size() == 1 ) is_border = true;
4364  }
4365  return is_border;
4366 }

References ahf, elementype, moab::error(), ErrorCode, moab::HalfFacetRep::get_sibling_map(), moab::HalfFacetRep::get_up_adjacencies_face_3d(), moab::HalfFacetRep::lConnMap2D, MB_CHK_ERR, MB_SET_ERR, meshdim, and moab::HalfFacetRep::LocalMaps2D::num_verts_in_face.

Referenced by is_entity_on_boundary().

◆ is_vertex_on_boundary()

bool moab::NestedRefine::is_vertex_on_boundary ( const EntityHandle entity)
protected

Boundary extraction functions Given a vertex at a certain level, it returns a boolean value true if it lies on the domain boundary. Note: This is a specialization of the NestedRefine::is_entity_on_boundary function and applies only to vertex queries.

Parameters
entity

Definition at line 4248 of file NestedRefine.cpp.

4249 {
4250  ErrorCode error;
4251  EntityHandle sibents[27];
4252  int siblids[27];
4253  std::vector< EntityHandle > ent;
4254  std::vector< int > lid;
4255 
4256  int nhf;
4257  if( elementype == MBEDGE )
4258  nhf = 2;
4259  else if( ( elementype == MBTRI ) || ( elementype == MBQUAD ) )
4261  else if( ( elementype == MBTET ) || ( elementype == MBHEX ) )
4262  {
4263  int idx = ahf->get_index_in_lmap( *_incells.begin() );
4264  nhf = ahf->lConnMap3D[idx].num_faces_in_cell;
4265  }
4266  else
4267  MB_SET_ERR( MB_FAILURE, "Requesting vertex boundary information for an unsupported entity type" );
4268 
4269  error = ahf->get_incident_map( elementype, vertex, ent, lid );
4270  MB_CHK_ERR( error );
4271  error = ahf->get_sibling_map( elementype, ent[0], &sibents[0], &siblids[0], nhf );
4272  MB_CHK_ERR( error );
4273 
4274  return ( sibents[lid[0]] == 0 );
4275 }

References _incells, ahf, moab::Range::begin(), elementype, moab::error(), ErrorCode, moab::HalfFacetRep::get_incident_map(), moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::get_sibling_map(), moab::HalfFacetRep::lConnMap2D, moab::HalfFacetRep::lConnMap3D, MB_CHK_ERR, MB_SET_ERR, MBEDGE, MBHEX, MBQUAD, MBTET, MBTRI, moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell, and moab::HalfFacetRep::LocalMaps2D::num_verts_in_face.

Referenced by is_entity_on_boundary().

◆ parent_to_child()

ErrorCode moab::NestedRefine::parent_to_child ( EntityHandle  parent,
int  parent_level,
int  child_level,
std::vector< EntityHandle > &  children 
)

Given an entity from a certain level, it returns a std::vector of all its children from the requested child level. NOTE: This query does not support vertices.

Parameters
parentEntityHandle of the entity whose children in subsequent level is requested
parent_levelMesh level where the parent exists
child_levelMesh level from which its children are requested
childrenVector containing all childrens from the requested child_level

Definition at line 291 of file NestedRefine.cpp.

295 {
296  assert( ( child_level > 0 ) && ( child_level > parent_level ) );
297  EntityType type = mbImpl->type_from_handle( parent );
298  assert( type != MBVERTEX );
299 
300  int parent_index;
301  if( type == MBEDGE )
302  {
303  if( parent_level > 0 )
304  parent_index = parent - level_mesh[parent_level - 1].start_edge;
305  else
306  parent_index = _inedges.index( parent );
307  }
308  else if( type == MBTRI || type == MBQUAD )
309  {
310  if( parent_level > 0 )
311  parent_index = parent - level_mesh[parent_level - 1].start_face;
312  else
313  parent_index = _infaces.index( parent );
314  }
315  else if( type == MBTET || type == MBHEX )
316  {
317  if( parent_level > 0 )
318  parent_index = parent - level_mesh[parent_level - 1].start_cell;
319  else
320  parent_index = _incells.index( parent );
321  }
322  else
323  MB_SET_ERR( MB_FAILURE, "Requesting children for unsupported entity type" );
324 
325  int start, end;
326  start = end = parent_index;
327  for( int i = parent_level; i < child_level; i++ )
328  {
330  int nch = refTemplates[type - 1][d].total_new_ents;
331  start = start * nch;
332  end = end * nch + nch - 1;
333  }
334 
335  int num_child = end - start;
336  children.reserve( num_child );
337 
338  for( int i = start; i <= end; i++ )
339  {
340  EntityHandle child;
341  if( type == MBEDGE )
342  child = level_mesh[child_level - 1].start_edge + i;
343  else if( type == MBTRI || type == MBQUAD )
344  child = level_mesh[child_level - 1].start_face + i;
345  else if( type == MBTET || type == MBHEX )
346  child = level_mesh[child_level - 1].start_cell + i;
347 
348  children.push_back( child );
349  }
350 
351  return MB_SUCCESS;
352 }

References _incells, _inedges, _infaces, get_index_from_degree(), moab::Range::index(), level_dsequence, level_mesh, MB_SET_ERR, MB_SUCCESS, MBEDGE, MBHEX, mbImpl, MBQUAD, MBTET, MBTRI, MBVERTEX, refTemplates, moab::NestedRefine::level_memory::start_cell, moab::NestedRefine::level_memory::start_edge, moab::NestedRefine::level_memory::start_face, moab::NestedRefine::refPatterns::total_new_ents, and moab::Core::type_from_handle().

Referenced by update_special_tags(), and vertex_to_entities_down().

◆ print_maps_1D()

ErrorCode moab::NestedRefine::print_maps_1D ( int  level)
protected

◆ print_maps_2D()

ErrorCode moab::NestedRefine::print_maps_2D ( int  level,
EntityType  type 
)
protected

◆ print_maps_3D()

ErrorCode moab::NestedRefine::print_maps_3D ( int  level,
EntityType  type 
)
protected

◆ reorder_indices() [1/4]

ErrorCode moab::NestedRefine::reorder_indices ( EntityHandle face1_conn,
EntityHandle face2_conn,
int  nvF,
int *  conn_map,
int &  comb,
int *  orient = NULL 
)
protected

Definition at line 4714 of file NestedRefine.cpp.

4720 {
4721  // Given connectivities of two faces and a degree, get the permuted indices of the children
4722  // faces w.r.t first face.
4723 
4724  // Step 1: First find the combination
4725  int nco = permutation[nvF - 3].num_comb;
4726  int c = 0;
4727  for( int i = 0; i < nco; i++ )
4728  {
4729  int count = 0;
4730  for( int j = 0; j < nvF; j++ )
4731  {
4732  int id = permutation[nvF - 3].comb[i][j];
4733  if( face1_conn[j] == face2_conn[id] ) count += 1;
4734  }
4735 
4736  if( count == nvF )
4737  {
4738  c = i;
4739  break;
4740  }
4741  }
4742 
4743  if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" );
4744 
4745  comb = c;
4746 
4747  if( orient ) orient[0] = permutation[nvF - 3].orient[c];
4748 
4749  for( int j = 0; j < nvF; j++ )
4750  {
4751  conn_map[j] = permutation[nvF - 3].comb[c][j];
4752  }
4753 
4754  return MB_SUCCESS;
4755 }

References moab::NestedRefine::pmat::comb, MB_SET_ERR, MB_SUCCESS, moab::NestedRefine::pmat::num_comb, moab::NestedRefine::pmat::orient, and permutation.

◆ reorder_indices() [2/4]

ErrorCode moab::NestedRefine::reorder_indices ( int  cur_level,
int  deg,
EntityHandle  cell,
int  lfid,
EntityHandle  sib_cell,
int  sib_lfid,
int  index,
int *  id_sib 
)
protected

Definition at line 4557 of file NestedRefine.cpp.

4565 {
4566  // Reorders the indices of either vertices or children cell local ids to match with order of the
4567  // given cell and a local face. index = 0 : vertices,
4568  // = 1 : face
4569 
4570  assert( deg == 2 || deg == 3 );
4571 
4572  ErrorCode error;
4573  int idx = ahf->get_index_in_lmap( *_incells.begin() );
4574  int nvF = ahf->lConnMap3D[idx].hf2v_num[lfid];
4575  int nco = permutation[nvF - 3].num_comb;
4576 
4577  if( !index && ( ( nvF == 3 && deg == 3 ) || ( nvF == 4 && deg == 2 ) ) )
4578  {
4579  id_sib[0] = 1;
4580  }
4581  else
4582  {
4583  // Get connectivity of the cell and its sibling cell
4584  std::vector< EntityHandle > conn, sib_conn;
4585  error = get_connectivity( cell, cur_level, conn );
4586  MB_CHK_ERR( error );
4587 
4588  error = get_connectivity( sib_cell, cur_level, sib_conn );
4589  MB_CHK_ERR( error );
4590 
4591  // Get the connectivity of the local face in the cell and its sibling
4592  std::vector< EntityHandle > lface( nvF );
4593  std::vector< EntityHandle > lface_sib( nvF );
4594  for( int i = 0; i < nvF; i++ )
4595  {
4596  int id = ahf->lConnMap3D[idx].hf2v[lfid][i];
4597  lface[i] = conn[id];
4598 
4599  id = ahf->lConnMap3D[idx].hf2v[sib_lfid][i];
4600  lface_sib[i] = sib_conn[id];
4601  }
4602 
4603  // Find the combination
4604  int c = 0;
4605  for( int i = 0; i < nco; i++ )
4606  {
4607  int count = 0;
4608  for( int j = 0; j < nvF; j++ )
4609  {
4610  int id = permutation[nvF - 3].comb[i][j];
4611  if( lface[j] == lface_sib[id] ) count += 1;
4612  }
4613 
4614  if( count == nvF )
4615  {
4616  c = i;
4617  break;
4618  }
4619  }
4620 
4621  if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" );
4622 
4623  // Get the ordered indices
4624  if( ( ( !index ) && ( nvF == 4 ) && ( deg == 3 ) ) || ( deg == 2 ) )
4625  {
4626  for( int i = 0; i < 4; i++ )
4627  id_sib[i] = permutation[nvF - 3].porder2[c][i];
4628  }
4629  else
4630  {
4631  for( int i = 0; i < 9; i++ )
4632  id_sib[i] = permutation[nvF - 3].porder3[c][i];
4633  }
4634  }
4635 
4636  return MB_SUCCESS;
4637 }

References _incells, ahf, moab::Range::begin(), moab::NestedRefine::pmat::comb, moab::error(), ErrorCode, get_connectivity(), moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::LocalMaps3D::hf2v, moab::HalfFacetRep::LocalMaps3D::hf2v_num, moab::index, moab::HalfFacetRep::lConnMap3D, MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, moab::NestedRefine::pmat::num_comb, and permutation.

Referenced by construct_hm_2D(), update_global_ahf_3D(), and update_tracking_verts().

◆ reorder_indices() [3/4]

ErrorCode moab::NestedRefine::reorder_indices ( int  deg,
EntityHandle face1_conn,
EntityHandle face2_conn,
int  nvF,
std::vector< int > &  lemap,
std::vector< int > &  vidx,
int *  leorient = NULL 
)
protected

Definition at line 4639 of file NestedRefine.cpp.

4646 {
4647  // Given the connectivities of two faces, get the permuted indices w.r.t first face.
4648  // Step 1: First find the orientation
4649  int nco = permutation[nvF - 3].num_comb;
4650  int c = 0;
4651  for( int i = 0; i < nco; i++ )
4652  {
4653  int count = 0;
4654  for( int j = 0; j < nvF; j++ )
4655  {
4656  int id = permutation[nvF - 3].comb[i][j];
4657  if( face1_conn[j] == face2_conn[id] ) count += 1;
4658  }
4659 
4660  if( count == nvF )
4661  {
4662  c = i;
4663  break;
4664  }
4665  }
4666 
4667  if( c > nco ) MB_SET_ERR( MB_FAILURE, "Getting a combination number more than currently supported" );
4668 
4669  // Add the corresponding local edges
4670  lemap.reserve( nvF );
4671  for( int i = 0; i < nvF; i++ )
4672  {
4673  lemap.push_back( permutation[nvF - 3].lemap[c][i] );
4674  }
4675  if( leorient ) leorient[0] = permutation[nvF - 3].orient[c];
4676 
4677  if( nvF == 3 && deg == 2 ) return MB_SUCCESS;
4678 
4679  if( ( nvF == 3 && deg == 3 ) || ( nvF == 4 && deg == 2 ) )
4680  {
4681  vidx.push_back( 1 );
4682  }
4683  else if( nvF == 4 && deg == 3 )
4684  {
4685  for( int i = 0; i < 4; i++ )
4686  vidx.push_back( permutation[nvF - 3].porder2[c][i] );
4687  }
4688 
4689  return MB_SUCCESS;
4690 }

References moab::NestedRefine::pmat::comb, MB_SET_ERR, MB_SUCCESS, moab::NestedRefine::pmat::num_comb, moab::NestedRefine::pmat::orient, permutation, and moab::NestedRefine::pmat::porder2.

◆ reorder_indices() [4/4]

ErrorCode moab::NestedRefine::reorder_indices ( int  deg,
int  nvF,
int  comb,
int *  childfid_map 
)
protected

Definition at line 4692 of file NestedRefine.cpp.

4693 {
4694  // Given connectivities of two faces and a degree, get the permuted indices of the children
4695  // faces w.r.t first face.
4696 
4697  assert( deg == 2 || deg == 3 );
4698 
4699  // Get the ordered indices
4700  if( deg == 2 )
4701  {
4702  for( int i = 0; i < 4; i++ )
4703  childfid_map[i] = permutation[nvF - 3].porder2[comb][i];
4704  }
4705  else
4706  {
4707  for( int i = 0; i < 9; i++ )
4708  childfid_map[i] = permutation[nvF - 3].porder3[comb][i];
4709  }
4710 
4711  return MB_SUCCESS;
4712 }

References MB_SUCCESS, and permutation.

◆ subdivide_cells()

ErrorCode moab::NestedRefine::subdivide_cells ( EntityType  type,
int  cur_level,
int  deg 
)
protected

Definition at line 1505 of file NestedRefine.cpp.

1506 {
1507  ErrorCode error;
1508  int nverts_prev, nents_prev;
1509  if( cur_level )
1510  {
1511  nverts_prev = level_mesh[cur_level - 1].num_verts;
1512  nents_prev = level_mesh[cur_level - 1].num_cells;
1513  }
1514  else
1515  {
1516  nverts_prev = _inverts.size();
1517  nents_prev = _incells.size();
1518  }
1519 
1520  // Create some book-keeping arrays over the parent mesh to avoid introducing duplicate vertices
1521  int cindex = type - 1;
1522  int d = get_index_from_degree( deg );
1523  int ne = refTemplates[cindex][d].nv_edge;
1524  int nvf = refTemplates[cindex][d].nv_face;
1525  int nvtotal = refTemplates[cindex][d].total_new_verts;
1526 
1527  int index = ahf->get_index_in_lmap( *( _incells.begin() ) );
1528  int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
1529  int nepc = ahf->lConnMap3D[index].num_edges_in_cell;
1530  int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
1531 
1532  int vtotal = nvpc + nvtotal;
1533  std::vector< EntityHandle > vbuffer( vtotal );
1534 
1535  std::vector< EntityHandle > trackvertsC_edg( nepc * ne * nents_prev, 0 );
1536  std::vector< EntityHandle > trackvertsC_face( nfpc * nvf * nents_prev, 0 );
1537 
1538  int cur_nverts = level_mesh[cur_level].num_verts;
1539  std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 );
1540 
1541  int count_nverts = nverts_prev;
1542  int count_ents = 0;
1543  std::vector< EntityHandle > conn, cur_conn;
1544 
1545  // Step 1: Create the subentities via refinement of the previous mesh
1546  for( int cid = 0; cid < nents_prev; cid++ )
1547  {
1548  conn.clear();
1549  cur_conn.clear();
1550  for( int i = 0; i < vtotal; i++ )
1551  vbuffer[i] = 0;
1552 
1553  // EntityHandle of the working cell
1554  EntityHandle cell;
1555  if( cur_level )
1556  cell = level_mesh[cur_level - 1].start_cell + cid;
1557  else
1558  cell = _incells[cid];
1559 
1560  error = get_connectivity( cell, cur_level, conn );
1561  MB_CHK_ERR( error );
1562 
1563  // Step 1: Add vertices from the current level for the working face that will be used for
1564  // subdivision.
1565  // Add the corners to vbuffer
1566  for( int i = 0; i < (int)conn.size(); i++ )
1567  {
1568  if( cur_level )
1569  vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex );
1570  else
1571  vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() );
1572 
1573  cur_conn.push_back( vbuffer[i] );
1574  }
1575 
1576  // Gather vertices already added to tracking array due to refinement of the sibling cells
1577  for( int i = 0; i < nepc; i++ )
1578  {
1579  for( int j = 0; j < ne; j++ )
1580  {
1581  int idx = refTemplates[cindex][d].vert_on_edges[i][j];
1582  vbuffer[idx] = trackvertsC_edg[cid * nepc * ne + ne * i + j];
1583  }
1584  }
1585 
1586  // Add remaining new vertex handles
1587  for( int i = 0; i < nfpc; i++ )
1588  {
1589  for( int j = 0; j < nvf; j++ )
1590  {
1591  int idx = refTemplates[cindex][d].vert_on_faces[i][j];
1592  vbuffer[idx] = trackvertsC_face[cid * nfpc * nvf + nvf * i + j];
1593  }
1594  }
1595 
1596  // Add the remaining vertex handles to vbuffer for the current level for the working cell
1597  for( int i = 0; i < nvtotal; i++ )
1598  {
1599  if( !vbuffer[i + nvpc] )
1600  {
1601  vbuffer[i + nvpc] = level_mesh[cur_level].start_vertex + count_nverts;
1602  count_nverts += 1;
1603  }
1604  }
1605 
1606  // Step 2: Use the template to obtain the subentities. The coordinates and local ahf maps
1607  // are also constructed. Connectivity of the children
1608  int etotal = refTemplates[type - 1][d].total_new_ents;
1609  std::vector< EntityHandle > ent_buffer( etotal );
1610 
1611  for( int i = 0; i < etotal; i++ )
1612  {
1613  for( int k = 0; k < nvpc; k++ )
1614  {
1615  int idx = refTemplates[type - 1][d].ents_conn[i][k];
1616  level_mesh[cur_level].cell_conn[nvpc * count_ents + k] = vbuffer[idx];
1617  }
1618  ent_buffer[i] = level_mesh[cur_level].start_cell + count_ents;
1619  count_ents += 1;
1620  }
1621 
1622  // Step 3: Update local ahf maps
1623  error = update_local_ahf( deg, type, &vbuffer[0], &ent_buffer[0], etotal );
1624  MB_CHK_ERR( error );
1625 
1626  // Step 4: Update tracking information
1627  error = update_tracking_verts( cell, cur_level, deg, trackvertsC_edg, trackvertsC_face, &vbuffer[0] );
1628  MB_CHK_ERR( error );
1629 
1630  // Step 5: Coordinates of the new vertices
1631  std::vector< double > corner_coords( nvpc * 3 );
1632  error = get_coordinates( &cur_conn[0], nvpc, cur_level + 1, &corner_coords[0] );
1633  MB_CHK_ERR( error );
1634 
1635  error = compute_coordinates( cur_level, deg, type, &vbuffer[0], vtotal, &corner_coords[0], flag_verts,
1636  nverts_prev );
1637  MB_CHK_ERR( error );
1638  }
1639 
1640  // error = ahf->print_tags(3);
1641 
1642  // Step 6: Update the global maps
1643  error = update_global_ahf( type, cur_level, deg );
1644  MB_CHK_ERR( error );
1645 
1646  // Step 7: If edges exists, refine them as well.
1647  if( level_mesh[cur_level].num_edges != 0 )
1648  {
1649  error = construct_hm_1D( cur_level, deg, type, trackvertsC_edg );
1650  MB_CHK_ERR( error );
1651  }
1652 
1653  // Step 8: If faces exists, refine them as well.
1654  if( !_infaces.empty() )
1655  {
1656  error = construct_hm_2D( cur_level, deg, type, trackvertsC_edg, trackvertsC_face );
1657  MB_CHK_ERR( error );
1658  }
1659 
1660  // error = ahf->print_tags(3);
1661 
1662  return MB_SUCCESS;
1663 }

References _incells, _infaces, _inverts, ahf, moab::Range::begin(), moab::NestedRefine::level_memory::cell_conn, compute_coordinates(), construct_hm_1D(), construct_hm_2D(), moab::Range::empty(), moab::NestedRefine::refPatterns::ents_conn, moab::error(), ErrorCode, get_connectivity(), get_coordinates(), get_index_from_degree(), moab::HalfFacetRep::get_index_in_lmap(), moab::index, moab::HalfFacetRep::lConnMap3D, level_mesh, MB_CHK_ERR, MB_SUCCESS, moab::NestedRefine::level_memory::num_cells, moab::HalfFacetRep::LocalMaps3D::num_edges_in_cell, moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell, moab::NestedRefine::level_memory::num_verts, moab::HalfFacetRep::LocalMaps3D::num_verts_in_cell, moab::NestedRefine::refPatterns::nv_edge, moab::NestedRefine::refPatterns::nv_face, refTemplates, moab::Range::size(), moab::NestedRefine::level_memory::start_cell, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::NestedRefine::refPatterns::total_new_verts, update_global_ahf(), update_local_ahf(), update_tracking_verts(), moab::NestedRefine::refPatterns::vert_on_edges, and moab::NestedRefine::refPatterns::vert_on_faces.

Referenced by construct_hm_3D().

◆ subdivide_tets()

ErrorCode moab::NestedRefine::subdivide_tets ( int  cur_level,
int  deg 
)
protected

Definition at line 1665 of file NestedRefine.cpp.

1666 {
1667  ErrorCode error;
1668  int nverts_prev, nents_prev;
1669  if( cur_level )
1670  {
1671  nverts_prev = level_mesh[cur_level - 1].num_verts;
1672  nents_prev = level_mesh[cur_level - 1].num_cells;
1673  }
1674  else
1675  {
1676  nverts_prev = _inverts.size();
1677  nents_prev = _incells.size();
1678  }
1679 
1680  EntityType type = MBTET;
1681  int cindex = type - 1;
1682  int d = get_index_from_degree( deg );
1683  int ne = refTemplates[cindex][d].nv_edge;
1684  int nvf = refTemplates[cindex][d].nv_face;
1685  int nvtotal = refTemplates[cindex][d].total_new_verts;
1686 
1687  int index = ahf->get_index_in_lmap( *( _incells.begin() ) );
1688  int nvpc = ahf->lConnMap3D[index].num_verts_in_cell;
1689  int nepc = ahf->lConnMap3D[index].num_edges_in_cell;
1690  int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
1691 
1692  // Create vertex buffer
1693  int vtotal = nvpc + nvtotal;
1694  std::vector< EntityHandle > vbuffer( vtotal );
1695 
1696  // Create book-keeping arrays over the parent mesh to avoid introducing duplicate vertices
1697  std::vector< EntityHandle > trackvertsC_edg( nepc * ne * nents_prev, 0 );
1698  std::vector< EntityHandle > trackvertsC_face( nfpc * nvf * nents_prev, 0 );
1699 
1700  int cur_nverts = level_mesh[cur_level].num_verts;
1701  std::vector< int > flag_verts( cur_nverts - nverts_prev, 0 );
1702  std::vector< int > cell_patterns( nents_prev, 0 );
1703 
1704  int count_nverts = nverts_prev;
1705  int count_ents = 0;
1706  std::vector< EntityHandle > conn, cur_conn;
1707 
1708  // Step 1: Create the subentities via refinement of the previous mesh
1709  for( int cid = 0; cid < nents_prev; cid++ )
1710  {
1711  conn.clear();
1712  cur_conn.clear();
1713  for( int i = 0; i < vtotal; i++ )
1714  vbuffer[i] = 0;
1715 
1716  // EntityHandle of the working cell
1717  EntityHandle cell;
1718  if( cur_level )
1719  cell = level_mesh[cur_level - 1].start_cell + cid;
1720  else
1721  cell = _incells[cid];
1722 
1723  error = get_connectivity( cell, cur_level, conn );
1724  MB_CHK_ERR( error );
1725 
1726  // Step 1: Add vertices from the current level for the working face that will be used for
1727  // subdivision.
1728  // Add the corners to vbuffer
1729  for( int i = 0; i < (int)conn.size(); i++ )
1730  {
1731  if( cur_level )
1732  vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - level_mesh[cur_level - 1].start_vertex );
1733  else
1734  vbuffer[i] = level_mesh[cur_level].start_vertex + ( conn[i] - *_inverts.begin() );
1735 
1736  cur_conn.push_back( vbuffer[i] );
1737  }
1738 
1739  // Gather vertices already added to tracking array due to refinement of the sibling cells
1740  for( int i = 0; i < nepc; i++ )
1741  {
1742  for( int j = 0; j < ne; j++ )
1743  {
1744  int idx = refTemplates[cindex][d].vert_on_edges[i][j];
1745  vbuffer[idx] = trackvertsC_edg[cid * nepc * ne + ne * i + j];
1746  }
1747  }
1748 
1749  // Add remaining new vertex handles
1750  for( int i = 0; i < nfpc; i++ )
1751  {
1752  for( int j = 0; j < nvf; j++ )
1753  {
1754  int idx = refTemplates[cindex][d].vert_on_faces[i][j];
1755  vbuffer[idx] = trackvertsC_face[cid * nfpc * nvf + nvf * i + j];
1756  }
1757  }
1758 
1759  // Add the remaining vertex handles to vbuffer for the current level for the working cell
1760  for( int i = 0; i < nvtotal; i++ )
1761  {
1762  if( !vbuffer[i + nvpc] )
1763  {
1764  vbuffer[i + nvpc] = level_mesh[cur_level].start_vertex + count_nverts;
1765  count_nverts += 1;
1766  }
1767  }
1768 
1769  // Step 2: Coordinates of the new vertices
1770  std::vector< double > corner_coords( nvpc * 3 );
1771  error = get_coordinates( &cur_conn[0], nvpc, cur_level + 1, &corner_coords[0] );
1772  MB_CHK_ERR( error );
1773 
1774  error = compute_coordinates( cur_level, deg, type, &vbuffer[0], vtotal, &corner_coords[0], flag_verts,
1775  nverts_prev );
1776  MB_CHK_ERR( error );
1777 
1778  // Step 3: Choose the tet refine pattern to be used for this tet
1779  int diag = find_shortest_diagonal_octahedron( cur_level, deg, &vbuffer[0] );
1780  int pat_id = diag + 2;
1781  cell_patterns[cid] = pat_id;
1782 
1783  // Step 4: Use the template to obtain the subentities. The coordinates and local ahf maps
1784  // are also constructed. Connectivity of the children
1785  int etotal = refTemplates[pat_id][d].total_new_ents;
1786  std::vector< EntityHandle > ent_buffer( etotal );
1787 
1788  for( int i = 0; i < etotal; i++ )
1789  {
1790  for( int k = 0; k < nvpc; k++ )
1791  {
1792  int idx = refTemplates[pat_id][d].ents_conn[i][k];
1793  level_mesh[cur_level].cell_conn[nvpc * count_ents + k] = vbuffer[idx];
1794  }
1795  ent_buffer[i] = level_mesh[cur_level].start_cell + count_ents;
1796  count_ents += 1;
1797  }
1798 
1799  // Step 5: Update local ahf maps
1800  error = update_local_ahf( deg, MBTET, pat_id, &vbuffer[0], &ent_buffer[0], etotal );
1801  MB_CHK_ERR( error );
1802 
1803  // Step 6: Update tracking information
1804  error = update_tracking_verts( cell, cur_level, deg, trackvertsC_edg, trackvertsC_face, &vbuffer[0] );
1805  MB_CHK_ERR( error );
1806  }
1807 
1808  // Step 7: Update the global maps
1809  // error = update_global_ahf(cur_level, deg, cell_patterns); MB_CHK_ERR(error);
1810  error = update_global_ahf( type, cur_level, deg, &cell_patterns );
1811  MB_CHK_ERR( error );
1812 
1813  // Step 8: If edges exists, refine them as well.
1814  if( level_mesh[cur_level].num_edges != 0 )
1815  {
1816  error = construct_hm_1D( cur_level, deg, type, trackvertsC_edg );
1817  MB_CHK_ERR( error );
1818  }
1819 
1820  // Step 9: If faces exists, refine them as well.
1821  if( !_infaces.empty() )
1822  {
1823  error = construct_hm_2D( cur_level, deg, type, trackvertsC_edg, trackvertsC_face );
1824  MB_CHK_ERR( error );
1825  }
1826 
1827  return MB_SUCCESS;
1828 }

References _incells, _infaces, _inverts, ahf, moab::Range::begin(), moab::NestedRefine::level_memory::cell_conn, compute_coordinates(), construct_hm_1D(), construct_hm_2D(), moab::Range::empty(), moab::NestedRefine::refPatterns::ents_conn, moab::error(), ErrorCode, find_shortest_diagonal_octahedron(), get_connectivity(), get_coordinates(), get_index_from_degree(), moab::HalfFacetRep::get_index_in_lmap(), moab::index, moab::HalfFacetRep::lConnMap3D, level_mesh, MB_CHK_ERR, MB_SUCCESS, MBTET, moab::NestedRefine::level_memory::num_cells, moab::HalfFacetRep::LocalMaps3D::num_edges_in_cell, moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell, moab::NestedRefine::level_memory::num_verts, moab::HalfFacetRep::LocalMaps3D::num_verts_in_cell, moab::NestedRefine::refPatterns::nv_edge, moab::NestedRefine::refPatterns::nv_face, refTemplates, moab::Range::size(), moab::NestedRefine::level_memory::start_cell, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::NestedRefine::refPatterns::total_new_verts, update_global_ahf(), update_local_ahf(), update_tracking_verts(), moab::NestedRefine::refPatterns::vert_on_edges, and moab::NestedRefine::refPatterns::vert_on_faces.

Referenced by construct_hm_3D().

◆ update_ahf_1D()

ErrorCode moab::NestedRefine::update_ahf_1D ( int  cur_level)
protected

Definition at line 3593 of file NestedRefine.cpp.

3594 {
3595  ErrorCode error;
3596  error = ahf->determine_sibling_halfverts( level_mesh[cur_level].verts, level_mesh[cur_level].edges );
3597  MB_CHK_ERR( error );
3598 
3599  error = ahf->determine_incident_halfverts( level_mesh[cur_level].edges );
3600  MB_CHK_ERR( error );
3601 
3602  return MB_SUCCESS;
3603 }

References ahf, moab::HalfFacetRep::determine_incident_halfverts(), moab::HalfFacetRep::determine_sibling_halfverts(), moab::error(), ErrorCode, level_mesh, MB_CHK_ERR, and MB_SUCCESS.

Referenced by construct_hm_2D().

◆ update_global_ahf()

ErrorCode moab::NestedRefine::update_global_ahf ( EntityType  type,
int  cur_level,
int  deg,
std::vector< int > *  pattern_ids = NULL 
)
protected

Definition at line 3292 of file NestedRefine.cpp.

3293 {
3294 
3295  ErrorCode error;
3296 
3297  // Get the number of half-facets and number of children of each type
3298  if( type == MBEDGE )
3299  {
3300  assert( pattern_ids == NULL );
3301  error = update_global_ahf_1D( cur_level, deg );
3302  MB_CHK_ERR( error );
3303  }
3304  else if( type == MBTRI || type == MBQUAD )
3305  {
3306  assert( pattern_ids == NULL );
3307  error = update_global_ahf_2D( cur_level, deg );
3308  MB_CHK_ERR( error );
3309  }
3310  else if( type == MBHEX )
3311  {
3312  assert( pattern_ids == NULL );
3313  error = update_global_ahf_3D( cur_level, deg );
3314  MB_CHK_ERR( error );
3315  }
3316  else if( type == MBTET )
3317  {
3318  assert( pattern_ids != NULL );
3319  error = update_global_ahf_3D( cur_level, deg, pattern_ids );
3320  MB_CHK_ERR( error );
3321  }
3322  else
3323  MB_SET_ERR( MB_NOT_IMPLEMENTED, "Requesting AHF update for an unsupported mesh entity type" );
3324 
3325  return MB_SUCCESS;
3326 }

References moab::error(), ErrorCode, MB_CHK_ERR, MB_NOT_IMPLEMENTED, MB_SET_ERR, MB_SUCCESS, MBEDGE, MBHEX, MBQUAD, MBTET, MBTRI, update_global_ahf_1D(), update_global_ahf_2D(), and update_global_ahf_3D().

Referenced by construct_hm_1D(), construct_hm_2D(), subdivide_cells(), and subdivide_tets().

◆ update_global_ahf_1D()

ErrorCode moab::NestedRefine::update_global_ahf_1D ( int  cur_level,
int  deg 
)
protected

Definition at line 3336 of file NestedRefine.cpp.

3337 {
3338  ErrorCode error;
3339  int d = get_index_from_degree( deg );
3340  int nhf, nchilds, nverts_prev, nents_prev;
3341  nhf = 2;
3342  nchilds = refTemplates[0][d].total_new_ents;
3343  if( cur_level )
3344  {
3345  nverts_prev = level_mesh[cur_level - 1].num_verts;
3346  nents_prev = level_mesh[cur_level - 1].num_edges;
3347  }
3348  else
3349  {
3350  nverts_prev = _inverts.size();
3351  nents_prev = _inedges.size();
3352  }
3353 
3354  std::vector< EntityHandle > inci_ent, child_ents;
3355  std::vector< int > inci_lid, child_lids;
3356 
3357  // Update the vertex to half-facet maps for duplicate vertices
3358  for( int i = 0; i < nverts_prev; i++ )
3359  {
3360  inci_ent.clear();
3361  inci_lid.clear();
3362  child_ents.clear();
3363  child_lids.clear();
3364 
3365  // Vertex id in the previous mesh and the current one
3366  EntityHandle vid;
3367  if( cur_level )
3368  vid = level_mesh[cur_level - 1].start_vertex + i;
3369  else
3370  vid = _inverts[i];
3371  EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i;
3372 
3373  // Get the incident half-vert in the previous mesh
3374  error = ahf->get_incident_map( MBEDGE, vid, inci_ent, inci_lid );
3375  MB_CHK_ERR( error );
3376 
3377  // Obtain the corresponding incident child in the current mesh
3378  int lvid = get_local_vid( vid, inci_ent[0], cur_level - 1 );
3379  if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
3380  int chid = refTemplates[0][d].v2hf[lvid][0] - 1;
3381 
3382  int pid;
3383  if( cur_level )
3384  pid = inci_ent[0] - level_mesh[cur_level - 1].start_edge;
3385  else
3386  pid = inci_ent[0] - *_inedges.begin();
3387 
3388  int ind = nchilds * pid;
3389 
3390  child_ents.push_back( level_mesh[cur_level].start_edge + ind + chid );
3391  child_lids.push_back( refTemplates[0][d].v2hf[lvid][1] );
3392 
3393  error = ahf->set_incident_map( MBEDGE, cur_vid, child_ents, child_lids );
3394  MB_CHK_ERR( error );
3395  }
3396 
3397  // Update the sibling half-facet maps across entities
3398  for( int i = 0; i < nents_prev; i++ )
3399  {
3400  EntityHandle ent;
3401  if( cur_level )
3402  ent = level_mesh[cur_level - 1].start_edge + i;
3403  else
3404  ent = _inedges[i];
3405 
3406  std::vector< EntityHandle > sib_entids( nhf );
3407  std::vector< int > sib_lids( nhf );
3408 
3409  error = ahf->get_sibling_map( MBEDGE, ent, &sib_entids[0], &sib_lids[0], nhf );
3410  MB_CHK_ERR( error );
3411 
3412  int id, idx;
3413 
3414  for( int l = 0; l < nhf; l++ )
3415  {
3416  if( !sib_entids[l] ) continue;
3417 
3418  // Find the child incident on the half-facet
3419  id = refTemplates[0][d].ents_on_pent[l][1] - 1;
3420  idx = nchilds * i;
3421  EntityHandle child_ent = level_mesh[cur_level].start_edge + idx + id;
3422  int ch_lid = l;
3423 
3424  // Find the sibling of the child
3425  std::vector< EntityHandle > sib_childs( nhf );
3426  std::vector< int > sib_chlids( nhf );
3427 
3428  error = ahf->get_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );
3429  MB_CHK_ERR( error );
3430 
3431  // If the sibling already exists, dont do anything
3432  if( sib_childs[ch_lid] ) continue;
3433 
3434  // Get the correponding child of the sibling of the current parent
3435  int psib;
3436  if( cur_level )
3437  psib = sib_entids[l] - level_mesh[cur_level - 1].start_edge;
3438  else
3439  psib = sib_entids[l] - *_inedges.begin();
3440 
3441  int plid = sib_lids[l];
3442 
3443  id = refTemplates[0][d].ents_on_pent[plid][1] - 1;
3444  idx = nchilds * psib;
3445 
3446  EntityHandle psib_child = level_mesh[cur_level].start_edge + idx + id;
3447  int psib_chlid = plid;
3448 
3449  // Set the siblings
3450  sib_childs[ch_lid] = psib_child;
3451  sib_chlids[ch_lid] = psib_chlid;
3452 
3453  error = ahf->set_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );
3454  MB_CHK_ERR( error );
3455  }
3456  }
3457 
3458  return MB_SUCCESS;
3459 }

References _inedges, _inverts, ahf, moab::Range::begin(), moab::NestedRefine::refPatterns::ents_on_pent, moab::error(), ErrorCode, moab::HalfFacetRep::get_incident_map(), get_index_from_degree(), get_local_vid(), moab::HalfFacetRep::get_sibling_map(), level_mesh, MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, MBEDGE, moab::NestedRefine::level_memory::num_edges, moab::NestedRefine::level_memory::num_verts, refTemplates, moab::HalfFacetRep::set_incident_map(), moab::HalfFacetRep::set_sibling_map(), moab::Range::size(), moab::NestedRefine::level_memory::start_edge, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, and moab::NestedRefine::refPatterns::v2hf.

Referenced by update_global_ahf().

◆ update_global_ahf_1D_sub()

ErrorCode moab::NestedRefine::update_global_ahf_1D_sub ( int  cur_level,
int  deg 
)
protected

Definition at line 3461 of file NestedRefine.cpp.

3462 {
3463  ErrorCode error;
3464  int d = get_index_from_degree( deg );
3465  int nhf, nchilds, nents_prev;
3466  nhf = 2;
3467  nchilds = refTemplates[0][d].total_new_ents;
3468  if( cur_level )
3469  {
3470  nents_prev = level_mesh[cur_level - 1].num_edges;
3471  }
3472  else
3473  {
3474  nents_prev = _inedges.size();
3475  }
3476 
3477  // Update the sibling half-facet maps across entities
3478 
3479  std::vector< EntityHandle > conn;
3480  for( int i = 0; i < nents_prev; i++ )
3481  {
3482  EntityHandle ent;
3483  if( cur_level )
3484  ent = level_mesh[cur_level - 1].start_edge + i;
3485  else
3486  ent = _inedges[i];
3487 
3488  // Set incident hv maps
3489  conn.clear();
3490  error = get_connectivity( ent, cur_level, conn );
3491  MB_CHK_ERR( error );
3492 
3493  std::vector< EntityHandle > inci_ent, child_ents;
3494  std::vector< int > inci_lid, child_lids;
3495  for( int j = 0; j < 2; j++ )
3496  {
3497  inci_ent.clear();
3498  inci_lid.clear();
3499  child_ents.clear();
3500  child_lids.clear();
3501 
3502  // Get the entityhandle of the vertex from previous level in the current level
3503  EntityHandle cur_vid;
3504  if( cur_level )
3505  cur_vid = level_mesh[cur_level].start_vertex + ( conn[j] - level_mesh[cur_level - 1].start_vertex );
3506  else
3507  cur_vid = level_mesh[cur_level].start_vertex + ( conn[j] - *_inverts.begin() );
3508 
3509  // Obtain the incident half-facet. If exists, then no need to assign another
3510  error = ahf->get_incident_map( MBEDGE, cur_vid, inci_ent, inci_lid );
3511  MB_CHK_ERR( error );
3512  if( inci_ent[0] != 0 ) continue;
3513 
3514  // Get the incident half-facet on the old vertex
3515  error = ahf->get_incident_map( MBEDGE, conn[j], inci_ent, inci_lid );
3516  MB_CHK_ERR( error );
3517 
3518  // Obtain the corresponding incident child in the current mesh
3519  int lvid = get_local_vid( conn[j], inci_ent[0], cur_level - 1 );
3520  if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
3521  int chid = refTemplates[0][d].v2hf[lvid][0] - 1;
3522 
3523  int pid;
3524  if( cur_level )
3525  pid = inci_ent[0] - level_mesh[cur_level - 1].start_edge;
3526  else
3527  pid = inci_ent[0] - *_inedges.begin();
3528 
3529  int ind = nchilds * pid;
3530 
3531  child_ents.push_back( level_mesh[cur_level].start_edge + ind + chid );
3532  child_lids.push_back( refTemplates[0][d].v2hf[lvid][1] );
3533 
3534  error = ahf->set_incident_map( MBEDGE, cur_vid, child_ents, child_lids );
3535  MB_CHK_ERR( error );
3536  }
3537 
3538  std::vector< EntityHandle > sib_entids( nhf );
3539  std::vector< int > sib_lids( nhf );
3540 
3541  error = ahf->get_sibling_map( MBEDGE, ent, &sib_entids[0], &sib_lids[0], nhf );
3542  MB_CHK_ERR( error );
3543 
3544  int id, idx;
3545 
3546  for( int l = 0; l < nhf; l++ )
3547  {
3548  if( !sib_entids[l] ) continue;
3549 
3550  // Find the child incident on the half-facet
3551  id = refTemplates[0][d].ents_on_pent[l][1] - 1;
3552  idx = nchilds * i;
3553  EntityHandle child_ent = level_mesh[cur_level].start_edge + idx + id;
3554  int ch_lid = l;
3555 
3556  // Find the sibling of the child
3557  std::vector< EntityHandle > sib_childs( nhf );
3558  std::vector< int > sib_chlids( nhf );
3559 
3560  error = ahf->get_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );
3561  MB_CHK_ERR( error );
3562 
3563  // If the sibling already exists, dont do anything
3564  if( sib_childs[ch_lid] ) continue;
3565 
3566  // Get the correponding child of the sibling of the current parent
3567  int psib;
3568  if( cur_level )
3569  psib = sib_entids[l] - level_mesh[cur_level - 1].start_edge;
3570  else
3571  psib = sib_entids[l] - *_inedges.begin();
3572 
3573  int plid = sib_lids[l];
3574 
3575  id = refTemplates[0][d].ents_on_pent[plid][1] - 1;
3576  idx = nchilds * psib;
3577 
3578  EntityHandle psib_child = level_mesh[cur_level].start_edge + idx + id;
3579  int psib_chlid = plid;
3580 
3581  // Set the siblings
3582  sib_childs[ch_lid] = psib_child;
3583  sib_chlids[ch_lid] = psib_chlid;
3584 
3585  error = ahf->set_sibling_map( MBEDGE, child_ent, &sib_childs[0], &sib_chlids[0], nhf );
3586  MB_CHK_ERR( error );
3587  }
3588  }
3589 
3590  return MB_SUCCESS;
3591 }

References _inedges, _inverts, ahf, moab::Range::begin(), moab::Range::clear(), moab::NestedRefine::refPatterns::ents_on_pent, moab::error(), ErrorCode, get_connectivity(), moab::HalfFacetRep::get_incident_map(), get_index_from_degree(), get_local_vid(), moab::HalfFacetRep::get_sibling_map(), level_mesh, MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, MBEDGE, moab::NestedRefine::level_memory::num_edges, refTemplates, moab::HalfFacetRep::set_incident_map(), moab::HalfFacetRep::set_sibling_map(), moab::Range::size(), moab::NestedRefine::level_memory::start_edge, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, and moab::NestedRefine::refPatterns::v2hf.

Referenced by construct_hm_1D().

◆ update_global_ahf_2D()

ErrorCode moab::NestedRefine::update_global_ahf_2D ( int  cur_level,
int  deg 
)
protected

Definition at line 3605 of file NestedRefine.cpp.

3606 {
3607  ErrorCode error;
3608 
3609  EntityType type = mbImpl->type_from_handle( *_infaces.begin() );
3610  int nhf, nchilds, nverts_prev, nents_prev;
3611 
3612  nhf = ahf->lConnMap2D[type - 2].num_verts_in_face;
3613  int d = get_index_from_degree( deg );
3614  nchilds = refTemplates[type - 1][d].total_new_ents;
3615 
3616  if( cur_level )
3617  {
3618  nverts_prev = level_mesh[cur_level - 1].num_verts;
3619  nents_prev = level_mesh[cur_level - 1].num_faces;
3620  }
3621  else
3622  {
3623  nverts_prev = _inverts.size();
3624  nents_prev = _infaces.size();
3625  }
3626 
3627  std::vector< EntityHandle > inci_ent, child_ents;
3628  std::vector< int > inci_lid, child_lids;
3629 
3630  // Update the vertex to half-edge maps for old/duplicate vertices
3631  for( int i = 0; i < nverts_prev; i++ )
3632  {
3633  inci_ent.clear();
3634  inci_lid.clear();
3635  child_ents.clear();
3636  child_lids.clear();
3637 
3638  // Vertex id in the previous mesh
3639  EntityHandle vid;
3640  if( cur_level )
3641  vid = level_mesh[cur_level - 1].start_vertex + i;
3642  else
3643  vid = _inverts[i];
3644  EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i;
3645 
3646  // Get the incident half-vert in the previous mesh
3647  error = ahf->get_incident_map( type, vid, inci_ent, inci_lid );
3648  MB_CHK_ERR( error );
3649 
3650  // Obtain the corresponding incident child in the current mesh
3651  for( int j = 0; j < (int)inci_ent.size(); j++ )
3652  {
3653  int lvid = get_local_vid( vid, inci_ent[j], cur_level - 1 );
3654  if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
3655  int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1;
3656 
3657  int pid;
3658  if( cur_level )
3659  pid = inci_ent[j] - level_mesh[cur_level - 1].start_face;
3660  else
3661  pid = inci_ent[j] - *_infaces.begin();
3662 
3663  int ind = nchilds * pid;
3664 
3665  child_ents.push_back( level_mesh[cur_level].start_face + ind + chid );
3666  child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] );
3667  }
3668  error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );
3669  MB_CHK_ERR( error );
3670  }
3671 
3672  EntityHandle fedge[2];
3673 
3674  // Update the sibling half-facet maps across entities
3675  for( int i = 0; i < nents_prev; i++ )
3676  {
3677  EntityHandle ent;
3678  if( cur_level )
3679  ent = level_mesh[cur_level - 1].start_face + i;
3680  else
3681  ent = _infaces[i];
3682 
3683  std::vector< EntityHandle > fid_conn;
3684  error = get_connectivity( ent, cur_level, fid_conn );
3685  if( MB_SUCCESS != error ) return error;
3686 
3687  std::vector< EntityHandle > sib_entids( nhf );
3688  std::vector< int > sib_lids( nhf );
3689 
3690  error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );
3691  MB_CHK_ERR( error );
3692 
3693  int id, idx;
3694 
3695  for( int l = 0; l < nhf; l++ )
3696  {
3697  if( !sib_entids[l] ) continue;
3698 
3699  int nidx = ahf->lConnMap2D[type - 2].next[l];
3700  fedge[0] = fid_conn[l];
3701  fedge[1] = fid_conn[nidx];
3702 
3703  EntityHandle sfid = sib_entids[l];
3704  int slid = sib_lids[l];
3705 
3706  std::vector< EntityHandle > conn;
3707  error = get_connectivity( sfid, cur_level, conn );
3708  if( MB_SUCCESS != error ) return error;
3709 
3710  bool orient = true;
3711  nidx = ahf->lConnMap2D[type - 2].next[slid];
3712  if( ( fedge[1] == conn[slid] ) && ( fedge[0] == conn[nidx] ) ) orient = false;
3713 
3714  if( orient ) assert( ( fedge[0] == conn[slid] ) && ( fedge[1] == conn[nidx] ) );
3715 
3716  // Find the childrens incident on the half-facet
3717  int nch = refTemplates[type - 1][d].ents_on_pent[l][0];
3718  idx = nchilds * i;
3719 
3720  // Loop over all the incident childrens
3721  for( int k = 0; k < nch; k++ )
3722  {
3723  id = refTemplates[type - 1][d].ents_on_pent[l][k + 1] - 1;
3724  EntityHandle child_ent = level_mesh[cur_level].start_face + idx + id;
3725  int child_lid = l;
3726 
3727  // Find the sibling of the child
3728  EntityHandle child_sibent;
3729  int child_siblid;
3730  error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );
3731  MB_CHK_ERR( error );
3732 
3733  if( child_sibent != 0 ) continue;
3734 
3735  // Get the correponding child of the sibling of the current parent
3736  int psib;
3737  if( cur_level )
3738  psib = sfid - level_mesh[cur_level - 1].start_face;
3739  else
3740  psib = sfid - *_infaces.begin();
3741 
3742  int plid = slid;
3743 
3744  if( orient )
3745  id = refTemplates[type - 1][d].ents_on_pent[plid][k + 1] - 1;
3746  else
3747  id = refTemplates[type - 1][d].ents_on_pent[plid][nch - k] - 1;
3748 
3749  int sidx = nchilds * psib;
3750 
3751  EntityHandle psib_child = level_mesh[cur_level].start_face + sidx + id;
3752  int psib_chlid = plid;
3753 
3754  // Set the siblings
3755  error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );
3756  MB_CHK_ERR( error );
3757  }
3758  }
3759  }
3760 
3761  return MB_SUCCESS;
3762 }

References _infaces, _inverts, ahf, moab::Range::begin(), moab::NestedRefine::refPatterns::ents_on_pent, moab::error(), ErrorCode, get_connectivity(), moab::HalfFacetRep::get_incident_map(), get_index_from_degree(), get_local_vid(), moab::HalfFacetRep::get_sibling_map(), moab::HalfFacetRep::lConnMap2D, level_mesh, MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, mbImpl, moab::HalfFacetRep::LocalMaps2D::next, moab::NestedRefine::level_memory::num_faces, moab::NestedRefine::level_memory::num_verts, moab::HalfFacetRep::LocalMaps2D::num_verts_in_face, refTemplates, moab::HalfFacetRep::set_incident_map(), moab::HalfFacetRep::set_sibling_map(), moab::Range::size(), moab::NestedRefine::level_memory::start_face, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::Core::type_from_handle(), and moab::NestedRefine::refPatterns::v2hf.

Referenced by update_global_ahf().

◆ update_global_ahf_2D_sub()

ErrorCode moab::NestedRefine::update_global_ahf_2D_sub ( int  cur_level,
int  deg 
)
protected

Definition at line 3764 of file NestedRefine.cpp.

3765 {
3766  ErrorCode error;
3767  int d = get_index_from_degree( deg );
3768  EntityType type = mbImpl->type_from_handle( *_infaces.begin() );
3769  int nhf, nchilds, nents_prev;
3770  nhf = ahf->lConnMap2D[type - 2].num_verts_in_face;
3771  nchilds = refTemplates[type - 1][d].total_new_ents;
3772 
3773  if( cur_level )
3774  nents_prev = level_mesh[cur_level - 1].num_faces;
3775  else
3776  nents_prev = _infaces.size();
3777 
3778  EntityHandle fedge[2];
3779 
3780  // Update the sibling half-facet maps across entities
3781  for( int i = 0; i < nents_prev; i++ )
3782  {
3783  EntityHandle ent;
3784  if( cur_level )
3785  ent = level_mesh[cur_level - 1].start_face + i;
3786  else
3787  ent = _infaces[i];
3788 
3789  std::vector< EntityHandle > fid_conn;
3790  error = get_connectivity( ent, cur_level, fid_conn );
3791  if( MB_SUCCESS != error ) return error;
3792 
3793  std::vector< EntityHandle > inci_ent, child_ents;
3794  std::vector< int > inci_lid, child_lids;
3795 
3796  // Set incident half-edges
3797  for( int j = 0; j < nhf; j++ )
3798  {
3799  inci_ent.clear();
3800  inci_lid.clear();
3801  child_ents.clear();
3802  child_lids.clear();
3803  EntityHandle cur_vid;
3804  if( cur_level )
3805  cur_vid = level_mesh[cur_level].start_vertex + ( fid_conn[j] - level_mesh[cur_level - 1].start_vertex );
3806  else
3807  cur_vid = level_mesh[cur_level].start_vertex + ( fid_conn[j] - *_inverts.begin() );
3808 
3809  // Obtain the incident half-facet. If exists, then no need to assign another
3810  error = ahf->get_incident_map( type, cur_vid, inci_ent, inci_lid );
3811  MB_CHK_ERR( error );
3812  if( inci_ent[0] != 0 ) continue;
3813 
3814  // Get the incident half-facet on the old vertex
3815  error = ahf->get_incident_map( type, fid_conn[j], inci_ent, inci_lid );
3816  MB_CHK_ERR( error );
3817 
3818  // Obtain the corresponding incident child in the current mesh
3819  for( int k = 0; k < (int)inci_ent.size(); k++ )
3820  {
3821  int lvid = get_local_vid( fid_conn[j], inci_ent[k], cur_level - 1 );
3822  if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
3823  int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1;
3824 
3825  int pid;
3826  if( cur_level )
3827  pid = inci_ent[k] - level_mesh[cur_level - 1].start_face;
3828  else
3829  pid = inci_ent[k] - *_infaces.begin();
3830 
3831  int ind = nchilds * pid;
3832 
3833  child_ents.push_back( level_mesh[cur_level].start_face + ind + chid );
3834  child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] );
3835  }
3836 
3837  error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );
3838  MB_CHK_ERR( error );
3839  }
3840 
3841  // Set sibling half-edges
3842  std::vector< EntityHandle > sib_entids( nhf );
3843  std::vector< int > sib_lids( nhf );
3844 
3845  error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );
3846  MB_CHK_ERR( error );
3847 
3848  int id, idx;
3849 
3850  for( int l = 0; l < nhf; l++ )
3851  {
3852  if( !sib_entids[l] ) continue;
3853 
3854  int nidx = ahf->lConnMap2D[type - 2].next[l];
3855  fedge[0] = fid_conn[l];
3856  fedge[1] = fid_conn[nidx];
3857 
3858  EntityHandle sfid = sib_entids[l];
3859  int slid = sib_lids[l];
3860 
3861  std::vector< EntityHandle > conn;
3862  error = get_connectivity( sfid, cur_level, conn );
3863  MB_CHK_ERR( error );
3864 
3865  assert( (int)conn.size() > nidx && (int)conn.size() > slid );
3866 
3867  bool orient = true;
3868  nidx = ahf->lConnMap2D[type - 2].next[slid];
3869  if( ( fedge[1] == conn[slid] ) && ( fedge[0] == conn[nidx] ) ) orient = false;
3870 
3871  if( orient ) assert( ( fedge[0] == conn[slid] ) && ( fedge[1] == conn[nidx] ) );
3872 
3873  // Find the childrens incident on the half-facet
3874  int nch = refTemplates[type - 1][d].ents_on_pent[l][0];
3875  idx = nchilds * i;
3876 
3877  // Loop over all the incident childrens
3878  for( int k = 0; k < nch; k++ )
3879  {
3880  id = refTemplates[type - 1][d].ents_on_pent[l][k + 1] - 1;
3881  EntityHandle child_ent = level_mesh[cur_level].start_face + idx + id;
3882  int child_lid = l;
3883 
3884  // Find the sibling of the child
3885  EntityHandle child_sibent;
3886  int child_siblid;
3887  error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );
3888  MB_CHK_ERR( error );
3889 
3890  if( child_sibent != 0 ) continue;
3891 
3892  // Get the correponding child of the sibling of the current parent
3893  int psib;
3894  if( cur_level )
3895  psib = sfid - level_mesh[cur_level - 1].start_face;
3896  else
3897  psib = sfid - *_infaces.begin();
3898 
3899  int plid = slid;
3900 
3901  if( orient )
3902  id = refTemplates[type - 1][d].ents_on_pent[plid][k + 1] - 1;
3903  else
3904  id = refTemplates[type - 1][d].ents_on_pent[plid][nch - k] - 1;
3905 
3906  int sidx = nchilds * psib;
3907 
3908  EntityHandle psib_child = level_mesh[cur_level].start_face + sidx + id;
3909  int psib_chlid = plid;
3910 
3911  // Set the siblings
3912  error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );
3913  MB_CHK_ERR( error );
3914  }
3915  }
3916  }
3917 
3918  return MB_SUCCESS;
3919 }

References _infaces, _inverts, ahf, moab::Range::begin(), moab::NestedRefine::refPatterns::ents_on_pent, moab::error(), ErrorCode, get_connectivity(), moab::HalfFacetRep::get_incident_map(), get_index_from_degree(), get_local_vid(), moab::HalfFacetRep::get_sibling_map(), moab::HalfFacetRep::lConnMap2D, level_mesh, MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, mbImpl, moab::HalfFacetRep::LocalMaps2D::next, moab::NestedRefine::level_memory::num_faces, moab::HalfFacetRep::LocalMaps2D::num_verts_in_face, refTemplates, moab::HalfFacetRep::set_incident_map(), moab::HalfFacetRep::set_sibling_map(), moab::Range::size(), moab::NestedRefine::level_memory::start_face, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::Core::type_from_handle(), and moab::NestedRefine::refPatterns::v2hf.

Referenced by construct_hm_2D().

◆ update_global_ahf_3D()

ErrorCode moab::NestedRefine::update_global_ahf_3D ( int  cur_level,
int  deg,
std::vector< int > *  pattern_ids = NULL 
)
protected

Definition at line 3921 of file NestedRefine.cpp.

3922 {
3923  ErrorCode error;
3924  int nvpc, ne, nhf, nchilds, nverts_prev, nents_prev;
3925 
3926  EntityType type = mbImpl->type_from_handle( *_incells.begin() );
3927  int index = ahf->get_index_in_lmap( *_incells.begin() );
3928  int d = get_index_from_degree( deg );
3929 
3933  nchilds = refTemplates[type - 1][d].total_new_ents;
3934 
3935  if( cur_level )
3936  {
3937  nverts_prev = level_mesh[cur_level - 1].num_verts;
3938  nents_prev = level_mesh[cur_level - 1].num_cells;
3939  }
3940  else
3941  {
3942  nverts_prev = _inverts.size();
3943  nents_prev = _incells.size();
3944  }
3945 
3946  std::vector< EntityHandle > inci_ent, child_ents;
3947  std::vector< int > inci_lid, child_lids;
3948 
3949  // Step 1: Update the V2HF maps for old/duplicate vertices
3950  for( int i = 0; i < nverts_prev; i++ )
3951  {
3952  inci_ent.clear();
3953  inci_lid.clear();
3954  child_ents.clear();
3955  child_lids.clear();
3956 
3957  // Vertex id in the previous mesh
3958  EntityHandle vid;
3959  if( cur_level )
3960  vid = level_mesh[cur_level - 1].start_vertex + i;
3961  else
3962  vid = _inverts[i];
3963  EntityHandle cur_vid = level_mesh[cur_level].start_vertex + i;
3964 
3965  // Get the incident half-vert in the previous mesh
3966  error = ahf->get_incident_map( type, vid, inci_ent, inci_lid );
3967  MB_CHK_ERR( error );
3968 
3969  // Obtain the corresponding incident child in the current mesh
3970  for( int j = 0; j < (int)inci_ent.size(); j++ )
3971  {
3972  int lvid = get_local_vid( vid, inci_ent[j], cur_level - 1 );
3973  if( lvid < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex ix " );
3974  int chid = refTemplates[type - 1][d].v2hf[lvid][0] - 1;
3975 
3976  int pid;
3977  if( cur_level )
3978  pid = inci_ent[j] - level_mesh[cur_level - 1].start_cell;
3979  else
3980  pid = inci_ent[j] - *_incells.begin();
3981 
3982  int ind = nchilds * pid;
3983 
3984  // EntityHandle child_ent = level_mesh[cur_level].start_cell + ind+chid ;
3985  // int child_lid = refTemplates[type-1][d].v2hf[lvid][1];
3986  child_ents.push_back( level_mesh[cur_level].start_cell + ind + chid );
3987  child_lids.push_back( refTemplates[type - 1][d].v2hf[lvid][1] );
3988  }
3989 
3990  error = ahf->set_incident_map( type, cur_vid, child_ents, child_lids );
3991  MB_CHK_ERR( error );
3992  }
3993 
3994  // error = ahf->determine_incident_halffaces( level_mesh[cur_level].cells);MB_CHK_ERR(error);
3995 
3996  // Step 2: Update SIBHFS maps
3997  for( int i = 0; i < nents_prev; i++ )
3998  {
3999  EntityHandle ent;
4000  if( cur_level )
4001  ent = level_mesh[cur_level - 1].start_cell + i;
4002  else
4003  ent = _incells[i];
4004 
4005  std::vector< EntityHandle > sib_entids( nhf );
4006  std::vector< int > sib_lids( nhf );
4007 
4008  error = ahf->get_sibling_map( type, ent, &sib_entids[0], &sib_lids[0], nhf );
4009  MB_CHK_ERR( error );
4010 
4011  int id, idx;
4012 
4013  for( int l = 0; l < nhf; l++ )
4014  {
4015 
4016  if( !sib_entids[l] ) continue;
4017 
4018  // Get the number of children incident on this half-face
4019  int pat_id;
4020  if( type == MBTET )
4021  pat_id = ( *pattern_ids )[i];
4022  else
4023  pat_id = type - 1;
4024  int nch = refTemplates[pat_id][d].ents_on_pent[l][0];
4025 
4026  // Get the order of children indices incident on this half-face
4027  std::vector< int > id_sib( nch );
4028  for( int k = 0; k < nch; k++ )
4029  id_sib[k] = 0;
4030 
4031  error = reorder_indices( cur_level, deg, ent, l, sib_entids[l], sib_lids[l], 1, &id_sib[0] );
4032  MB_CHK_ERR( error );
4033 
4034  // Get the parent index of the sibling cell
4035  int psib;
4036  if( cur_level )
4037  psib = sib_entids[l] - level_mesh[cur_level - 1].start_cell;
4038  else
4039  psib = sib_entids[l] - *_incells.begin();
4040 
4041  int plid = sib_lids[l];
4042  int sidx = nchilds * psib;
4043  int sibpat_id;
4044  if( type == MBTET )
4045  sibpat_id = ( *pattern_ids )[psib];
4046  else
4047  sibpat_id = type - 1;
4048 
4049  // Loop over all the childs incident on the working half-face
4050  idx = nchilds * i;
4051 
4052  for( int k = 0; k < nch; k++ )
4053  {
4054  id = refTemplates[pat_id][d].ents_on_pent[l][k + 1] - 1;
4055  EntityHandle child_ent = level_mesh[cur_level].start_cell + idx + id;
4056  int child_lid = l;
4057 
4058  // Find the sibling of the working child
4059  EntityHandle child_sibent;
4060  int child_siblid;
4061  error = ahf->get_sibling_map( type, child_ent, child_lid, child_sibent, child_siblid );
4062  MB_CHK_ERR( error );
4063 
4064  if( child_sibent != 0 ) continue;
4065 
4066  // Get the correponding child of the sibling of the current parent
4067  // We have already computed the order the children on incident corresponding to the
4068  // working half-face
4069  id = refTemplates[sibpat_id][d].ents_on_pent[plid][id_sib[k]] - 1;
4070 
4071  EntityHandle psib_child = level_mesh[cur_level].start_cell + sidx + id;
4072  int psib_chlid = plid;
4073 
4074  // Set the siblings of children incident on current half-face
4075  error = ahf->set_sibling_map( type, child_ent, child_lid, psib_child, psib_chlid );
4076  MB_CHK_ERR( error );
4077 
4078  // Set the sibling of the sibling of the children to the children
4079  error = ahf->set_sibling_map( type, psib_child, psib_chlid, child_ent, child_lid );
4080  MB_CHK_ERR( error );
4081  }
4082  }
4083 
4084  // Loop over edges to check if there are any non-manifold edges. If there are then the v2hfs
4085  // map should be updated for the new vertices on it.
4086  const EntityHandle* conn;
4087  error = mbImpl->get_connectivity( ent, conn, nvpc );
4088  MB_CHK_ERR( error );
4089 
4090  int nv = refTemplates[type - 1][d].nv_edge; //#verts on each edge
4091  for( int l = 0; l < ne; l++ )
4092  {
4093  id = ahf->lConnMap3D[index].e2v[l][0];
4094  EntityHandle v_start = conn[id];
4095  id = ahf->lConnMap3D[index].e2v[l][1];
4096  EntityHandle v_end = conn[id];
4097 
4098  bool visited = false;
4099 
4100  std::vector< EntityHandle > inci_ent1, inci_ent2;
4101  std::vector< int > inci_lid1, inci_lid2;
4102  error = ahf->get_incident_map( type, v_start, inci_ent1, inci_lid1 );
4103  MB_CHK_ERR( error );
4104  error = ahf->get_incident_map( type, v_end, inci_ent2, inci_lid2 );
4105  MB_CHK_ERR( error );
4106 
4107  if( inci_ent1.size() > 1 && inci_ent2.size() > 1 )
4108  {
4109  std::vector< EntityHandle > cell_comps;
4110  std::vector< int > leid_comps;
4111 
4112  error = ahf->get_up_adjacencies_edg_3d_comp( ent, l, cell_comps, &leid_comps );
4113  MB_CHK_ERR( error );
4114 
4115  int ncomps = cell_comps.size();
4116  std::vector< EntityHandle > edgverts;
4117  std::vector< EntityHandle > compchildents( nv * ncomps );
4118  std::vector< int > compchildlfids( nv * ncomps );
4119 
4120  for( int s = 0; s < nv * ncomps; s++ )
4121  {
4122  compchildents[s] = 0;
4123  compchildlfids[s] = 0;
4124  }
4125 
4126  for( int j = 0; j < (int)cell_comps.size(); j++ )
4127  {
4128  int ind;
4129  if( cur_level )
4130  ind = level_mesh[cur_level - 1].cells.index( cell_comps[j] );
4131  else
4132  ind = _incells.index( cell_comps[j] );
4133 
4134  for( int k = 0; k < nv; k++ )
4135  {
4136  int chid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k] - 1;
4137  int lfid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k + 1];
4138  int lvid = refTemplates[type - 1][d].ents_on_vedge[leid_comps[j]][3 * k + 2];
4139 
4140  EntityHandle childcell = level_mesh[cur_level].start_cell + ind * nchilds + chid;
4141 
4142  const EntityHandle* econn;
4143  error = mbImpl->get_connectivity( childcell, econn, nvpc );
4144  MB_CHK_ERR( error );
4145 
4146  EntityHandle vert = econn[lvid];
4147 
4148  if( ahf->check_nonmanifold_vertices( type, vert ) )
4149  {
4150  visited = true;
4151  break;
4152  }
4153 
4154  if( edgverts.empty() )
4155  {
4156  edgverts.push_back( vert );
4157  compchildents[0] = childcell;
4158  compchildlfids[0] = lfid;
4159  }
4160  else
4161  {
4162  std::vector< EntityHandle >::iterator it;
4163  it = find( edgverts.begin(), edgverts.end(), vert );
4164  int indx = it - edgverts.begin();
4165 
4166  if( it == edgverts.end() )
4167  {
4168  edgverts.push_back( vert );
4169  compchildents[k * ncomps] = childcell;
4170  compchildlfids[k * ncomps] = lfid;
4171  }
4172  else
4173  {
4174  compchildents[indx * ncomps + j] = childcell;
4175  compchildlfids[indx * ncomps + j] = lfid;
4176  }
4177  }
4178  }
4179  }
4180 
4181  if( visited )
4182  {
4183  break;
4184  }
4185 
4186  // Set the incident half-facet map
4187  for( int k = 0; k < nv; k++ )
4188  {
4189  std::vector< EntityHandle > set_childents;
4190  std::vector< int > set_childlfids;
4191  for( int j = 0; j < ncomps; j++ )
4192  {
4193  set_childents.push_back( compchildents[k * ncomps + j] );
4194  set_childlfids.push_back( compchildlfids[k * ncomps + j] );
4195  }
4196 
4197  error = ahf->set_incident_map( type, edgverts[k], set_childents, set_childlfids );
4198  MB_CHK_ERR( error );
4199  }
4200  }
4201  }
4202  }
4203 
4204  return MB_SUCCESS;
4205 }

References _incells, _inverts, ahf, moab::Range::begin(), moab::NestedRefine::level_memory::cells, moab::HalfFacetRep::check_nonmanifold_vertices(), moab::HalfFacetRep::LocalMaps3D::e2v, moab::NestedRefine::refPatterns::ents_on_pent, moab::NestedRefine::refPatterns::ents_on_vedge, moab::error(), ErrorCode, moab::Core::get_connectivity(), moab::HalfFacetRep::get_incident_map(), get_index_from_degree(), moab::HalfFacetRep::get_index_in_lmap(), get_local_vid(), moab::HalfFacetRep::get_sibling_map(), moab::HalfFacetRep::get_up_adjacencies_edg_3d_comp(), moab::index, moab::Range::index(), moab::HalfFacetRep::lConnMap3D, level_mesh, MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, mbImpl, MBTET, moab::NestedRefine::level_memory::num_cells, moab::HalfFacetRep::LocalMaps3D::num_edges_in_cell, moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell, moab::NestedRefine::level_memory::num_verts, moab::HalfFacetRep::LocalMaps3D::num_verts_in_cell, moab::NestedRefine::refPatterns::nv_edge, refTemplates, reorder_indices(), moab::HalfFacetRep::set_incident_map(), moab::HalfFacetRep::set_sibling_map(), moab::Range::size(), moab::NestedRefine::level_memory::start_cell, moab::NestedRefine::level_memory::start_vertex, moab::NestedRefine::refPatterns::total_new_ents, moab::Core::type_from_handle(), and moab::NestedRefine::refPatterns::v2hf.

Referenced by update_global_ahf().

◆ update_local_ahf() [1/2]

ErrorCode moab::NestedRefine::update_local_ahf ( int  deg,
EntityType  type,
EntityHandle vbuffer,
EntityHandle ent_buffer,
int  etotal 
)
protected

Definition at line 3278 of file NestedRefine.cpp.

3283 {
3284  ErrorCode error;
3285  assert( type != MBTET );
3286  error = update_local_ahf( deg, type, type - 1, vbuffer, ent_buffer, etotal );
3287  MB_CHK_ERR( error );
3288 
3289  return MB_SUCCESS;
3290 }

References moab::error(), ErrorCode, MB_CHK_ERR, MB_SUCCESS, and MBTET.

Referenced by construct_hm_1D(), construct_hm_2D(), subdivide_cells(), and subdivide_tets().

◆ update_local_ahf() [2/2]

ErrorCode moab::NestedRefine::update_local_ahf ( int  deg,
EntityType  type,
int  pat_id,
EntityHandle vbuffer,
EntityHandle ent_buffer,
int  etotal 
)
protected

Definition at line 3178 of file NestedRefine.cpp.

3184 {
3185  ErrorCode error;
3186  int nhf = 0, nv = 0, total_new_verts = 0;
3187  int d = get_index_from_degree( deg );
3188 
3189  // Get the number of half-facets
3190  if( type == MBEDGE )
3191  {
3192  nhf = 2;
3193  nv = 2;
3194  total_new_verts = refTemplates[0][d].total_new_verts;
3195  }
3196  else if( type == MBTRI || type == MBQUAD )
3197  {
3198  nhf = ahf->lConnMap2D[type - 2].num_verts_in_face;
3199  nv = nhf;
3200  total_new_verts = refTemplates[pat_id][d].total_new_verts;
3201  }
3202  else if( type == MBTET || type == MBHEX )
3203  {
3204  int index = ahf->get_index_in_lmap( *_incells.begin() );
3207  total_new_verts = refTemplates[pat_id][d].total_new_verts;
3208  }
3209 
3210  std::vector< EntityHandle > ent;
3211  std::vector< int > lid;
3212 
3213  // Update the vertex to half-facet map
3214  for( int i = 0; i < total_new_verts; i++ )
3215  {
3216  ent.clear();
3217  lid.clear();
3218  EntityHandle vid = vbuffer[i + nv];
3219  error = ahf->get_incident_map( type, vid, ent, lid );
3220  MB_CHK_ERR( error );
3221 
3222  if( ent[0] ) continue;
3223 
3224  int id = refTemplates[pat_id][d].v2hf[i + nv][0] - 1;
3225  ent[0] = ent_buffer[id];
3226  lid[0] = refTemplates[pat_id][d].v2hf[i + nv][1];
3227 
3228  error = ahf->set_incident_map( type, vid, ent, lid );
3229  MB_CHK_ERR( error );
3230  }
3231 
3232  // Update the sibling half-facet map
3233  for( int i = 0; i < etotal; i++ )
3234  {
3235  std::vector< EntityHandle > sib_entids( nhf );
3236  std::vector< int > sib_lids( nhf );
3237 
3238  error = ahf->get_sibling_map( type, ent_buffer[i], &sib_entids[0], &sib_lids[0], nhf );
3239  MB_CHK_ERR( error );
3240 
3241  for( int l = 0; l < nhf; l++ )
3242  {
3243  if( sib_entids[l] ) continue;
3244 
3245  // Fill out the sibling values
3246  int id = refTemplates[pat_id][d].ents_opphfs[i][2 * l];
3247  if( id )
3248  {
3249  sib_entids[l] = ent_buffer[id - 1];
3250  sib_lids[l] = refTemplates[pat_id][d].ents_opphfs[i][2 * l + 1];
3251  }
3252  else
3253  {
3254  sib_entids[l] = 0;
3255  sib_lids[l] = 0;
3256  }
3257  }
3258 
3259  error = ahf->set_sibling_map( type, ent_buffer[i], &sib_entids[0], &sib_lids[0], nhf );
3260  MB_CHK_ERR( error );
3261 
3262  for( int l = 0; l < nhf; l++ )
3263  {
3264  if( sib_entids[l] )
3265  {
3266 
3267  EntityHandle set_entid = ent_buffer[i];
3268  int set_lid = l;
3269 
3270  error = ahf->set_sibling_map( type, sib_entids[l], sib_lids[l], set_entid, set_lid );
3271  MB_CHK_ERR( error );
3272  }
3273  }
3274  }
3275  return MB_SUCCESS;
3276 }

References _incells, ahf, moab::Range::begin(), moab::NestedRefine::refPatterns::ents_opphfs, moab::error(), ErrorCode, moab::HalfFacetRep::get_incident_map(), get_index_from_degree(), moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::get_sibling_map(), moab::index, moab::HalfFacetRep::lConnMap2D, moab::HalfFacetRep::lConnMap3D, MB_CHK_ERR, MB_SUCCESS, MBEDGE, MBHEX, MBQUAD, MBTET, MBTRI, moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell, moab::HalfFacetRep::LocalMaps3D::num_verts_in_cell, moab::HalfFacetRep::LocalMaps2D::num_verts_in_face, refTemplates, moab::HalfFacetRep::set_incident_map(), moab::HalfFacetRep::set_sibling_map(), moab::NestedRefine::refPatterns::total_new_verts, and moab::NestedRefine::refPatterns::v2hf.

◆ update_special_tags()

ErrorCode moab::NestedRefine::update_special_tags ( int  level,
EntityHandle lset 
)

Definition at line 518 of file NestedRefine.cpp.

519 {
520  assert( level > 0 && level < nlevels + 1 );
521 
523  std::vector< Tag > mtags( 3 );
524 
526  MB_CHK_ERR( error );
528  MB_CHK_ERR( error );
530  MB_CHK_ERR( error );
531 
532  for( int i = 0; i < 3; i++ )
533  {
534  // Gather sets of a particular tag
535  Range sets;
536  error = mbImpl->get_entities_by_type_and_tag( _rset, MBENTITYSET, &mtags[i], NULL, 1, sets );
537  MB_CHK_ERR( error );
538 
539  // Loop over all sets, gather entities in each set and add their children at all levels to
540  // the set
541  Range set_ents;
542  Range::iterator set_it;
543  std::vector< EntityHandle > childs;
544 
545  for( set_it = sets.begin(); set_it != sets.end(); ++set_it )
546  {
547  // Get the entities in the set, recursively
548  set_ents.clear();
549  childs.clear();
550  error = mbImpl->get_entities_by_handle( *set_it, set_ents, true );
551  MB_CHK_ERR( error );
552 
553  // Gather child entities at the input level
554  for( Range::iterator sit = set_ents.begin(); sit != set_ents.end(); sit++ )
555  {
556  EntityType type = mbImpl->type_from_handle( *sit );
557  if( type == MBVERTEX )
558  {
559  Range conn;
560  std::vector< EntityHandle > cents;
561  error = vertex_to_entities_down( *sit, 0, level, cents );
562  MB_CHK_ERR( error );
563  error = mbImpl->get_connectivity( &cents[0], (int)cents.size(), conn, true );
564  MB_CHK_ERR( error );
565  childs.insert( childs.end(), cents.begin(), cents.end() );
566  }
567  else
568  {
569  error = parent_to_child( *sit, 0, level, childs );
570  MB_CHK_ERR( error );
571  }
572 
573  std::sort( childs.begin(), childs.end() );
574  childs.erase( std::unique( childs.begin(), childs.end() ), childs.end() );
575 
576  // Add child entities to tagged sets
577  error = mbImpl->add_entities( *set_it, &childs[0], childs.size() );
578  MB_CHK_ERR( error );
579  }
580 
581  // Remove the coarse entities
582  error = mbImpl->remove_entities( *set_it, set_ents );
583  MB_CHK_ERR( error );
584 
585  // Add
586  error = mbImpl->add_entities( lset, &( *set_it ), 1 );
587  MB_CHK_ERR( error );
588  }
589  }
590  return MB_SUCCESS;
591 }

References _rset, moab::Core::add_entities(), moab::Range::begin(), moab::Range::clear(), DIRICHLET_SET_TAG_NAME, moab::Range::end(), moab::error(), ErrorCode, moab::Core::get_connectivity(), moab::Core::get_entities_by_handle(), moab::Core::get_entities_by_type_and_tag(), MATERIAL_SET_TAG_NAME, MB_CHK_ERR, MB_SUCCESS, MB_TYPE_INTEGER, MBENTITYSET, mbImpl, MBVERTEX, NEUMANN_SET_TAG_NAME, nlevels, parent_to_child(), moab::Core::remove_entities(), moab::Core::tag_get_handle(), moab::Core::type_from_handle(), and vertex_to_entities_down().

◆ update_tracking_verts()

ErrorCode moab::NestedRefine::update_tracking_verts ( EntityHandle  cid,
int  cur_level,
int  deg,
std::vector< EntityHandle > &  trackvertsC_edg,
std::vector< EntityHandle > &  trackvertsC_face,
EntityHandle vbuffer 
)
protected

Definition at line 4428 of file NestedRefine.cpp.

4434 {
4435  // The vertices in the vbuffer are added to appropriate edges and faces of cells that are
4436  // incident on the working cell.
4437  ErrorCode error;
4438 
4439  EntityHandle cstart_prev;
4440  if( cur_level )
4441  cstart_prev = level_mesh[cur_level - 1].start_cell;
4442  else
4443  cstart_prev = *_incells.begin();
4444 
4445  EntityType cell_type = mbImpl->type_from_handle( cstart_prev );
4446  int cindex = cell_type - 1;
4447  int d = get_index_from_degree( deg );
4448 
4449  int nve = refTemplates[cindex][d].nv_edge;
4450  int nvf = refTemplates[cindex][d].nv_face;
4451 
4452  int index = ahf->get_index_in_lmap( *( _incells.begin() ) );
4453  int nepc = ahf->lConnMap3D[index].num_edges_in_cell;
4454  int nfpc = ahf->lConnMap3D[index].num_faces_in_cell;
4455 
4456  // Step 1: Add the vertices on an edge of the working cell to tracking array of incident cells.
4457  for( int i = 0; i < nepc; i++ )
4458  {
4459  // Add the vertices to edges of the current cell
4460  for( int j = 0; j < nve; j++ )
4461  {
4462  int id = refTemplates[cindex][d].vert_on_edges[i][j];
4463  int idx = cid - cstart_prev;
4464  int aid = idx * nve * nepc + nve * i + j;
4465 
4466  if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id];
4467  }
4468 
4469  // Obtain all the incident cells
4470  std::vector< EntityHandle > inc_cids;
4471  std::vector< int > inc_leids, inc_orient;
4472 
4473  error = ahf->get_up_adjacencies_edg_3d( cid, i, inc_cids, &inc_leids, &inc_orient );
4474  MB_CHK_ERR( error );
4475 
4476  if( inc_cids.size() == 1 ) continue;
4477 
4478  // Add the vertices to the edges of the incident cells
4479  for( int k = 0; k < (int)inc_cids.size(); k++ )
4480  {
4481  if( inc_cids[k] == cid ) continue;
4482 
4483  int idx = inc_cids[k] - cstart_prev;
4484 
4485  if( inc_orient[k] ) // Same edge direction as the current edge
4486  {
4487  for( int j = 0; j < nve; j++ )
4488  {
4489  int id = refTemplates[cindex][d].vert_on_edges[i][j];
4490  int aid = idx * nve * nepc + nve * inc_leids[k] + j;
4491 
4492  if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id];
4493  }
4494  }
4495  else
4496  {
4497  for( int j = 0; j < nve; j++ )
4498  {
4499  int id = refTemplates[cindex][d].vert_on_edges[i][nve - j - 1];
4500  int aid = idx * nve * nepc + nve * inc_leids[k] + j;
4501 
4502  if( !trackvertsC_edg[aid] ) trackvertsC_edg[aid] = vbuffer[id];
4503  }
4504  }
4505  }
4506  }
4507 
4508  // Step 2: Add the vertices on a face of the working cell to tracking array of incident cells.
4509  if( nvf )
4510  {
4511 
4512  for( int i = 0; i < nfpc; i++ )
4513  {
4514  // Add vertices to the tracking array of vertices on faces for the current cell
4515  std::vector< EntityHandle > face_vbuf( nvf, 0 );
4516  for( int j = 0; j < nvf; j++ )
4517  {
4518  int id = refTemplates[cindex][d].vert_on_faces[i][j];
4519  int idx = cid - cstart_prev;
4520  int aid = idx * nvf * nfpc + nvf * i + j;
4521 
4522  if( !trackvertsC_face[aid] ) trackvertsC_face[aid] = vbuffer[id];
4523 
4524  face_vbuf[j] = vbuffer[id];
4525  }
4526 
4527  // Obtain all the incident cells
4528  std::vector< EntityHandle > sib_cids;
4529  std::vector< int > sib_lfids;
4530  error = ahf->get_up_adjacencies_face_3d( cid, i, sib_cids, &sib_lfids );
4531  MB_CHK_ERR( error );
4532 
4533  if( sib_cids.size() == 1 ) continue;
4534 
4535  // Reorder the vertex local ids incident on the half-face
4536  std::vector< int > id_sib( nvf );
4537  for( int k = 0; k < nvf; k++ )
4538  id_sib[k] = 0;
4539 
4540  error = reorder_indices( cur_level, deg, sib_cids[1], sib_lfids[1], cid, i, 0, &id_sib[0] );
4541  MB_CHK_ERR( error );
4542 
4543  // Add vertices to the tracking array of vertices on faces for the sibling cell of the
4544  // current cell
4545  for( int j = 0; j < nvf; j++ )
4546  {
4547  int idx = sib_cids[1] - cstart_prev;
4548  int aid = idx * nvf * nfpc + nvf * sib_lfids[1] + j;
4549 
4550  if( !trackvertsC_face[aid] ) trackvertsC_face[aid] = face_vbuf[id_sib[j] - 1];
4551  }
4552  }
4553  }
4554  return MB_SUCCESS;
4555 }

References _incells, ahf, moab::Range::begin(), moab::error(), ErrorCode, get_index_from_degree(), moab::HalfFacetRep::get_index_in_lmap(), moab::HalfFacetRep::get_up_adjacencies_edg_3d(), moab::HalfFacetRep::get_up_adjacencies_face_3d(), moab::index, moab::HalfFacetRep::lConnMap3D, level_mesh, MB_CHK_ERR, MB_SUCCESS, mbImpl, moab::HalfFacetRep::LocalMaps3D::num_edges_in_cell, moab::HalfFacetRep::LocalMaps3D::num_faces_in_cell, moab::NestedRefine::refPatterns::nv_edge, moab::NestedRefine::refPatterns::nv_face, refTemplates, reorder_indices(), moab::NestedRefine::level_memory::start_cell, moab::Core::type_from_handle(), moab::NestedRefine::refPatterns::vert_on_edges, and moab::NestedRefine::refPatterns::vert_on_faces.

Referenced by subdivide_cells(), and subdivide_tets().

◆ vertex_to_entities_down()

ErrorCode moab::NestedRefine::vertex_to_entities_down ( EntityHandle  vertex,
int  vert_level,
int  child_level,
std::vector< EntityHandle > &  incident_entities 
)

Given a vertex from a certain level, it returns a std::vector of all children entities of incident entities to vertex from any subsequent levels

Parameters
vertexEntityHandle of the vertex
vert_levelMesh level of the vertex
child_levelMesh level from which child entities are requested
incident_entitiesVector containing entities from the child level

Definition at line 398 of file NestedRefine.cpp.

402 {
403  assert( vert_level < child_level );
405 
406  // Step 1: Get the incident entities at the current level
407  std::vector< EntityHandle > inents;
408  if( meshdim == 1 )
409  {
410  error = ahf->get_up_adjacencies_1d( vertex, inents );
411  MB_CHK_ERR( error );
412  }
413  else if( meshdim == 2 )
414  {
416  MB_CHK_ERR( error );
417  }
418  else if( meshdim == 3 )
419  {
421  MB_CHK_ERR( error );
422  }
423 
424  // Step 2: Loop over all the incident entities at the current level and gather their parents
425  std::vector< EntityHandle > childs;
426  for( int i = 0; i < (int)inents.size(); i++ )
427  {
428  childs.clear();
429  EntityHandle ent = inents[i];
430  error = parent_to_child( ent, vert_level, child_level, childs );
431  MB_CHK_ERR( error );
432  for( int j = 0; j < (int)childs.size(); j++ )
433  incident_entities.push_back( childs[j] );
434  }
435 
436  return MB_SUCCESS;
437 }

References ahf, moab::error(), ErrorCode, moab::HalfFacetRep::get_up_adjacencies_1d(), moab::HalfFacetRep::get_up_adjacencies_vert_2d(), moab::HalfFacetRep::get_up_adjacencies_vert_3d(), MB_CHK_ERR, MB_SUCCESS, meshdim, and parent_to_child().

Referenced by update_special_tags().

◆ vertex_to_entities_up()

ErrorCode moab::NestedRefine::vertex_to_entities_up ( EntityHandle  vertex,
int  vert_level,
int  parent_level,
std::vector< EntityHandle > &  incident_entities 
)

Given a vertex from a certain level, it returns a std::vector of all entities from any previous levels that contains it.

Parameters
vertexEntityHandle of the vertex
vert_levelMesh level of the vertex
parent_levelMesh level from which entities containing vertex is requested
incident_entitiesVector containing entities from the parent level incident on the vertex

Definition at line 354 of file NestedRefine.cpp.

358 {
359  assert( vert_level > parent_level );
361 
362  // Step 1: Get the incident entities at the current level
363  std::vector< EntityHandle > inents;
364  if( meshdim == 1 )
365  {
366  error = ahf->get_up_adjacencies_1d( vertex, inents );
367  MB_CHK_ERR( error );
368  }
369  else if( meshdim == 2 )
370  {
372  MB_CHK_ERR( error );
373  }
374  else if( meshdim == 3 )
375  {
377  MB_CHK_ERR( error );
378  }
379 
380  // Step 2: Loop over all the incident entities at the current level and gather their parents
381  for( int i = 0; i < (int)inents.size(); i++ )
382  {
383  EntityHandle ent = inents[i];
384  EntityHandle parent;
385  error = child_to_parent( ent, vert_level, parent_level, &parent );
386  MB_CHK_ERR( error );
387  incident_entities.push_back( parent );
388  }
389 
390  // Step 3: Sort and remove duplicates
391  std::sort( incident_entities.begin(), incident_entities.end() );
392  incident_entities.erase( std::unique( incident_entities.begin(), incident_entities.end() ),
393  incident_entities.end() );
394 
395  return MB_SUCCESS;
396 }

References ahf, child_to_parent(), moab::error(), ErrorCode, moab::HalfFacetRep::get_up_adjacencies_1d(), moab::HalfFacetRep::get_up_adjacencies_vert_2d(), moab::HalfFacetRep::get_up_adjacencies_vert_3d(), MB_CHK_ERR, MB_SUCCESS, and meshdim.

Member Data Documentation

◆ _incells

◆ _inedges

◆ _infaces

◆ _inverts

◆ _rset

EntityHandle moab::NestedRefine::_rset
protected

◆ ahf

◆ deg_index

std::map< int, int > moab::NestedRefine::deg_index
protected

Definition at line 180 of file NestedRefine.hpp.

Referenced by get_index_from_degree(), and initialize().

◆ elementype

EntityType moab::NestedRefine::elementype
protected

◆ hasghost

bool moab::NestedRefine::hasghost
protected

Definition at line 181 of file NestedRefine.hpp.

Referenced by exchange_ghosts(), and initialize().

◆ intFacEdg

const NestedRefine::intFEdge moab::NestedRefine::intFacEdg
staticprotected
Initial value:
= {
{ { 3, { { 3, 4 }, { 4, 5 }, { 5, 3 } } },
{ 9, { { 8, 3 }, { 3, 9 }, { 9, 4 }, { 4, 5 }, { 5, 9 }, { 9, 8 }, { 7, 9 }, { 9, 6 }, { 6, 7 } } } },
{ { 4, { { 4, 8 }, { 7, 8 }, { 8, 6 }, { 8, 5 } } },
{ 12,
{ { 4, 12 },
{ 12, 15 },
{ 15, 9 },
{ 5, 13 },
{ 13, 14 },
{ 14, 8 },
{ 11, 12 },
{ 12, 13 },
{ 13, 6 },
{ 10, 15 },
{ 15, 14 },
{ 14, 7 } } } } }

Definition at line 241 of file NestedRefine.hpp.

Referenced by construct_hm_2D(), and estimate_hm_storage().

◆ level_dsequence

int moab::NestedRefine::level_dsequence[MAX_LEVELS]
protected

Definition at line 179 of file NestedRefine.hpp.

Referenced by child_to_parent(), generate_mesh_hierarchy(), and parent_to_child().

◆ level_mesh

◆ mbImpl

◆ meshdim

◆ nlevels

int moab::NestedRefine::nlevels
protected

Definition at line 178 of file NestedRefine.hpp.

Referenced by generate_hm(), generate_mesh_hierarchy(), and update_special_tags().

◆ pcomm

ParallelComm* moab::NestedRefine::pcomm
protected

Definition at line 170 of file NestedRefine.hpp.

Referenced by exchange_ghosts(), generate_hm(), initialize(), and NestedRefine().

◆ permutation

const NestedRefine::pmat moab::NestedRefine::permutation
staticprotected

Definition at line 333 of file NestedRefine.hpp.

Referenced by reorder_indices().

◆ refTemplates

◆ timeall

codeperf moab::NestedRefine::timeall

Definition at line 166 of file NestedRefine.hpp.

Referenced by generate_hm(), and main().

◆ tm

CpuTimer* moab::NestedRefine::tm
protected

Definition at line 172 of file NestedRefine.hpp.

Referenced by generate_hm(), initialize(), and ~NestedRefine().


The documentation for this class was generated from the following files: