Tpetra parallel linear algebra  Version of the Day
Tpetra_FEMultiVector_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_FEMULTIVECTOR_DEF_HPP
43 #define TPETRA_FEMULTIVECTOR_DEF_HPP
44 
47 
48 #include "Tpetra_Map.hpp"
49 #include "Tpetra_MultiVector.hpp"
50 #include "Tpetra_Import.hpp"
52 
53 
54 namespace Tpetra {
55 
56 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
57 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
58 FEMultiVector (const Teuchos::RCP<const map_type>& map,
59  const Teuchos::RCP<const Import<local_ordinal_type, global_ordinal_type, node_type>>& importer,
60  const size_t numVecs,
61  const bool zeroOut) :
62  base_type (importer.is_null () ? map : importer->getTargetMap (),
63  numVecs, zeroOut),
64  activeMultiVector_ (Teuchos::rcp (new FEWhichActive (FE_ACTIVE_OWNED_PLUS_SHARED))),
65  importer_ (importer)
66 {
67  const char tfecfFuncName[] = "FEMultiVector constructor: ";
68 
69  if (! importer_.is_null ()) {
70  const bool debug = ::Tpetra::Details::Behavior::debug ();
71  if (debug) {
72  // Checking Map sameness may require an all-reduce, so we should
73  // reserve it for debug mode.
74  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
75  (! importer_->getSourceMap ()->isSameAs (*map),
76  std::runtime_error,
77  "If you provide a nonnull Import, then the input Map "
78  "must be the same as the input Import's source Map.");
79 
80  // Checking whether one Map is locally fitted to another could be
81  // expensive.
82  const bool locallyFitted =
83  importer->getTargetMap ()->isLocallyFitted (* (importer->getSourceMap ()));
84  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
85  (! locallyFitted, std::runtime_error,
86  "If you provide a nonnull Import, then its target Map must be "
87  "locally fitted (see Map::isLocallyFitted documentation) to its "
88  "source Map.");
89  }
90 
91  using range_type = Kokkos::pair<size_t, size_t>;
92  auto dv = Kokkos::subview (this->view_,
93  range_type (0, map->getNodeNumElements ()),
94  Kokkos::ALL ());
95  // Memory aliasing is required for FEMultiVector
96  inactiveMultiVector_ =
97  Teuchos::rcp (new base_type (importer_->getSourceMap (), dv));
98  }
99 }
100 
101 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
102 void
103 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
104 beginFill ()
105 {
106  // The FEMultiVector is in owned+shared mode on construction, so we
107  // do not throw in that case.
108  if (*activeMultiVector_ == FE_ACTIVE_OWNED) {
109  switchActiveMultiVector ();
110  }
111 }
112 
113 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
114 void
115 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
116 endFill ()
117 {
118  const char tfecfFuncName[] = "endFill: ";
119 
120  if (*activeMultiVector_ == FE_ACTIVE_OWNED_PLUS_SHARED) {
121  doOwnedPlusSharedToOwned (Tpetra::ADD);
122  switchActiveMultiVector ();
123  }
124  else {
125  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
126  (true, std::runtime_error, "Owned+Shared MultiVector already active; "
127  "cannot call endFill.");
128  }
129 }
130 
131 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
132 void
133 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
134 globalAssemble ()
135 {
136  endFill ();
137 }
138 
139 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
140 void
141 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
142 replaceMap (const Teuchos::RCP<const map_type>& /* newMap */)
143 {
144  const char tfecfFuncName[] = "replaceMap: ";
145 
146  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
147  (true, std::runtime_error, "This method is not implemented.");
148 }
149 
150 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
151 void
152 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
153 doOwnedPlusSharedToOwned (const CombineMode CM)
154 {
155  if (! importer_.is_null () &&
156  *activeMultiVector_ == FE_ACTIVE_OWNED_PLUS_SHARED) {
157  inactiveMultiVector_->doExport (*this, *importer_, CM);
158  }
159 }
160 
161 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
162 void
163 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
164 doOwnedToOwnedPlusShared (const CombineMode CM)
165 {
166  if (! importer_.is_null () &&
167  *activeMultiVector_ == FE_ACTIVE_OWNED) {
168  inactiveMultiVector_->doImport (*this, *importer_, CM);
169  }
170 }
171 
172 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
173 void
174 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
175 switchActiveMultiVector ()
176 {
177  if (*activeMultiVector_ == FE_ACTIVE_OWNED_PLUS_SHARED) {
178  *activeMultiVector_ = FE_ACTIVE_OWNED;
179  }
180  else {
181  *activeMultiVector_ = FE_ACTIVE_OWNED_PLUS_SHARED;
182  }
183 
184  if (importer_.is_null ()) {
185  return;
186  }
187 
188  // Use MultiVector's swap routine here
189  this->swap (*inactiveMultiVector_);
190 }
191 
192 } // namespace Tpetra
193 
194 //
195 // Explicit instantiation macro
196 //
197 // Must be expanded from within the Tpetra namespace!
198 //
199 
200 #define TPETRA_FEMULTIVECTOR_INSTANT(SCALAR,LO,GO,NODE) \
201  template class FEMultiVector< SCALAR , LO , GO , NODE >;
202 
203 #endif // TPETRA_FEMULTIVECTOR_DEF_HPP
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
static bool debug()
Whether Tpetra is in debug mode.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
CombineMode
Rule for combining data in an Import or Export.
@ ADD
Sum new values into existing values.