46 #include "EpetraExt_BlockUtility.h"
47 #include "EpetraExt_BlockMultiVector.h"
59 num_mp_blocks(mp_block_map_->NumMyElements()),
61 mp_block_map(mp_block_map_),
64 x_map(me->get_x_map()),
65 f_map(me->get_f_map()),
82 if (
x_map != Teuchos::null)
104 if (
me->get_x_dot_init() != Teuchos::null) {
121 InArgs me_inargs =
me->createInArgs();
122 num_p = me_inargs.Np();
125 for (
int i=0; i<
num_p; i++) {
126 if (me_inargs.supports(IN_ARG_p_mp, i))
144 if (p_names != Teuchos::null) {
147 for (
int j=0;
j<p_names->size();
j++) {
148 std::stringstream ss;
149 ss << (*p_names)[
j] <<
" -- MP Coefficient " << i;
168 OutArgs me_outargs =
me->createOutArgs();
169 num_g = me_outargs.Ng();
172 for (
int i=0; i<
num_g; i++) {
173 if (me_outargs.supports(OUT_ARG_g_mp, i))
207 "Error! Invalid p map index " << l);
209 return me->get_p_map(l);
211 return mp_p_map[l-num_p];
213 return Teuchos::null;
220 "Error! Invalid g map index " <<
j);
228 "Error! Invalid p map index " << l);
230 return me->get_p_names(l);
232 return mp_p_names[l-num_p];
234 return Teuchos::null;
240 return mp_x_init->getBlockVector();
246 return mp_x_dot_init->getBlockVector();
253 "Error! Invalid p map index " << l);
255 return me->get_p_init(l);
256 else if (l < num_p + num_p_mp)
257 return mp_p_init[l-num_p]->getBlockVector();
259 return Teuchos::null;
269 mp_x_map, mp_f_map));
270 my_W->setupOperator(W_mp_blocks);
275 return Teuchos::null;
283 Teuchos::rcp(&(params->sublist(
"MP Preconditioner")),
false);
286 mp_prec_factory.
build(mp_comm, num_mp_blocks, x_map, mp_x_map);
287 return Teuchos::rcp(
new EpetraExt::ModelEvaluator::Preconditioner(precOp,
291 return Teuchos::null;
299 "Error: dg/dx index " <<
j <<
" is not supported!");
301 int jj = mp_g_index_map[
j];
304 OutArgs me_outargs = me->createOutArgs();
305 DerivativeSupport ds = me_outargs.supports(OUT_ARG_DgDx_mp, jj);
306 if (ds.supports(DERIV_LINEAR_OP)) {
309 mp_block_map, x_map, g_map, mp_g_map[
j], mp_comm));
310 for (
unsigned int i=0; i<num_mp_blocks; i++)
313 else if (ds.supports(DERIV_MV_BY_COL)) {
316 mp_block_map, g_map, mp_g_map[
j],
320 mp_mv_blocks,
false));
322 else if (ds.supports(DERIV_TRANS_MV_BY_ROW)) {
325 mp_block_map, x_map, mp_x_map,
329 mp_mv_blocks,
true));
333 "Error! me_outargs.supports(OUT_ARG_DgDx_mp, " <<
j
334 <<
").none() is true!");
338 mp_comm, num_mp_blocks, x_map, g_map,
339 mp_x_map, mp_g_map[
j]));
349 "Error: dg/dx_dot index " <<
j <<
" is not supported!");
351 int jj = mp_g_index_map[
j];
354 OutArgs me_outargs = me->createOutArgs();
355 DerivativeSupport ds = me_outargs.supports(OUT_ARG_DgDx_dot_mp, jj);
356 if (ds.supports(DERIV_LINEAR_OP)) {
359 mp_block_map, x_map, g_map, mp_g_map[
j],
361 for (
unsigned int i=0; i<num_mp_blocks; i++)
362 mp_blocks->
setCoeffPtr(i, me->create_DgDx_dot_op(jj));
364 else if (ds.supports(DERIV_MV_BY_COL)) {
367 mp_block_map, g_map, mp_g_map[
j],
371 mp_mv_blocks,
false));
373 else if (ds.supports(DERIV_TRANS_MV_BY_ROW)) {
376 mp_block_map, x_map, mp_x_map,
380 mp_mv_blocks,
true));
384 "Error! me_outargs.supports(OUT_ARG_DgDx_dot_mp, "
385 <<
j <<
").none() is true!");
389 mp_comm, num_mp_blocks, x_map, g_map,
390 mp_x_map, mp_g_map[
j]));
399 j < 0 || j >= num_g_mp || i < 0 || i >= num_p+num_p_mp,
401 "Error: dg/dp index " <<
j <<
"," << i <<
" is not supported!");
403 OutArgs me_outargs = me->createOutArgs();
404 int jj = mp_g_index_map[
j];
407 if (me_outargs.supports(OUT_ARG_DgDp_mp,jj,i).supports(DERIV_LINEAR_OP)) {
410 mp_block_map, me->get_p_map(i), g_map,
411 mp_g_map[
j], mp_comm));
412 for (
unsigned int l=0; l<num_mp_blocks; l++)
418 true, std::logic_error,
419 "Error: Underlying model evaluator must support DERIV_LINER_OP " <<
420 "to create operator for dg/dp index " <<
j <<
"," << i <<
"!");
423 int ii = mp_p_index_map[i-num_p];
426 DerivativeSupport ds = me_outargs.supports(OUT_ARG_DgDp_mp,jj,ii);
427 if (ds.supports(DERIV_LINEAR_OP)) {
430 mp_block_map, p_map, g_map,
431 mp_g_map[
j], mp_comm));
432 for (
unsigned int l=0; l<num_mp_blocks; l++)
433 mp_blocks->
setCoeffPtr(l, me->create_DgDp_op(jj,ii));
435 else if (ds.supports(DERIV_MV_BY_COL)) {
438 mp_block_map, g_map, mp_g_map[
j],
442 mp_mv_blocks,
false));
444 else if (ds.supports(DERIV_TRANS_MV_BY_ROW)) {
447 mp_block_map, p_map, mp_p_map[i-num_p],
451 mp_mv_blocks,
true));
455 "Error! me_outargs.supports(OUT_ARG_DgDp_mp, " << jj
456 <<
"," << ii <<
").none() is true!");
460 mp_comm, num_mp_blocks, p_map, g_map,
461 mp_p_map[i-num_p], mp_g_map[
j]));
466 return Teuchos::null;
474 "Error: df/dp index " << i <<
" is not supported!");
476 OutArgs me_outargs = me->createOutArgs();
478 if (me_outargs.supports(OUT_ARG_DfDp_mp,i).supports(DERIV_LINEAR_OP)) {
481 mp_block_map, me->get_p_map(i), me->get_f_map(),
483 for (
unsigned int l=0; l<num_mp_blocks; l++)
489 true, std::logic_error,
490 "Error: Underlying model evaluator must support DERIV_LINER_OP " <<
491 "to create operator for df/dp index " << i <<
"!");
494 int ii = mp_p_index_map[i-num_p];
497 DerivativeSupport ds = me_outargs.supports(OUT_ARG_DfDp_mp,ii);
498 if (ds.supports(DERIV_LINEAR_OP)) {
501 mp_block_map, me->get_p_map(ii), me->get_f_map(),
503 for (
unsigned int l=0; l<num_mp_blocks; l++)
506 else if (ds.supports(DERIV_MV_BY_COL)) {
509 mp_block_map, f_map, mp_f_map,
513 mp_mv_blocks,
false));
515 else if (ds.supports(DERIV_TRANS_MV_BY_ROW)) {
518 mp_block_map, p_map, mp_p_map[i-num_p],
522 mp_mv_blocks,
true));
526 "Error! me_outargs.supports(OUT_ARG_DfDp_mp, " << ii
527 <<
").none() is true!");
532 mp_comm, num_mp_blocks,
533 p_map, f_map, mp_p_map[i-num_p], mp_f_map));
538 return Teuchos::null;
541 EpetraExt::ModelEvaluator::InArgs
545 InArgs me_inargs = me->createInArgs();
547 inArgs.setModelEvalDescription(this->description());
548 inArgs.set_Np(num_p + num_p_mp);
549 inArgs.setSupports(IN_ARG_x_dot, me_inargs.supports(IN_ARG_x_dot));
550 inArgs.setSupports(IN_ARG_x, me_inargs.supports(IN_ARG_x));
551 inArgs.setSupports(IN_ARG_t, me_inargs.supports(IN_ARG_t));
552 inArgs.setSupports(IN_ARG_alpha, me_inargs.supports(IN_ARG_alpha));
553 inArgs.setSupports(IN_ARG_beta, me_inargs.supports(IN_ARG_beta));
558 EpetraExt::ModelEvaluator::OutArgs
561 OutArgsSetup outArgs;
562 OutArgs me_outargs = me->createOutArgs();
564 outArgs.setModelEvalDescription(this->description());
565 outArgs.set_Np_Ng(num_p + num_p_mp, num_g_mp);
566 outArgs.setSupports(OUT_ARG_f, me_outargs.supports(OUT_ARG_f));
567 outArgs.setSupports(OUT_ARG_W, me_outargs.supports(OUT_ARG_W));
568 outArgs.setSupports(OUT_ARG_WPrec, me_outargs.supports(OUT_ARG_W));
569 for (
int j=0;
j<num_p;
j++)
570 outArgs.setSupports(OUT_ARG_DfDp,
j,
571 me_outargs.supports(OUT_ARG_DfDp,
j));
572 for (
int j=0;
j<num_p_mp;
j++)
573 if (!me_outargs.supports(OUT_ARG_DfDp_mp, mp_p_index_map[
j]).none())
574 outArgs.setSupports(OUT_ARG_DfDp,
j+num_p, DERIV_LINEAR_OP);
575 for (
int i=0; i<num_g_mp; i++) {
576 int ii = mp_g_index_map[i];
577 if (!me_outargs.supports(OUT_ARG_DgDx_dot_mp, ii).none())
578 outArgs.setSupports(OUT_ARG_DgDx_dot, i, DERIV_LINEAR_OP);
579 if (!me_outargs.supports(OUT_ARG_DgDx_mp, ii).none())
580 outArgs.setSupports(OUT_ARG_DgDx, i, DERIV_LINEAR_OP);
581 for (
int j=0;
j<num_p;
j++)
582 outArgs.setSupports(OUT_ARG_DgDp, i,
j,
583 me_outargs.supports(OUT_ARG_DgDp_mp, ii,
j));
584 for (
int j=0;
j<num_p_mp;
j++)
585 if (!me_outargs.supports(OUT_ARG_DgDp_mp, ii, mp_p_index_map[
j]).none())
586 outArgs.setSupports(OUT_ARG_DgDp, i,
j+num_p, DERIV_LINEAR_OP);
594 const OutArgs& outArgs)
const
598 if (inArgs.supports(IN_ARG_x)) {
600 if (
x != Teuchos::null)
604 if (inArgs.supports(IN_ARG_x_dot))
605 x_dot = inArgs.get_x_dot();
608 EpetraExt::ModelEvaluator::Evaluation<Epetra_Vector> f_out;
609 if (outArgs.supports(OUT_ARG_f))
610 f_out = outArgs.get_f();
612 if (outArgs.supports(OUT_ARG_W))
613 W_out = outArgs.get_W();
615 if (outArgs.supports(OUT_ARG_WPrec))
616 WPrec_out = outArgs.get_WPrec();
620 bool eval_prec = (W_out == Teuchos::null && WPrec_out != Teuchos::null);
627 Teuchos::rcp_dynamic_cast<Stokhos::MPPreconditioner>(WPrec_out,
true);
631 bool done = (f_out == Teuchos::null);
632 for (
int i=0; i<outArgs.Ng(); i++) {
633 done = done && (outArgs.get_g(i) == Teuchos::null);
634 for (
int j=0;
j<outArgs.Np();
j++)
635 if (!outArgs.supports(OUT_ARG_DgDp, i,
j).none())
636 done = done && (outArgs.get_DgDp(i,
j).isEmpty());
643 InArgs me_inargs = me->createInArgs();
644 if (
x != Teuchos::null) {
646 create_x_mp(
View,
x.get());
647 me_inargs.set_x_mp(x_mp);
649 if (x_dot != Teuchos::null) {
651 create_x_mp(
View, x_dot.
get());
652 me_inargs.set_x_dot_mp(x_dot_mp);
654 if (me_inargs.supports(IN_ARG_alpha))
655 me_inargs.set_alpha(inArgs.get_alpha());
656 if (me_inargs.supports(IN_ARG_beta))
657 me_inargs.set_beta(inArgs.get_beta());
658 if (me_inargs.supports(IN_ARG_t))
659 me_inargs.set_t(inArgs.get_t());
662 for (
int i=0; i<num_p; i++)
663 me_inargs.set_p(i, inArgs.get_p(i));
664 for (
int i=0; i<num_p_mp; i++) {
669 if (p == Teuchos::null)
670 p = mp_p_init[i]->getBlockVector();
674 create_p_mp(mp_p_index_map[i],
View, p.
get());
675 me_inargs.set_p_mp(mp_p_index_map[i], p_mp);
679 OutArgs me_outargs = me->createOutArgs();
682 if (f_out != Teuchos::null) {
684 create_f_mp(
View, f_out.get());
685 me_outargs.set_f_mp(f_mp);
689 if (W_out != Teuchos::null && !eval_prec)
690 me_outargs.set_W_mp(W_mp_blocks);
693 for (
int i=0; i<num_p; i++) {
694 if (!outArgs.supports(OUT_ARG_DfDp, i).none()) {
695 Derivative dfdp = outArgs.get_DfDp(i);
696 if (dfdp.getMultiVector() != Teuchos::null) {
698 if (dfdp.getMultiVectorOrientation() == DERIV_MV_BY_COL)
701 mp_block_map, me->get_f_map(), mp_f_map, mp_comm,
702 View, *(dfdp.getMultiVector())));
703 else if (dfdp.getMultiVectorOrientation() == DERIV_TRANS_MV_BY_ROW)
706 mp_block_map, me->get_p_map(i), mp_p_map[i], mp_comm,
707 View, *(dfdp.getMultiVector())));
708 me_outargs.set_DfDp_mp(i,
709 MPDerivative(dfdp_mp,
710 dfdp.getMultiVectorOrientation()));
712 else if (dfdp.getLinearOp() != Teuchos::null) {
714 Teuchos::rcp_dynamic_cast<Stokhos::ProductEpetraOperator>(dfdp.getLinearOp(),
true);
715 me_outargs.set_DfDp_mp(i, MPDerivative(dfdp_mp));
721 for (
int i=0; i<num_p_mp; i++) {
722 if (!outArgs.supports(OUT_ARG_DfDp, i+num_p).none()) {
723 Derivative dfdp = outArgs.get_DfDp(i+num_p);
724 if (dfdp.getLinearOp() != Teuchos::null) {
726 Teuchos::rcp_dynamic_cast<Stokhos::BlockDiagonalOperator>(dfdp.getLinearOp(),
true);
729 int ii = mp_p_index_map[i];
730 if (me_outargs.supports(OUT_ARG_DfDp_mp,ii).supports(DERIV_LINEAR_OP))
731 me_outargs.set_DfDp_mp(ii, MPDerivative(dfdp_op_mp));
734 Teuchos::rcp_dynamic_cast<Stokhos::ProductEpetraMultiVectorOperator>(dfdp_op_mp,
true);
737 if (me_outargs.supports(OUT_ARG_DfDp_mp,ii).supports(DERIV_MV_BY_COL))
738 me_outargs.set_DfDp_mp(
739 ii, MPDerivative(dfdp_mp, DERIV_MV_BY_COL));
741 me_outargs.set_DfDp_mp(
742 ii, MPDerivative(dfdp_mp, DERIV_TRANS_MV_BY_ROW));
746 dfdp.getLinearOp() == Teuchos::null && dfdp.isEmpty() ==
false,
748 "Error! Stokhos::MPModelEvaluator::evalModel: " <<
749 "Operator form of df/dp(" << i+num_p <<
") is required!");
754 for (
int i=0; i<num_g_mp; i++) {
755 int ii = mp_g_index_map[i];
759 if (
g != Teuchos::null) {
761 create_g_mp(ii,
View,
g.get());
762 me_outargs.set_g_mp(ii, g_mp);
766 if (outArgs.supports(OUT_ARG_DgDx_dot, i).supports(DERIV_LINEAR_OP)) {
767 Derivative dgdx_dot = outArgs.get_DgDx_dot(i);
768 if (dgdx_dot.getLinearOp() != Teuchos::null) {
770 Teuchos::rcp_dynamic_cast<Stokhos::BlockDiagonalOperator>(
771 dgdx_dot.getLinearOp(),
true);
774 if (me_outargs.supports(OUT_ARG_DgDx, ii).supports(DERIV_LINEAR_OP))
775 me_outargs.set_DgDx_dot_mp(ii, mp_blocks);
778 Teuchos::rcp_dynamic_cast<Stokhos::ProductEpetraMultiVectorOperator>(mp_blocks,
true);
781 if (me_outargs.supports(OUT_ARG_DgDx_dot_mp, ii).supports(DERIV_MV_BY_COL))
782 me_outargs.set_DgDx_dot_mp(ii, MPDerivative(dgdx_dot_mp,
785 me_outargs.set_DgDx_dot_mp(ii, MPDerivative(dgdx_dot_mp,
786 DERIV_TRANS_MV_BY_ROW));
790 dgdx_dot.isEmpty() ==
false,
792 "Error! Stokhos::MPModelEvaluator::evalModel: " <<
793 "Operator form of dg/dxdot is required!");
797 if (outArgs.supports(OUT_ARG_DgDx, i).supports(DERIV_LINEAR_OP)) {
798 Derivative dgdx = outArgs.get_DgDx(i);
799 if (dgdx.getLinearOp() != Teuchos::null) {
801 Teuchos::rcp_dynamic_cast<Stokhos::BlockDiagonalOperator>(
802 dgdx.getLinearOp(),
true);
805 if (me_outargs.supports(OUT_ARG_DgDx, ii).supports(DERIV_LINEAR_OP))
806 me_outargs.set_DgDx_mp(ii, mp_blocks);
809 Teuchos::rcp_dynamic_cast<Stokhos::ProductEpetraMultiVectorOperator>(mp_blocks,
true);
812 if (me_outargs.supports(OUT_ARG_DgDx_mp, ii).supports(DERIV_MV_BY_COL))
813 me_outargs.set_DgDx_mp(ii, MPDerivative(dgdx_mp,
816 me_outargs.set_DgDx_mp(ii, MPDerivative(dgdx_mp,
817 DERIV_TRANS_MV_BY_ROW));
821 dgdx.isEmpty() ==
false,
823 "Error! Stokhos::MPModelEvaluator::evalModel: " <<
824 "Operator form of dg/dxdot is required!");
828 for (
int j=0;
j<num_p;
j++) {
829 if (!outArgs.supports(OUT_ARG_DgDp, i,
j).none()) {
830 Derivative dgdp = outArgs.get_DgDp(i,
j);
831 if (dgdp.getMultiVector() != Teuchos::null) {
833 if (dgdp.getMultiVectorOrientation() == DERIV_MV_BY_COL)
836 mp_block_map, me->get_g_map(ii), mp_g_map[i],
837 mp_comm,
View, *(dgdp.getMultiVector())));
838 else if (dgdp.getMultiVectorOrientation() == DERIV_TRANS_MV_BY_ROW)
841 mp_block_map, me->get_p_map(
j), mp_p_map[
j],
842 mp_comm,
View, *(dgdp.getMultiVector())));
843 me_outargs.set_DgDp_mp(
844 ii,
j, MPDerivative(dgdp_mp, dgdp.getMultiVectorOrientation()));
846 else if (dgdp.getLinearOp() != Teuchos::null) {
848 Teuchos::rcp_dynamic_cast<Stokhos::ProductEpetraOperator>(dgdp.getLinearOp(),
true);
849 me_outargs.set_DgDp_mp(ii,
j, MPDerivative(dgdp_mp));
855 for (
int j=0;
j<num_p_mp;
j++) {
856 if (!outArgs.supports(OUT_ARG_DgDp, i,
j+num_p).none()) {
857 Derivative dgdp = outArgs.get_DgDp(i,
j+num_p);
858 if (dgdp.getLinearOp() != Teuchos::null) {
860 Teuchos::rcp_dynamic_cast<Stokhos::BlockDiagonalOperator>(dgdp.getLinearOp(),
true);
863 int jj = mp_p_index_map[
j];
864 if (me_outargs.supports(OUT_ARG_DgDp_mp,ii,jj).supports(DERIV_LINEAR_OP))
865 me_outargs.set_DgDp_mp(ii, jj, MPDerivative(dgdp_op_mp));
868 Teuchos::rcp_dynamic_cast<Stokhos::ProductEpetraMultiVectorOperator>(dgdp_op_mp,
true);
871 if (me_outargs.supports(OUT_ARG_DgDp_mp,ii,jj).supports(DERIV_MV_BY_COL))
872 me_outargs.set_DgDp_mp(
873 ii, jj, MPDerivative(dgdp_mp, DERIV_MV_BY_COL));
875 me_outargs.set_DgDp_mp(
876 ii, jj, MPDerivative(dgdp_mp, DERIV_TRANS_MV_BY_ROW));
880 dgdp.getLinearOp() == Teuchos::null && dgdp.isEmpty() ==
false,
882 "Error! Stokhos::MPModelEvaluator::evalModel: " <<
883 "Operator form of dg/dp(" << i <<
"," <<
j+num_p <<
") is required!");
890 me->evalModel(me_inargs, me_outargs);
893 if (W_out != Teuchos::null && !eval_prec) {
895 if (W_out != Teuchos::null)
900 Teuchos::rcp_dynamic_cast<Stokhos::BlockDiagonalOperator>(W,
true);
903 if (WPrec_out != Teuchos::null) {
905 Teuchos::rcp_dynamic_cast<Stokhos::MPPreconditioner>(WPrec_out,
true);
915 *mp_x_init = x_mp_in;
922 *mp_x_dot_init = x_dot_mp_in;
934 return mp_x_dot_init;
942 mp_p_index_map.end(),
945 "Error! Invalid p map index " << i);
946 int ii = it - mp_p_index_map.
begin();
947 *mp_p_init[ii] = p_mp_in;
954 mp_p_index_map.end(),
957 "Error! Invalid p map index " << l);
958 int ll = it - mp_p_index_map.
begin();
959 return mp_p_init[ll];
965 return mp_p_index_map;
971 return mp_g_index_map;
978 for (
int i=0; i<num_g; i++)
979 base_maps[i] = me->get_g_map(i);
990 mp_block_map, x_map, mp_x_map, mp_comm));
993 mp_block_map, x_map, mp_x_map, mp_comm,
1005 mp_block_map, x_map, mp_x_map, mp_comm,
1009 mp_block_map, x_map, mp_x_map, mp_comm,
1020 mp_p_index_map.end(),
1023 "Error! Invalid p map index " << l);
1024 int ll = it - mp_p_index_map.
begin();
1027 mp_block_map, me->get_p_map(l),
1028 mp_p_map[ll], mp_comm));
1031 mp_block_map, me->get_p_map(l),
1032 mp_p_map[ll], mp_comm, CV, *v));
1043 mp_p_index_map.end(),
1046 "Error! Invalid p map index " << l);
1047 int ll = it - mp_p_index_map.
begin();
1050 mp_block_map, me->get_p_map(l),
1051 mp_p_map[ll], mp_comm, num_vecs));
1054 mp_block_map, me->get_p_map(l),
1055 mp_p_map[ll], mp_comm, CV, *v));
1066 mp_block_map, f_map, mp_f_map, mp_comm));
1069 mp_block_map, f_map, mp_f_map, mp_comm,
1083 mp_block_map, f_map, mp_f_map, mp_comm,
1087 mp_block_map, f_map, mp_f_map, mp_comm,
1098 mp_g_index_map.end(),
1101 "Error! Invalid g map index " << l);
1102 int ll = it - mp_g_index_map.
begin();
1107 mp_g_map[ll], mp_comm));
1112 mp_g_map[ll], mp_comm, CV, *v));
1123 mp_g_index_map.end(),
1126 "Error! Invalid g map index " << l);
1127 int ll = it - mp_g_index_map.
begin();
1132 mp_g_map[ll], mp_comm, num_vecs));
1137 mp_g_map[ll], mp_comm, CV, *v));