1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/** \file   ReorderTool.hpp
 *  \author Jason Kraftcheck
 *  \date   2011-05-23
 */

#ifndef moab_REORDER_TOOL_HPP
#define moab_REORDER_TOOL_HPP

#include "moab/Types.hpp"
#include <vector>

namespace moab
{

class Core;
class Range;

class ReorderTool
{
  public:
    ReorderTool( Core* moab ) : mMB( moab ) {}

    /**\brief Calculate new handle order by tag value.
     *
     * Given a tag containing integer values, calculate new order for entities
     * in the database (except entity sets) such that all entities
     * with tag value A occur before all entities with tag value B
     * in the handle space where A < B.  Ordering will be stable for
     * entities with the same tag value.
     *
     *\param ordering_tag  Sinlge integer tag, where value on each entity
     *                     determines the new position in the handle ordering.
     *                     Entities may have duplicate values.
     *\param ordering_tag_skip_value Do not reorder entities with this tag
     *                     value. This is typically the default value of
     *                     ordering_tag.  Specifying this limits the re-ordering
     *                     to only those entities for which ordering_tag has
     *                     been set.
     *\param new_handle_tag_out  Passed back new tag handle containing the
     *                     entity mapping.  The returned tag will be anonymous.
     *                     The caller is responsible for releasing the tag.
     *                     The value of this tag on each handle is the new
     *                     handle that the entity will will be moved to. The
     *                     tag value will be zero for entities that were not
     *                     re-ordered.
     */
    ErrorCode handle_order_from_int_tag( Tag ordering_tag, int ordering_tag_skip_value, Tag& new_handle_tag_out );

    /**\brief Calculate new handle order by tag value.
     *
     * Given a tag containing integer values, calculate new order for entities
     * in the database (except entity sets) such that all entities
     * with tag value A occur before all entities with tag value B
     * in the handle space where A < B.  Ordering will be stable for
     * entities with the same tag value.
     *
     *\param type          Entity type for which to calculate re-ordering.
     *\param vals_per_ent  Zero for vertices.  Connectivity length for elements.
     *\param ordering_tag  Sinlge integer tag, where value on each entity
     *                     determines the new position in the handle ordering.
     *                     Entities may have duplicate values.
     *\param ordering_tag_skip_value Do not reorder entities with this tag
     *                     value. This is typically the default value of
     *                     ordering_tag.  Specifying this limits the re-ordering
     *                     to only those entities for which ordering_tag has
     *                     been set.
     *\param new_handle_tag Tag into which to store new handle for each
     *                     entity.  Tag must be defined to store a single
     *                     entity handle and must have a default value of
     *                     zero.
     */
    ErrorCode handle_order_from_int_tag( EntityType type,
                                         int vals_per_ent,
                                         Tag ordering_tag,
                                         int ordering_tag_skip_value,
                                         Tag new_handle_tag );

    /**\brief Calculate new handle order by set containment
     *
     * Given a list of sets, re-order entities such that handles are
     * grouped contiguously by set.  Will also group all adjacent mesh
     * entities, such that entities that are are adjacent to members of
     * two or more of the input sets will ge grouped by the combined
     * list of sets (e.g. if the input sets contain elements then all
     * vertices that are adjacent to only elements in the first two sets
     * will be grouped together).
     *
     *\param sets          Entity sets by which to group entities.
     *\param new_handle_tag_out  Passed back new tag handle containing the
     *                     entity mapping.  The returned tag will be anonymous.
     *                     The caller is responsible for releasing the tag.
     *                     The value of this tag on each handle is the new
     *                     handle that the entity will will be moved to. The
     *                     tag value will be zero for entities that were not
     *                     re-ordered.
     */
    ErrorCode handle_order_from_sets_and_adj( const Range& sets, Tag& new_handle_tag_out );

    /**\brief Do the re-ordering indicated by the passed handle tag.
     *
     * The specified re-ordering must be a permutation.  Each existing
     * entity must be moved to a new, existing handle such that no
     * two entities are moved to the same new handle.
     *
     * Given a tag storing handles that define a permution, apply the
     * described re-ordering.  The passed tag must contain one entity
     * handle per entity.  The value of the tag must be zero for all
     * entities that are not to be re-ordered.  For entities to be
     * re-ordered, the tag must contain the new handle that the entity
     * is to be moved to.  No two entities may have the same value for
     * this tag (other than a value of zero.)
     *
     *\param new_handle_tag Tag containing new handles for entities to
     *                      reorder.  Typically the output of
     *                      handle_order_from_int_tag or similar.
     */
    ErrorCode reorder_entities( Tag new_handle_tag );

  private:
    /**\brief helper function for reorder_entities
     *
     * Reorder tag data for all entities of specified type.
     *
     * Also updates tag values for MB_TYPE_HANDLE tags.
     *\param type  Entity type to reorder
     *\param new_handles Tag containing old->new handle mapping
     *\param reorder_tag The tag data to reorder
     */
    ErrorCode reorder_tag_data( EntityType type, Tag new_handles, Tag reorder_tag );

    /**\brief helper function for reorder_entities
     *
     * Update set contents for changed handles.
     *\param new_handles Tag containing old->new handle mapping
     */
    ErrorCode update_set_contents( Tag new_handles );

    /**\brief Get all entities of specified type and size
     *\param t the type of entity to retreive
     *\param vals_per_ent entity size (connectivity length for elements,
     *         dimension for vertices)
     */
    void get_entities( EntityType t, int vals_per_ent, Range& result );

    /**\brief Get new handles corresponding to old handles
     *\param tag Tag containing old->new mapping
     */
    ErrorCode get_reordered_handles( Tag tag, const Range& old_handles, std::vector< EntityHandle >& new_handles );

    /**\brief Get new handles corresponding to old handles
     *\param tag Tag containing old->new mapping
     */
    ErrorCode get_reordered_handles( Tag tag,
                                     const std::vector< EntityHandle >& old_handles,
                                     std::vector< EntityHandle >& new_handles );

    /**\brief Get new handles corresponding to old handles
     *\param tag Tag containing old->new mapping
     */
    ErrorCode get_reordered_handles( Tag tag,
                                     const EntityHandle* old_handles,
                                     EntityHandle* new_handles,
                                     size_t num_handles );

    /**\brief Remove any non-ordered handles and return new handles for remaining
     *\param tag Tag containing old->new mapping
     */
    ErrorCode get_new_handles( Tag tag, Range& old_handles, std::vector< EntityHandle >& newhandles );

    /**\brief convert from input for \c handle_order_from_sets_and_adj to
     *        \c input for handle_order_from_int_tag
     */
    ErrorCode int_order_from_sets_and_adj( const Range& sets,
                                           Tag order_tag,
                                           int skip_val,
                                           std::vector< std::vector< EntityHandle >* >& data );

    Core* mMB;
};

}  // namespace moab

#endif  // moab_REORDER_TOOL_HPP