Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "MOR_StkNodalMeshReduction.hpp"
00007
00008 #include "stk_mesh/base/MetaData.hpp"
00009 #include "stk_mesh/base/GetEntities.hpp"
00010 #include "stk_mesh/base/BulkModification.hpp"
00011
00012 #include "Teuchos_Ptr.hpp"
00013
00014 #include <boost/iterator/indirect_iterator.hpp>
00015
00016 #include <algorithm>
00017 #include <iterator>
00018
00019 namespace MOR {
00020
00021 class BulkModification {
00022 public:
00023 explicit BulkModification(stk::mesh::BulkData &target) :
00024 target_(target)
00025 { target_.modification_begin(); }
00026
00027 ~BulkModification() { target_.modification_end(); }
00028
00029 const stk::mesh::BulkData &target() const { return target_; }
00030 stk::mesh::BulkData &target() { return target_; }
00031
00032 private:
00033 stk::mesh::BulkData &target_;
00034
00035 BulkModification(const BulkModification &);
00036 BulkModification &operator=(const BulkModification &);
00037 };
00038
00039 void addNodesToPart(
00040 const Teuchos::ArrayView<const stk::mesh::EntityId> &nodeIds,
00041 stk::mesh::Part &samplePart,
00042 stk::mesh::BulkData& bulkData)
00043 {
00044 const stk::mesh::EntityRank nodeEntityRank(0);
00045 const stk::mesh::PartVector samplePartVec(1, &samplePart);
00046 const stk::mesh::Selector locallyOwned = stk::mesh::MetaData::get(bulkData).locally_owned_part();
00047
00048 BulkModification mod(bulkData);
00049 typedef Teuchos::ArrayView<const stk::mesh::EntityId>::const_iterator Iter;
00050 for (Iter it = nodeIds.begin(), it_end = nodeIds.end(); it != it_end; ++it) {
00051 const Teuchos::Ptr<stk::mesh::Entity> node(bulkData.get_entity(nodeEntityRank, *it));
00052 if (Teuchos::nonnull(node) && locallyOwned(*node)) {
00053 bulkData.change_entity_parts(*node, samplePartVec);
00054 }
00055 }
00056 }
00057
00058 class EntityDestructor : public std::iterator<std::output_iterator_tag, void, void, void, void> {
00059 public:
00060 EntityDestructor() : modification_() {}
00061 explicit EntityDestructor(BulkModification &m) : modification_(&m) {}
00062
00063
00064 EntityDestructor &operator++() { return *this; }
00065 EntityDestructor &operator++(int) { return *this; }
00066 EntityDestructor &operator*() { return *this; }
00067
00068 EntityDestructor &operator=(stk::mesh::Entity *&e) {
00069 (void) modification_->target().destroy_entity(e);
00070 return *this;
00071 }
00072 EntityDestructor &operator=(stk::mesh::Entity *const &e) {
00073 stk::mesh::Entity *e_copy = e;
00074 return this->operator=(e_copy);
00075 }
00076
00077 private:
00078 BulkModification *modification_;
00079 };
00080
00081 void performNodalMeshReduction(
00082 stk::mesh::Part &samplePart,
00083 stk::mesh::BulkData& bulkData)
00084 {
00085 const stk::mesh::EntityRank nodeEntityRank(0);
00086 const stk::mesh::MetaData &metaData = stk::mesh::MetaData::get(bulkData);
00087
00088 std::vector<stk::mesh::Entity *> sampleNodes;
00089 stk::mesh::get_selected_entities(samplePart, bulkData.buckets(nodeEntityRank), sampleNodes);
00090
00091 const stk::mesh::Selector locallyOwned = stk::mesh::MetaData::get(bulkData).locally_owned_part();
00092
00093 std::vector<stk::mesh::Entity *> relatedEntities;
00094 typedef boost::indirect_iterator<std::vector<stk::mesh::Entity *>::const_iterator> EntityIterator;
00095 for (EntityIterator it(sampleNodes.begin()), it_end(sampleNodes.end()); it != it_end; ++it) {
00096 const stk::mesh::PairIterRelation relations = it->relations();
00097 typedef stk::mesh::PairIterRelation::first_type RelationIterator;
00098 for (RelationIterator rel_it = relations.first, rel_it_end = relations.second; rel_it != rel_it_end; ++rel_it) {
00099 const Teuchos::Ptr<stk::mesh::Entity> relatedEntity(rel_it->entity());
00100 if (Teuchos::nonnull(relatedEntity) && locallyOwned(*relatedEntity)) {
00101 relatedEntities.push_back(relatedEntity.get());
00102 }
00103 }
00104 }
00105 std::sort(relatedEntities.begin(), relatedEntities.end(), stk::mesh::EntityLess());
00106 relatedEntities.erase(
00107 std::unique(relatedEntities.begin(), relatedEntities.end(), stk::mesh::EntityEqual()),
00108 relatedEntities.end());
00109
00110 std::vector<stk::mesh::Entity *> sampleClosure;
00111 stk::mesh::find_closure(bulkData, relatedEntities, sampleClosure);
00112
00113
00114 {
00115 const stk::mesh::Selector ownedOrShared = metaData.locally_owned_part() | metaData.globally_shared_part();
00116 typedef boost::indirect_iterator<std::vector<stk::mesh::Entity *>::const_iterator> EntityIterator;
00117 EntityIterator allKeepersEnd(sampleClosure.end());
00118 const EntityIterator allKeepersBegin(sampleClosure.begin());
00119 for (stk::mesh::EntityRank candidateRankCount = metaData.entity_rank_count(); candidateRankCount > 0; --candidateRankCount) {
00120 const stk::mesh::EntityRank candidateRank = candidateRankCount - 1;
00121 const EntityIterator keepersBegin = std::lower_bound(allKeepersBegin, allKeepersEnd,
00122 stk::mesh::EntityKey(candidateRank, 0),
00123 stk::mesh::EntityLess());
00124 const EntityIterator keepersEnd = allKeepersEnd;
00125 std::vector<stk::mesh::Entity *> candidates;
00126 stk::mesh::get_selected_entities(ownedOrShared, bulkData.buckets(candidateRank), candidates);
00127 {
00128 BulkModification modification(bulkData);
00129 std::set_difference(candidates.begin(), candidates.end(),
00130 keepersBegin.base(), keepersEnd.base(),
00131 EntityDestructor(modification),
00132 stk::mesh::EntityLess());
00133 }
00134 allKeepersEnd = keepersBegin;
00135 }
00136 }
00137 }
00138
00139 }