43 const Teuchos::RCP<
const Teuchos::Comm<int>> &comm,
44 const GO numGlobalElements,
const SC zMin,
const SC zMax,
const SC a,
47 numGlobalElements_(numGlobalElements),
52 showGetInvalidArg_(false)
56 using ::Thyra::VectorBase;
57 using MEB = ::Thyra::ModelEvaluatorBase;
58 using ST = Teuchos::ScalarTraits<SC>;
60 TEUCHOS_ASSERT(nonnull(
comm_));
63 const auto myRank =
comm_->getRank();
70 if (
comm_->getSize() == 1) {
74 LO overlapNumMyElements;
75 GO overlapGetMinGLobalIndex;
76 overlapNumMyElements =
xOwnedMap_->getLocalNumElements() + 2;
77 if ((myRank == 0) || (myRank == (
comm_->getSize() - 1))) {
78 overlapNumMyElements--;
82 overlapGetMinGLobalIndex =
xOwnedMap_->getMinGlobalIndex();
85 overlapGetMinGLobalIndex =
xOwnedMap_->getMinGlobalIndex() - 1;
88 Teuchos::Array<GO> overlapMyGlobalNodes(overlapNumMyElements);
90 GO getGlobalElement = overlapGetMinGLobalIndex;
91 for (
auto &globalElem : overlapMyGlobalNodes) {
92 globalElem = overlapGetMinGLobalIndex;
97 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
110 V_S(
x0_.ptr(), ST::zero());
120 const auto minGI =
xOwnedMap_->getMinGlobalIndex();
123 Kokkos::parallel_for(
"coords_fill",
xOwnedMap_->getLocalNumElements(),
129 MEB::InArgsSetup<SC> inArgs;
130 inArgs.setModelEvalDescription(this->description());
131 inArgs.setSupports(MEB::IN_ARG_t);
132 inArgs.setSupports(MEB::IN_ARG_x);
133 inArgs.setSupports(MEB::IN_ARG_beta);
134 inArgs.setSupports(MEB::IN_ARG_x_dot);
135 inArgs.setSupports(MEB::IN_ARG_alpha);
138 MEB::OutArgsSetup<SC> outArgs;
139 outArgs.setModelEvalDescription(this->description());
140 outArgs.setSupports(MEB::OUT_ARG_f);
141 outArgs.setSupports(MEB::OUT_ARG_W);
142 outArgs.setSupports(MEB::OUT_ARG_W_op);
143 outArgs.setSupports(MEB::OUT_ARG_W_prec);
150 auto x_dot_init = Thyra::createMember(this->
get_x_space());
151 Thyra::put_scalar(SC(0.0), x_dot_init.ptr());
161 auto W_graph = Teuchos::rcp(
new tpetra_graph(xOwnedMap_, 5));
162 W_graph->resumeFill();
164 auto overlapNumMyElements =
165 static_cast<LO
>(xGhostedMap_->getLocalNumElements());
168 for (LO elem = 0; elem < overlapNumMyElements - 1; elem++) {
170 for (LO i = 0; i < 2; i++) {
171 auto row = xGhostedMap_->getGlobalElement(elem + i);
174 for (LO j = 0; j < 2; j++) {
176 if (xOwnedMap_->isNodeGlobalElement(row)) {
177 auto colIndex = xGhostedMap_->getGlobalElement(elem + j);
178 Teuchos::ArrayView<const GO> column(&colIndex, 1);
179 W_graph->insertGlobalIndices(row, column);
184 W_graph->fillComplete();
299 const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
300 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs)
const
304 using Teuchos::rcp_dynamic_cast;
306 TEUCHOS_ASSERT(nonnull(inArgs.get_x()));
307 TEUCHOS_ASSERT(nonnull(inArgs.get_x_dot()));
309 auto f_out = outArgs.get_f();
310 auto W_out = outArgs.get_W_op();
311 auto W_prec_out = outArgs.get_W_prec();
313 if (nonnull(f_out) || nonnull(W_out) || nonnull(W_prec_out)) {
319 if (nonnull(f_out)) {
320 f = tpetra_extract::getTpetraVector(outArgs.get_f());
323 RCP<tpetra_matrix> J;
324 if (nonnull(W_out)) {
325 auto W_epetra = tpetra_extract::getTpetraOperator(W_out);
326 J = rcp_dynamic_cast<tpetra_matrix>(W_epetra);
327 TEUCHOS_ASSERT(nonnull(J));
330 RCP<tpetra_matrix> M_inv;
331 if (nonnull(W_prec_out)) {
332 auto M_tpetra = tpetra_extract::getTpetraOperator(
333 W_prec_out->getNonconstRightPrecOp());
334 M_inv = rcp_dynamic_cast<tpetra_matrix>(M_tpetra);
335 TEUCHOS_ASSERT(nonnull(M_inv));
336 jDiag_ = Teuchos::rcp(
new tpetra_vec(xOwnedMap_));
337 jDiag_->putScalar(0.0);
345 if (comm_->getRank() == 0) {
346 auto x = Teuchos::rcp_const_cast<Thyra::VectorBase<SC>>(inArgs.get_x());
347 auto xVec = tpetra_extract::getTpetraVector(x);
348 auto xView = xVec->getLocalViewHost(Tpetra::Access::ReadWrite);
352 if (is_null(uPtr_)) {
353 uPtr_ = Teuchos::rcp(
new tpetra_vec(xGhostedMap_));
356 uPtr_->doImport(*(tpetra_extract::getConstTpetraVector(inArgs.get_x())),
357 *importer_, Tpetra::INSERT);
359 if (is_null(uDotPtr_)) {
360 uDotPtr_ = Teuchos::rcp(
new tpetra_vec(xGhostedMap_));
364 *(tpetra_extract::getConstTpetraVector(inArgs.get_x_dot())), *importer_,
367 if (is_null(xPtr_)) {
368 xPtr_ = Teuchos::rcp(
new tpetra_vec(xGhostedMap_));
369 xPtr_->doImport(*nodeCoordinates_, *importer_, Tpetra::INSERT);
372 auto overlapNumMyElements =
373 static_cast<LO
>(xGhostedMap_->getLocalNumElements());
381 J->setAllToScalar(0.0);
384 if (nonnull(M_inv)) {
385 M_inv->setAllToScalar(0.0);
390 comm_->getRank(), a_, k_);
391 Kokkos::parallel_for(
"DfDp2EvaluatorFunctor", overlapNumMyElements - 1,
396 const auto alpha = inArgs.get_alpha();
397 const auto beta = inArgs.get_beta();
401 *J, *xPtr_, *uPtr_, *uDotPtr_, comm_->getRank(), a_, k_, alpha, beta);
404 Kokkos::parallel_for(
"JacobianEvaluatorFunctor", overlapNumMyElements - 1,
410 if (nonnull(M_inv)) {
412 *M_inv, *xPtr_, *uPtr_, *uDotPtr_, comm_->getRank(), a_, k_, alpha,
416 Kokkos::parallel_for(
"PreconditionerEvaluatorFunctor",
417 overlapNumMyElements - 1, mFunctor);
419 M_inv->fillComplete();
422 if (nonnull(M_inv)) {
424 auto &diag = *jDiag_;
425 M_inv->getLocalDiagCopy(diag);
426 diag.reciprocal(diag);
428 M_inv->rightScale(diag);
429 M_inv->rightScale(diag);