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
54namespace Tpetra {
55
56template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
57FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
58FEMultiVector (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
98template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
99void
100FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
101beginFill ()
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
110template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
111void
112FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
113endFill ()
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
128template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
129void 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
140template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
141void 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
152template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
153void 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
163template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
164void 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
174template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
175void
176FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
177globalAssemble ()
178{
179 endFill ();
180}
181
182template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
183void
184FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
185replaceMap (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
193template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
194void
195FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
196doOwnedPlusSharedToOwned (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
204template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
205void
206FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
207doOwnedToOwnedPlusShared (const CombineMode CM)
208{
209 if (! importer_.is_null () &&
210 *activeMultiVector_ == FE_ACTIVE_OWNED) {
211 inactiveMultiVector_->doImport (*this, *importer_, CM);
212 }
213}
214
215template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
216void
217FEMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
218switchActiveMultiVector ()
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.