44 #ifndef TPETRA_APPLYDIRICHLETBOUNDARYCONDITION_HPP
45 #define TPETRA_APPLYDIRICHLETBOUNDARYCONDITION_HPP
51 #include "Tpetra_CrsMatrix.hpp"
52 #include "Tpetra_Vector.hpp"
53 #include "Tpetra_Map.hpp"
54 #include "KokkosSparse_CrsMatrix.hpp"
55 #include "Kokkos_ArithTraits.hpp"
68 template<
class CrsMatrixType>
71 (
const typename CrsMatrixType::execution_space& execSpace,
74 typename CrsMatrixType::local_ordinal_type*,
75 typename CrsMatrixType::device_type> & lclRowInds);
86 template<
class CrsMatrixType>
91 typename CrsMatrixType::local_ordinal_type*,
92 typename CrsMatrixType::device_type>& lclRowInds);
103 template<
class CrsMatrixType>
108 typename CrsMatrixType::local_ordinal_type*,
109 Kokkos::HostSpace> & lclRowInds);
121 template<
class CrsMatrixType>
124 (
const typename CrsMatrixType::execution_space& execSpace,
127 typename CrsMatrixType::local_ordinal_type*,
128 typename CrsMatrixType::device_type> & lclRowInds);
143 template<
class CrsMatrixType>
148 typename CrsMatrixType::local_ordinal_type*,
149 Kokkos::HostSpace> & lclRowInds);
160 template<
class CrsMatrixType>
165 typename CrsMatrixType::local_ordinal_type*,
166 typename CrsMatrixType::device_type> & lclRowInds);
171 template<
class SC,
class LO,
class GO,
class NT>
172 struct ApplyDirichletBoundaryConditionToLocalMatrixRows {
175 using local_row_indices_type =
176 Kokkos::View<const LO*, Kokkos::AnonymousSpace>;
179 run (
const execution_space& execSpace,
181 const local_row_indices_type& lclRowInds,
182 const bool runOnHost)
190 using KAT = Kokkos::ArithTraits<IST>;
192 const auto rowMap = A.getRowMap ();
193 TEUCHOS_TEST_FOR_EXCEPTION
194 (rowMap.get () ==
nullptr, std::invalid_argument,
195 "The matrix must have a row Map.");
196 const auto colMap = A.getColMap ();
197 TEUCHOS_TEST_FOR_EXCEPTION
198 (colMap.get () ==
nullptr, std::invalid_argument,
199 "The matrix must have a column Map.");
200 auto A_lcl = A.getLocalMatrixDevice ();
202 const LO lclNumRows =
static_cast<LO
> (rowMap->getLocalNumElements ());
203 TEUCHOS_TEST_FOR_EXCEPTION
204 (lclNumRows != 0 && static_cast<LO>(A_lcl.graph.numRows ()) != lclNumRows,
205 std::invalid_argument,
"The matrix must have been either created "
206 "with a KokkosSparse::CrsMatrix, or must have been fill-completed "
209 auto lclRowMap = A.getRowMap ()->getLocalMap ();
210 auto lclColMap = A.getColMap ()->getLocalMap ();
211 auto rowptr = A_lcl.graph.row_map;
212 auto colind = A_lcl.graph.entries;
213 auto values = A_lcl.values;
215 const bool wasFillComplete = A.isFillComplete ();
216 if (wasFillComplete) {
220 const LO numInputRows = lclRowInds.extent (0);
222 using range_type = Kokkos::RangePolicy<execution_space, LO>;
224 (
"Tpetra::CrsMatrix apply Dirichlet: Device",
225 range_type (execSpace, 0, numInputRows),
226 KOKKOS_LAMBDA (
const LO i) {
227 LO row = lclRowInds(i);
228 const GO row_gid = lclRowMap.getGlobalElement(row);
229 for (
auto j = rowptr(row); j < rowptr(row+1); ++j) {
231 lclColMap.getGlobalElement (colind(j)) == row_gid;
232 values(j) = diagEnt ? KAT::one () : KAT::zero ();
238 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace, LO>;
240 (
"Tpetra::CrsMatrix apply Dirichlet: Host",
241 range_type (0, numInputRows),
243 LO row = lclRowInds(i);
244 const GO row_gid = lclRowMap.getGlobalElement(row);
245 for (
auto j = rowptr(row); j < rowptr(row+1); ++j) {
247 lclColMap.getGlobalElement (colind(j)) == row_gid;
248 values(j) = diagEnt ? KAT::one () : KAT::zero ();
252 if (wasFillComplete) {
253 A.fillComplete (A.getDomainMap (), A.getRangeMap ());
260 template<
class SC,
class LO,
class GO,
class NT>
261 struct ApplyDirichletBoundaryConditionToLocalMatrixColumns {
264 using local_col_flag_type =
265 Kokkos::View<bool*, Kokkos::AnonymousSpace>;
269 run (
const execution_space& execSpace,
271 const local_col_flag_type& lclColFlags,
272 const bool runOnHost)
280 using KAT = Kokkos::ArithTraits<IST>;
282 const auto rowMap = A.getRowMap ();
283 TEUCHOS_TEST_FOR_EXCEPTION
284 (rowMap.get () ==
nullptr, std::invalid_argument,
285 "The matrix must have a row Map.");
286 const auto colMap = A.getColMap ();
287 TEUCHOS_TEST_FOR_EXCEPTION
288 (colMap.get () ==
nullptr, std::invalid_argument,
289 "The matrix must have a column Map.");
290 auto A_lcl = A.getLocalMatrixDevice ();
292 const LO lclNumRows =
static_cast<LO
> (rowMap->getLocalNumElements ());
293 TEUCHOS_TEST_FOR_EXCEPTION
294 (lclNumRows != 0 && static_cast<LO>(A_lcl.graph.numRows ()) != lclNumRows,
295 std::invalid_argument,
"The matrix must have been either created "
296 "with a KokkosSparse::CrsMatrix, or must have been fill-completed "
299 auto lclRowMap = A.getRowMap()->getLocalMap ();
300 auto lclColMap = A.getColMap()->getLocalMap ();
301 auto rowptr = A_lcl.graph.row_map;
302 auto colind = A_lcl.graph.entries;
303 auto values = A_lcl.values;
305 const bool wasFillComplete = A.isFillComplete ();
306 if (wasFillComplete) {
310 const LO numRows = (LO) A.getRowMap()->getLocalNumElements();
312 using range_type = Kokkos::RangePolicy<execution_space, LO>;
314 (
"Tpetra::CrsMatrix apply Dirichlet cols: Device",
315 range_type (execSpace, 0, numRows),
316 KOKKOS_LAMBDA (
const LO i) {
317 for (
auto j = rowptr(i); j < rowptr(i+1); ++j) {
318 if(lclColFlags[colind[j]])
319 values(j) = KAT::zero();
325 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace, LO>;
327 (
"Tpetra::CrsMatrix apply Dirichlet cols: Host",
328 range_type (0, numRows),
329 KOKKOS_LAMBDA (
const LO i) {
330 for (
auto j = rowptr(i); j < rowptr(i+1); ++j) {
331 if(lclColFlags[colind[j]])
332 values(j) = KAT::zero();
336 if (wasFillComplete) {
337 A.fillComplete (A.getDomainMap (), A.getRangeMap ());
344 template<
class SC,
class LO,
class GO,
class NT>
345 void localRowsToColumns(
const typename ::Tpetra::CrsMatrix<SC, LO, GO, NT>::execution_space& execSpace, const ::Tpetra::CrsMatrix<SC, LO, GO, NT>& A,
const Kokkos::View<const LO*,Kokkos::AnonymousSpace> & dirichletRowIds, Kokkos::View<bool*,Kokkos::AnonymousSpace> & dirichletColFlags) {
347 using execution_space =
typename crs_matrix_type::execution_space;
348 using memory_space =
typename crs_matrix_type::device_type::memory_space;
351 TEUCHOS_TEST_FOR_EXCEPTION(A.getColMap().get () ==
nullptr, std::invalid_argument,
"The matrix must have a column Map.");
355 TEUCHOS_TEST_FOR_EXCEPTION(!A.getRowMap()->isSameAs(*A.getDomainMap()),std::invalid_argument,
"localRowsToColumns: Row/Domain maps do not match");
358 TEUCHOS_TEST_FOR_EXCEPTION(A.getColMap()->getLocalNumElements() != dirichletColFlags.size(), std::invalid_argument,
"localRowsToColumns: dirichletColFlags must be the correct size");
360 LO numDirichletRows = (LO) dirichletRowIds.size();
361 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
363 if(A.getCrsGraph()->getImporter().is_null()) {
365 using range_type = Kokkos::RangePolicy<execution_space, LO>;
366 auto lclRowMap = A.getRowMap()->getLocalMap();
367 auto lclColMap = A.getColMap()->getLocalMap();
370 using range_type = Kokkos::RangePolicy<execution_space, LO>;
372 (
"Tpetra::CrsMatrix flag Dirichlet cols",
373 range_type (execSpace, 0, numDirichletRows),
374 KOKKOS_LAMBDA (
const LO i) {
375 GO row_gid = lclRowMap.getGlobalElement(dirichletRowIds[i]);
376 LO col_lid = lclColMap.getLocalElement(row_gid);
377 if(col_lid != LO_INVALID)
378 dirichletColFlags[col_lid] =
true;
383 auto Importer = A.getCrsGraph()->getImporter();
384 auto lclRowMap = A.getRowMap()->getLocalMap();
385 auto lclColMap = A.getColMap()->getLocalMap();
388 const LO one = Teuchos::OrdinalTraits<LO>::one();
389 using range_type = Kokkos::RangePolicy<execution_space, LO>;
391 auto domain_data = domainDirichlet.template getLocalView<memory_space>(Access::ReadWrite);
393 (
"Tpetra::CrsMatrix flag Dirichlet domains",
394 range_type (execSpace, 0, numDirichletRows),
395 KOKKOS_LAMBDA (
const LO i) {
396 GO row_gid = lclRowMap.getGlobalElement(dirichletRowIds[i]);
397 LO col_lid = lclColMap.getLocalElement(row_gid);
398 if(col_lid != LO_INVALID)
399 domain_data(col_lid,0) = one;
402 colDirichlet.doImport(domainDirichlet,*Importer,::
Tpetra::INSERT);
403 LO numCols = (LO) A.getColMap()->getLocalNumElements();
405 auto col_data = colDirichlet.template getLocalView<memory_space>(Access::ReadOnly);
407 (
"Tpetra::CrsMatrix flag Dirichlet cols",
408 range_type (execSpace, 0, numCols),
409 KOKKOS_LAMBDA (
const LO i) {
410 dirichletColFlags[i] = (col_data(i,0) == one) ?
true :
false;
418 template<
class CrsMatrixType>
421 (
const typename CrsMatrixType::execution_space& execSpace,
424 typename CrsMatrixType::local_ordinal_type*,
425 typename CrsMatrixType::device_type> & lclRowInds)
427 using SC =
typename CrsMatrixType::scalar_type;
428 using LO =
typename CrsMatrixType::local_ordinal_type;
429 using GO =
typename CrsMatrixType::global_ordinal_type;
430 using NT =
typename CrsMatrixType::node_type;
432 using local_row_indices_type =
433 Kokkos::View<const LO*, Kokkos::AnonymousSpace>;
434 const local_row_indices_type lclRowInds_a (lclRowInds);
436 using Details::ApplyDirichletBoundaryConditionToLocalMatrixRows;
438 ApplyDirichletBoundaryConditionToLocalMatrixRows<SC, LO, GO, NT>;
439 const bool runOnHost =
false;
440 impl_type::run (execSpace, A, lclRowInds_a, runOnHost);
443 template<
class CrsMatrixType>
448 typename CrsMatrixType::local_ordinal_type*,
449 typename CrsMatrixType::device_type> & lclRowInds)
451 using execution_space =
typename CrsMatrixType::execution_space;
455 template<
class CrsMatrixType>
460 typename CrsMatrixType::local_ordinal_type*,
461 Kokkos::HostSpace> & lclRowInds)
463 using SC =
typename CrsMatrixType::scalar_type;
464 using LO =
typename CrsMatrixType::local_ordinal_type;
465 using GO =
typename CrsMatrixType::global_ordinal_type;
466 using NT =
typename CrsMatrixType::node_type;
468 using execution_space =
typename crs_matrix_type::execution_space;
469 using memory_space =
typename crs_matrix_type::device_type::memory_space;
471 using Details::ApplyDirichletBoundaryConditionToLocalMatrixRows;
473 ApplyDirichletBoundaryConditionToLocalMatrixRows<SC, LO, GO, NT>;
476 const bool runOnHost = Kokkos::SpaceAccessibility<Kokkos::Serial,memory_space>::accessible;
478 using local_row_indices_type = Kokkos::View<const LO*, Kokkos::AnonymousSpace>;
479 const local_row_indices_type lclRowInds_a (lclRowInds);
480 impl_type::run (execution_space (), A, lclRowInds_a,
true);
483 auto lclRowInds_a = Kokkos::create_mirror_view_and_copy(execution_space(),lclRowInds);
484 impl_type::run (execution_space (), A, lclRowInds_a,
false);
489 template<
class CrsMatrixType>
494 typename CrsMatrixType::local_ordinal_type*,
495 Kokkos::HostSpace> & lclRowInds) {
496 using SC =
typename CrsMatrixType::scalar_type;
497 using LO =
typename CrsMatrixType::local_ordinal_type;
498 using GO =
typename CrsMatrixType::global_ordinal_type;
499 using NT =
typename CrsMatrixType::node_type;
501 using execution_space =
typename crs_matrix_type::execution_space;
502 using memory_space =
typename crs_matrix_type::device_type::memory_space;
504 TEUCHOS_TEST_FOR_EXCEPTION(A.getColMap().get () ==
nullptr, std::invalid_argument,
"The matrix must have a column Map.");
507 auto lclRowInds_d = Kokkos::create_mirror_view_and_copy(execution_space(),lclRowInds);
509 Kokkos::View<bool*,memory_space> dirichletColFlags(
"dirichletColFlags",A.getColMap()->getLocalNumElements());
510 Kokkos::View<bool*, Kokkos::AnonymousSpace> dirichletColFlags_a(dirichletColFlags);
511 Details::localRowsToColumns<SC,LO,GO,NT>(execution_space(),A,lclRowInds_d,dirichletColFlags_a);
513 Details::ApplyDirichletBoundaryConditionToLocalMatrixColumns<SC, LO, GO, NT>::run(execution_space(),A,dirichletColFlags,
false);
514 Details::ApplyDirichletBoundaryConditionToLocalMatrixRows<SC, LO, GO, NT>::run(execution_space(),A,lclRowInds_d,
false);
518 template<
class CrsMatrixType>
523 typename CrsMatrixType::local_ordinal_type*,
524 typename CrsMatrixType::device_type> & lclRowInds_d) {
525 using SC =
typename CrsMatrixType::scalar_type;
526 using LO =
typename CrsMatrixType::local_ordinal_type;
527 using GO =
typename CrsMatrixType::global_ordinal_type;
528 using NT =
typename CrsMatrixType::node_type;
530 using execution_space =
typename crs_matrix_type::execution_space;
531 using memory_space =
typename crs_matrix_type::device_type::memory_space;
533 TEUCHOS_TEST_FOR_EXCEPTION(A.getColMap().get () ==
nullptr, std::invalid_argument,
"The matrix must have a column Map.");
535 Kokkos::View<bool*,memory_space> dirichletColFlags(
"dirichletColFlags",A.getColMap()->getLocalNumElements());
536 Kokkos::View<bool*, Kokkos::AnonymousSpace> dirichletColFlags_a(dirichletColFlags);
537 Details::localRowsToColumns<SC,LO,GO,NT>(execution_space(),A,lclRowInds_d,dirichletColFlags_a);
539 Details::ApplyDirichletBoundaryConditionToLocalMatrixColumns<SC, LO, GO, NT>::run(execution_space(),A,dirichletColFlags,
false);
540 Details::ApplyDirichletBoundaryConditionToLocalMatrixRows<SC, LO, GO, NT>::run(execution_space(),A,lclRowInds_d,
false);
545 template<
class CrsMatrixType>
548 (
const typename CrsMatrixType::execution_space& execSpace,
551 typename CrsMatrixType::local_ordinal_type*,
552 typename CrsMatrixType::device_type> & lclRowInds_d) {
553 using SC =
typename CrsMatrixType::scalar_type;
554 using LO =
typename CrsMatrixType::local_ordinal_type;
555 using GO =
typename CrsMatrixType::global_ordinal_type;
556 using NT =
typename CrsMatrixType::node_type;
559 using memory_space =
typename crs_matrix_type::device_type::memory_space;
561 TEUCHOS_TEST_FOR_EXCEPTION(A.getColMap().get () ==
nullptr, std::invalid_argument,
"The matrix must have a column Map.");
563 Kokkos::View<bool*,memory_space> dirichletColFlags(
"dirichletColFlags",A.getColMap()->getLocalNumElements());
564 Kokkos::View<bool*, Kokkos::AnonymousSpace> dirichletColFlags_a(dirichletColFlags);
565 Details::localRowsToColumns<SC,LO,GO,NT>(execSpace,A,lclRowInds_d,dirichletColFlags_a);
567 Details::ApplyDirichletBoundaryConditionToLocalMatrixColumns<SC, LO, GO, NT>::run(execSpace,A,dirichletColFlags,
false);
568 Details::ApplyDirichletBoundaryConditionToLocalMatrixRows<SC, LO, GO, NT>::run(execSpace,A,lclRowInds_d,
false);
575 #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.
void applyDirichletBoundaryConditionToLocalMatrixRowsAndColumns(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 and column lclRowInds[k] of A to have 1 on the ...
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
Insert new values that don't currently exist.
typename row_matrix_type::impl_scalar_type impl_scalar_type
The type used internally in place of Scalar.
A distributed dense vector.
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...