EpetraExt Development
EpetraExt_MultiPointModelEvaluator.cpp
Go to the documentation of this file.
00001 /*
00002 //@HEADER
00003 // ***********************************************************************
00004 //
00005 //     EpetraExt: Epetra Extended - Linear Algebra Services Package
00006 //                 Copyright (2011) Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //@HEADER
00042 */
00043 
00044 #include "EpetraExt_MultiPointModelEvaluator.h"
00045 #include "Epetra_Map.h"
00046 #include "Teuchos_as.hpp"
00047 
00048 EpetraExt::MultiPointModelEvaluator::MultiPointModelEvaluator(
00049     Teuchos::RefCountPtr<EpetraExt::ModelEvaluator> underlyingME_,
00050     const Teuchos::RefCountPtr<EpetraExt::MultiComm> &globalComm_,
00051     const std::vector<Epetra_Vector*> initGuessVec_,
00052     Teuchos::RefCountPtr<std::vector< Teuchos::RefCountPtr<Epetra_Vector> > >  q_vec_,
00053     Teuchos::RefCountPtr<std::vector< Teuchos::RefCountPtr<Epetra_Vector> > >  matching_vec_
00054     ) :
00055     underlyingME(underlyingME_),
00056     globalComm(globalComm_),
00057     q_vec(q_vec_),
00058     underlyingNg(0),
00059     timeStepsOnTimeDomain(globalComm_->NumTimeStepsOnDomain()),
00060     numTimeDomains(globalComm_->NumSubDomains()),
00061     timeDomain(globalComm_->SubDomainRank()),
00062 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00063     rowStencil_int(0),
00064 #endif
00065 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00066     rowStencil_LL(0),
00067 #endif
00068 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00069     rowIndex_int(0),
00070 #endif
00071 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00072     rowIndex_LL(0),
00073 #endif
00074     matching_vec(matching_vec_)
00075 {
00076   using Teuchos::as;
00077   if (globalComm->MyPID()==0) {
00078      std::cout  << "----------MultiPoint Partition Info------------"
00079            << "\n\tNumProcs              = " << globalComm->NumProc()
00080            << "\n\tSpatial Decomposition = " << globalComm->SubDomainComm().NumProc()
00081            << "\n\tNumber of Domains     = " << numTimeDomains
00082            << "\n\tSteps on Domain 0     = " << timeStepsOnTimeDomain
00083            << "\n\tTotal Number of Steps = " << globalComm->NumTimeSteps();
00084     std::cout   << "\n-----------------------------------------------" << std::endl;
00085     }
00086 
00087    // Construct global block matrix graph from split W and stencil,
00088    // which is just diagonal in this case
00089 
00090    split_W = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(underlyingME->create_W());
00091 
00092 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00093    if(split_W->RowMatrixRowMap().GlobalIndicesInt()) {
00094      longlong = false;
00095      rowStencil_int = new std::vector< std::vector<int> >(timeStepsOnTimeDomain);
00096      rowIndex_int = new std::vector<int>;
00097      for (int i=0; i < timeStepsOnTimeDomain; i++) {
00098        (*rowStencil_int)[i].push_back(0);
00099        (*rowIndex_int).push_back(i + globalComm->FirstTimeStepOnDomain());
00100      }
00101      block_W = Teuchos::rcp(new EpetraExt::BlockCrsMatrix(*split_W,
00102                                *rowStencil_int, *rowIndex_int, *globalComm));
00103    }
00104    else
00105 #endif
00106 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00107    if(split_W->RowMatrixRowMap().GlobalIndicesInt()) {
00108      longlong = true;
00109      rowStencil_LL = new std::vector< std::vector<long long> >(timeStepsOnTimeDomain);
00110      rowIndex_LL = new std::vector<long long>;
00111      for (int i=0; i < timeStepsOnTimeDomain; i++) {
00112        (*rowStencil_LL)[i].push_back(0);
00113        (*rowIndex_LL).push_back(i + globalComm->FirstTimeStepOnDomain());
00114      }
00115      block_W = Teuchos::rcp(new EpetraExt::BlockCrsMatrix(*split_W,
00116                                *rowStencil_LL, *rowIndex_LL, *globalComm));
00117    }
00118    else
00119 #endif
00120      throw "EpetraExt::MultiPointModelEvaluator::MultiPointModelEvaluator: Global indices unknown";
00121 
00122    // Test for g vector
00123    EpetraExt::ModelEvaluator::OutArgs underlyingOutArgs = underlyingME->createOutArgs();
00124 
00125    underlyingNg = underlyingOutArgs.Ng();
00126    if (underlyingNg) {
00127      if (underlyingOutArgs.supports(OUT_ARG_DgDp,0,0).supports(DERIV_TRANS_MV_BY_ROW))
00128        orientation_DgDp = DERIV_TRANS_MV_BY_ROW;
00129      else
00130        orientation_DgDp = DERIV_MV_BY_COL;
00131    }
00132 
00133    // This code assumes 2 parameter vectors, 1 for opt, second for MultiPoint states
00134    TEUCHOS_TEST_FOR_EXCEPT(underlyingOutArgs.Np()!=2);
00135 
00136    // temporary quantities
00137    const Epetra_Map& split_map = split_W->RowMatrixRowMap();
00138    num_p0 =  underlyingME_->get_p_map(0)->NumMyElements();
00139    if (underlyingNg)  num_g0 = underlyingME_->get_g_map(0)->NumMyElements();
00140    else num_g0 = 0;
00141    num_dg0dp0 = num_g0 * num_p0;
00142 
00143    // Construct global solution vector, residual vector -- local storage
00144    block_x = new EpetraExt::BlockVector(split_map, block_W->RowMap());
00145    block_f = new EpetraExt::BlockVector(*block_x);
00146    block_DfDp = new EpetraExt::BlockMultiVector(split_map, block_W->RowMap(), num_p0);
00147     if (underlyingNg)
00148    block_DgDx = new EpetraExt::BlockMultiVector(split_map, block_W->RowMap(), num_g0);
00149 
00150    // Allocate local storage of epetra vectors
00151    split_x = Teuchos::rcp(new Epetra_Vector(split_map));
00152    split_f = Teuchos::rcp(new Epetra_Vector(split_map));
00153    split_DfDp = Teuchos::rcp(new Epetra_MultiVector(split_map, num_p0));
00154    if (underlyingNg)
00155      split_DgDx = Teuchos::rcp(new Epetra_MultiVector(split_map, num_g0));
00156    if (underlyingNg) {
00157      if(orientation_DgDp == DERIV_TRANS_MV_BY_ROW)
00158        split_DgDp = Teuchos::rcp(new Epetra_MultiVector(*(underlyingME_->get_p_map(0)), num_g0));
00159      else
00160        split_DgDp = Teuchos::rcp(new Epetra_MultiVector(*(underlyingME_->get_g_map(0)), num_p0));
00161    }
00162    if (underlyingNg)
00163      split_g = Teuchos::rcp(new Epetra_Vector(*(underlyingME_->get_g_map(0))));
00164 
00165    // Packaging required for getting multivectors back as Derivatives
00166    derivMV_DfDp = new EpetraExt::ModelEvaluator::DerivativeMultiVector(split_DfDp);
00167    deriv_DfDp = new EpetraExt::ModelEvaluator::Derivative(*derivMV_DfDp);
00168    if (underlyingNg)  {
00169      derivMV_DgDx = new EpetraExt::ModelEvaluator::DerivativeMultiVector(split_DgDx, DERIV_TRANS_MV_BY_ROW);
00170      deriv_DgDx = new EpetraExt::ModelEvaluator::Derivative(*derivMV_DgDx);
00171      derivMV_DgDp = new EpetraExt::ModelEvaluator::DerivativeMultiVector(split_DgDp, orientation_DgDp);
00172      deriv_DgDp = new EpetraExt::ModelEvaluator::Derivative(*derivMV_DgDp);
00173    }
00174 
00175    // For 4D, we will need the overlap vector and importer between them
00176    // Overlap not needed for MultiPoint -- no overlap between blocks
00177    /*   solutionOverlap = new EpetraExt::BlockVector(split_W->RowMatrixRowMap(),
00178                                                      block_W->ColMap());
00179         overlapImporter = new Epetra_Import(solutionOverlap->Map(), block_x->Map());
00180    */
00181 
00182    // Load initial guess into block solution vector
00183    solution_init = Teuchos::rcp(new EpetraExt::BlockVector(*block_x));
00184 
00185    if(longlong) {
00186 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00187      for (int i=0; i < timeStepsOnTimeDomain; i++)
00188              solution_init->LoadBlockValues(*(initGuessVec_[i]), (*rowIndex_LL)[i]);
00189 #endif
00190    }
00191    else {
00192 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00193      for (int i=0; i < timeStepsOnTimeDomain; i++)
00194              solution_init->LoadBlockValues(*(initGuessVec_[i]), (*rowIndex_int)[i]);
00195 #endif
00196    }
00197 
00198 
00199    //Prepare logic for matching problem
00200    if (Teuchos::is_null(matching_vec))  matchingProblem = false;
00201    else matchingProblem = true;
00202 
00203    if (matchingProblem) {
00204      TEUCHOS_TEST_FOR_EXCEPT(as<int>(matching_vec->size())!=timeStepsOnTimeDomain);
00205      TEUCHOS_TEST_FOR_EXCEPT(!(*matching_vec)[0]->Map().SameAs(*(underlyingME_->get_g_map(0))));
00206      TEUCHOS_TEST_FOR_EXCEPT(num_g0 != 1); //This restriction may be lifted later
00207    }
00208 }
00209 
00210 EpetraExt::MultiPointModelEvaluator::~MultiPointModelEvaluator()
00211 {
00212   delete block_x;
00213   delete block_f;
00214   delete block_DfDp;
00215   if (underlyingNg)  delete block_DgDx;
00216 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00217   delete rowStencil_int;
00218   delete rowIndex_int;
00219 #endif
00220 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00221   delete rowStencil_LL;
00222   delete rowIndex_LL;
00223 #endif
00224 
00225   delete derivMV_DfDp;
00226   delete deriv_DfDp;
00227   if (underlyingNg) {
00228     delete derivMV_DgDx;
00229     delete deriv_DgDx;
00230     delete derivMV_DgDp;
00231     delete deriv_DgDp;
00232   }
00233 }
00234 
00235 Teuchos::RefCountPtr<const Epetra_Map> EpetraExt::MultiPointModelEvaluator::get_x_map() const
00236 {
00237   return Teuchos::rcp(&(block_W->OperatorDomainMap()), false);
00238 }
00239 
00240 Teuchos::RefCountPtr<const Epetra_Map> EpetraExt::MultiPointModelEvaluator::get_f_map() const
00241 {
00242   return get_x_map();
00243 }
00244 
00245 Teuchos::RefCountPtr<const Epetra_Map> EpetraExt::MultiPointModelEvaluator::get_p_map(int l) const
00246 {
00247   return underlyingME->get_p_map(l);
00248 }
00249 
00250 Teuchos::RefCountPtr<const Epetra_Map> EpetraExt::MultiPointModelEvaluator::get_g_map(int j) const
00251 {
00252   return underlyingME->get_g_map(j);
00253 }
00254 
00255 Teuchos::RefCountPtr<const Epetra_Vector> EpetraExt::MultiPointModelEvaluator::get_x_init() const
00256 {
00257   return solution_init;
00258 }
00259 
00260 Teuchos::RefCountPtr<const Epetra_Vector> EpetraExt::MultiPointModelEvaluator::get_p_init(int l) const
00261 {
00262   return underlyingME->get_p_init(l);
00263 }
00264 
00265 Teuchos::RefCountPtr<Epetra_Operator> EpetraExt::MultiPointModelEvaluator::create_W() const
00266 {
00267   return block_W;
00268 }
00269 
00270 EpetraExt::ModelEvaluator::InArgs EpetraExt::MultiPointModelEvaluator::createInArgs() const
00271 {
00272   //return underlyingME->createInArgs();
00273   InArgsSetup inArgs;
00274   inArgs.setModelEvalDescription(this->description());
00275   inArgs.set_Np(1);
00276   inArgs.setSupports(IN_ARG_x,true);
00277   return inArgs;
00278 }
00279 
00280 EpetraExt::ModelEvaluator::OutArgs EpetraExt::MultiPointModelEvaluator::createOutArgs() const
00281 {
00282   //return underlyingME->createOutArgs();
00283   OutArgsSetup outArgs;
00284   outArgs.setModelEvalDescription(this->description());
00285   outArgs.set_Np_Ng(1, underlyingNg);
00286   outArgs.setSupports(OUT_ARG_f,true);
00287   outArgs.setSupports(OUT_ARG_W,true);
00288   outArgs.set_W_properties(
00289     DerivativeProperties(
00290       DERIV_LINEARITY_NONCONST
00291       ,DERIV_RANK_FULL
00292       ,true // supportsAdjoint
00293       )
00294     );
00295   outArgs.setSupports(OUT_ARG_DfDp,0,DERIV_MV_BY_COL);
00296   outArgs.set_DfDp_properties(
00297     0,DerivativeProperties(
00298       DERIV_LINEARITY_CONST
00299       ,DERIV_RANK_DEFICIENT
00300       ,true // supportsAdjoint
00301       )
00302     );
00303 
00304   if (underlyingNg) {
00305     outArgs.setSupports(OUT_ARG_DgDx,0,DERIV_TRANS_MV_BY_ROW);
00306     outArgs.set_DgDx_properties(
00307       0,DerivativeProperties(
00308         DERIV_LINEARITY_NONCONST
00309         ,DERIV_RANK_DEFICIENT
00310         ,true // supportsAdjoint
00311         )
00312       );
00313     outArgs.setSupports(OUT_ARG_DgDp,0,0, orientation_DgDp);
00314     outArgs.set_DgDp_properties(
00315       0,0,DerivativeProperties(
00316         DERIV_LINEARITY_NONCONST
00317         ,DERIV_RANK_DEFICIENT
00318         ,true // supportsAdjoint
00319         )
00320       );
00321   }
00322   return outArgs;
00323 }
00324 
00325 void EpetraExt::MultiPointModelEvaluator::evalModel( const InArgs& inArgs,
00326                                             const OutArgs& outArgs ) const
00327 {
00328 
00329   EpetraExt::ModelEvaluator::InArgs  underlyingInArgs  = underlyingME->createInArgs();
00330   EpetraExt::ModelEvaluator::OutArgs underlyingOutArgs = underlyingME->createOutArgs();
00331 
00332   //temp code for multipoint param q vec
00333 /*
00334   Teuchos::RefCountPtr<Epetra_Vector> q =
00335     Teuchos::rcp(new Epetra_Vector(*(underlyingME->get_p_map(1))));
00336 */
00337 
00338   // Parse InArgs
00339   Teuchos::RefCountPtr<const Epetra_Vector> p_in = inArgs.get_p(0);
00340   if (p_in.get()) underlyingInArgs.set_p(0, p_in);
00341 
00342   Teuchos::RefCountPtr<const Epetra_Vector> x_in = inArgs.get_x();
00343   block_x->Epetra_Vector::operator=(*x_in); //copy into block vector
00344 
00345   // Parse OutArgs
00346   Teuchos::RefCountPtr<Epetra_Vector> f_out = outArgs.get_f();
00347 
00348   Teuchos::RefCountPtr<Epetra_Operator> W_out = outArgs.get_W();
00349   Teuchos::RefCountPtr<EpetraExt::BlockCrsMatrix> W_block =
00350      Teuchos::rcp_dynamic_cast<EpetraExt::BlockCrsMatrix>(W_out);
00351 
00352   Teuchos::RefCountPtr<Epetra_Vector> g_out;
00353   if (underlyingNg) g_out = outArgs.get_g(0);
00354   if (g_out.get()) g_out->PutScalar(0.0);
00355 
00356   EpetraExt::ModelEvaluator::Derivative DfDp_out = outArgs.get_DfDp(0);
00357 
00358   EpetraExt::ModelEvaluator::Derivative DgDx_out;
00359   EpetraExt::ModelEvaluator::Derivative DgDp_out;
00360   if (underlyingNg) {
00361     DgDx_out = outArgs.get_DgDx(0);
00362     DgDp_out = outArgs.get_DgDp(0,0);
00363     if (!DgDx_out.isEmpty()) DgDx_out.getMultiVector()->PutScalar(0.0);
00364     if (!DgDp_out.isEmpty()) DgDp_out.getMultiVector()->PutScalar(0.0);
00365   }
00366 
00367   // For mathcingProblems, g is needed to calc DgDx DgDp, so ask for
00368   //  g even if it isn't requested.
00369   bool need_g = g_out.get();
00370   if (matchingProblem)
00371     if ( !DgDx_out.isEmpty() || !DgDp_out.isEmpty() ) need_g = true;
00372 
00373 
00374   // Begin loop over Points (steps) owned on this proc
00375   for (int i=0; i < timeStepsOnTimeDomain; i++) {
00376 
00377     // Set MultiPoint parameter vector
00378     underlyingInArgs.set_p(1, (*q_vec)[i]);
00379 
00380     // Set InArgs
00381     if(longlong) {
00382 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00383       block_x->ExtractBlockValues(*split_x, (*rowIndex_LL)[i]);
00384 #endif
00385     }
00386     else {
00387 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00388       block_x->ExtractBlockValues(*split_x, (*rowIndex_int)[i]);
00389 #endif
00390     }
00391     underlyingInArgs.set_x(split_x);
00392 
00393     // Set OutArgs
00394     if (f_out.get()) underlyingOutArgs.set_f(split_f);
00395 
00396     if (need_g) underlyingOutArgs.set_g(0, split_g);
00397 
00398     if (W_out.get()) underlyingOutArgs.set_W(split_W);
00399 
00400     if (!DfDp_out.isEmpty()) underlyingOutArgs.set_DfDp(0, *deriv_DfDp);
00401 
00402     if (!DgDx_out.isEmpty()) underlyingOutArgs.set_DgDx(0, *deriv_DgDx);
00403 
00404     if (!DgDp_out.isEmpty()) underlyingOutArgs.set_DgDp(0, 0, *deriv_DgDp);
00405 
00406     //********Eval Model ********/
00407     underlyingME->evalModel(underlyingInArgs, underlyingOutArgs);
00408     //********Eval Model ********/
00409 
00410     // If matchingProblem, modify all g-related quantitites G = 0.5*(g-g*)^2 / g*^2
00411     if (matchingProblem) {
00412       if (need_g) {
00413         double diff = (*split_g)[0] -  (*(*matching_vec)[i])[0];
00414         double nrmlz = fabs((*(*matching_vec)[i])[0]) + 1.0e-6;
00415         (*split_g)[0] = 0.5 * diff * diff/(nrmlz*nrmlz);
00416         if (!DgDx_out.isEmpty()) split_DgDx->Scale(diff/(nrmlz*nrmlz));
00417         if (!DgDp_out.isEmpty()) split_DgDp->Scale(diff/(nrmlz*nrmlz));
00418       }
00419     }
00420 
00421     // Repackage block components into global block matrx/vector/multivector
00422     if(longlong) {
00423 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
00424       if (f_out.get()) block_f->LoadBlockValues(*split_f, (*rowIndex_LL)[i]);
00425       if (W_out.get()) W_block->LoadBlock(*split_W, i, 0);
00426         // note: split_DfDp points inside deriv_DfDp
00427       if (!DfDp_out.isEmpty()) block_DfDp->LoadBlockValues(*split_DfDp, (*rowIndex_LL)[i]);
00428       if (!DgDx_out.isEmpty()) block_DgDx->LoadBlockValues(*split_DgDx, (*rowIndex_LL)[i]);
00429 #endif
00430     }
00431     else {
00432 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
00433       if (f_out.get()) block_f->LoadBlockValues(*split_f, (*rowIndex_int)[i]);
00434       if (W_out.get()) W_block->LoadBlock(*split_W, i, 0);
00435         // note: split_DfDp points inside deriv_DfDp
00436       if (!DfDp_out.isEmpty()) block_DfDp->LoadBlockValues(*split_DfDp, (*rowIndex_int)[i]);
00437       if (!DgDx_out.isEmpty()) block_DgDx->LoadBlockValues(*split_DgDx, (*rowIndex_int)[i]);
00438 #endif
00439     }
00440 
00441     // Assemble multiple steps on this domain into g and dgdp(0) vectors
00442     if (g_out.get()) g_out->Update(1.0, *split_g, 1.0);
00443 
00444     if (!DgDp_out.isEmpty())
00445       DgDp_out.getMultiVector()->Update(1.0, *split_DgDp, 1.0);
00446 
00447   } // End loop over multiPoint steps on this domain/cluster
00448 
00449   //Copy block vectors into *_out vectors of same size
00450   if (f_out.get()) f_out->operator=(*block_f);
00451   if (!DfDp_out.isEmpty())
00452     DfDp_out.getMultiVector()->operator=(*block_DfDp);
00453   if (!DgDx_out.isEmpty())
00454     DgDx_out.getMultiVector()->operator=(*block_DgDx);
00455 
00456   //Sum together obj fn contributions from differnt Domains (clusters).
00457   if (numTimeDomains > 1) {
00458     double factorToZeroOutCopies = 0.0;
00459     if (globalComm->SubDomainComm().MyPID()==0) factorToZeroOutCopies = 1.0;
00460     if (g_out.get()) {
00461       (*g_out).Scale(factorToZeroOutCopies);
00462       double* vPtr = &((*g_out)[0]);
00463       Epetra_Vector tmp = *(g_out.get());
00464       globalComm->SumAll( &(tmp[0]), vPtr, num_g0);
00465     }
00466     if (!DgDp_out.isEmpty()) {
00467       DgDp_out.getMultiVector()->Scale(factorToZeroOutCopies);
00468       double* mvPtr = (*DgDp_out.getMultiVector())[0];
00469       Epetra_MultiVector tmp = *(DgDp_out.getMultiVector());
00470       globalComm->SumAll(tmp[0], mvPtr, num_dg0dp0);
00471     }
00472   }
00473 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines