Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_applyDirichletBoundaryCondition.hpp
Go to the documentation of this file.
1 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Tpetra: Templated Linear Algebra Services Package
6 // Copyright (2008) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ************************************************************************
41 // @HEADER
42 */
43 
44 #ifndef TPETRA_APPLYDIRICHLETBOUNDARYCONDITION_HPP
45 #define TPETRA_APPLYDIRICHLETBOUNDARYCONDITION_HPP
46 
50 
51 #include "Tpetra_CrsMatrix.hpp"
52 #include "Tpetra_Map.hpp"
53 #include "KokkosSparse_CrsMatrix.hpp"
54 #include "Kokkos_ArithTraits.hpp"
55 
56 namespace Tpetra {
57 
67 template<class CrsMatrixType>
68 void
70 (const typename CrsMatrixType::execution_space& execSpace,
71  CrsMatrixType& A,
72  const Kokkos::View<
73  typename CrsMatrixType::local_ordinal_type*,
74  typename CrsMatrixType::device_type> & lclRowInds);
75 
85 template<class CrsMatrixType>
86 void
88 (CrsMatrixType& A,
89  const Kokkos::View<
90  typename CrsMatrixType::local_ordinal_type*,
91  typename CrsMatrixType::device_type>& lclRowInds);
92 
102 template<class CrsMatrixType>
103 void
105 (CrsMatrixType& A,
106  const Kokkos::View<
107  typename CrsMatrixType::local_ordinal_type*,
108  Kokkos::HostSpace> & lclRowInds);
109 
110 namespace Details {
111 
112 template<class SC, class LO, class GO, class NT>
113 struct ApplyDirichletBoundaryConditionToLocalMatrixRows {
114  using crs_matrix_type = ::Tpetra::CrsMatrix<SC, LO, GO, NT>;
115  using execution_space = typename crs_matrix_type::execution_space;
116  using local_row_indices_type =
117  Kokkos::View<const LO*, Kokkos::AnonymousSpace>;
118 
119  static void
120  run (const execution_space& execSpace,
121  crs_matrix_type& A,
122  const local_row_indices_type& lclRowInds,
123  const bool runOnHost)
124  {
125  using IST = typename crs_matrix_type::impl_scalar_type;
126  using KAT = Kokkos::ArithTraits<IST>;
127 
128  const auto rowMap = A.getRowMap ();
129  TEUCHOS_TEST_FOR_EXCEPTION
130  (rowMap.get () == nullptr, std::invalid_argument,
131  "The matrix must have a row Map.");
132  const auto colMap = A.getColMap ();
133  TEUCHOS_TEST_FOR_EXCEPTION
134  (colMap.get () == nullptr, std::invalid_argument,
135  "The matrix must have a column Map.");
136  auto A_lcl = A.getLocalMatrix ();
137 
138  const LO lclNumRows = static_cast<LO> (rowMap->getNodeNumElements ());
139  TEUCHOS_TEST_FOR_EXCEPTION
140  (lclNumRows != 0 && static_cast<LO>(A_lcl.graph.numRows ()) != lclNumRows,
141  std::invalid_argument, "The matrix must have been either created "
142  "with a KokkosSparse::CrsMatrix, or must have been fill-completed "
143  "at least once.");
144 
145  auto lclRowMap = A.getRowMap ()->getLocalMap ();
146  auto lclColMap = A.getColMap ()->getLocalMap ();
147  auto rowptr = A_lcl.graph.row_map;
148  auto colind = A_lcl.graph.entries;
149  auto values = A_lcl.values;
150 
151  const bool wasFillComplete = A.isFillComplete ();
152  if (wasFillComplete) {
153  A.resumeFill ();
154  }
155 
156  const LO numInputRows = lclRowInds.extent (0);
157  if (! runOnHost) {
158  using range_type = Kokkos::RangePolicy<execution_space, LO>;
159  Kokkos::parallel_for
160  ("Tpetra::CrsMatrix apply Dirichlet: Device",
161  range_type (execSpace, 0, numInputRows),
162  KOKKOS_LAMBDA (const LO i) {
163  const GO row_gid = lclRowMap.getGlobalElement (lclRowInds(i));
164  for (auto j = rowptr(i); j < rowptr(i+1); ++j) {
165  const bool diagEnt =
166  lclColMap.getGlobalElement (colind(j)) == row_gid;
167  values(j) = diagEnt ? KAT::one () : KAT::zero ();
168  }
169  });
170  }
171  else {
172  using range_type =
173  Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace, LO>;
174  Kokkos::parallel_for
175  ("Tpetra::CrsMatrix apply Dirichlet: Host",
176  range_type (0, numInputRows),
177  [&] (const LO i) {
178  const GO row_gid = lclRowMap.getGlobalElement (lclRowInds(i));
179  for (auto j = rowptr(i); j < rowptr(i+1); ++j) {
180  const bool diagEnt =
181  lclColMap.getGlobalElement (colind(j)) == row_gid;
182  values(j) = diagEnt ? KAT::one () : KAT::zero ();
183  }
184  });
185  }
186  if (wasFillComplete) {
187  A.fillComplete (A.getDomainMap (), A.getRangeMap ());
188  }
189  }
190 };
191 
192 } // namespace Details
193 
194 template<class CrsMatrixType>
195 void
197 (const typename CrsMatrixType::execution_space& execSpace,
198  CrsMatrixType& A,
199  const Kokkos::View<
200  typename CrsMatrixType::local_ordinal_type*,
201  typename CrsMatrixType::device_type> & lclRowInds)
202 {
203  using SC = typename CrsMatrixType::scalar_type;
204  using LO = typename CrsMatrixType::local_ordinal_type;
205  using GO = typename CrsMatrixType::global_ordinal_type;
206  using NT = typename CrsMatrixType::node_type;
207 
208  using local_row_indices_type =
209  Kokkos::View<const LO*, Kokkos::AnonymousSpace>;
210  const local_row_indices_type lclRowInds_a (lclRowInds);
211 
212  using Details::ApplyDirichletBoundaryConditionToLocalMatrixRows;
213  using impl_type =
214  ApplyDirichletBoundaryConditionToLocalMatrixRows<SC, LO, GO, NT>;
215  const bool runOnHost = false;
216  impl_type::run (execSpace, A, lclRowInds_a, runOnHost);
217 }
218 
219 template<class CrsMatrixType>
220 void
222 (CrsMatrixType& A,
223  const Kokkos::View<
224  typename CrsMatrixType::local_ordinal_type*,
225  typename CrsMatrixType::device_type> & lclRowInds)
226 {
227  using execution_space = typename CrsMatrixType::execution_space;
228  applyDirichletBoundaryConditionToLocalMatrixRows (execution_space (), A, lclRowInds);
229 }
230 
231 template<class CrsMatrixType>
232 void
234 (CrsMatrixType& A,
235  const Kokkos::View<
236  typename CrsMatrixType::local_ordinal_type*,
237  Kokkos::HostSpace> & lclRowInds)
238 {
239  using SC = typename CrsMatrixType::scalar_type;
240  using LO = typename CrsMatrixType::local_ordinal_type;
241  using GO = typename CrsMatrixType::global_ordinal_type;
242  using NT = typename CrsMatrixType::node_type;
243  using crs_matrix_type = ::Tpetra::CrsMatrix<SC, LO, GO, NT>;
244  using execution_space = typename crs_matrix_type::execution_space;
245 
246  using local_row_indices_type =
247  Kokkos::View<const LO*, Kokkos::AnonymousSpace>;
248  const local_row_indices_type lclRowInds_a (lclRowInds);
249 
250  using Details::ApplyDirichletBoundaryConditionToLocalMatrixRows;
251  using impl_type =
252  ApplyDirichletBoundaryConditionToLocalMatrixRows<SC, LO, GO, NT>;
253  const bool runOnHost = true;
254  impl_type::run (execution_space (), A, lclRowInds_a, runOnHost);
255 }
256 
257 } // namespace Tpetra
258 
259 #endif // TPETRA_APPLYDIRICHLETBOUNDARYCONDITION_HPP
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
typename device_type::execution_space execution_space
The Kokkos execution space.
typename Kokkos::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
void applyDirichletBoundaryConditionToLocalMatrixRows(const typename CrsMatrixType::execution_space &execSpace, CrsMatrixType &A, const Kokkos::View< typename CrsMatrixType::local_ordinal_type *, typename CrsMatrixType::device_type > &lclRowInds)
For all k in [0, lclRowInds.extent(0)), set local row lclRowInds[k] of A to have 1 on the diagonal an...