9 #ifndef NOX_THYRA_MODEL_EVALUATOR_1DFEM_DEF_HPP
10 #define NOX_THYRA_MODEL_EVALUATOR_1DFEM_DEF_HPP
13 #include "Thyra_DefaultSpmdVectorSpace.hpp"
14 #include "Thyra_DefaultSerialDenseLinearOpWithSolveFactory.hpp"
15 #include "Thyra_DetachedMultiVectorView.hpp"
16 #include "Thyra_DetachedVectorView.hpp"
17 #include "Thyra_MultiVectorStdOps.hpp"
18 #include "Thyra_VectorStdOps.hpp"
19 #include "Thyra_PreconditionerBase.hpp"
22 #include "Thyra_EpetraThyraWrappers.hpp"
23 #include "Thyra_EpetraLinearOp.hpp"
24 #include "Thyra_get_Epetra_Operator.hpp"
25 #include "Epetra_Comm.h"
26 #include "Epetra_Map.h"
27 #include "Epetra_Vector.h"
28 #include "Epetra_Import.h"
29 #include "Epetra_CrsGraph.h"
30 #include "Epetra_CrsMatrix.h"
36 template<
class Scalar>
38 CDR_Model(
const Teuchos::RCP<const Epetra_Comm>& comm,
39 const int num_global_elements,
45 num_global_elements_(num_global_elements),
50 showGetInvalidArg_(false)
54 using ::Thyra::VectorBase;
55 typedef ::Thyra::ModelEvaluatorBase MEB;
56 typedef Teuchos::ScalarTraits<Scalar> ST;
58 TEUCHOS_ASSERT(nonnull(
comm_));
67 if (
comm_->NumProc() == 1) {
71 int OverlapNumMyElements;
73 OverlapNumMyElements =
x_owned_map_->NumMyElements() + 2;
74 if ( (
comm_->MyPID() == 0) || (
comm_->MyPID() == (
comm_->NumProc() - 1)) )
75 OverlapNumMyElements --;
77 if (
comm_->MyPID() == 0)
82 int* OverlapMyGlobalElements =
new int[OverlapNumMyElements];
84 for (
int i = 0; i < OverlapNumMyElements; i ++)
85 OverlapMyGlobalElements[i] = OverlapMinMyGID + i;
88 Teuchos::rcp(
new Epetra_Map(-1,
90 OverlapMyGlobalElements,
94 delete [] OverlapMyGlobalElements;
105 V_S(
x0_.ptr(), ST::zero());
125 MEB::InArgsSetup<Scalar> inArgs;
126 inArgs.setModelEvalDescription(this->description());
127 inArgs.setSupports(MEB::IN_ARG_t);
128 inArgs.setSupports(MEB::IN_ARG_x);
129 inArgs.setSupports( MEB::IN_ARG_beta );
130 inArgs.setSupports( MEB::IN_ARG_x_dot );
131 inArgs.setSupports( MEB::IN_ARG_alpha );
134 MEB::OutArgsSetup<Scalar> outArgs;
135 outArgs.setModelEvalDescription(this->description());
136 outArgs.setSupports(MEB::OUT_ARG_f);
137 outArgs.setSupports(MEB::OUT_ARG_W);
138 outArgs.setSupports(MEB::OUT_ARG_W_op);
139 outArgs.setSupports(MEB::OUT_ARG_W_prec);
150 auto x_dot_init = Thyra::createMember(this->
get_x_space());
151 Thyra::put_scalar(Scalar(0.0),x_dot_init.ptr());
157 template<
class Scalar>
158 Teuchos::RCP<Epetra_CrsGraph>
161 Teuchos::RCP<Epetra_CrsGraph> W_graph;
164 W_graph = Teuchos::rcp(
new Epetra_CrsGraph(Copy, *x_owned_map_, 5));
169 int OverlapNumMyElements = x_ghosted_map_->NumMyElements();
172 for (
int ne=0; ne < OverlapNumMyElements-1; ne++) {
175 for (
int i=0; i< 2; i++) {
176 row=x_ghosted_map_->GID(ne+i);
179 for(
int j=0;j < 2; j++) {
182 if (x_owned_map_->MyGID(row)) {
183 column=x_ghosted_map_->GID(ne+j);
184 W_graph->InsertGlobalIndices(row, 1, &column);
189 W_graph->FillComplete();
193 template<
class Scalar>
197 TEUCHOS_ASSERT_EQUALITY(x_space_->dim(), x0_in.size());
199 Thyra::DetachedVectorView<Scalar> x0(x0_);
200 x0.sv().values()().assign(x0_in);
204 template<
class Scalar>
207 showGetInvalidArg_ = showGetInvalidArg;
210 template<
class Scalar>
212 set_W_factory(
const Teuchos::RCP<const ::Thyra::LinearOpWithSolveFactoryBase<Scalar> >& W_factory)
214 W_factory_ = W_factory;
220 template<
class Scalar>
221 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
228 template<
class Scalar>
229 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
236 template<
class Scalar>
237 Thyra::ModelEvaluatorBase::InArgs<Scalar>
240 return nominalValues_;
244 template<
class Scalar>
245 Teuchos::RCP<Thyra::LinearOpWithSolveBase<double> >
248 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<double> > W_factory =
249 this->get_W_factory();
251 TEUCHOS_TEST_FOR_EXCEPTION(is_null(W_factory),std::runtime_error,
"W_factory in CDR_Model has a null W_factory!");
253 Teuchos::RCP<Thyra::LinearOpBase<double> > matrix = this->create_W_op();
255 Teuchos::RCP<Thyra::LinearOpWithSolveBase<double> > W =
256 Thyra::linearOpWithSolve<double>(*W_factory,matrix);
261 template<
class Scalar>
262 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
265 Teuchos::RCP<Epetra_CrsMatrix> W_epetra =
266 Teuchos::rcp(
new Epetra_CrsMatrix(::Copy,*W_graph_));
268 return Thyra::nonconstEpetraLinearOp(W_epetra);
271 template<
class Scalar>
272 Teuchos::RCP< ::Thyra::PreconditionerBase<Scalar> >
275 Teuchos::RCP<Epetra_CrsMatrix> W_epetra =
276 Teuchos::rcp(
new Epetra_CrsMatrix(::Copy,*W_graph_));
278 const Teuchos::RCP<Thyra::LinearOpBase< Scalar > > W_op =
279 Thyra::nonconstEpetraLinearOp(W_epetra);
281 Teuchos::RCP<Thyra::DefaultPreconditioner<Scalar> > prec =
282 Teuchos::rcp(
new Thyra::DefaultPreconditioner<Scalar>);
284 prec->initializeRight(W_op);
289 template<
class Scalar>
290 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
297 template<
class Scalar>
298 Thyra::ModelEvaluatorBase::InArgs<Scalar>
301 return prototypeInArgs_;
308 template<
class Scalar>
309 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
312 return prototypeOutArgs_;
316 template<
class Scalar>
318 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
319 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs
324 using Teuchos::rcp_dynamic_cast;
326 TEUCHOS_ASSERT(nonnull(inArgs.get_x()));
327 TEUCHOS_ASSERT(nonnull(inArgs.get_x_dot()));
331 const RCP<Thyra::VectorBase<Scalar> > f_out = outArgs.get_f();
332 const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
333 const RCP<Thyra::PreconditionerBase<Scalar> > W_prec_out = outArgs.get_W_prec();
336 if ( nonnull(f_out) || nonnull(W_out) || nonnull(W_prec_out) ) {
342 RCP<Epetra_Vector> f;
343 if (nonnull(f_out)) {
344 f = Thyra::get_Epetra_Vector(*f_owned_map_,outArgs.get_f());
347 RCP<Epetra_CrsMatrix> J;
348 if (nonnull(W_out)) {
349 RCP<Epetra_Operator> W_epetra = Thyra::get_Epetra_Operator(*W_out);
350 J = rcp_dynamic_cast<Epetra_CrsMatrix>(W_epetra);
351 TEUCHOS_ASSERT(nonnull(J));
354 RCP<Epetra_CrsMatrix> M_inv;
355 if (nonnull(W_prec_out)) {
356 RCP<Epetra_Operator> M_epetra = Thyra::get_Epetra_Operator(*(W_prec_out->getNonconstRightPrecOp()));
357 M_inv = rcp_dynamic_cast<Epetra_CrsMatrix>(M_epetra);
358 TEUCHOS_ASSERT(nonnull(M_inv));
359 J_diagonal_ = Teuchos::rcp(
new Epetra_Vector(*x_owned_map_));
367 u_ptr = Teuchos::rcp(
new Epetra_Vector(*x_ghosted_map_));
369 u_ptr->Import(*(Thyra::get_Epetra_Vector(*x_owned_map_,inArgs.get_x())), *importer_, Insert);
371 if (is_null(u_dot_ptr))
372 u_dot_ptr = Teuchos::rcp(
new Epetra_Vector(*x_ghosted_map_));
374 u_dot_ptr->Import(*(Thyra::get_Epetra_Vector(*x_owned_map_,inArgs.get_x_dot())), *importer_, Insert);
376 if (is_null(x_ptr)) {
377 x_ptr = Teuchos::rcp(
new Epetra_Vector(*x_ghosted_map_));
378 x_ptr->Import(*node_coordinates_, *importer_, Insert);
381 Epetra_Vector& u = *u_ptr;
382 Epetra_Vector& u_dot = *u_dot_ptr;
383 Epetra_Vector& x = *x_ptr;
386 int OverlapNumMyElements = x_ghosted_map_->NumMyElements();
392 const auto alpha = inArgs.get_alpha();
393 const auto beta = inArgs.get_beta();
401 M_inv->PutScalar(0.0);
404 for (
int ne=0; ne < OverlapNumMyElements-1; ne++) {
407 for(
int gp=0; gp < 2; gp++) {
414 uu_dot[1]=u_dot[ne+1];
419 for (
int i=0; i< 2; i++) {
420 int row=x_ghosted_map_->GID(ne+i);
423 if (x_owned_map_->MyGID(row)) {
425 (*f)[x_owned_map_->LID(x_ghosted_map_->GID(ne+i))]+=
428 +(a_/basis.
dz*basis.
duu*basis.
phi[i]
430 +k_*basis.
uu*basis.
uu*basis.
phi[i] );
435 for(
int j=0;j < 2; j++) {
436 if (x_owned_map_->MyGID(row)) {
437 int column=x_ghosted_map_->GID(ne+j);
440 alpha * basis.
phi[i] * basis.
phi[j]
444 +2.0*k_*basis.
uu*basis.
phi[j]*basis.
phi[i]
447 ierr=J->SumIntoGlobalValues(row, 1, &jac, &column);
451 if (nonnull(M_inv)) {
452 for(
int j=0;j < 2; j++) {
453 if (x_owned_map_->MyGID(row)) {
454 int column=x_ghosted_map_->GID(ne+j);
459 alpha * basis.
phi[i] * basis.
phi[j]
463 +2.0*k_*basis.
uu*basis.
phi[j]*basis.
phi[i]
466 ierr = M_inv->SumIntoGlobalValues(row, 1, &jac, &column);
477 if (comm_->MyPID() == 0) {
483 ierr = J->ReplaceGlobalValues(0, 1, &jac, &column);
486 ierr = J->ReplaceGlobalValues(0, 1, &jac, &column);
488 if (nonnull(M_inv)) {
491 ierr = M_inv->ReplaceGlobalValues(0, 1, &jac, &column);
494 ierr = M_inv->ReplaceGlobalValues(0, 1, &jac, &column);
501 if (nonnull(M_inv)) {
503 M_inv->ExtractDiagonalCopy(*J_diagonal_);
505 for (
int i=0; i < J_diagonal_->MyLength(); ++i)
506 (*J_diagonal_)[i] = 1.0 / ((*J_diagonal_)[i]);
508 M_inv->PutScalar(0.0);
509 M_inv->ReplaceDiagonalValues(*J_diagonal_);
510 M_inv->FillComplete();
513 TEUCHOS_ASSERT(ierr > -1);
546 if (gp==0) {
eta=-1.0/sqrt(3.0);
wt=1.0;}
547 if (gp==1) {
eta=1.0/sqrt(3.0);
wt=1.0;}
562 for (
int i=0; i < N; i++) {