All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Xpetra_StridedMap.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //             Xpetra: A linear algebra interface package
00006 //                  Copyright 2012 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact
00039 //                    Jeremie Gaidamour (jngaida@sandia.gov)
00040 //                    Jonathan Hu       (jhu@sandia.gov)
00041 //                    Ray Tuminaro      (rstumin@sandia.gov)
00042 //
00043 // ***********************************************************************
00044 //
00045 // @HEADER
00046 
00047 // WARNING: This code is experimental. Backwards compatibility should not be expected.
00048 
00049 #ifndef XPETRA_STRIDEDMAP_HPP
00050 #define XPETRA_STRIDEDMAP_HPP
00051 
00052 /* this file is automatically generated - do not edit (see script/interfaces.py) */
00053 
00054 #include <Kokkos_DefaultNode.hpp>
00055 #include <Teuchos_Describable.hpp>
00056 #include "Xpetra_Map.hpp"
00057 #include "Xpetra_ConfigDefs.hpp"
00058 
00059 #include "Xpetra_Exceptions.hpp"
00060 
00061 // MPI helper
00062 #define sumAll(rcpComm, in, out)                                        \
00063   Teuchos::reduceAll(*rcpComm, Teuchos::REDUCE_SUM, in, Teuchos::outArg(out));
00064 #define minAll(rcpComm, in, out)                                        \
00065   Teuchos::reduceAll(*rcpComm, Teuchos::REDUCE_MIN, in, Teuchos::outArg(out));
00066 #define maxAll(rcpComm, in, out)                                        \
00067   Teuchos::reduceAll(*rcpComm, Teuchos::REDUCE_MAX, in, Teuchos::outArg(out));
00068 
00069 namespace Xpetra {
00070 
00099   template <class LocalOrdinal, class GlobalOrdinal = LocalOrdinal, class Node = Kokkos::DefaultNode::DefaultNodeType>
00100   class StridedMap
00101     : public virtual Map<LocalOrdinal, GlobalOrdinal, Node>
00102   {
00103 
00104   public:
00105 
00107 
00108 
00109     StridedMap(global_size_t numGlobalElements, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId, GlobalOrdinal offset = 0)
00110     : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset)
00111     { 
00112       TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
00113       //TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % getFixedBlockSize() != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
00114 
00115     }
00116 
00117     StridedMap(global_size_t numGlobalElements, size_t numLocalElements, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId, GlobalOrdinal offset = 0)
00118     : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset)
00119     { 
00120       TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
00121       //TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % getFixedBlockSize() != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
00122       //TEUCHOS_TEST_FOR_EXCEPTION(numLocalElements % getFixedBlockSize() != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numLocalElements.");
00123     
00124     }
00125 
00126     StridedMap(std::vector<size_t>& stridingInfo, LocalOrdinal stridedBlockId, GlobalOrdinal offset = 0)
00127     : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId), offset_(offset)
00128     {
00129     }
00130 
00131     StridedMap(global_size_t numGlobalElements, const Teuchos::ArrayView< const GlobalOrdinal > &elementList, GlobalOrdinal indexBase, std::vector<size_t>& stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId=-1)
00132     : stridingInfo_(stridingInfo), stridedBlockId_(stridedBlockId)
00133     {
00134       TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo.size() == 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: stridingInfo.size() = 0?");
00135       TEUCHOS_TEST_FOR_EXCEPTION(stridedBlockId < -1, Exceptions::RuntimeError, "StridedMap::StridedMap: stridedBlockId must not be smaller than -1.");
00136 
00137       // the following tests are not valid if stridedBlockId != 1
00138       if(stridedBlockId == -1) {
00139         TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % getFixedBlockSize() != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of numGlobalElements.");
00140         TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % getFixedBlockSize() != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: getFixedBlockSize is not an integer multiple of elementList.size().");
00141       } else {
00142         // numGlobalElements can be -1! FIXME
00143         //TEUCHOS_TEST_FOR_EXCEPTION(numGlobalElements % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of numGlobalElements.");
00144         TEUCHOS_TEST_FOR_EXCEPTION(elementList.size() % stridingInfo[stridedBlockId] != 0, Exceptions::RuntimeError, "StridedMap::StridedMap: stridingInfo not valid: stridingBlockInfo[stridedBlockId] is not an integer multiple of elementList.size().");
00145       }
00146        
00147       // calculate offset_
00148 
00149       // find minimum GID over all procs
00150       GlobalOrdinal minGidOnCurProc = 99999;  // TODO use scalar traits for max possible gid.
00151       for(Teuchos_Ordinal k=0; k<elementList.size(); ++k) { // TODO fix occurence of Teuchos_Ordinal
00152         if(elementList[k] < minGidOnCurProc) minGidOnCurProc = elementList[k];
00153       }
00154       Teuchos::reduceAll(*comm, Teuchos::REDUCE_MIN, minGidOnCurProc, Teuchos::outArg(offset_));
00155 
00156       // calculate striding index
00157       size_t nStridedOffset = 0;
00158       for(int j=0; j<stridedBlockId; j++) {
00159         nStridedOffset += stridingInfo[j];
00160       }
00161       const GlobalOrdinal goStridedOffset = Teuchos::as<GlobalOrdinal>(nStridedOffset);
00162 
00163       // adapt offset_
00164       offset_ -= goStridedOffset;
00165     }
00166      
00168     virtual ~StridedMap() { }
00169 
00171 
00173 
00174     
00175     std::vector<size_t> getStridingData() const { return stridingInfo_; }
00176 
00177     void setStridingData(std::vector<size_t> stridingInfo) { stridingInfo_ = stridingInfo; }
00178 
00179     size_t getFixedBlockSize() const {
00180       // sum up size of all strided blocks (= number of dofs per node)
00181       size_t blkSize = 0;
00182       std::vector<size_t>::const_iterator it;
00183       for(it = stridingInfo_.begin(); it != stridingInfo_.end(); ++it) {
00184         blkSize += *it;
00185       }
00186       return blkSize;
00187     }
00188 
00191     LocalOrdinal getStridedBlockId() const { return stridedBlockId_; }
00192 
00194     bool isStrided() { return stridingInfo_.size() > 1 ? true : false; }
00195 
00198     bool isBlocked() { return getFixedBlockSize() > 1 ? true : false; }
00199     
00200     GlobalOrdinal getOffset() const { return offset_; } 
00201     
00202     void setOffset( GlobalOrdinal offset ) { offset_ = offset; }
00203     
00204     // returns number of strided block id which gid belongs to.
00205     size_t GID2StridingBlockId( GlobalOrdinal gid ) const {
00206       GlobalOrdinal tgid = gid - offset_;
00207       tgid = tgid % getFixedBlockSize();
00208 
00209       size_t nStridedOffset = 0;
00210       size_t stridedBlockId = 0;
00211       for(size_t j=0; j<stridingInfo_.size(); j++) {
00212         nStridedOffset += stridingInfo_[j];
00213         if(Teuchos::as<size_t>(tgid) < nStridedOffset) {
00214           stridedBlockId = j;
00215           break;
00216         }
00217       }
00218       return stridedBlockId;
00219     }
00220 
00221     /* // function currently not needed but maybe useful
00222     std::vector<GlobalOrdinal> NodeId2GlobalDofIds(GlobalOrdinal nodeId) const {
00223       TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_.size() == 0, Exceptions::RuntimeError, "StridedMap::NodeId2GlobalDofIds: stridingInfo not valid: stridingInfo.size() = 0?");
00224       std::vector<GlobalOrdinal> dofs;
00225       if(stridedBlockId_ > -1) {
00226           TEUCHOS_TEST_FOR_EXCEPTION(stridingInfo_[stridedBlockId_] == 0, Exceptions::RuntimeError, "StridedMap::NodeId2GlobalDofIds: stridingInfo not valid: stridingInfo[stridedBlockId] = 0?");
00227 
00228           // determine nStridedOffset
00229           size_t nStridedOffset = 0;
00230           for(int j=0; j<stridedBlockId_; j++) {
00231             nStridedOffset += stridingInfo_[j];
00232           }
00233 
00234           for(size_t i = 0; i<stridingInfo_[stridedBlockId_]; i++) {
00235             GlobalOrdinal gid =
00236                 nodeId * Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) +
00237                 offset_ +
00238                 Teuchos::as<GlobalOrdinal>(nStridedOffset) +
00239                 Teuchos::as<GlobalOrdinal>(i);
00240             dofs.push_back(gid);
00241           }
00242       } else {
00243         for(size_t i = 0; i<getFixedBlockSize(); i++) {
00244           GlobalOrdinal gid =
00245               nodeId * Teuchos::as<GlobalOrdinal>(getFixedBlockSize()) +
00246               offset_ +
00247               Teuchos::as<GlobalOrdinal>(i);
00248           dofs.push_back(gid);
00249         }
00250       }
00251       return dofs;
00252     }*/
00254 
00255   private:
00256     virtual bool CheckConsistency() = 0;
00257 
00258   protected:
00259     std::vector<size_t> stridingInfo_;   
00260     LocalOrdinal stridedBlockId_;        
00261                                          // stridedBlock == -1: the full map (with all strided block dofs)
00262                                          // stridedBlock >  -1: only dofs of strided block with index "stridedBlockId" are stored in this map
00263     GlobalOrdinal offset_;     
00264 
00265   }; // StridedMap class
00266 
00267 } // Xpetra namespace
00268 
00269 #define XPETRA_STRIDEDMAP_SHORT
00270 #endif // XPETRA_STRIDEDMAP_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines