00001
00002
00003
00004
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
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
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
00243 InArgs fullInArgs = fullOrderModel_->createInArgs();
00244 {
00245
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
00254 TEUCHOS_TEST_FOR_EXCEPT(is_null(inArgs.get_x()));
00255 fullInArgs.set_x(solutionSpace_->expansion(*inArgs.get_x()));
00256
00257
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
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
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
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
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
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
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
00363 fullOrderModel_->evalModel(fullInArgs, fullOutArgs);
00364
00365
00366 if (fullJacobianRequired) {
00367 reducedOpFactory_->fullJacobianIs(*fullOutArgs.get_W());
00368 }
00369
00370
00371 if (requestedResidual) {
00372 reducedOpFactory_->leftProjection(*fullOutArgs.get_f(), *outArgs.get_f());
00373 }
00374
00375
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
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
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
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 }