• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

MOR_ReducedOrderModelEvaluator.cpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 #include "MOR_ReducedOrderModelEvaluator.hpp"
00007 
00008 #include "MOR_ReducedSpace.hpp"
00009 #include "MOR_ReducedOperatorFactory.hpp"
00010 
00011 #include "Epetra_Vector.h"
00012 #include "Epetra_CrsMatrix.h"
00013 
00014 #include "Teuchos_Tuple.hpp"
00015 #include "Teuchos_TestForException.hpp"
00016 
00017 namespace MOR {
00018 
00019 using Teuchos::RCP;
00020 using Teuchos::rcp;
00021 using Teuchos::rcp_dynamic_cast;
00022 using Teuchos::null;
00023 using Teuchos::is_null;
00024 using Teuchos::nonnull;
00025 using Teuchos::Tuple;
00026 using Teuchos::tuple;
00027 
00028 ReducedOrderModelEvaluator::ReducedOrderModelEvaluator(const RCP<EpetraExt::ModelEvaluator> &fullOrderModel,
00029                                                        const RCP<const ReducedSpace> &solutionSpace,
00030                                                        const RCP<ReducedOperatorFactory> &reducedOpFactory) :
00031   fullOrderModel_(fullOrderModel),
00032   solutionSpace_(solutionSpace),
00033   reducedOpFactory_(reducedOpFactory),
00034   x_init_(null),
00035   x_dot_init_(null)
00036 {
00037   reset_x_and_x_dot_init();
00038 }
00039 
00040 void ReducedOrderModelEvaluator::reset_x_and_x_dot_init()
00041 {
00042   reset_x_init();
00043   reset_x_dot_init();
00044 }
00045 
00046 void ReducedOrderModelEvaluator::reset_x_init()
00047 {
00048   if (nonnull(fullOrderModel_->get_x_init())) {
00049     x_init_ = solutionSpace_->reduction(*fullOrderModel_->get_x_init());
00050   } else {
00051     x_init_ = null;
00052   }
00053 }
00054 
00055 void ReducedOrderModelEvaluator::reset_x_dot_init()
00056 {
00057   if (nonnull(fullOrderModel_->get_x_dot_init())) {
00058     x_dot_init_ = solutionSpace_->linearReduction(*fullOrderModel_->get_x_dot_init());
00059   } else {
00060     x_dot_init_ = null;
00061   }
00062 }
00063 
00064 Teuchos::RCP<const EpetraExt::ModelEvaluator> ReducedOrderModelEvaluator::getFullOrderModel() const
00065 {
00066   return fullOrderModel_;
00067 }
00068 
00069 Teuchos::RCP<const ReducedSpace> ReducedOrderModelEvaluator::getSolutionSpace() const
00070 {
00071   return solutionSpace_;
00072 }
00073 
00074 const Epetra_Map &ReducedOrderModelEvaluator::componentMap() const
00075 {
00076   return solutionSpace_->componentMap();
00077 }
00078 
00079 RCP<const Epetra_Map> ReducedOrderModelEvaluator::componentMapRCP() const
00080 {
00081   // TODO more efficient
00082   return rcp(new Epetra_Map(this->componentMap()));
00083 }
00084 
00085 RCP<const Epetra_Map> ReducedOrderModelEvaluator::get_x_map() const
00086 {
00087   return componentMapRCP();
00088 }
00089 
00090 RCP<const Epetra_Map> ReducedOrderModelEvaluator::get_f_map() const
00091 {
00092   return componentMapRCP();
00093 }
00094 
00095 RCP<const Epetra_Map> ReducedOrderModelEvaluator::get_p_map(int l) const
00096 {
00097   return fullOrderModel_->get_p_map(l);
00098 }
00099 
00100 RCP<const Teuchos::Array<std::string> > ReducedOrderModelEvaluator::get_p_names(int l) const
00101 {
00102   return fullOrderModel_->get_p_names(l);
00103 }
00104 
00105 RCP<const Epetra_Map> ReducedOrderModelEvaluator::get_g_map(int j) const
00106 {
00107   return fullOrderModel_->get_g_map(j);
00108 }
00109 
00110 RCP<const Epetra_Vector> ReducedOrderModelEvaluator::get_x_init() const
00111 {
00112   return x_init_;
00113 }
00114 
00115 RCP<const Epetra_Vector> ReducedOrderModelEvaluator::get_x_dot_init() const
00116 {
00117   return x_dot_init_;
00118 }
00119 
00120 RCP<const Epetra_Vector> ReducedOrderModelEvaluator::get_p_init(int l) const
00121 {
00122   return fullOrderModel_->get_p_init(l);
00123 }
00124 
00125 double ReducedOrderModelEvaluator::get_t_init() const
00126 {
00127   return fullOrderModel_->get_t_init();
00128 }
00129 
00130 double ReducedOrderModelEvaluator::getInfBound() const
00131 {
00132   return fullOrderModel_->getInfBound();
00133 }
00134 
00135 RCP<const Epetra_Vector> ReducedOrderModelEvaluator::get_p_lower_bounds(int l) const
00136 {
00137   return fullOrderModel_->get_p_lower_bounds(l);
00138 }
00139 
00140 RCP<const Epetra_Vector> ReducedOrderModelEvaluator::get_p_upper_bounds(int l) const
00141 {
00142   return fullOrderModel_->get_p_upper_bounds(l);
00143 }
00144 
00145 double ReducedOrderModelEvaluator::get_t_lower_bound() const
00146 {
00147   return fullOrderModel_->get_t_lower_bound();
00148 }
00149 
00150 double ReducedOrderModelEvaluator::get_t_upper_bound() const
00151 {
00152   return fullOrderModel_->get_t_upper_bound();
00153 }
00154 
00155 RCP<Epetra_Operator> ReducedOrderModelEvaluator::create_W() const
00156 {
00157   const RCP<Epetra_Operator> fullOrderOperator = fullOrderModel_->create_W();
00158   if (is_null(fullOrderOperator)) {
00159     return null;
00160   }
00161 
00162   return reducedOpFactory_->reducedJacobianNew();
00163 }
00164 
00165 RCP<Epetra_Operator> ReducedOrderModelEvaluator::create_DgDp_op(int j, int l) const
00166 {
00167   return fullOrderModel_->create_DgDp_op(j, l);
00168 }
00169 
00170 EpetraExt::ModelEvaluator::InArgs ReducedOrderModelEvaluator::createInArgs() const
00171 {
00172   const InArgs fullInArgs = fullOrderModel_->createInArgs();
00173 
00174   InArgsSetup result;
00175 
00176   result.setModelEvalDescription("MOR applied to " + fullInArgs.modelEvalDescription());
00177 
00178   result.set_Np(fullInArgs.Np());
00179 
00180   // Requires underlying full order model to accept a state input
00181   TEUCHOS_TEST_FOR_EXCEPT(!fullInArgs.supports(IN_ARG_x));
00182   const Tuple<EInArgsMembers, 5> optionalMembers = tuple(IN_ARG_x, IN_ARG_x_dot, IN_ARG_t, IN_ARG_alpha, IN_ARG_beta);
00183   for (Tuple<EInArgsMembers, 5>::const_iterator it = optionalMembers.begin(); it != optionalMembers.end(); ++it) {
00184     const EInArgsMembers member = *it;
00185     result.setSupports(member, fullInArgs.supports(member));
00186   }
00187 
00188   return result;
00189 }
00190 
00191 EpetraExt::ModelEvaluator::OutArgs ReducedOrderModelEvaluator::createOutArgs() const
00192 {
00193   const OutArgs fullOutArgs = fullOrderModel_->createOutArgs();
00194 
00195   OutArgsSetup result;
00196 
00197   result.setModelEvalDescription("MOR applied to " + fullOutArgs.modelEvalDescription());
00198 
00199   result.set_Np_Ng(fullOutArgs.Np(), fullOutArgs.Ng());
00200 
00201   for (int j = 0; j < fullOutArgs.Ng(); ++j) {
00202     if (fullOutArgs.supports(OUT_ARG_DgDx, j).supports(DERIV_TRANS_MV_BY_ROW)) {
00203       result.setSupports(OUT_ARG_DgDx, j, DERIV_TRANS_MV_BY_ROW);
00204       result.set_DgDx_properties(j, fullOutArgs.get_DgDx_properties(j));
00205     }
00206   }
00207 
00208   for (int j = 0; j < fullOutArgs.Ng(); ++j) {
00209     if (fullOutArgs.supports(OUT_ARG_DgDx_dot, j).supports(DERIV_TRANS_MV_BY_ROW)) {
00210       result.setSupports(OUT_ARG_DgDx_dot, j, DERIV_TRANS_MV_BY_ROW);
00211       result.set_DgDx_dot_properties(j, fullOutArgs.get_DgDx_dot_properties(j));
00212     }
00213   }
00214 
00215   for (int l = 0; l < fullOutArgs.Np(); ++l) {
00216     if (fullOutArgs.supports(OUT_ARG_DfDp, l).supports(DERIV_MV_BY_COL)) {
00217       result.setSupports(OUT_ARG_DfDp, l, DERIV_MV_BY_COL);
00218       result.set_DfDp_properties(l, fullOutArgs.get_DfDp_properties(l));
00219     }
00220   }
00221 
00222   for (int j = 0; j < fullOutArgs.Ng(); ++j) {
00223     for (int l = 0; l < fullOutArgs.Np(); ++l) {
00224       result.setSupports(OUT_ARG_DgDp, j, l, fullOutArgs.supports(OUT_ARG_DgDp, j, l));
00225       result.set_DgDp_properties(j, l, fullOutArgs.get_DgDp_properties(j, l));
00226     }
00227   }
00228 
00229   const Tuple<EOutArgsMembers, 2> optionalMembers = tuple(OUT_ARG_f, OUT_ARG_W);
00230   for (Tuple<EOutArgsMembers, 2>::const_iterator it = optionalMembers.begin(); it != optionalMembers.end(); ++it) {
00231     const EOutArgsMembers member = *it;
00232     result.setSupports(member, fullOutArgs.supports(member));
00233   }
00234 
00235   result.set_W_properties(fullOutArgs.get_W_properties());
00236 
00237   return result;
00238 }
00239 
00240 void ReducedOrderModelEvaluator::evalModel(const InArgs &inArgs, const OutArgs &outArgs) const
00241 {
00242   // Copy arguments to be able to modify x and x_dot
00243   InArgs fullInArgs = fullOrderModel_->createInArgs();
00244   {
00245     // Copy untouched supported inArgs content
00246     if (fullInArgs.supports(IN_ARG_t))     fullInArgs.set_t(inArgs.get_t());
00247     if (fullInArgs.supports(IN_ARG_alpha)) fullInArgs.set_alpha(inArgs.get_alpha());
00248     if (fullInArgs.supports(IN_ARG_beta))  fullInArgs.set_beta(inArgs.get_beta());
00249     for (int l = 0; l < fullInArgs.Np(); ++l) {
00250       fullInArgs.set_p(l, inArgs.get_p(l));
00251     }
00252 
00253     // x <- basis * x_r + x_origin
00254     TEUCHOS_TEST_FOR_EXCEPT(is_null(inArgs.get_x()));
00255     fullInArgs.set_x(solutionSpace_->expansion(*inArgs.get_x()));
00256 
00257     // x_dot <- basis * x_dot_r
00258     if (inArgs.supports(IN_ARG_x_dot) && nonnull(inArgs.get_x_dot())) {
00259       fullInArgs.set_x_dot(solutionSpace_->linearExpansion(*inArgs.get_x_dot()));
00260     }
00261   }
00262 
00263   // Copy arguments to be able to modify f and W
00264   OutArgs fullOutArgs = fullOrderModel_->createOutArgs();
00265 
00266   const bool supportsResidual = fullOutArgs.supports(OUT_ARG_f);
00267   const bool requestedResidual = supportsResidual && nonnull(outArgs.get_f());
00268 
00269   const bool supportsJacobian = fullOutArgs.supports(OUT_ARG_W);
00270   const bool requestedJacobian = supportsJacobian && nonnull(outArgs.get_W());
00271 
00272   bool requestedAnyDfDp = false;
00273   for (int l = 0; l < outArgs.Np(); ++l) {
00274     const bool supportsDfDp = !outArgs.supports(OUT_ARG_DfDp, l).none();
00275     const bool requestedDfDp = supportsDfDp && (!outArgs.get_DfDp(l).isEmpty());
00276     if (requestedDfDp) {
00277       requestedAnyDfDp = true;
00278       break;
00279     }
00280   }
00281   const bool requestedProjection = requestedResidual || requestedAnyDfDp;
00282 
00283   const bool fullJacobianRequired =
00284     reducedOpFactory_->fullJacobianRequired(requestedProjection, requestedJacobian);
00285 
00286   {
00287     // Prepare forwarded outArgs content (g and DgDp)
00288     for (int j = 0; j < outArgs.Ng(); ++j) {
00289       fullOutArgs.set_g(j, outArgs.get_g(j));
00290       for (int l = 0; l < inArgs.Np(); ++l) {
00291         if (!outArgs.supports(OUT_ARG_DgDp, j, l).none()) {
00292           fullOutArgs.set_DgDp(j, l, outArgs.get_DgDp(j, l));
00293         }
00294       }
00295     }
00296 
00297     // Prepare reduced residual (f_r)
00298     if (requestedResidual) {
00299       const Evaluation<Epetra_Vector> f_r = outArgs.get_f();
00300       const Evaluation<Epetra_Vector> f(
00301           rcp(new Epetra_Vector(*fullOrderModel_->get_f_map(), false)),
00302           f_r.getType());
00303       fullOutArgs.set_f(f);
00304     }
00305 
00306     if (fullJacobianRequired) {
00307       fullOutArgs.set_W(fullOrderModel_->create_W());
00308     }
00309 
00310     // Prepare reduced sensitivities DgDx_r (Only mv with gradient orientation is supported)
00311     for (int j = 0; j < outArgs.Ng(); ++j) {
00312       if (!outArgs.supports(OUT_ARG_DgDx, j).none()) {
00313         TEUCHOS_ASSERT(outArgs.supports(OUT_ARG_DgDx, j).supports(DERIV_TRANS_MV_BY_ROW));
00314         if (!outArgs.get_DgDx(j).isEmpty()) {
00315           TEUCHOS_ASSERT(
00316               nonnull(outArgs.get_DgDx(j).getMultiVector()) &&
00317               outArgs.get_DgDx(j).getMultiVectorOrientation() == DERIV_TRANS_MV_BY_ROW);
00318           const int g_size = fullOrderModel_->get_g_map(j)->NumGlobalElements();
00319           const RCP<Epetra_MultiVector> full_dgdx_mv = rcp(
00320               new Epetra_MultiVector(*fullOrderModel_->get_x_map(), g_size, false));
00321           const Derivative full_dgdx_deriv(full_dgdx_mv, DERIV_TRANS_MV_BY_ROW);
00322           fullOutArgs.set_DgDx(j, full_dgdx_deriv);
00323         }
00324       }
00325     }
00326 
00327     // Prepare reduced sensitivities DgDx_dot_r (Only mv with gradient orientation is supported)
00328     for (int j = 0; j < outArgs.Ng(); ++j) {
00329       if (!outArgs.supports(OUT_ARG_DgDx_dot, j).none()) {
00330         TEUCHOS_ASSERT(outArgs.supports(OUT_ARG_DgDx_dot, j).supports(DERIV_TRANS_MV_BY_ROW));
00331         if (!outArgs.get_DgDx_dot(j).isEmpty()) {
00332           TEUCHOS_ASSERT(
00333               nonnull(outArgs.get_DgDx_dot(j).getMultiVector()) &&
00334               outArgs.get_DgDx_dot(j).getMultiVectorOrientation() == DERIV_TRANS_MV_BY_ROW);
00335           const int g_size = fullOrderModel_->get_g_map(j)->NumGlobalElements();
00336           const RCP<Epetra_MultiVector> full_dgdx_dot_mv = rcp(
00337               new Epetra_MultiVector(*fullOrderModel_->get_x_map(), g_size, false));
00338           const Derivative full_dgdx_dot_deriv(full_dgdx_dot_mv, DERIV_TRANS_MV_BY_ROW);
00339           fullOutArgs.set_DgDx_dot(j, full_dgdx_dot_deriv);
00340         }
00341       }
00342     }
00343 
00344     // Prepare reduced sensitivities DfDp_r (Only mv with jacobian orientation is supported)
00345     for (int l = 0; l < outArgs.Np(); ++l) {
00346       if (!outArgs.supports(OUT_ARG_DfDp, l).none()) {
00347         TEUCHOS_ASSERT(outArgs.supports(OUT_ARG_DfDp, l).supports(DERIV_MV_BY_COL));
00348         if (!outArgs.get_DfDp(l).isEmpty()) {
00349           TEUCHOS_ASSERT(
00350               nonnull(outArgs.get_DfDp(l).getMultiVector()) &&
00351               outArgs.get_DfDp(l).getMultiVectorOrientation() == DERIV_MV_BY_COL);
00352           const int p_size = fullOrderModel_->get_p_map(l)->NumGlobalElements();
00353           const RCP<Epetra_MultiVector> full_dfdp_mv = rcp(
00354               new Epetra_MultiVector(*fullOrderModel_->get_f_map(), p_size, false));
00355           const Derivative full_dfdp_deriv(full_dfdp_mv, DERIV_MV_BY_COL);
00356           fullOutArgs.set_DfDp(l, full_dfdp_deriv);
00357         }
00358       }
00359     }
00360   }
00361 
00362   // (f, W) <- fullOrderModel(x, x_dot, ...)
00363   fullOrderModel_->evalModel(fullInArgs, fullOutArgs);
00364 
00365   // (W * basis, W_r) <- W
00366   if (fullJacobianRequired) {
00367     reducedOpFactory_->fullJacobianIs(*fullOutArgs.get_W());
00368   }
00369 
00370   // f_r <- leftBasis^T * f
00371   if (requestedResidual) {
00372     reducedOpFactory_->leftProjection(*fullOutArgs.get_f(), *outArgs.get_f());
00373   }
00374 
00375   // Wr <- leftBasis^T * W * basis
00376   if (requestedJacobian) {
00377     const RCP<Epetra_CrsMatrix> W_r = rcp_dynamic_cast<Epetra_CrsMatrix>(outArgs.get_W());
00378     TEUCHOS_TEST_FOR_EXCEPT(is_null((W_r)));
00379     reducedOpFactory_->reducedJacobian(*W_r);
00380   }
00381 
00382   // (DgDx_r)^T <- basis^T * (DgDx)^T
00383   for (int j = 0; j < outArgs.Ng(); ++j) {
00384     if (!outArgs.supports(OUT_ARG_DgDx, j).none()) {
00385       const RCP<Epetra_MultiVector> dgdx_r_mv = outArgs.get_DgDx(j).getMultiVector();
00386       if (nonnull(dgdx_r_mv)) {
00387         const RCP<const Epetra_MultiVector> full_dgdx_mv = fullOutArgs.get_DgDx(j).getMultiVector();
00388         solutionSpace_->linearReduction(*full_dgdx_mv, *dgdx_r_mv);
00389       }
00390     }
00391   }
00392 
00393   // (DgDx_dot_r)^T <- basis^T * (DgDx_dot)^T
00394   for (int j = 0; j < outArgs.Ng(); ++j) {
00395     if (!outArgs.supports(OUT_ARG_DgDx_dot, j).none()) {
00396       const RCP<Epetra_MultiVector> dgdx_dot_r_mv = outArgs.get_DgDx_dot(j).getMultiVector();
00397       if (nonnull(dgdx_dot_r_mv)) {
00398         const RCP<const Epetra_MultiVector> full_dgdx_dot_mv = fullOutArgs.get_DgDx_dot(j).getMultiVector();
00399         solutionSpace_->linearReduction(*full_dgdx_dot_mv, *dgdx_dot_r_mv);
00400       }
00401     }
00402   }
00403 
00404   // DfDp_r <- leftBasis^T * DfDp
00405   for (int l = 0; l < outArgs.Np(); ++l) {
00406     if (!outArgs.supports(OUT_ARG_DfDp, l).none()) {
00407       const RCP<Epetra_MultiVector> dfdp_r_mv = outArgs.get_DfDp(l).getMultiVector();
00408       if (nonnull(dfdp_r_mv)) {
00409         const RCP<const Epetra_MultiVector> full_dfdp_mv = fullOutArgs.get_DfDp(l).getMultiVector();
00410         reducedOpFactory_->leftProjection(*full_dfdp_mv, *dfdp_r_mv);
00411       }
00412     }
00413   }
00414 }
00415 
00416 } // namespace MOR

Generated on Wed Mar 26 2014 18:36:40 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1