[MOAB-dev] r1892 - MOAB/trunk/refiner
dcthomp at mcs.anl.gov
dcthomp at mcs.anl.gov
Thu Jun 12 20:30:49 CDT 2008
Author: dcthomp
Date: 2008-06-12 20:30:49 -0500 (Thu, 12 Jun 2008)
New Revision: 1892
Added:
MOAB/trunk/refiner/MBRefinerTagManager.cpp
MOAB/trunk/refiner/MBRefinerTagManager.hpp
Modified:
MOAB/trunk/refiner/CMakeLists.txt
MOAB/trunk/refiner/MBEdgeSizeEvaluator.cpp
MOAB/trunk/refiner/MBEdgeSizeEvaluator.hpp
MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.cpp
MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.hpp
MOAB/trunk/refiner/MBMeshRefiner.cpp
MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.cpp
MOAB/trunk/refiner/test_mesh_refiner.cpp
Log:
ENH: Broke MBRefinerTagManager out of MBEdgeSizeEvaluator.
ENH: Added state to MBRefinerTagManager for case when input
is not output mesh, plus a routine to create tags as
required on the output mesh.
ENH: Work on a more general way to store vertex handles
indexed by the corners of their parent (unrefined)
entity.
Modified: MOAB/trunk/refiner/CMakeLists.txt
===================================================================
--- MOAB/trunk/refiner/CMakeLists.txt 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/CMakeLists.txt 2008-06-13 01:30:49 UTC (rev 1892)
@@ -3,6 +3,7 @@
MBEdgeSizeSimpleImplicit.cpp
MBEntityRefiner.cpp
MBMeshRefiner.cpp
+ MBRefinerTagManager.cpp
MBSimplexTemplateRefiner.cpp
MBSimplexTemplateTagAssigner.cpp
)
Modified: MOAB/trunk/refiner/MBEdgeSizeEvaluator.cpp
===================================================================
--- MOAB/trunk/refiner/MBEdgeSizeEvaluator.cpp 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/MBEdgeSizeEvaluator.cpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -5,12 +5,9 @@
#include <assert.h>
/// Construct an evaluator.
-MBEdgeSizeEvaluator::MBEdgeSizeEvaluator( MBInterface* parentMesh )
+MBEdgeSizeEvaluator::MBEdgeSizeEvaluator( MBInterface* mesh_in, MBInterface* mesh_out )
+ : MBRefinerTagManager( mesh_in, mesh_out )
{
- assert( parentMesh );
-
- this->mesh = parentMesh;
- this->reset_vertex_tags();
}
/// Destruction is virtual so subclasses may clean up after refinement.
@@ -36,61 +33,3 @@
* populate vertex_tags before evaluate_edge() is called.
*/
-/// Clear the list of tag values that will appear past the vertex coordinates in \a p0, \a p1, and \a p2.
-void MBEdgeSizeEvaluator::reset_vertex_tags()
-{
- this->vertex_size = 0;
- this->vertex_tags.clear();
-}
-
-/** Add a tag to the list of tag values that will appear past the vertex coordinates.
- * The return value is the offset into each vertex coordinate pointer (\a p0, \a p1, \a p2) where the
- * tag value(s) will be stored.
- */
-int MBEdgeSizeEvaluator::add_vertex_tag( MBTag tag_handle )
-{
- int offset = this->vertex_size; // old size is offset of tag being added
- int tag_size;
- MBTagType tagType;
- if ( this->mesh->tag_get_size( tag_handle, tag_size ) != MB_SUCCESS )
- return -1;
-
- if ( this->mesh->tag_get_type( tag_handle, tagType ) != MB_SUCCESS )
- return -1;
-
- if ( tagType == MB_TAG_BIT )
- {
- // Pad any bit tags to a size in full bytes.
- tag_size = ( tag_size % 8 ? 1 : 0 ) + ( tag_size / 8 );
- }
-
- // Now pad so that the next tag will be word-aligned:
- while ( tag_size % sizeof(int) )
- ++tag_size;
-
- this->vertex_size += tag_size;
-
- this->vertex_tags.push_back( std::pair< MBTag, int >( tag_handle, offset ) );
- return offset;
-}
-
-/**\fn int MBEdgeSizeEvaluator::get_vertex_tag_size()
- *\brief Return the number of bytes to allocate for tag data per point.
- */
-
-/**\fn int MBEdgeSizeEvaluator::get_number_of_vertex_tags() const
- *\brief Return the number of tags that will be output with each new vertex.
- */
-
-/**\brief Return the tag handle and its offset in the array of tag data of each vertex.
- *
- * @param[in] i An index into the list of tags for the vertex.
- * @param[out] tag The tag handle for the $i$-th vertex tag.
- * @param[out] byte_offset The offset (in bytes) of the start of this tag's data in a vertex tag record.
- */
-void MBEdgeSizeEvaluator::get_vertex_tag( int i, MBTag& tag, int& byte_offset )
-{
- std::vector< std::pair< MBTag, int > >::iterator it = this->vertex_tags.begin() + i;
- tag = it->first;
- byte_offset = it->second;
-}
Modified: MOAB/trunk/refiner/MBEdgeSizeEvaluator.hpp
===================================================================
--- MOAB/trunk/refiner/MBEdgeSizeEvaluator.hpp 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/MBEdgeSizeEvaluator.hpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -26,34 +26,18 @@
#ifndef MB_EDGESIZEEVALUATOR_H
#define MB_EDGESIZEEVALUATOR_H
-#include "MBTypes.h" // for MB_DLL_EXPORT
+#include "MBRefinerTagManager.hpp"
-#include <vector>
-
-class MBInterface;
-
-class MB_DLL_EXPORT MBEdgeSizeEvaluator
+class MB_DLL_EXPORT MBEdgeSizeEvaluator : public MBRefinerTagManager
{
public:
- MBEdgeSizeEvaluator( MBInterface* );
+ MBEdgeSizeEvaluator( MBInterface*, MBInterface* );
virtual ~MBEdgeSizeEvaluator();
virtual bool evaluate_edge(
const double* p0, const void* t0,
double* p1, void* t1,
const double* p2, const void* t2 ) = 0;
-
- void reset_vertex_tags();
- int add_vertex_tag( MBTag tag_handle );
- int get_vertex_tag_size() const { return this->vertex_size; }
-
- int get_number_of_vertex_tags() const { return this->vertex_tags.size(); }
- void get_vertex_tag( int i, MBTag& tag, int& byte_offset );
-
-protected:
- std::vector< std::pair< MBTag, int > > vertex_tags;
- int vertex_size;
- MBInterface* mesh;
};
#endif // MB_EDGESIZEEVALUATOR_H
Modified: MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.cpp
===================================================================
--- MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.cpp 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.cpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -1,7 +1,7 @@
#include "MBEdgeSizeSimpleImplicit.hpp"
-MBEdgeSizeSimpleImplicit::MBEdgeSizeSimpleImplicit( MBInterface* parentMesh )
- : MBEdgeSizeEvaluator( parentMesh )
+MBEdgeSizeSimpleImplicit::MBEdgeSizeSimpleImplicit( MBInterface* mesh_in, MBInterface* mesh_out )
+ : MBEdgeSizeEvaluator( mesh_in, mesh_out )
{
int i;
// Default to the plane: x = 0.
Modified: MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.hpp
===================================================================
--- MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.hpp 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.hpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -36,7 +36,7 @@
{
public:
/// Construct an evaluator.
- MBEdgeSizeSimpleImplicit( MBInterface* );
+ MBEdgeSizeSimpleImplicit( MBInterface*, MBInterface* );
/// Destruction is virtual so subclasses may clean up after refinement.
virtual ~MBEdgeSizeSimpleImplicit();
Modified: MOAB/trunk/refiner/MBMeshRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBMeshRefiner.cpp 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/MBMeshRefiner.cpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -113,7 +113,7 @@
int tag_offset;
for ( int i = 0; i < num_tags; ++i )
{
- this->edge_size_evaluator->get_vertex_tag( i, tag_handle, tag_offset );
+ this->edge_size_evaluator->get_output_vertex_tag( i, tag_handle, tag_offset );
this->mesh->tag_set_data( tag_handle, &vertex_handle, 1, (char*)vtags + tag_offset );
}
return vertex_handle;
@@ -133,7 +133,7 @@
int tag_offset;
for ( int i = 0; i < num_tags; ++i )
{
- this->edge_size_evaluator->get_vertex_tag( i, tag_handle, tag_offset );
+ this->edge_size_evaluator->get_output_vertex_tag( i, tag_handle, tag_offset );
this->mesh->tag_set_data( tag_handle, &hv, 1, (char*)vtags + tag_offset );
}
return hv;
Added: MOAB/trunk/refiner/MBRefinerTagManager.cpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.cpp (rev 0)
+++ MOAB/trunk/refiner/MBRefinerTagManager.cpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -0,0 +1,165 @@
+#include "MBRefinerTagManager.hpp"
+
+#include "MBInterface.hpp"
+
+#include <iostream>
+#include <assert.h>
+
+/// Construct an evaluator.
+MBRefinerTagManager::MBRefinerTagManager( MBInterface* in_mesh, MBInterface* out_mesh )
+{
+ assert( in_mesh );
+ if ( ! out_mesh )
+ out_mesh = in_mesh;
+
+ this->input_mesh = in_mesh;
+ this->output_mesh = out_mesh;
+ this->reset_vertex_tags();
+}
+
+/// Destruction is virtual so subclasses may clean up after refinement.
+MBRefinerTagManager::~MBRefinerTagManager()
+{
+}
+
+/**\fn bool MBRefinerTagManager::evaluate_edge( \
+ * const double* p0, const void* t0, double* p1, void* t1, const double* p2, const void* t2 )
+ *\brief Returns true if the edge \a p0 - \a p2 should be subdivided, false otherwise.
+ *
+ * The arguments \a p0, \a p1, and \a p2 are all pointers to arrays of 6 doubles each
+ * while the arguments \a t0, \a t1, and \a t2 are all pointers to arrays of tag data
+ * defined at the corresponding point. While the endpoints \a p0 and \a p2 are
+ * immutable, the mid-edge point coordinates \a p1 and tag data \a t1 may be altered by
+ * evaluate_edge(). Altered values will be ignored if evaluate_edge() returns false.
+ * Be careful to ensure that all calls to evaluate_edge() perform identical modifications
+ * given identical input values!
+ *
+ * A list of tags passed in \a t0, \a t1, and \a t2 is stored in the \a input_vertex_tags member.
+ * (for tag handles defined on the input mesh) and the \a output_vertex_tags (for the same tag handles
+ * defined on the output mesh).
+ * The vertex_size member stores the total length of data associated with each pointer (in bytes).
+ * Subclasses may access input_vertex_tags, output_vertex_tags, and vertex_size directly;
+ * the refiner uses public methods to set them before any entities are evaluated for subdivision.
+ * The output_vertex_tags member is populated when the refiner calls create_output_tags().
+ * When the input mesh and output mesh pointers are identical, this simply copies input_vertex_tags
+ * to output_vertex_tags.
+ * When the pointers are distinct, tags are created on the output mesh.
+ */
+
+/// Clear the list of tag values that will appear past the vertex coordinates in \a p0, \a p1, and \a p2.
+void MBRefinerTagManager::reset_vertex_tags()
+{
+ this->vertex_size = 0;
+ this->input_vertex_tags.clear();
+ this->output_vertex_tags.clear();
+}
+
+/** Add a tag to the list of tag values that will appear past the vertex coordinates.
+ * The return value is the offset into each vertex coordinate pointer (\a p0, \a p1, \a p2) where the
+ * tag value(s) will be stored.
+ */
+int MBRefinerTagManager::add_vertex_tag( MBTag tag_handle )
+{
+ int offset = this->vertex_size; // old size is offset of tag being added
+ int tag_size;
+ MBTagType tagType;
+ if ( this->input_mesh->tag_get_size( tag_handle, tag_size ) != MB_SUCCESS )
+ return -1;
+
+ if ( this->input_mesh->tag_get_type( tag_handle, tagType ) != MB_SUCCESS )
+ return -1;
+
+ if ( tagType == MB_TAG_BIT )
+ {
+ // Pad any bit tags to a size in full bytes.
+ tag_size = ( tag_size % 8 ? 1 : 0 ) + ( tag_size / 8 );
+ }
+
+ // Now pad so that the next tag will be word-aligned:
+ while ( tag_size % sizeof(int) )
+ ++tag_size;
+
+ this->vertex_size += tag_size;
+
+ this->input_vertex_tags.push_back( std::pair< MBTag, int >( tag_handle, offset ) );
+ return offset;
+}
+
+/**\fn int MBRefinerTagManager::get_vertex_tag_size()
+ *\brief Return the number of bytes to allocate for tag data per point.
+ */
+
+/**\fn int MBRefinerTagManager::get_number_of_vertex_tags() const
+ *\brief Return the number of tags that will be output with each new vertex.
+ */
+
+/**\brief Populate the list of output tags to match the list of input tags.
+ *
+ * When the input mesh and output mesh pointers are identical, this simply copies the list of input tags.
+ * When the two meshes are distinct, the corresponding tags are created on the output mesh.
+ */
+void MBRefinerTagManager::create_output_tags()
+{
+ if ( this->input_mesh == this->output_mesh )
+ {
+ this->output_vertex_tags = this->input_vertex_tags;
+ return;
+ }
+
+ std::pair< MBTag, int > tag_rec;
+ std::vector< std::pair< MBTag, int > >::iterator it;
+ std::vector< char > tag_default;
+ std::string tag_name;
+ MBTagType tag_type;
+ MBDataType tag_data_type;
+ int tag_size;
+ for ( it = this->input_vertex_tags.begin(); it != this->output_vertex_tags.end(); ++ it )
+ {
+ MBTag tag_in = it->first;
+ tag_rec.second = it->second;
+ this->input_mesh->tag_get_name( tag_in, tag_name );
+ this->input_mesh->tag_get_size( tag_in, tag_size );
+ this->input_mesh->tag_get_type( tag_in, tag_type );
+ this->input_mesh->tag_get_data_type( tag_in, tag_data_type );
+ this->input_mesh->tag_get_default_value( tag_in, (void*) &tag_default[0] );
+ tag_default.resize( tag_size );
+ MBErrorCode res = this->output_mesh->tag_create(
+ tag_name.c_str(), tag_size, tag_type, tag_data_type, tag_rec.first, (void*) &tag_default[0], true );
+ if ( res == MB_FAILURE )
+ {
+ std::cerr
+ << "Could not create output tag name: \"" << tag_name.c_str() << "\" type: "
+ << tag_type << " data type: " << tag_data_type << "\n";
+ }
+ else
+ {
+ this->output_vertex_tags.push_back( tag_rec );
+ }
+ }
+}
+
+/**\brief Return the tag handle and its offset in the array of tag data of each vertex.
+ *
+ * @param[in] i An index into the list of tags for the vertex.
+ * @param[out] tag The tag handle on the input mesh for the $i$-th vertex tag.
+ * @param[out] byte_offset The offset (in bytes) of the start of this tag's data in a vertex tag record.
+ */
+void MBRefinerTagManager::get_input_vertex_tag( int i, MBTag& tag, int& byte_offset )
+{
+ std::vector< std::pair< MBTag, int > >::iterator it = this->input_vertex_tags.begin() + i;
+ tag = it->first;
+ byte_offset = it->second;
+}
+
+/**\brief Return the tag handle and its offset in the array of tag data of each vertex.
+ *
+ * @param[in] i An index into the list of tags for the vertex.
+ * @param[out] tag The tag handle on the output mesh for the $i$-th vertex tag.
+ * @param[out] byte_offset The offset (in bytes) of the start of this tag's data in a vertex tag record.
+ */
+void MBRefinerTagManager::get_output_vertex_tag( int i, MBTag& tag, int& byte_offset )
+{
+ std::vector< std::pair< MBTag, int > >::iterator it = this->output_vertex_tags.begin() + i;
+ tag = it->first;
+ byte_offset = it->second;
+}
Added: MOAB/trunk/refiner/MBRefinerTagManager.hpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.hpp (rev 0)
+++ MOAB/trunk/refiner/MBRefinerTagManager.hpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -0,0 +1,59 @@
+/**
+ * MOAB, a Mesh-Oriented datABase, is a software component for creating,
+ * storing and accessing finite element mesh data.
+ *
+ * Copyright 2004 Sandia Corporation. Under the terms of Contract
+ * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
+ * retains certain rights in this software.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ */
+
+/** \class MBRefinerTagManager
+ *
+ * This a class that manages which tags an edge refiner should include
+ * on output vertices created during mesh refinement.
+ * The
+ *
+ * \author David Thompson
+ *
+ * \date 12 June 2008
+ */
+#ifndef MB_REFINERTAGMANAGER_H
+#define MB_REFINERTAGMANAGER_H
+
+#include "MBTypes.h" // for MB_DLL_EXPORT
+
+#include <vector>
+
+class MBInterface;
+
+class MB_DLL_EXPORT MBRefinerTagManager
+{
+public:
+ MBRefinerTagManager( MBInterface* in_mesh, MBInterface* out_mesh );
+ virtual ~MBRefinerTagManager();
+
+ void reset_vertex_tags();
+ int add_vertex_tag( MBTag tag_handle );
+ int get_vertex_tag_size() const { return this->vertex_size; }
+ int get_number_of_vertex_tags() const { return this->input_vertex_tags.size(); }
+
+ void create_output_tags();
+
+ void get_input_vertex_tag( int i, MBTag& tag, int& byte_offset );
+ void get_output_vertex_tag( int i, MBTag& tag, int& byte_offset );
+
+protected:
+ std::vector< std::pair< MBTag, int > > input_vertex_tags;
+ std::vector< std::pair< MBTag, int > > output_vertex_tags;
+ int vertex_size;
+ MBInterface* input_mesh;
+ MBInterface* output_mesh;
+};
+
+#endif // MB_REFINERTAGMANAGER_H
Modified: MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -67,7 +67,7 @@
tag_data = this->heap_tag_storage();
for ( int i = 0; i < this->edge_size_evaluator->get_number_of_vertex_tags(); ++ i )
{
- this->edge_size_evaluator->get_vertex_tag( i, tag_handle, tag_offset );
+ this->edge_size_evaluator->get_input_vertex_tag( i, tag_handle, tag_offset );
if ( this->mesh->tag_get_data( tag_handle, &conn[n], 1, (char*)tag_data + tag_offset ) != MB_SUCCESS )
{
return false;
Modified: MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.cpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.cpp 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.cpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -61,7 +61,7 @@
int tag_offset;
for ( int i = 0; i < num_tags; ++i )
{
- this->edge_size_evaluator->get_vertex_tag( i, tag_handle, tag_offset );
+ this->edge_size_evaluator->get_input_vertex_tag( i, tag_handle, tag_offset );
this->mesh_refiner->get_mesh()->tag_get_data_type( tag_handle, data_type );
this->mesh_refiner->get_mesh()->tag_get_size( tag_handle, tag_size );
Modified: MOAB/trunk/refiner/test_mesh_refiner.cpp
===================================================================
--- MOAB/trunk/refiner/test_mesh_refiner.cpp 2008-06-11 19:08:53 UTC (rev 1891)
+++ MOAB/trunk/refiner/test_mesh_refiner.cpp 2008-06-13 01:30:49 UTC (rev 1892)
@@ -10,21 +10,100 @@
#endif // USE_MPI
#include <iostream>
+#include <map>
-class MBTestOutputFunctor : public MBEntityRefinerOutputFunctor
+template< int _n >
+class MBSplitVertexIndex
{
public:
- typedef std::vector<MBEntityHandle> node_list_t;
- typedef std::pair<MBEntityHandle,MBEntityHandle> node_pair_t;
- typedef std::map<MBEntityHandle,MBEntityHandle> node_hash_t;
- typedef std::map<node_pair_t,MBEntityHandle> edge_hash_t;
+ MBSplitVertexIndex() { }
+ MBSplitVertexIndex( const MBEntityHandle* src )
+ { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src[i]; std::sort( this->handles, this->handles + _n ); }
+ MBSplitVertexIndex( const MBSplitVertexIndex<_n>& src )
+ { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; }
+ MBSplitVertexIndex& operator = ( const MBSplitVertexIndex<_n>& src )
+ { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; return *this; }
+ virtual bool operator < ( const MBSplitVertexIndex<_n>& other ) const
+ {
+ for ( int i = 0; i < _n; ++ i )
+ if ( this->handles[i] < other.handles[i] )
+ return true;
+ else if ( this->handles[i] > other.handles[i] )
+ return false;
+ return true;
+ }
+
+ MBEntityHandle handles[_n];
+};
+
+class MBSplitVerticesBase
+{
+public:
+ MBSplitVerticesBase( MBInterface* m )
+ {
+ this->mesh = m;
+ }
+ virtual bool find_or_create( const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle ) = 0;
MBInterface* mesh;
+};
+
+template< int _n >
+class MBSplitVertices : public std::map<MBSplitVertexIndex<_n>,MBEntityHandle>, public MBSplitVerticesBase
+{
+public:
+ typedef std::map<MBSplitVertexIndex<_n>,MBEntityHandle> MapType;
+ typedef typename std::map<MBSplitVertexIndex<_n>,MBEntityHandle>::iterator MapIteratorType;
+
+ MBSplitVertices( MBInterface* m )
+ : MBSplitVerticesBase( m )
+ {
+ }
+ virtual bool find_or_create( const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle )
+ {
+ MapIteratorType it = this->find( MBSplitVertexIndex<_n>( split_src ) );
+ if ( it == this->end() )
+ {
+ if ( this->mesh->create_vertex( coords, vert_handle ) != MB_SUCCESS )
+ {
+ return false;
+ }
+ return true;
+ }
+ vert_handle = it->second;
+ return false;
+ }
+};
+
+
+class MBTestOutputFunctor : public MBEntityRefinerOutputFunctor
+{
+public:
+ MBInterface* mesh;
bool input_is_output;
- node_hash_t node_hash;
- edge_hash_t edge_hash;
- node_list_t elem_vert;
+ std::vector<MBSplitVerticesBase*> split_vertices;
+ std::vector<MBEntityHandle> elem_vert;
+ MBEdgeSizeEvaluator* edge_size_evaluator;
+ MBTestOutputFunctor( MBInterface* imesh, MBInterface* omesh, MBEdgeSizeEvaluator* size_eval )
+ {
+ this->mesh = omesh;
+ this->input_is_output = ( imesh == omesh );
+ this->edge_size_evaluator = size_eval;
+
+ this->split_vertices.resize( 4 );
+ this->split_vertices[0] = 0; // Vertices (0-faces) cannot be split
+ this->split_vertices[1] = new MBSplitVertices<1>( this->mesh );
+ this->split_vertices[2] = new MBSplitVertices<2>( this->mesh );
+ this->split_vertices[3] = new MBSplitVertices<3>( this->mesh );
+ }
+
+ ~MBTestOutputFunctor()
+ {
+ for ( int i = 0; i < 4; ++ i )
+ delete this->split_vertices[i];
+ }
+
void print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
{
std::cout << "+ {";
@@ -46,6 +125,21 @@
std::cout << " >\n";
}
+ void assign_tags( MBEntityHandle vhandle, const void* vtags )
+ {
+ if ( ! vhandle )
+ return; // Ignore bad vertices
+
+ int num_tags = this->edge_size_evaluator->get_number_of_vertex_tags();
+ MBTag tag_handle;
+ int tag_offset;
+ for ( int i = 0; i < num_tags; ++i )
+ {
+ this->edge_size_evaluator->get_output_vertex_tag( i, tag_handle, tag_offset );
+ this->mesh->tag_set_data( tag_handle, &vhandle, 1, vtags );
+ }
+ }
+
virtual MBEntityHandle operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags )
{
if ( this->input_is_output )
@@ -58,6 +152,7 @@
{
std::cerr << "Could not insert mid-edge vertex!\n";
}
+ this->assign_tags( vertex_handle, vtags );
this->print_vert_crud( vertex_handle, 1, &vhash, vcoords, vtags );
return vertex_handle;
}
@@ -69,39 +164,23 @@
{
vertex_handle = (*this)( *vhash, vcoords, vtags );
}
- else if ( nvhash == 2 )
+ else if ( nvhash < 4 )
{
- node_pair_t pr;
- if ( vhash[0] < vhash[1] )
+ bool newly_created = this->split_vertices[nvhash]->find_or_create( vhash, vcoords, vertex_handle );
+ if ( newly_created )
{
- pr.first = vhash[0];
- pr.second = vhash[1];
+ this->assign_tags( vertex_handle, vtags );
}
- else
+ if ( ! vertex_handle )
{
- pr.first = vhash[1];
- pr.second = vhash[0];
+ std::cerr << "Could not insert mid-edge vertex!\n";
}
- edge_hash_t::iterator it = this->edge_hash.find( pr );
- if ( it == this->edge_hash.end() )
- {
- if ( this->mesh->create_vertex( vcoords + 3, vertex_handle ) != MB_SUCCESS )
- {
- std::cerr << "Could not insert mid-edge vertex!\n";
- }
- this->edge_hash[pr] = vertex_handle;
- }
- else
- {
- vertex_handle = it->second;
- }
- this->print_vert_crud( vertex_handle, 2, vhash, vcoords, vtags );
+ this->print_vert_crud( vertex_handle, nvhash, vhash, vcoords, vtags );
}
else
{
- vertex_handle = -1;
- std::cerr << "Not handling mid-face vertices yet.\n";
- // FIXME: Handle face midpoint.
+ vertex_handle = 0;
+ std::cerr << "Not handling splits on faces with " << nvhash << " corners yet.\n";
}
return vertex_handle;
}
@@ -137,14 +216,11 @@
rank = 0;
#endif // USE_MPI
- MBInterface* iface = new MBCore;
- MBEdgeSizeSimpleImplicit* eval = new MBEdgeSizeSimpleImplicit( iface );
+ bool input_is_output = ( argc > 1 && ! strcmp( argv[1], "-new-mesh" ) ) ? false : true;
+ MBInterface* imesh = new MBCore;
+ MBInterface* omesh = input_is_output ? imesh : new MBCore;
+ MBEdgeSizeSimpleImplicit* eval = new MBEdgeSizeSimpleImplicit( imesh, omesh );
- double p0[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- double p1[6] = { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0 };
- double p2[6] = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 };
- double p3[6] = { 0.6, 2.0, 0.0, 0.6, 2.0, 0.0 };
-
double coords[][6] = {
{ 0. , 0.0, 0. , 0. , 0.0, 0. }, // 0
{ -1. , 0.0, 0.5, -1. , 0.0, 0.5 }, // 1
@@ -207,50 +283,55 @@
MBEntityHandle tri_handle;
MBTag tag_floatular;
- iface->tag_create( "floatular", 2 * sizeof( double ), MB_TAG_DENSE, MB_TYPE_DOUBLE, tag_floatular, default_floatular );
+ imesh->tag_create( "floatular", 2 * sizeof( double ), MB_TAG_DENSE, MB_TYPE_DOUBLE, tag_floatular, default_floatular );
MBTag tag_intular;
- iface->tag_create( "intular", 4 * sizeof( int ), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_intular, default_intular );
+ imesh->tag_create( "intular", 4 * sizeof( int ), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_intular, default_intular );
MBTag tag_gid;
- iface->tag_create( PARALLEL_GID_TAG_NAME, sizeof( int ), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_gid, default_gid );
+ imesh->tag_create( PARALLEL_GID_TAG_NAME, sizeof( int ), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_gid, default_gid );
+ MBTag tag_spr;
+ imesh->tag_create( PARALLEL_SHARED_PROCS_TAG_NAME, 4 * sizeof( int ), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_spr, default_gid );
+
void const* iptrs[4];
void const* fptrs[4];
void const* gptrs[4];
+ void const* sptrs[4];
for ( int i = 0; i < 4; ++ i )
{
- iface->create_vertex( coords[proc_nodes[rank][i]], node_handles[i] );
+ imesh->create_vertex( coords[proc_nodes[rank][i]], node_handles[i] );
iptrs[i] = (void const*) intular_values[proc_nodes[rank][i]];
fptrs[i] = (void const*) floatular_values[proc_nodes[rank][i]];
gptrs[i] = (void const*) &gid_values[proc_nodes[rank][i]];
+ sptrs[i] = (void const*) &node_procs[proc_nodes[rank][i]];
}
- iface->tag_set_data( tag_floatular, node_handles, 4, fptrs, 0 );
+ imesh->tag_set_data( tag_floatular, node_handles, 4, fptrs, 0 );
eval->add_vertex_tag( tag_floatular );
- iface->tag_set_data( tag_intular, node_handles, 4, iptrs, 0 );
+ imesh->tag_set_data( tag_intular, node_handles, 4, iptrs, 0 );
eval->add_vertex_tag( tag_intular );
- iface->tag_set_data( tag_gid, node_handles, 4, gptrs, 0 );
+ imesh->tag_set_data( tag_gid, node_handles, 4, gptrs, 0 );
+ imesh->tag_set_data( tag_spr, node_handles, 4, sptrs, 0 );
- iface->create_element( MBTET, node_handles, 4, tet_handle );
- iface->tag_set_data( tag_gid, &tet_handle, 1, gid_values + 6 + rank );
- iface->list_entities( 0, 1 );
+ imesh->create_element( MBTET, node_handles, 4, tet_handle );
+ imesh->tag_set_data( tag_gid, &tet_handle, 1, gid_values + 6 + rank );
+ imesh->list_entities( 0, 1 );
- MBSimplexTemplateRefiner eref( iface );
- MBTestOutputFunctor* ofunc = new MBTestOutputFunctor;
- ofunc->input_is_output = ( argc > 1 && ! strcmp( argv[1], "-new-mesh" ) ) ? false : true;
- ofunc->mesh = ofunc->input_is_output ? iface : new MBCore;
+ MBSimplexTemplateRefiner eref( imesh );
+ MBTestOutputFunctor* ofunc = new MBTestOutputFunctor( imesh, omesh, eval );
eref.set_edge_size_evaluator( eval );
eref.set_output_functor( ofunc );
+ eval->create_output_tags();
eref.refine_entity( tet_handle );
ofunc->mesh->list_entities( 0, 1 );
if ( ! ofunc->input_is_output )
delete ofunc->mesh;
- delete iface;
+ delete imesh;
#ifdef USE_MPI
err = MPI_Barrier( MPI_COMM_WORLD );
More information about the moab-dev
mailing list