EpetraExt::MultiPointModelEvaluator::MultiPointModelEvaluator( Teuchos::RefCountPtr<EpetraExt::ModelEvaluator> underlyingME_, const Teuchos::RefCountPtr<EpetraExt::MultiComm> &globalComm_, const std::vector<Epetra_Vector*> initGuessVec_, Teuchos::RefCountPtr<std::vector< Teuchos::RefCountPtr<Epetra_Vector> > > q_vec_, Teuchos::RefCountPtr<std::vector< Teuchos::RefCountPtr<Epetra_Vector> > > matching_vec_ ) : underlyingME(underlyingME_), globalComm(globalComm_), q_vec(q_vec_), underlyingNg(0), timeStepsOnTimeDomain(globalComm_->NumTimeStepsOnDomain()), numTimeDomains(globalComm_->NumSubDomains()), timeDomain(globalComm_->SubDomainRank()), #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES rowStencil_int(0), #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES rowStencil_LL(0), #endif #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES rowIndex_int(0), #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES rowIndex_LL(0), #endif matching_vec(matching_vec_) { using Teuchos::as; if (globalComm->MyPID()==0) { std::cout << "----------MultiPoint Partition Info------------" << "\n\tNumProcs = " << globalComm->NumProc() << "\n\tSpatial Decomposition = " << globalComm->SubDomainComm().NumProc() << "\n\tNumber of Domains = " << numTimeDomains << "\n\tSteps on Domain 0 = " << timeStepsOnTimeDomain << "\n\tTotal Number of Steps = " << globalComm->NumTimeSteps(); std::cout << "\n-----------------------------------------------" << std::endl; } // Construct global block matrix graph from split W and stencil, // which is just diagonal in this case split_W = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(underlyingME->create_W()); #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(split_W->RowMatrixRowMap().GlobalIndicesInt()) { longlong = false; rowStencil_int = new std::vector< std::vector<int> >(timeStepsOnTimeDomain); rowIndex_int = new std::vector<int>; for (int i=0; i < timeStepsOnTimeDomain; i++) { (*rowStencil_int)[i].push_back(0); (*rowIndex_int).push_back(i + globalComm->FirstTimeStepOnDomain()); } block_W = Teuchos::rcp(new EpetraExt::BlockCrsMatrix(*split_W, *rowStencil_int, *rowIndex_int, *globalComm)); } else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(split_W->RowMatrixRowMap().GlobalIndicesInt()) { longlong = true; rowStencil_LL = new std::vector< std::vector<long long> >(timeStepsOnTimeDomain); rowIndex_LL = new std::vector<long long>; for (int i=0; i < timeStepsOnTimeDomain; i++) { (*rowStencil_LL)[i].push_back(0); (*rowIndex_LL).push_back(i + globalComm->FirstTimeStepOnDomain()); } block_W = Teuchos::rcp(new EpetraExt::BlockCrsMatrix(*split_W, *rowStencil_LL, *rowIndex_LL, *globalComm)); } else #endif throw "EpetraExt::MultiPointModelEvaluator::MultiPointModelEvaluator: Global indices unknown"; // Test for g vector EpetraExt::ModelEvaluator::OutArgs underlyingOutArgs = underlyingME->createOutArgs(); underlyingNg = underlyingOutArgs.Ng(); if (underlyingNg) { if (underlyingOutArgs.supports(OUT_ARG_DgDp,0,0).supports(DERIV_TRANS_MV_BY_ROW)) orientation_DgDp = DERIV_TRANS_MV_BY_ROW; else orientation_DgDp = DERIV_MV_BY_COL; } // This code assumes 2 parameter vectors, 1 for opt, second for MultiPoint states TEUCHOS_TEST_FOR_EXCEPT(underlyingOutArgs.Np()!=2); // temporary quantities const Epetra_Map& split_map = split_W->RowMatrixRowMap(); num_p0 = underlyingME_->get_p_map(0)->NumMyElements(); if (underlyingNg) num_g0 = underlyingME_->get_g_map(0)->NumMyElements(); else num_g0 = 0; num_dg0dp0 = num_g0 * num_p0; // Construct global solution vector, residual vector -- local storage block_x = new EpetraExt::BlockVector(split_map, block_W->RowMap()); block_f = new EpetraExt::BlockVector(*block_x); block_DfDp = new EpetraExt::BlockMultiVector(split_map, block_W->RowMap(), num_p0); if (underlyingNg) block_DgDx = new EpetraExt::BlockMultiVector(split_map, block_W->RowMap(), num_g0); // Allocate local storage of epetra vectors split_x = Teuchos::rcp(new Epetra_Vector(split_map)); split_f = Teuchos::rcp(new Epetra_Vector(split_map)); split_DfDp = Teuchos::rcp(new Epetra_MultiVector(split_map, num_p0)); if (underlyingNg) split_DgDx = Teuchos::rcp(new Epetra_MultiVector(split_map, num_g0)); if (underlyingNg) { if(orientation_DgDp == DERIV_TRANS_MV_BY_ROW) split_DgDp = Teuchos::rcp(new Epetra_MultiVector(*(underlyingME_->get_p_map(0)), num_g0)); else split_DgDp = Teuchos::rcp(new Epetra_MultiVector(*(underlyingME_->get_g_map(0)), num_p0)); } if (underlyingNg) split_g = Teuchos::rcp(new Epetra_Vector(*(underlyingME_->get_g_map(0)))); // Packaging required for getting multivectors back as Derivatives derivMV_DfDp = new EpetraExt::ModelEvaluator::DerivativeMultiVector(split_DfDp); deriv_DfDp = new EpetraExt::ModelEvaluator::Derivative(*derivMV_DfDp); if (underlyingNg) { derivMV_DgDx = new EpetraExt::ModelEvaluator::DerivativeMultiVector(split_DgDx, DERIV_TRANS_MV_BY_ROW); deriv_DgDx = new EpetraExt::ModelEvaluator::Derivative(*derivMV_DgDx); derivMV_DgDp = new EpetraExt::ModelEvaluator::DerivativeMultiVector(split_DgDp, orientation_DgDp); deriv_DgDp = new EpetraExt::ModelEvaluator::Derivative(*derivMV_DgDp); } // For 4D, we will need the overlap vector and importer between them // Overlap not needed for MultiPoint -- no overlap between blocks /* solutionOverlap = new EpetraExt::BlockVector(split_W->RowMatrixRowMap(), block_W->ColMap()); overlapImporter = new Epetra_Import(solutionOverlap->Map(), block_x->Map()); */ // Load initial guess into block solution vector solution_init = Teuchos::rcp(new EpetraExt::BlockVector(*block_x)); if(longlong) { #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES for (int i=0; i < timeStepsOnTimeDomain; i++) solution_init->LoadBlockValues(*(initGuessVec_[i]), (*rowIndex_LL)[i]); #endif } else { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES for (int i=0; i < timeStepsOnTimeDomain; i++) solution_init->LoadBlockValues(*(initGuessVec_[i]), (*rowIndex_int)[i]); #endif } //Prepare logic for matching problem if (Teuchos::is_null(matching_vec)) matchingProblem = false; else matchingProblem = true; if (matchingProblem) { TEUCHOS_TEST_FOR_EXCEPT(as<int>(matching_vec->size())!=timeStepsOnTimeDomain); TEUCHOS_TEST_FOR_EXCEPT(!(*matching_vec)[0]->Map().SameAs(*(underlyingME_->get_g_map(0)))); TEUCHOS_TEST_FOR_EXCEPT(num_g0 != 1); //This restriction may be lifted later } }