00001 #include "GLpApp_AdvDiffReactOptModel.hpp"
00002 #include "Epetra_SerialComm.h"
00003 #include "Epetra_CrsMatrix.h"
00004 #include "Teuchos_ScalarTraits.hpp"
00005 #include "Teuchos_VerboseObject.hpp"
00006 #include "Teuchos_TimeMonitor.hpp"
00007
00008 #ifdef HAVE_EPETRAEXT_THYRA
00009
00010 #include "sillyModifiedGramSchmidt.hpp"
00011 #include "Thyra_EpetraThyraWrappers.hpp"
00012 #include "Thyra_MultiVectorStdOps.hpp"
00013 #include "Thyra_SpmdVectorSpaceBase.hpp"
00014 #endif // HAVE_EPETRAEXT_THYRA
00015
00016
00017
00018 namespace {
00019
00020 Teuchos::RefCountPtr<Teuchos::Time>
00021 initalizationTimer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Init"),
00022 evalTimer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval"),
00023 p_bar_Timer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval:p_bar"),
00024 R_p_bar_Timer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval:R_p_bar"),
00025 f_Timer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval:f"),
00026 g_Timer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval:g"),
00027 W_Timer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval:W"),
00028 DfDp_Timer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval:DfDp"),
00029 DgDx_Timer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval:DgDx"),
00030 DgDp_Timer = Teuchos::TimeMonitor::getNewTimer("AdvDiffReact:Eval:DgDp");
00031
00032 inline double sqr( const double& s ) { return s*s; }
00033
00034 inline double dot( const Epetra_Vector &x, const Epetra_Vector &y )
00035 {
00036 double dot[1];
00037 x.Dot(y,dot);
00038 return dot[0];
00039 }
00040
00041 }
00042
00043 namespace GLpApp {
00044
00045 AdvDiffReactOptModel::AdvDiffReactOptModel(
00046 const Teuchos::RefCountPtr<const Epetra_Comm> &comm
00047 ,const double beta
00048 ,const double len_x
00049 ,const double len_y
00050 ,const int local_nx
00051 ,const int local_ny
00052 ,const char meshFile[]
00053 ,const int np
00054 ,const double x0
00055 ,const double p0
00056 ,const double reactionRate
00057 ,const bool normalizeBasis
00058 )
00059 :np_(np)
00060 {
00061 Teuchos::TimeMonitor initalizationTimerMonitor(*initalizationTimer);
00062 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00063 Teuchos::RefCountPtr<Teuchos::FancyOStream>
00064 out = Teuchos::VerboseObjectBase::getDefaultOStream();
00065 Teuchos::OSTab tab(out);
00066 *out << "\nEntering AdvDiffReactOptModel::AdvDiffReactOptModel(...) ...\n";
00067 #endif
00068
00069
00070
00071 dat_ = Teuchos::rcp(new GLpApp::GLpYUEpetraDataPool(comm,beta,len_x,len_y,local_nx,local_ny,meshFile,false));
00072
00073
00074
00075 map_x_ = Teuchos::rcp(new Epetra_Map(dat_->getA()->OperatorDomainMap()));
00076 map_p_.resize(Np_);
00077 map_p_[p_rx_idx] = Teuchos::rcp(new Epetra_Map(1,1,0,*comm));
00078 map_p_bar_ = Teuchos::rcp(new Epetra_Map(dat_->getB()->OperatorDomainMap()));
00079 map_f_ = Teuchos::rcp(new Epetra_Map(dat_->getA()->OperatorRangeMap()));
00080 map_g_ = Teuchos::rcp(new Epetra_Map(1,1,0,*comm));
00081
00082
00083
00084 if( np_ > 0 ) {
00085
00086
00087
00088 const Epetra_SerialDenseMatrix &ipcoords = *dat_->getipcoords();
00089 const Epetra_IntSerialDenseVector &pindx = *dat_->getpindx();
00090 Epetra_Map overlapmap(-1,pindx.M(),const_cast<int*>(pindx.A()),1,*comm);
00091 const double pi = 2.0 * std::asin(1.0);
00092 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00093 *out << "\npi="<<pi<<"\n";
00094 #endif
00095 map_p_[p_bndy_idx] = Teuchos::rcp(new Epetra_Map(np_,np_,0,*comm));
00096 B_bar_ = Teuchos::rcp(new Epetra_MultiVector(*map_p_bar_,np_));
00097 (*B_bar_)(0)->PutScalar(1.0);
00098 if( np_ > 1 ) {
00099 const int numBndyNodes = map_p_bar_->NumMyElements();
00100 const int *bndyNodeGlobalIDs = map_p_bar_->MyGlobalElements();
00101 for( int i = 0; i < numBndyNodes; ++i ) {
00102 const int global_id = bndyNodeGlobalIDs[i];
00103 const int local_id = overlapmap.LID(bndyNodeGlobalIDs[i]);
00104 const double x = ipcoords(local_id,0), y = ipcoords(local_id,1);
00105 double z = -1.0, L = -1.0;
00106 if( x < 1e-10 || len_x - 1e-10 < x ) {
00107 z = y;
00108 L = len_y;
00109 }
00110 else {
00111 z = x;
00112 L = len_x;
00113 }
00114 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00115 *out << "\ni="<<i<<",global_id="<<global_id<<",local_id="<<local_id<<",x="<<x<<",y="<<y<<",z="<<z<<"\n";
00116 #endif
00117 for( int j = 1; j < np_; ++j ) {
00118 (*B_bar_)[j][i] = std::sin(j*pi*z/L);
00119 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00120 *out << "\nB("<<i<<","<<j<<")="<<(*B_bar_)[j][i]<<"\n";
00121 #endif
00122 }
00123 }
00124 if(normalizeBasis) {
00125 #ifdef HAVE_EPETRAEXT_THYRA
00126
00127
00128
00129 Teuchos::RefCountPtr<Thyra::MultiVectorBase<double> >
00130 thyra_B_bar = Thyra::create_MultiVector(
00131 B_bar_
00132 ,Thyra::create_VectorSpace(Teuchos::rcp(new Epetra_Map(*map_p_bar_)))
00133 ,Thyra::create_VectorSpace(Teuchos::rcp(new Epetra_Map(*map_p_[p_bndy_idx])))
00134 ),
00135 thyra_fact_R;
00136 sillyModifiedGramSchmidt(&*thyra_B_bar,&thyra_fact_R);
00137 Thyra::scale(double(numBndyNodes)/double(np_),&*thyra_B_bar);
00138
00139 #else // HAVE_EPETRAEXT_THYRA
00140 TEST_FOR_EXCEPTION(
00141 true,std::logic_error
00142 ,"Error, can not normalize basis since we do not have Thyra support enabled!"
00143 );
00144 #endif // HAVE_EPETRAEXT_THYRA
00145 }
00146 }
00147 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00148 *out << "\nB_bar =\n\n";
00149 B_bar_->Print(*Teuchos::OSTab(out).getOStream());
00150 #endif
00151 }
00152 else {
00153
00154 map_p_[p_bndy_idx] = map_p_bar_;
00155 }
00156
00157
00158
00159 x0_ = Teuchos::rcp(new Epetra_Vector(*map_x_));
00160
00161
00162 p0_.resize(Np_);
00163 p0_[p_bndy_idx] = Teuchos::rcp(new Epetra_Vector(*map_p_[p_bndy_idx]));
00164 p0_[p_rx_idx] = Teuchos::rcp(new Epetra_Vector(*map_p_[p_rx_idx]));
00165 pL_.resize(Np_);
00166 pU_.resize(Np_);
00167
00168
00169
00170
00171
00172 x0_->PutScalar(x0);
00173 p0_[p_bndy_idx]->PutScalar(p0);
00174 p0_[p_rx_idx]->PutScalar(reactionRate);
00175
00176
00177
00178 dat_->computeNpy(x0_);
00179
00180
00181 W_graph_ = Teuchos::rcp(new Epetra_CrsGraph(dat_->getA()->Graph()));
00182
00183
00184
00185 q_ = Teuchos::rcp(new Epetra_Vector(*(*dat_->getq())(0)));
00186
00187 isInitialized_ = true;
00188 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00189 *out << "\nLeaving AdvDiffReactOptModel::AdvDiffReactOptModel(...) ...\n";
00190 #endif
00191 }
00192
00193 void AdvDiffReactOptModel::set_q( Teuchos::RefCountPtr<const Epetra_Vector> const& q )
00194 {
00195 q_ = q;
00196 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00197 Teuchos::RefCountPtr<Teuchos::FancyOStream>
00198 dout = Teuchos::VerboseObjectBase::getDefaultOStream();
00199 Teuchos::OSTab dtab(dout);
00200 *dout << "\nIn AdvDiffReactOptModel::set_q(q): q =\n\n";
00201 q_->Print(*Teuchos::OSTab(dout).getOStream());
00202 #endif
00203 }
00204
00205
00206
00207 Teuchos::RefCountPtr<const Epetra_Map>
00208 AdvDiffReactOptModel::get_x_map() const
00209 {
00210 return map_x_;
00211 }
00212
00213 Teuchos::RefCountPtr<const Epetra_Map>
00214 AdvDiffReactOptModel::get_f_map() const
00215 {
00216 return map_x_;
00217 }
00218
00219 Teuchos::RefCountPtr<const Epetra_Map>
00220 AdvDiffReactOptModel::get_p_map(int l) const
00221 {
00222 TEST_FOR_EXCEPT(!(0<=l<=Np_));
00223 return map_p_[l];
00224 }
00225
00226 Teuchos::RefCountPtr<const Epetra_Map>
00227 AdvDiffReactOptModel::get_g_map(int j) const
00228 {
00229 TEST_FOR_EXCEPT(j!=0);
00230 return map_g_;
00231 }
00232
00233 Teuchos::RefCountPtr<const Epetra_Vector>
00234 AdvDiffReactOptModel::get_x_init() const
00235 {
00236 return x0_;
00237 }
00238
00239 Teuchos::RefCountPtr<const Epetra_Vector>
00240 AdvDiffReactOptModel::get_p_init(int l) const
00241 {
00242 TEST_FOR_EXCEPT(!(0<=l<=Np_));
00243 return p0_[l];
00244 }
00245
00246 Teuchos::RefCountPtr<const Epetra_Vector>
00247 AdvDiffReactOptModel::get_x_lower_bounds() const
00248 {
00249 return xL_;
00250 }
00251
00252 Teuchos::RefCountPtr<const Epetra_Vector>
00253 AdvDiffReactOptModel::get_x_upper_bounds() const
00254 {
00255 return xU_;
00256 }
00257
00258 Teuchos::RefCountPtr<const Epetra_Vector>
00259 AdvDiffReactOptModel::get_p_lower_bounds(int l) const
00260 {
00261 TEST_FOR_EXCEPT(!(0<=l<=Np_));
00262 return pL_[l];
00263 }
00264
00265 Teuchos::RefCountPtr<const Epetra_Vector>
00266 AdvDiffReactOptModel::get_p_upper_bounds(int l) const
00267 {
00268 TEST_FOR_EXCEPT(!(0<=l<=Np_));
00269 return pU_[l];
00270 }
00271
00272 Teuchos::RefCountPtr<Epetra_Operator>
00273 AdvDiffReactOptModel::create_W() const
00274 {
00275 return Teuchos::rcp(new Epetra_CrsMatrix(::Copy,*W_graph_));
00276 }
00277
00278 Teuchos::RefCountPtr<Epetra_Operator>
00279 AdvDiffReactOptModel::create_DfDp_op(int l) const
00280 {
00281 TEST_FOR_EXCEPT(l!=0);
00282 return Teuchos::rcp(new Epetra_CrsMatrix(::Copy,dat_->getB()->Graph()));
00283
00284 }
00285
00286 EpetraExt::ModelEvaluator::InArgs
00287 AdvDiffReactOptModel::createInArgs() const
00288 {
00289 InArgsSetup inArgs;
00290 inArgs.setModelEvalDescription(this->description());
00291 inArgs.set_Np(2);
00292 inArgs.setSupports(IN_ARG_x,true);
00293 return inArgs;
00294 }
00295
00296 EpetraExt::ModelEvaluator::OutArgs
00297 AdvDiffReactOptModel::createOutArgs() const
00298 {
00299 OutArgsSetup outArgs;
00300 outArgs.setModelEvalDescription(this->description());
00301 outArgs.set_Np_Ng(2,1);
00302 outArgs.setSupports(OUT_ARG_f,true);
00303 outArgs.setSupports(OUT_ARG_W,true);
00304 outArgs.set_W_properties(
00305 DerivativeProperties(
00306 DERIV_LINEARITY_NONCONST
00307 ,DERIV_RANK_FULL
00308 ,true
00309 )
00310 );
00311 outArgs.setSupports(
00312 OUT_ARG_DfDp,0
00313 ,( np_ > 0
00314 ? DerivativeSupport(DERIV_MV_BY_COL)
00315 : DerivativeSupport(DERIV_LINEAR_OP,DERIV_MV_BY_COL)
00316 )
00317 );
00318 outArgs.set_DfDp_properties(
00319 0,DerivativeProperties(
00320 DERIV_LINEARITY_CONST
00321 ,DERIV_RANK_DEFICIENT
00322 ,true
00323 )
00324 );
00325 outArgs.setSupports(OUT_ARG_DgDx,0,DERIV_TRANS_MV_BY_ROW);
00326 outArgs.set_DgDx_properties(
00327 0,DerivativeProperties(
00328 DERIV_LINEARITY_NONCONST
00329 ,DERIV_RANK_DEFICIENT
00330 ,true
00331 )
00332 );
00333 outArgs.setSupports(OUT_ARG_DgDp,0,0,DERIV_TRANS_MV_BY_ROW);
00334 outArgs.set_DgDp_properties(
00335 0,0,DerivativeProperties(
00336 DERIV_LINEARITY_NONCONST
00337 ,DERIV_RANK_DEFICIENT
00338 ,true
00339 )
00340 );
00341 return outArgs;
00342 }
00343
00344 void AdvDiffReactOptModel::evalModel( const InArgs& inArgs, const OutArgs& outArgs ) const
00345 {
00346 Teuchos::TimeMonitor evalTimerMonitor(*evalTimer);
00347 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00348 Teuchos::RefCountPtr<Teuchos::FancyOStream>
00349 dout = Teuchos::VerboseObjectBase::getDefaultOStream();
00350 Teuchos::OSTab dtab(dout);
00351 *dout << "\nEntering AdvDiffReactOptModel::evalModel(...) ...\n";
00352 #endif
00353 using Teuchos::dyn_cast;
00354 using Teuchos::rcp_dynamic_cast;
00355
00356 Teuchos::RefCountPtr<Teuchos::FancyOStream> out = this->getOStream();
00357 const bool trace = ( static_cast<int>(this->getVerbLevel()) >= static_cast<int>(Teuchos::VERB_LOW) );
00358 const bool dumpAll = ( static_cast<int>(this->getVerbLevel()) >= static_cast<int>(Teuchos::VERB_EXTREME) );
00359
00360 Teuchos::OSTab tab(out);
00361 if(out.get() && trace) *out << "\n*** Entering AdvDiffReactOptModel::evalModel(...) ...\n";
00362
00363
00364
00365 const Epetra_Vector *p_in = inArgs.get_p(p_bndy_idx).get();
00366 const Epetra_Vector &p = (p_in ? *p_in : *p0_[p_bndy_idx]);
00367 const Epetra_Vector *rx_vec_in = inArgs.get_p(p_rx_idx).get();
00368 const double reactionRate = ( rx_vec_in ? (*rx_vec_in)[0] : (*p0_[p_rx_idx])[0] );
00369 const Epetra_Vector &x = *inArgs.get_x();
00370 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00371 *dout << "\nx =\n\n";
00372 x.Print(*Teuchos::OSTab(dout).getOStream());
00373 *dout << "\np =\n\n";
00374 p.Print(*Teuchos::OSTab(dout).getOStream());
00375 #endif
00376
00377
00378
00379 Epetra_Vector *f_out = outArgs.get_f().get();
00380 Epetra_Vector *g_out = outArgs.get_g(0).get();
00381 Epetra_Operator *W_out = outArgs.get_W().get();
00382 Derivative DfDp_out = outArgs.get_DfDp(0);
00383 Epetra_MultiVector *DgDx_trans_out = get_DgDx_mv(0,outArgs,DERIV_TRANS_MV_BY_ROW).get();
00384 Epetra_MultiVector *DgDp_trans_out = get_DgDp_mv(0,0,outArgs,DERIV_TRANS_MV_BY_ROW).get();
00385
00386
00387
00388
00389 Teuchos::RefCountPtr<const Epetra_Vector> p_bar;
00390 if(np_ > 0) {
00391 Teuchos::TimeMonitor p_bar_TimerMonitor(*p_bar_Timer);
00392 Teuchos::RefCountPtr<Epetra_Vector> _p_bar;
00393 _p_bar = Teuchos::rcp(new Epetra_Vector(*map_p_bar_));
00394 _p_bar->Multiply('N','N',1.0,*B_bar_,p,0.0);
00395 p_bar = _p_bar;
00396 }
00397 else {
00398 p_bar = Teuchos::rcp(&p,false);
00399 }
00400
00401 Teuchos::RefCountPtr<const Epetra_Vector> R_p_bar;
00402 if( g_out || DgDp_trans_out ) {
00403 Teuchos::TimeMonitor R_p_bar_TimerMonitor(*R_p_bar_Timer);
00404 Teuchos::RefCountPtr<Epetra_Vector>
00405 _R_p_bar = Teuchos::rcp(new Epetra_Vector(*map_p_bar_));
00406 dat_->getR()->Multiply(false,*p_bar,*_R_p_bar);
00407 R_p_bar = _R_p_bar;
00408 }
00409
00410
00411
00412 if(f_out) {
00413
00414
00415
00416 Teuchos::TimeMonitor f_TimerMonitor(*f_Timer);
00417 Epetra_Vector &f = *f_out;
00418 Epetra_Vector Ax(*map_f_);
00419 dat_->getA()->Multiply(false,x,Ax);
00420 f.Update(1.0,Ax,0.0);
00421 if(reactionRate!=0.0) {
00422 dat_->computeNy(Teuchos::rcp(&x,false));
00423 f.Update(reactionRate,*dat_->getNy(),1.0);
00424 }
00425 Epetra_Vector Bp(*map_f_);
00426 dat_->getB()->Multiply(false,*p_bar,Bp);
00427 f.Update(1.0,Bp,-1.0,*dat_->getb(),1.0);
00428 }
00429 if(g_out) {
00430
00431
00432
00433 Teuchos::TimeMonitor g_TimerMonitor(*g_Timer);
00434 Epetra_Vector &g = *g_out;
00435 Epetra_Vector xq(x);
00436 xq.Update(-1.0, *q_, 1.0);
00437 Epetra_Vector Hxq(x);
00438 dat_->getH()->Multiply(false,xq,Hxq);
00439 g[0] = 0.5*dot(xq,Hxq) + 0.5*dat_->getbeta()*dot(*p_bar,*R_p_bar);
00440 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00441 *dout << "q =\n\n";
00442 q_->Print(*Teuchos::OSTab(dout).getOStream());
00443 *dout << "x =\n\n";
00444 x.Print(*Teuchos::OSTab(dout).getOStream());
00445 *dout << "x-q =\n\n";
00446 xq.Print(*Teuchos::OSTab(dout).getOStream());
00447 *dout << "H*(x-q) =\n\n";
00448 Hxq.Print(*Teuchos::OSTab(dout).getOStream());
00449 *dout << "0.5*dot(xq,Hxq) = " << (0.5*dot(xq,Hxq)) << "\n";
00450 *dout << "0.5*regBeta*(B_bar*p)'*R*(B_bar*p) = " << (0.5*dat_->getbeta()*dot(*p_bar,*R_p_bar)) << "\n";
00451 #endif
00452 }
00453 if(W_out) {
00454
00455
00456
00457 Teuchos::TimeMonitor W_TimerMonitor(*W_Timer);
00458 Epetra_CrsMatrix &DfDx = dyn_cast<Epetra_CrsMatrix>(*W_out);
00459 if(reactionRate!=0.0)
00460 dat_->computeNpy(Teuchos::rcp(&x,false));
00461 Teuchos::RefCountPtr<Epetra_CrsMatrix>
00462 dat_A = dat_->getA(),
00463 dat_Npy = dat_->getNpy();
00464 const int numMyRows = dat_A->NumMyRows();
00465 for( int i = 0; i < numMyRows; ++i ) {
00466 int dat_A_num_row_entries=0; double *dat_A_row_vals=0; int *dat_A_row_inds=0;
00467 dat_A->ExtractMyRowView(i,dat_A_num_row_entries,dat_A_row_vals,dat_A_row_inds);
00468 int DfDx_num_row_entries=0; double *DfDx_row_vals=0; int *DfDx_row_inds=0;
00469 DfDx.ExtractMyRowView(i,DfDx_num_row_entries,DfDx_row_vals,DfDx_row_inds);
00470 #ifdef TEUCHOS_DEBUG
00471 TEST_FOR_EXCEPT(DfDx_num_row_entries!=dat_A_num_row_entries);
00472 #endif
00473 if(reactionRate!=0.0) {
00474 int dat_Npy_num_row_entries=0; double *dat_Npy_row_vals=0; int *dat_Npy_row_inds=0;
00475 dat_Npy->ExtractMyRowView(i,dat_Npy_num_row_entries,dat_Npy_row_vals,dat_Npy_row_inds);
00476 #ifdef TEUCHOS_DEBUG
00477 TEST_FOR_EXCEPT(dat_A_num_row_entries!=dat_Npy_num_row_entries);
00478 #endif
00479 for(int k = 0; k < DfDx_num_row_entries; ++k) {
00480 #ifdef TEUCHOS_DEBUG
00481 TEST_FOR_EXCEPT(dat_A_row_inds[k]!=dat_Npy_row_inds[k]||dat_A_row_inds[k]!=DfDx_row_inds[k]);
00482 #endif
00483 DfDx_row_vals[k] = dat_A_row_vals[k] + reactionRate * dat_Npy_row_vals[k];
00484 }
00485 }
00486 else {
00487 for(int k = 0; k < DfDx_num_row_entries; ++k) {
00488 #ifdef TEUCHOS_DEBUG
00489 TEST_FOR_EXCEPT(dat_A_row_inds[k]!=DfDx_row_inds[k]);
00490 #endif
00491 DfDx_row_vals[k] = dat_A_row_vals[k];
00492 }
00493 }
00494 }
00495 }
00496 if(!DfDp_out.isEmpty()) {
00497 if(out.get() && trace) *out << "\nComputing DfDp ...\n";
00498
00499
00500
00501 Teuchos::TimeMonitor DfDp_TimerMonitor(*DfDp_Timer);
00502 Epetra_CrsMatrix *DfDp_op = NULL;
00503 Epetra_MultiVector *DfDp_mv = NULL;
00504 if(out.get() && dumpAll)
00505 { *out << "\nB =\n"; { Teuchos::OSTab tab(out); dat_->getB()->Print(*out); } }
00506 if(DfDp_out.getLinearOp().get()) {
00507 DfDp_op = &dyn_cast<Epetra_CrsMatrix>(*DfDp_out.getLinearOp());
00508 }
00509 else {
00510 DfDp_mv = &*DfDp_out.getDerivativeMultiVector().getMultiVector();
00511 DfDp_mv->PutScalar(0.0);
00512 }
00513 Teuchos::RefCountPtr<Epetra_CrsMatrix>
00514 dat_B = dat_->getB();
00515 if(np_ > 0) {
00516
00517
00518
00519
00520 TEST_FOR_EXCEPT(DfDp_mv==NULL);
00521 dat_B->Multiply(false,*B_bar_,*DfDp_mv);
00522 }
00523 else {
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 if(DfDp_op) {
00534 const int numMyRows = dat_B->NumMyRows();
00535 for( int i = 0; i < numMyRows; ++i ) {
00536 int dat_B_num_row_entries=0; double *dat_B_row_vals=0; int *dat_B_row_inds=0;
00537 dat_B->ExtractMyRowView(i,dat_B_num_row_entries,dat_B_row_vals,dat_B_row_inds);
00538 int DfDp_num_row_entries=0; double *DfDp_row_vals=0; int *DfDp_row_inds=0;
00539 DfDp_op->ExtractMyRowView(i,DfDp_num_row_entries,DfDp_row_vals,DfDp_row_inds);
00540 #ifdef TEUCHOS_DEBUG
00541 TEST_FOR_EXCEPT(DfDp_num_row_entries!=dat_B_num_row_entries);
00542 #endif
00543 for(int k = 0; k < DfDp_num_row_entries; ++k) {
00544 #ifdef TEUCHOS_DEBUG
00545 TEST_FOR_EXCEPT(dat_B_row_inds[k]!=DfDp_row_inds[k]);
00546 #endif
00547 DfDp_row_vals[k] = dat_B_row_vals[k];
00548 }
00549
00550 }
00551 }
00552 else if(DfDp_mv) {
00553
00554
00555
00556
00557
00558 Teuchos::RefCountPtr<Epetra_Vector>
00559 etaVec = Teuchos::rcp(new Epetra_Vector(*map_p_bar_));
00560 Teuchos::RefCountPtr<const Thyra::SpmdVectorSpaceBase<double> >
00561 space_p_bar = Thyra::create_VectorSpace(Teuchos::rcp(new Epetra_Map(*map_p_bar_)));
00562 Teuchos::RefCountPtr<Thyra::VectorBase<double> >
00563 thyra_etaVec = Thyra::create_Vector(etaVec,space_p_bar);
00564 for( int i = 0; i < map_p_bar_->NumGlobalElements(); ++i ) {
00565 Thyra::assign(&*thyra_etaVec,0.0);
00566 Thyra::set_ele(i,1.0,&*thyra_etaVec);
00567 dat_B->Multiply(false,*etaVec,*(*DfDp_mv)(i));
00568 };
00569 }
00570 }
00571 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00572 if(DfDp_op) {
00573 *dout << "\nDfDp_op =\n\n";
00574 DfDp_op->Print(*Teuchos::OSTab(dout).getOStream());
00575 }
00576 if(DfDp_mv) {
00577 *dout << "\nDfDp_mv =\n\n";
00578 DfDp_mv->Print(*Teuchos::OSTab(dout).getOStream());
00579 }
00580 #endif
00581 }
00582 if(DgDx_trans_out) {
00583
00584
00585
00586 Teuchos::TimeMonitor DgDx_TimerMonitor(*DgDx_Timer);
00587 Epetra_Vector &DgDx_trans = *(*DgDx_trans_out)(0);
00588 Epetra_Vector xq(x);
00589 xq.Update(-1.0,*q_,1.0);
00590 dat_->getH()->Multiply(false,xq,DgDx_trans);
00591 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00592 *dout << "q =\n\n";
00593 q_->Print(*Teuchos::OSTab(dout).getOStream());
00594 *dout << "x =\n\n";
00595 x.Print(*Teuchos::OSTab(dout).getOStream());
00596 *dout << "x-q =\n\n";
00597 xq.Print(*Teuchos::OSTab(dout).getOStream());
00598 *dout << "DgDx_trans = H*(x-q) =\n\n";
00599 DgDx_trans.Print(*Teuchos::OSTab(dout).getOStream());
00600 #endif
00601 }
00602 if(DgDp_trans_out) {
00603
00604
00605
00606 Teuchos::TimeMonitor DgDp_TimerMonitor(*DgDp_Timer);
00607 Epetra_Vector &DgDp_trans = *(*DgDp_trans_out)(0);
00608 if(np_ > 0) {
00609 DgDp_trans.Multiply('T','N',dat_->getbeta(),*B_bar_,*R_p_bar,0.0);
00610 }
00611 else {
00612 DgDp_trans.Update(dat_->getbeta(),*R_p_bar,0.0);
00613 }
00614 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00615 *dout << "\nR_p_bar =\n\n";
00616 R_p_bar->Print(*Teuchos::OSTab(dout).getOStream());
00617 if(B_bar_.get()) {
00618 *dout << "\nB_bar =\n\n";
00619 B_bar_->Print(*Teuchos::OSTab(dout).getOStream());
00620 }
00621 *dout << "\nDgDp_trans =\n\n";
00622 DgDp_trans.Print(*Teuchos::OSTab(dout).getOStream());
00623 #endif
00624 }
00625 if(out.get() && trace) *out << "\n*** Leaving AdvDiffReactOptModel::evalModel(...) ...\n";
00626 #ifdef GLPAPP_ADVDIFFREACT_OPTMODEL_DUMP_STUFF
00627 *dout << "\nLeaving AdvDiffReactOptModel::evalModel(...) ...\n";
00628 #endif
00629 }
00630
00631 }