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  // Memory aliasing is required for FEMultiVector
92  inactiveMultiVector_ =
93  Teuchos::rcp (new base_type (*this, importer_->getSourceMap(), 0));
94  }
95  fillState_ = Teuchos::rcp(new FillState(FillState::closed));
96 }
97 
98 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
99 void
100 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
101 beginFill ()
102 {
103  // The FEMultiVector is in owned+shared mode on construction, so we
104  // do not throw in that case.
105  if (*activeMultiVector_ == FE_ACTIVE_OWNED) {
106  switchActiveMultiVector ();
107  }
108 }
109 
110 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
111 void
112 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
113 endFill ()
114 {
115  const char tfecfFuncName[] = "endFill: ";
116 
117  if (*activeMultiVector_ == FE_ACTIVE_OWNED_PLUS_SHARED) {
118  doOwnedPlusSharedToOwned (Tpetra::ADD);
119  switchActiveMultiVector ();
120  }
121  else {
122  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
123  (true, std::runtime_error, "Owned+Shared MultiVector already active; "
124  "cannot call endFill.");
125  }
126 }
127 
128 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
129 void FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::beginAssembly() {
130  const char tfecfFuncName[] = "FEMultiVector::beginAssembly: ";
131  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
132  *fillState_ != FillState::closed,
133  std::runtime_error,
134  "Cannot beginAssembly, matrix is not in a closed state"
135  );
136  *fillState_ = FillState::open;
137  this->beginFill();
138 }
139 
140 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
141 void FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::endAssembly() {
142  const char tfecfFuncName[] = "FEMultiVector::endAssembly: ";
143  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
144  *fillState_ != FillState::open,
145  std::runtime_error,
146  "Cannot endAssembly, matrix is not open to fill."
147  );
148  *fillState_ = FillState::closed;
149  this->endFill();
150 }
151 
152 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
153 void FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::beginModify() {
154  const char tfecfFuncName[] = "FEMultiVector::beginModify: ";
155  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
156  *fillState_ != FillState::closed,
157  std::runtime_error,
158  "Cannot beginModify, matrix is not in a closed state"
159  );
160  *fillState_ = FillState::modify;
161 }
162 
163 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
164 void FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::endModify() {
165  const char tfecfFuncName[] = "FEMultiVector::endModify: ";
166  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
167  *fillState_ != FillState::modify,
168  std::runtime_error,
169  "Cannot endModify, matrix is not open to modify."
170  );
171  *fillState_ = FillState::closed;
172 }
173 
174 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
175 void
176 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
177 globalAssemble ()
178 {
179  endFill ();
180 }
181 
182 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
183 void
184 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
185 replaceMap (const Teuchos::RCP<const map_type>& /* newMap */)
186 {
187  const char tfecfFuncName[] = "replaceMap: ";
188 
189  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
190  (true, std::runtime_error, "This method is not implemented.");
191 }
192 
193 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
194 void
195 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
196 doOwnedPlusSharedToOwned (const CombineMode CM)
197 {
198  if (! importer_.is_null () &&
199  *activeMultiVector_ == FE_ACTIVE_OWNED_PLUS_SHARED) {
200  inactiveMultiVector_->doExport (*this, *importer_, CM);
201  }
202 }
203 
204 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
205 void
206 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
207 doOwnedToOwnedPlusShared (const CombineMode CM)
208 {
209  if (! importer_.is_null () &&
210  *activeMultiVector_ == FE_ACTIVE_OWNED) {
211  inactiveMultiVector_->doImport (*this, *importer_, CM);
212  }
213 }
214 
215 template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
216 void
217 FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
218 switchActiveMultiVector ()
219 {
220  if (*activeMultiVector_ == FE_ACTIVE_OWNED_PLUS_SHARED) {
221  *activeMultiVector_ = FE_ACTIVE_OWNED;
222  }
223  else {
224  *activeMultiVector_ = FE_ACTIVE_OWNED_PLUS_SHARED;
225  }
226 
227  if (importer_.is_null ()) {
228  return;
229  }
230 
231  // Use MultiVector's swap routine here
232  this->swap (*inactiveMultiVector_);
233 }
234 
235 } // namespace Tpetra
236 
237 //
238 // Explicit instantiation macro
239 //
240 // Must be expanded from within the Tpetra namespace!
241 //
242 
243 #define TPETRA_FEMULTIVECTOR_INSTANT(SCALAR,LO,GO,NODE) \
244  template class FEMultiVector< SCALAR , LO , GO , NODE >;
245 
246 #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.