• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

MOR_StkNodalMeshReduction.cpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
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   // Trivial operations (implemented as noops)
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); // Ignore return value, may silently fails
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   // Keep only the closure, remove the rest, by decreasing entityRanks
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 } // end namespace MOR

Generated on Wed Mar 26 2014 18:36:40 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1