//Neumann BCs void Albany::PNPProblem::constructNeumannEvaluators(const Teuchos::RCP<Albany::MeshSpecsStruct>& meshSpecs) { // Note: we only enter this function if sidesets are defined in the mesh file // i.e. meshSpecs.ssNames.size() > 0 Albany::BCUtils<Albany::NeumannTraits> nbcUtils; // Check to make sure that Neumann BCs are given in the input file if(!nbcUtils.haveBCSpecified(this->params)) { return; } // Construct BC evaluators for all side sets and names // Note that the string index sets up the equation offset, so ordering is important // // Currently we aren't exactly doing this right. I think to do this // correctly we need different neumann evaluators for each DOF (velocity, // pressure, temperature, flux) since velocity is a vector and the // others are scalars. The dof_names stuff is only used // for robin conditions, so at this point, as long as we don't enable // robin conditions, this should work. std::vector<std::string> nbcNames; Teuchos::RCP< Teuchos::Array<std::string> > dof_names = Teuchos::rcp(new Teuchos::Array<std::string>); // TODO: arbitraty numSpecies Teuchos::Array<Teuchos::Array<int> > offsets; int idx = 0; nbcNames.push_back("C1"); offsets.push_back(Teuchos::Array<int>(1,idx++)); if (numSpecies>=2) { nbcNames.push_back("C2"); offsets.push_back(Teuchos::Array<int>(1,idx++)); } if (numSpecies==3) { nbcNames.push_back("C3"); offsets.push_back(Teuchos::Array<int>(1,idx++)); } nbcNames.push_back("Phi"); offsets.push_back(Teuchos::Array<int>(1,idx++)); dof_names->push_back("Concentration"); dof_names->push_back("Potential"); // Construct BC evaluators for all possible names of conditions // Should only specify flux vector components (dudx, dudy, dudz), or dudn, not both std::vector<std::string> condNames; //dudx, dudy, dudz, dudn, basal nfm[0] = nbcUtils.constructBCEvaluators(meshSpecs, nbcNames, Teuchos::arcp(dof_names), true, 0, condNames, offsets, dl, this->params, this->paramLib); }
void Tpetra::Utils::generateMatrix(const Teuchos::RCP<Teuchos::ParameterList> &plist, const Teuchos::RCP<const Teuchos::Comm<int> > &comm, const Teuchos::RCP<Node> &node, Teuchos::RCP< Tpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node,LocalMatOps> > &A) { typedef Teuchos::ScalarTraits<Scalar> ST; using Teuchos::as; TEUCHOS_TEST_FOR_EXCEPTION( plist == Teuchos::null, std::runtime_error, "Tpetra::Utils::generateMatrix(): ParameterList is null."); TEUCHOS_TEST_FOR_EXCEPTION( Teuchos::isParameterType<std::string>(*plist,"mat_type") == false, std::runtime_error, "Tpetra::Utils::generateMatrix(): ParameterList did not contain string parameter ""mat_type""."); std::string mat_type = plist->get<std::string>("mat_type"); if (mat_type == "Lap3D") { // 3D Laplacian, grid is a cube with dimension gridSize x gridSize x gridSize const GlobalOrdinal gridSize = as<GlobalOrdinal>(plist->get<int>("gridSize",100)); const GlobalOrdinal gS2 = gridSize*gridSize; const GlobalOrdinal numRows = gS2*gridSize; Teuchos::RCP<Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > rowMap; rowMap = Teuchos::rcp(new Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node>(as<global_size_t>(numRows),as<GlobalOrdinal>(0),comm,GloballyDistributed,node)); A = rcp(new Tpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>(rowMap,7,Tpetra::StaticProfile)); // fill matrix, one row at a time Teuchos::Array<GlobalOrdinal> neighbors; Teuchos::Array<Scalar> values(7, -ST::one()); values[0] = (Scalar)6; for (GlobalOrdinal r = rowMap->getMinGlobalIndex(); r <= rowMap->getMaxGlobalIndex(); ++r) { neighbors.clear(); neighbors.push_back(r); // add diagonal GlobalOrdinal ixy, iz, ix, iy; // (x,y,z) coords and index in xy plane ixy = r%gS2; iz = (r - ixy)/gS2; ix = ixy%gridSize; iy = (ixy - ix)/gridSize; // if ( ix != 0 ) neighbors.push_back( r-1 ); if ( ix != gridSize-1 ) neighbors.push_back( r+1 ); if ( iy != 0 ) neighbors.push_back( r-gridSize ); if ( iy != gridSize-1 ) neighbors.push_back( r+gridSize ); if ( iz != 0 ) neighbors.push_back( r-gS2 ); if ( iz != gridSize-1 ) neighbors.push_back( r+gS2 ); A->insertGlobalValues( r, neighbors(), values(0,neighbors.size()) ); } A->fillComplete(); } else { TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error, "Tpetra::Utils::generateMatrix(): ParameterList specified unsupported ""mat_type""."); } }
Teuchos::Array<int> getMyBlockLIDs( const Teuchos::ParameterList &blockingParams, const Albany::AbstractDiscretization &disc) { Teuchos::Array<int> result; const std::string nodeSetLabel = blockingParams.get<std::string>("Node Set"); const int dofRank = blockingParams.get<int>("Dof"); const Albany::NodeSetList &nodeSets = disc.getNodeSets(); const Albany::NodeSetList::const_iterator it = nodeSets.find(nodeSetLabel); TEUCHOS_TEST_FOR_EXCEPT(it == nodeSets.end()); { typedef Albany::NodeSetList::mapped_type NodeSetEntryList; const NodeSetEntryList &nodeEntries = it->second; for (NodeSetEntryList::const_iterator jt = nodeEntries.begin(); jt != nodeEntries.end(); ++jt) { typedef NodeSetEntryList::value_type NodeEntryList; const NodeEntryList &entries = *jt; result.push_back(entries[dofRank]); } } return result; }
Teuchos::Array<bool> createResponseTable( int count, const std::string selectionType, int index, const Teuchos::ArrayView<const int> &list) { Teuchos::Array<bool> result; if (count > 0) { if (selectionType == "All") { result.resize(count, true); } else if (selectionType == "Last") { result = createResponseTableFromIndex(count - 1, count); } else if (selectionType == "AllButLast") { result.reserve(count); result.resize(count - 1, true); result.push_back(false); } else if (selectionType == "Index") { result = createResponseTableFromIndex(index, count); } else if (selectionType == "List") { result.resize(count, false); for (Teuchos::ArrayView<const int>::const_iterator it = list.begin(), it_end = list.end(); it != it_end; ++it) { result.at(*it) = true; } } else { TEUCHOS_TEST_FOR_EXCEPT(false); } } return result; }
Teuchos::Array<GO> Albany::NodeGIDsSolutionCullingStrategy:: selectedGIDsT(Teuchos::RCP<const Tpetra_Map> sourceMapT) const { Teuchos::Array<GO> result; { Teuchos::Array<GO> mySelectedGIDs; // Subract 1 to convert exodus GIDs to our GIDs for (int i=0; i<nodeGIDs_.size(); i++) if (sourceMapT->isNodeGlobalElement(nodeGIDs_[i] -1) ) mySelectedGIDs.push_back(nodeGIDs_[i] - 1); Teuchos::RCP<const Teuchos::Comm<int> >commT = sourceMapT->getComm(); { GO selectedGIDCount; { GO mySelectedGIDCount = mySelectedGIDs.size(); Teuchos::reduceAll<LO, GO>(*commT, Teuchos::REDUCE_SUM, 1, &mySelectedGIDCount, &selectedGIDCount); } result.resize(selectedGIDCount); } const int ierr = Tpetra::GatherAllV( commT, mySelectedGIDs.getRawPtr(), mySelectedGIDs.size(), result.getRawPtr(), result.size()); TEUCHOS_ASSERT(ierr == 0); } std::sort(result.begin(), result.end()); return result; }
Teuchos::RCP<const Tpetra::Map<LO,GO,Node> > createMeshMap (const LO& blockSize, const Tpetra::Map<LO,GO,Node>& pointMap) { typedef Teuchos::OrdinalTraits<Tpetra::global_size_t> TOT; typedef Tpetra::Map<LO,GO,Node> map_type; //calculate mesh GIDs Teuchos::ArrayView<const GO> pointGids = pointMap.getNodeElementList(); Teuchos::Array<GO> meshGids; GO indexBase = pointMap.getIndexBase(); // Use hash table to track whether we've encountered this GID previously. This will happen // when striding through the point DOFs in a block. It should not happen otherwise. // I don't use sort/make unique because I don't want to change the ordering. meshGids.reserve(pointGids.size()); Tpetra::Details::HashTable<GO,int> hashTable(pointGids.size()); for (int i=0; i<pointGids.size(); ++i) { GO meshGid = (pointGids[i]-indexBase) / blockSize + indexBase; if (hashTable.get(meshGid) == -1) { hashTable.add(meshGid,1); //(key,value) meshGids.push_back(meshGid); } } Teuchos::RCP<const map_type> meshMap = Teuchos::rcp( new map_type(TOT::invalid(), meshGids(), 0, pointMap.getComm()) ); return meshMap; }
// ============================================================================ Teuchos::RCP<Recti::Domain::Abstract> Recti::Domain::Factory:: buildPolygon() const { const Teuchos::ParameterList & pointsList = pList_.sublist("Vertices"); Teuchos::Array<Point> vertices; Teuchos::ParameterList::ConstIterator k; for ( k=pointsList.begin(); k!=pointsList.end(); ++k ) { Teuchos::ParameterEntry e = pointsList.entry(k); TEUCHOS_ASSERT( e.isList() ); std::string label = pointsList.name(k); const Teuchos::ParameterList & coordinates = pointsList.sublist(label); Point X = Teuchos::tuple( coordinates.get<double>("x"), coordinates.get<double>("y"), 0.0 ); vertices.push_back( X ); } return Teuchos::rcp( new Polygon( vertices ) ); }
Teuchos::Array<int> Albany::NodeGIDsSolutionCullingStrategy:: selectedGIDs(const Epetra_BlockMap &sourceMap) const { Teuchos::Array<int> result; { Teuchos::Array<int> mySelectedGIDs; // Subract 1 to convert exodus GIDs to our GIDs for (int i=0; i<nodeGIDs_.size(); i++) if (sourceMap.MyGID(nodeGIDs_[i] -1) ) mySelectedGIDs.push_back(nodeGIDs_[i] - 1); const Epetra_Comm &comm = sourceMap.Comm(); { int selectedGIDCount; { int mySelectedGIDCount = mySelectedGIDs.size(); comm.SumAll(&mySelectedGIDCount, &selectedGIDCount, 1); } result.resize(selectedGIDCount); } const int ierr = Epetra::GatherAllV( comm, mySelectedGIDs.getRawPtr(), mySelectedGIDs.size(), result.getRawPtr(), result.size()); TEUCHOS_ASSERT(ierr == 0); } std::sort(result.begin(), result.end()); return result; }
Teuchos::Array<std::string> SolverFactory<Scalar, MV, OP>::supportedSolverNames () const { typedef std::vector<std::string>::const_iterator iter_type; Teuchos::Array<std::string> names; { std::vector<std::string> aliases = Details::solverNameAliases (); for (iter_type iter = aliases.begin (); iter != aliases.end (); ++iter) { names.push_back (*iter); } } { std::vector<std::string> canonicalNames = Details::canonicalSolverNames (); for (iter_type iter = canonicalNames.begin (); iter != canonicalNames.end (); ++iter) { names.push_back (*iter); } } return names; }
void EricksonManufacturedSolution::getConstraints(FieldContainer<double> &physicalPoints, FieldContainer<double> &unitNormals, vector<map<int,FieldContainer<double > > > &constraintCoeffs, vector<FieldContainer<double > > &constraintValues){ int numCells = physicalPoints.dimension(0); int numPoints = physicalPoints.dimension(1); int spaceDim = physicalPoints.dimension(2); map<int,FieldContainer<double> > outflowConstraint; FieldContainer<double> uCoeffs(numCells,numPoints); FieldContainer<double> beta_sigmaCoeffs(numCells,numPoints); FieldContainer<double> outflowValues(numCells,numPoints); double tol = 1e-12; // default to no constraints, apply on outflow only uCoeffs.initialize(0.0); beta_sigmaCoeffs.initialize(0.0); outflowValues.initialize(0.0); Teuchos::Array<int> pointDimensions; pointDimensions.push_back(2); for (int cellIndex=0;cellIndex<numCells;cellIndex++){ for (int pointIndex=0;pointIndex<numPoints;pointIndex++){ FieldContainer<double> physicalPoint(pointDimensions, &physicalPoints(cellIndex,pointIndex,0)); FieldContainer<double> unitNormal(pointDimensions, &unitNormals(cellIndex,pointIndex,0)); double x = physicalPoints(cellIndex,pointIndex,0); double y = physicalPoints(cellIndex,pointIndex,1); double beta_n = _beta_x*unitNormals(cellIndex,pointIndex,0)+_beta_y*unitNormals(cellIndex,pointIndex,1); if ( abs(x-1.0) < tol ) { // if on outflow boundary TEUCHOS_TEST_FOR_EXCEPTION(beta_n < 0,std::invalid_argument,"Inflow condition on boundary"); // this combo isolates sigma_n //uCoeffs(cellIndex,pointIndex) = 1.0; uCoeffs(cellIndex,pointIndex) = beta_n; beta_sigmaCoeffs(cellIndex,pointIndex) = -1.0; double beta_n_u_minus_sigma_n = solutionValue(ConfusionBilinearForm::BETA_N_U_MINUS_SIGMA_HAT, physicalPoint, unitNormal); double u_hat = solutionValue(ConfusionBilinearForm::U_HAT, physicalPoint, unitNormal); outflowValues(cellIndex,pointIndex) = beta_n*u_hat - beta_n_u_minus_sigma_n; // sigma_n } } } outflowConstraint[ConfusionBilinearForm::U_HAT] = uCoeffs; outflowConstraint[ConfusionBilinearForm::BETA_N_U_MINUS_SIGMA_HAT] = beta_sigmaCoeffs; if (!_useWallBC){ constraintCoeffs.push_back(outflowConstraint); // only one constraint on outflow constraintValues.push_back(outflowValues); // only one constraint on outflow } }
/*! \brief Get the parts belonging to this rank * \param numParts on return, set to the number of parts assigned to rank. * \param parts on return, pointer (view) to the parts assigned to rank */ void getMyPartsView(part_t &numParts, part_t *&parts) { bool useAlg = true; // Check first whether this algorithm answers getMyPartsView. if (mapping_algorithm != Teuchos::null) { try { mapping_algorithm->getMyPartsView(numParts, parts); } catch (NotImplemented &e) { // It is OK if the algorithm did not implement this method; // we'll get the information from the solution below. useAlg = false; } Z2_FORWARD_EXCEPTIONS; } if (!useAlg) { // Algorithm did not implement this method. // Did the algorithm register a result with the solution? if ((partsForRank==Teuchos::null) && (rankForPart==Teuchos::null)) { numParts = 0; parts = NULL; throw std::runtime_error("No mapping solution available."); } if (partsForRank == Teuchos::null) { // Need to create the array since we haven't created it before. Teuchos::Array<part_t> tmp; part_t cnt = 0; for (typename rankmap_t::iterator it = rankForPart->begin(); it != rankForPart->end(); it++) { if (it->second == myRank) { tmp.push_back(it->first); cnt++; } } if (cnt) partsForRank = arcp(&tmp[0], 0, cnt, true); } numParts = partsForRank.size(); if (numParts) parts = partsForRank.getRawPtr(); else parts = NULL; } }
void EricksonManufacturedSolution::imposeBC(int varID, FieldContainer<double> &physicalPoints, FieldContainer<double> &unitNormals, FieldContainer<double> &dirichletValues, FieldContainer<bool> &imposeHere) { int numCells = physicalPoints.dimension(0); int numPoints = physicalPoints.dimension(1); int spaceDim = physicalPoints.dimension(2); TEUCHOS_TEST_FOR_EXCEPTION( ( spaceDim != 2 ), std::invalid_argument, "ConfusionBC expects spaceDim==2."); TEUCHOS_TEST_FOR_EXCEPTION( ( dirichletValues.dimension(0) != numCells ) || ( dirichletValues.dimension(1) != numPoints ) || ( dirichletValues.rank() != 2 ), std::invalid_argument, "dirichletValues dimensions should be (numCells,numPoints)."); TEUCHOS_TEST_FOR_EXCEPTION( ( imposeHere.dimension(0) != numCells ) || ( imposeHere.dimension(1) != numPoints ) || ( imposeHere.rank() != 2 ), std::invalid_argument, "imposeHere dimensions should be (numCells,numPoints)."); Teuchos::Array<int> pointDimensions; pointDimensions.push_back(2); for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { FieldContainer<double> physicalPoint(pointDimensions, &physicalPoints(cellIndex,ptIndex,0)); FieldContainer<double> unitNormal(pointDimensions, &unitNormals(cellIndex,ptIndex,0)); double beta_n = unitNormals(cellIndex,ptIndex,0)*_beta_x + unitNormals(cellIndex,ptIndex,1)*_beta_y; double x = physicalPoint(cellIndex,ptIndex,0); double y = physicalPoint(cellIndex,ptIndex,1); imposeHere(cellIndex,ptIndex) = false; // if (varID==ConfusionBilinearForm::BETA_N_U_MINUS_SIGMA_HAT) { // dirichletValues(cellIndex,ptIndex) = solutionValue(varID, physicalPoint, unitNormal); if (varID==ConfusionBilinearForm::U_HAT) { dirichletValues(cellIndex,ptIndex) = solutionValue(varID, physicalPoint); if ( abs(x-1.0) > 1e-12) { // if not the outflow (pts on boundary already) imposeHere(cellIndex,ptIndex) = true; } // wall boundary if (abs(x-1.0)<1e-12 && _useWallBC){ dirichletValues(cellIndex,ptIndex) = solutionValue(varID, physicalPoint); imposeHere(cellIndex,ptIndex) = true; } } } } }
void epetraFromThyra( const Teuchos::RCP<const Epetra_Comm> &comm, const Teuchos::Array<Teuchos::RCP<const Thyra::VectorBase<double> > > &thyraResponses, const Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Thyra::MultiVectorBase<double> > > > &thyraSensitivities, Teuchos::Array<Teuchos::RCP<const Epetra_Vector> > &responses, Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Epetra_MultiVector> > > &sensitivities) { responses.clear(); responses.reserve(thyraResponses.size()); typedef Teuchos::Array<Teuchos::RCP<const Thyra::VectorBase<double> > > ThyraResponseArray; for (ThyraResponseArray::const_iterator it_begin = thyraResponses.begin(), it_end = thyraResponses.end(), it = it_begin; it != it_end; ++it) { responses.push_back(epetraVectorFromThyra(comm, *it)); } sensitivities.clear(); sensitivities.reserve(thyraSensitivities.size()); typedef Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Thyra::MultiVectorBase<double> > > > ThyraSensitivityArray; for (ThyraSensitivityArray::const_iterator it_begin = thyraSensitivities.begin(), it_end = thyraSensitivities.end(), it = it_begin; it != it_end; ++it) { ThyraSensitivityArray::const_reference sens_thyra = *it; Teuchos::Array<Teuchos::RCP<const Epetra_MultiVector> > sens; sens.reserve(sens_thyra.size()); for (ThyraSensitivityArray::value_type::const_iterator jt = sens_thyra.begin(), jt_end = sens_thyra.end(); jt != jt_end; ++jt) { sens.push_back(epetraMultiVectorFromThyra(comm, *jt)); } sensitivities.push_back(sens); } }
Teuchos::Array< int > splitStringOfIntsWithCommas(std::string data) { Teuchos::Array< int > result; size_t current = 0; while (current < data.size()) { size_t next = data.find(",", current); if (next == std::string::npos) next = data.size(); result.push_back(atoi(data.substr(current, next-current).c_str())); current = next + 1; } return result; }
void tpetraFromThyra( const Teuchos::Array<Teuchos::RCP<const Thyra::VectorBase<ST> > > &thyraResponses, const Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Thyra::MultiVectorBase<ST> > > > &thyraSensitivities, Teuchos::Array<Teuchos::RCP<const Tpetra_Vector> > &responses, Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Tpetra_MultiVector> > > &sensitivities) { responses.clear(); responses.reserve(thyraResponses.size()); typedef Teuchos::Array<Teuchos::RCP<const Thyra::VectorBase<ST> > > ThyraResponseArray; for (ThyraResponseArray::const_iterator it_begin = thyraResponses.begin(), it_end = thyraResponses.end(), it = it_begin; it != it_end; ++it) { responses.push_back(Teuchos::nonnull(*it) ? ConverterT::getConstTpetraVector(*it) : Teuchos::null); } sensitivities.clear(); sensitivities.reserve(thyraSensitivities.size()); typedef Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Thyra::MultiVectorBase<ST> > > > ThyraSensitivityArray; for (ThyraSensitivityArray::const_iterator it_begin = thyraSensitivities.begin(), it_end = thyraSensitivities.end(), it = it_begin; it != it_end; ++it) { ThyraSensitivityArray::const_reference sens_thyra = *it; Teuchos::Array<Teuchos::RCP<const Tpetra_MultiVector> > sens; sens.reserve(sens_thyra.size()); for (ThyraSensitivityArray::value_type::const_iterator jt = sens_thyra.begin(), jt_end = sens_thyra.end(); jt != jt_end; ++jt) { sens.push_back(Teuchos::nonnull(*jt) ? ConverterT::getConstTpetraMultiVector(*jt) : Teuchos::null); } sensitivities.push_back(sens); } }
Teuchos::Array<int> Albany::NodeSetSolutionCullingStrategy:: selectedGIDs(const Epetra_BlockMap &sourceMap) const { Teuchos::Array<int> result; { Teuchos::Array<int> mySelectedGIDs; { const NodeSetList &nodeSets = disc_->getNodeSets(); const NodeSetList::const_iterator it = nodeSets.find(nodeSetLabel_); if (it != nodeSets.end()) { typedef NodeSetList::mapped_type NodeSetEntryList; const NodeSetEntryList &sampleNodeEntries = it->second; for (NodeSetEntryList::const_iterator jt = sampleNodeEntries.begin(); jt != sampleNodeEntries.end(); ++jt) { typedef NodeSetEntryList::value_type NodeEntryList; const NodeEntryList &sampleEntries = *jt; for (NodeEntryList::const_iterator kt = sampleEntries.begin(); kt != sampleEntries.end(); ++kt) { mySelectedGIDs.push_back(sourceMap.GID(*kt)); } } } } const Epetra_Comm &comm = sourceMap.Comm(); { int selectedGIDCount; { int mySelectedGIDCount = mySelectedGIDs.size(); comm.SumAll(&mySelectedGIDCount, &selectedGIDCount, 1); } result.resize(selectedGIDCount); } const int ierr = Epetra::GatherAllV( comm, mySelectedGIDs.getRawPtr(), mySelectedGIDs.size(), result.getRawPtr(), result.size()); TEUCHOS_ASSERT(ierr == 0); } std::sort(result.begin(), result.end()); return result; }
Teuchos::Array<GO> Albany::NodeSetSolutionCullingStrategy:: selectedGIDsT(Teuchos::RCP<const Tpetra_Map> sourceMapT) const { Teuchos::Array<GO> result; { Teuchos::Array<GO> mySelectedGIDs; { const NodeSetList &nodeSets = disc_->getNodeSets(); const NodeSetList::const_iterator it = nodeSets.find(nodeSetLabel_); if (it != nodeSets.end()) { typedef NodeSetList::mapped_type NodeSetEntryList; const NodeSetEntryList &sampleNodeEntries = it->second; for (NodeSetEntryList::const_iterator jt = sampleNodeEntries.begin(); jt != sampleNodeEntries.end(); ++jt) { typedef NodeSetEntryList::value_type NodeEntryList; const NodeEntryList &sampleEntries = *jt; for (NodeEntryList::const_iterator kt = sampleEntries.begin(); kt != sampleEntries.end(); ++kt) { mySelectedGIDs.push_back(sourceMapT->getGlobalElement(*kt)); } } } } Teuchos::RCP<const Teuchos::Comm<int> >commT = sourceMapT->getComm(); { GO selectedGIDCount; { GO mySelectedGIDCount = mySelectedGIDs.size(); Teuchos::reduceAll<LO, GO>(*commT, Teuchos::REDUCE_SUM, 1, &mySelectedGIDCount, &selectedGIDCount); } result.resize(selectedGIDCount); } const int ierr = Tpetra::GatherAllV( commT, mySelectedGIDs.getRawPtr(), mySelectedGIDs.size(), result.getRawPtr(), result.size()); TEUCHOS_ASSERT(ierr == 0); } std::sort(result.begin(), result.end()); return result; }
void ExactSolution::solutionValues(FieldContainer<double> &values, int trialID, FieldContainer<double> &physicalPoints) { int numCells = physicalPoints.dimension(0); int numPoints = physicalPoints.dimension(1); int spaceDim = physicalPoints.dimension(2); Teuchos::Array<int> pointDimensions; pointDimensions.push_back(spaceDim); // cout << "ExactSolution: physicalPoints:\n" << physicalPoints; for (int cellIndex=0; cellIndex<numCells; cellIndex++) { for (int ptIndex=0; ptIndex<numPoints; ptIndex++) { FieldContainer<double> point(pointDimensions,&physicalPoints(cellIndex,ptIndex,0)); double value = solutionValue(trialID, point); values(cellIndex,ptIndex) = value; } } }
void EricksonManufacturedSolution::getValues(FieldContainer<double> &functionValues, const FieldContainer<double> &physicalPoints){ int numCells = physicalPoints.dimension(0); int numPoints = physicalPoints.dimension(1); int spaceDim = physicalPoints.dimension(2); functionValues.resize(numCells,numPoints); Teuchos::Array<int> pointDimensions; pointDimensions.push_back(spaceDim); for (int i=0;i<numCells;i++){ for (int j=0;j<numPoints;j++){ double x = physicalPoints(i,j,0); double y = physicalPoints(i,j,1); FieldContainer<double> physicalPoint(pointDimensions); physicalPoint(0) = x; physicalPoint(1) = y; functionValues(i,j) = solutionValue(ConfusionBilinearForm::U,physicalPoint); } } }
FCPtr BasisEvaluation::getTransformedVectorValuesWithComponentBasisValues(VectorBasisPtr basis, Camellia::EOperator op, constFCPtr componentReferenceValuesTransformed) { Camellia::EFunctionSpace fs = basis->functionSpace(); bool vectorizedBasis = Camellia::functionSpaceIsVectorized(fs); if ( !vectorizedBasis || ((op != Camellia::OP_VALUE) && (op != Camellia::OP_CROSS_NORMAL) )) { TEUCHOS_TEST_FOR_EXCEPTION( !vectorizedBasis || (op != Camellia::OP_VALUE), std::invalid_argument, "Only Vector HGRAD/HVOL with OP_VALUE supported by getTransformedVectorValuesWithComponentBasisValues. Please use getTransformedValuesWithBasisValues instead."); } BasisPtr componentBasis = basis->getComponentBasis(); Teuchos::Array<int> dimensions; componentReferenceValuesTransformed->dimensions(dimensions); dimensions[1] = basis->getCardinality(); // dimensions are (C,F,P,D) dimensions.push_back(basis->getNumComponents()); Teuchos::RCP<FieldContainer<double> > transformedValues = Teuchos::rcp(new FieldContainer<double>(dimensions)); int fieldIndex = 1; basis->getVectorizedValues(*transformedValues, *componentReferenceValuesTransformed,fieldIndex); return transformedValues; }
int main( int argc, char* argv[] ) { #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif // Create command line processor Teuchos::CommandLineProcessor RBGen_CLP; RBGen_CLP.recogniseAllOptions( false ); RBGen_CLP.throwExceptions( false ); // Generate list of acceptable command line options bool verbose = false; std::string xml_file = ""; RBGen_CLP.setOption("verbose", "quiet", &verbose, "Print messages and results."); RBGen_CLP.setOption("xml-file", &xml_file, "XML Input File"); // Process command line. Teuchos::CommandLineProcessor::EParseCommandLineReturn parseReturn= RBGen_CLP.parse( argc, argv ); if( parseReturn == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED ) { return 0; } if( parseReturn != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL ) { #ifdef EPETRA_MPI MPI_Finalize(); #endif return -1; // Error! } // Check to make sure an XML input file was provided TEUCHOS_TEST_FOR_EXCEPTION(xml_file == "", std::invalid_argument, "ERROR: An XML file was not provided; use --xml-file to provide an XML input file for this RBGen driver."); Teuchos::Array<Teuchos::RCP<Teuchos::Time> > timersRBGen; // // --------------------------------------------------------------- // CREATE THE INITIAL PARAMETER LIST FROM THE INPUT XML FILE // --------------------------------------------------------------- // Teuchos::RCP<Teuchos::ParameterList> BasisParams = RBGen::createParams( xml_file ); if (verbose && Comm.MyPID() == 0) { std::cout<<"-------------------------------------------------------"<<std::endl; std::cout<<"Input Parameter List: "<<std::endl; std::cout<<"-------------------------------------------------------"<<std::endl; BasisParams->print(); } // // --------------------------------------------------------------- // CREATE THE FILE I/O HANDLER // --------------------------------------------------------------- // // - First create the abstract factory for the file i/o handler. // RBGen::EpetraMVFileIOFactory fio_factory; // // - Then use the abstract factory to create the file i/o handler specified in the parameter list. // Teuchos::RCP<Teuchos::Time> timerFileIO = Teuchos::rcp( new Teuchos::Time("Create File I/O Handler") ); timersRBGen.push_back( timerFileIO ); // Teuchos::RCP< RBGen::FileIOHandler<Epetra_MultiVector> > mvFileIO; Teuchos::RCP< RBGen::FileIOHandler<Epetra_Operator> > opFileIO = Teuchos::rcp( new RBGen::EpetraCrsMatrixFileIOHandler() ); { Teuchos::TimeMonitor lcltimer( *timerFileIO ); mvFileIO = fio_factory.create( *BasisParams ); // // Initialize file IO handlers // mvFileIO->Initialize( BasisParams ); opFileIO->Initialize( BasisParams ); } if (verbose && Comm.MyPID() == 0) { std::cout<<"-------------------------------------------------------"<<std::endl; std::cout<<"File I/O Handlers Generated"<<std::endl; std::cout<<"-------------------------------------------------------"<<std::endl; } // // --------------------------------------------------------------- // READ IN THE DATA SET / SNAPSHOT SET & PREPROCESS // ( this will be a separate abstract class type ) // --------------------------------------------------------------- // Teuchos::RCP<std::vector<std::string> > filenames = RBGen::genFileList( *BasisParams ); Teuchos::RCP<Teuchos::Time> timerSnapshotIn = Teuchos::rcp( new Teuchos::Time("Reading in Snapshot Set") ); timersRBGen.push_back( timerSnapshotIn ); // Teuchos::RCP<Epetra_MultiVector> testMV; { Teuchos::TimeMonitor lcltimer( *timerSnapshotIn ); testMV = mvFileIO->Read( *filenames ); } RBGen::EpetraMVPreprocessorFactory preprocess_factory; Teuchos::RCP<Teuchos::Time> timerCreatePreprocessor = Teuchos::rcp( new Teuchos::Time("Create Preprocessor") ); timersRBGen.push_back( timerCreatePreprocessor ); Teuchos::RCP<RBGen::Preprocessor<Epetra_MultiVector> > prep; { Teuchos::TimeMonitor lcltimer( *timerCreatePreprocessor ); prep = preprocess_factory.create( *BasisParams ); // // Initialize preprocessor. // prep->Initialize( BasisParams, mvFileIO ); } Teuchos::RCP<Teuchos::Time> timerPreprocess = Teuchos::rcp( new Teuchos::Time("Preprocess Snapshot Set") ); timersRBGen.push_back( timerPreprocess ); { Teuchos::TimeMonitor lcltimer( *timerPreprocess ); prep->Preprocess( testMV ); } if (verbose && Comm.MyPID() == 0) { std::cout<<"-------------------------------------------------------"<<std::endl; std::cout<<"Snapshot Set Imported and Preprocessed"<<std::endl; std::cout<<"-------------------------------------------------------"<<std::endl; } // // --------------------------------------------------------------- // COMPUTE THE REDUCED BASIS // --------------------------------------------------------------- // // - First create the abstract factory for the reduced basis methods. // RBGen::EpetraMVMethodFactory mthd_factory; // // - Then use the abstract factory to create the method specified in the parameter list. // Teuchos::RCP<Teuchos::Time> timerCreateMethod = Teuchos::rcp( new Teuchos::Time("Create Reduced Basis Method") ); timersRBGen.push_back( timerCreateMethod ); Teuchos::RCP<RBGen::Method<Epetra_MultiVector,Epetra_Operator> > method; { Teuchos::TimeMonitor lcltimer( *timerCreateMethod ); method = mthd_factory.create( *BasisParams ); // // Initialize reduced basis method. // method->Initialize( BasisParams, testMV, opFileIO ); } // // - Call the computeBasis method on the reduced basis method object. // Teuchos::RCP<Teuchos::Time> timerComputeBasis = Teuchos::rcp( new Teuchos::Time("Reduced Basis Computation") ); timersRBGen.push_back( timerComputeBasis ); { Teuchos::TimeMonitor lcltimer( *timerComputeBasis ); method->computeBasis(); } // // - Retrieve the computed basis from the method object. // Teuchos::RCP<const Epetra_MultiVector> basisMV = method->getBasis(); // // Since we're using a POD method, we can dynamic cast to get the singular values. // Teuchos::RCP<RBGen::PODMethod<double> > pod_method = Teuchos::rcp_dynamic_cast<RBGen::PODMethod<double> >( method ); const std::vector<double> sv = pod_method->getSingularValues(); // if (verbose && Comm.MyPID() == 0) { std::cout<<"-------------------------------------------------------"<<std::endl; std::cout<<"Computed Singular Values : "<<std::endl; std::cout<<"-------------------------------------------------------"<<std::endl; for (unsigned int i=0; i<sv.size(); ++i) { std::cout << sv[i] << std::endl; } } if (Comm.MyPID() == 0) { std::cout<<"-------------------------------------------------------"<<std::endl; std::cout<<"RBGen Computation Time Breakdown (seconds) : "<<std::endl; std::cout<<"-------------------------------------------------------"<<std::endl; for (unsigned int i=0; i<timersRBGen.size(); ++i) std::cout << std::left << std::setw(40) << timersRBGen[i]->name() << " : " << std::setw(15) << timersRBGen[i]->totalElapsedTime() << std::endl; std::cout<<"-------------------------------------------------------"<<std::endl; } // // --------------------------------------------------------------- // POSTPROCESS BASIS (not necessary right now) // --------------------------------------------------------------- // // // --------------------------------------------------------------- // WRITE OUT THE REDUCED BASIS // --------------------------------------------------------------- // if ( BasisParams->isSublist( "File IO" ) ) { Teuchos::ParameterList fileio_params = BasisParams->sublist( "File IO" ); if ( fileio_params.isParameter( "Reduced Basis Output File" ) ) { std::string outfile = Teuchos::getParameter<std::string>( fileio_params, "Reduced Basis Output File" ); mvFileIO->Write( basisMV, outfile ); } } // #ifdef EPETRA_MPI // Finalize MPI MPI_Finalize(); #endif return 0; }
int main(int argc, char *argv[]) { // Communicators Teuchos::GlobalMPISession mpiSession(&argc, &argv); const Albany_MPI_Comm nativeComm = Albany_MPI_COMM_WORLD; const RCP<const Teuchos::Comm<int> > teuchosComm = Albany::createTeuchosCommFromMpiComm(nativeComm); // Standard output const RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream(); // Parse command-line argument for input file const std::string firstArg = (argc > 1) ? argv[1] : ""; if (firstArg.empty() || firstArg == "--help") { *out << "AlbanyRBGen input-file-path\n"; return 0; } const std::string inputFileName = argv[1]; // Parse XML input file const RCP<Teuchos::ParameterList> topLevelParams = Teuchos::createParameterList("Albany Parameters"); Teuchos::updateParametersFromXmlFileAndBroadcast(inputFileName, topLevelParams.ptr(), *teuchosComm); const bool sublistMustExist = true; // Setup discretization factory const RCP<Teuchos::ParameterList> discParams = Teuchos::sublist(topLevelParams, "Discretization", sublistMustExist); TEUCHOS_TEST_FOR_EXCEPT(discParams->get<std::string>("Method") != "Ioss"); const std::string outputParamLabel = "Exodus Output File Name"; const std::string sampledOutputParamLabel = "Reference Exodus Output File Name"; const RCP<const Teuchos::ParameterEntry> reducedOutputParamEntry = getEntryCopy(*discParams, outputParamLabel); const RCP<const Teuchos::ParameterEntry> sampledOutputParamEntry = getEntryCopy(*discParams, sampledOutputParamLabel); discParams->remove(outputParamLabel, /*throwIfNotExists =*/ false); discParams->remove(sampledOutputParamLabel, /*throwIfNotExists =*/ false); const RCP<const Teuchos::ParameterList> discParamsCopy = Teuchos::rcp(new Teuchos::ParameterList(*discParams)); const RCP<Teuchos::ParameterList> problemParams = Teuchos::sublist(topLevelParams, "Problem", sublistMustExist); const RCP<const Teuchos::ParameterList> problemParamsCopy = Teuchos::rcp(new Teuchos::ParameterList(*problemParams)); // Create original (full) discretization const RCP<Albany::AbstractDiscretization> disc = Albany::discretizationNew(topLevelParams, teuchosComm); // Determine mesh sample const RCP<Teuchos::ParameterList> samplingParams = Teuchos::sublist(topLevelParams, "Mesh Sampling", sublistMustExist); const int firstVectorRank = samplingParams->get("First Vector Rank", 0); const Teuchos::Ptr<const int> basisSizeMax = Teuchos::ptr(samplingParams->getPtr<int>("Basis Size Max")); const int sampleSize = samplingParams->get("Sample Size", 0); *out << "Sampling " << sampleSize << " nodes"; if (Teuchos::nonnull(basisSizeMax)) { *out << " based on no more than " << *basisSizeMax << " basis vectors"; } if (firstVectorRank != 0) { *out << " starting from vector rank " << firstVectorRank; } *out << "\n"; const RCP<Albany::STKDiscretization> stkDisc = Teuchos::rcp_dynamic_cast<Albany::STKDiscretization>(disc, /*throw_on_fail =*/ true); const RCP<MOR::AtomicBasisSource> rawBasisSource = Teuchos::rcp(new Albany::StkNodalBasisSource(stkDisc)); const RCP<MOR::AtomicBasisSource> basisSource = Teuchos::rcp( Teuchos::nonnull(basisSizeMax) ? new MOR::WindowedAtomicBasisSource(rawBasisSource, firstVectorRank, *basisSizeMax) : new MOR::WindowedAtomicBasisSource(rawBasisSource, firstVectorRank) ); MOR::CollocationMetricCriterionFactory criterionFactory(samplingParams); const Teuchos::RCP<const MOR::CollocationMetricCriterion> criterion = criterionFactory.instanceNew(basisSource->entryCountMax()); const Teuchos::RCP<MOR::GreedyAtomicBasisSample> sampler(new MOR::GreedyAtomicBasisSample(*basisSource, criterion)); sampler->sampleSizeInc(sampleSize); Teuchos::Array<stk::mesh::EntityId> sampleNodeIds; const Teuchos::ArrayView<const int> sampleAtoms = sampler->sample(); sampleNodeIds.reserve(sampleAtoms.size()); for (Teuchos::ArrayView<const int>::const_iterator it = sampleAtoms.begin(), it_end = sampleAtoms.end(); it != it_end; ++it) { sampleNodeIds.push_back(*it + 1); } *out << "Sample = " << sampleNodeIds << "\n"; // Choose first sample node as sensor const Teuchos::ArrayView<const stk::mesh::EntityId> sensorNodeIds = sampleNodeIds.view(0, 1); const Teuchos::Array<std::string> additionalNodeSets = Teuchos::tuple(std::string("sample_nodes"), std::string("sensors")); // Create sampled discretization if (Teuchos::nonnull(sampledOutputParamEntry)) { const RCP<Teuchos::ParameterList> discParamsLocalCopy = Teuchos::rcp(new Teuchos::ParameterList(*discParamsCopy)); discParamsLocalCopy->setEntry("Exodus Output File Name", *sampledOutputParamEntry); discParamsLocalCopy->set("Additional Node Sets", additionalNodeSets); topLevelParams->set("Discretization", *discParamsLocalCopy); topLevelParams->set("Problem", *problemParamsCopy); const bool performReduction = false; const RCP<Albany::AbstractDiscretization> sampledDisc = sampledDiscretizationNew(topLevelParams, teuchosComm, sampleNodeIds, sensorNodeIds, performReduction); if (Teuchos::nonnull(basisSizeMax)) { transferSolutionHistory(*stkDisc, *sampledDisc, *basisSizeMax + firstVectorRank); } else { transferSolutionHistory(*stkDisc, *sampledDisc); } } // Create reduced discretization if (Teuchos::nonnull(reducedOutputParamEntry)) { const RCP<Teuchos::ParameterList> discParamsLocalCopy = Teuchos::rcp(new Teuchos::ParameterList(*discParamsCopy)); discParamsLocalCopy->setEntry("Exodus Output File Name", *reducedOutputParamEntry); discParamsLocalCopy->set("Additional Node Sets", additionalNodeSets); topLevelParams->set("Discretization", *discParamsLocalCopy); topLevelParams->set("Problem", *problemParamsCopy); const bool performReduction = true; const RCP<Albany::AbstractDiscretization> reducedDisc = sampledDiscretizationNew(topLevelParams, teuchosComm, sampleNodeIds, sensorNodeIds, performReduction); if (Teuchos::nonnull(basisSizeMax)) { transferSolutionHistory(*stkDisc, *reducedDisc, *basisSizeMax + firstVectorRank); } else { transferSolutionHistory(*stkDisc, *reducedDisc); } } }
ReturnType RTRSolMgr<ScalarType,MV,OP>::solve() { using std::endl; typedef SolverUtils<ScalarType,MV,OP> msutils; const int nev = problem_->getNEV(); // clear num iters numIters_ = -1; #ifdef TEUCHOS_DEBUG Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(printer_->stream(Debug))); out->setShowAllFrontMatter(false).setShowProcRank(true); *out << "Entering Anasazi::RTRSolMgr::solve()\n"; #endif ////////////////////////////////////////////////////////////////////////////////////// // Sort manager Teuchos::RCP<BasicSort<MagnitudeType> > sorter = Teuchos::rcp( new BasicSort<MagnitudeType>(whch_) ); ////////////////////////////////////////////////////////////////////////////////////// // Status tests // Teuchos::RCP<StatusTest<ScalarType,MV,OP> > maxtest; Teuchos::RCP<StatusTest<ScalarType,MV,OP> > ordertest; Teuchos::RCP<StatusTest<ScalarType,MV,OP> > combotest; Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convtest; // maximum iters if (maxIters_ > 0) { maxtest = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>(maxIters_) ); } else { maxtest = Teuchos::null; } // // convergence convtest = Teuchos::rcp( new StatusTestResNorm<ScalarType,MV,OP>(convtol_,nev,convNorm_,relconvtol_) ); ordertest = Teuchos::rcp( new StatusTestWithOrdering<ScalarType,MV,OP>(convtest,sorter,nev) ); // // combo Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests; alltests.push_back(ordertest); if (maxtest != Teuchos::null) alltests.push_back(maxtest); combotest = Teuchos::rcp( new StatusTestCombo<ScalarType,MV,OP>( StatusTestCombo<ScalarType,MV,OP>::OR, alltests) ); // // printing StatusTest Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest; if ( printer_->isVerbosity(Debug) ) { outputtest = Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer_,combotest,1,Passed+Failed+Undefined ) ); } else { outputtest = Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer_,combotest,1,Passed ) ); } ////////////////////////////////////////////////////////////////////////////////////// // Orthomanager Teuchos::RCP<ICGSOrthoManager<ScalarType,MV,OP> > ortho = Teuchos::rcp( new ICGSOrthoManager<ScalarType,MV,OP>(problem_->getM(),numICGS_) ); ////////////////////////////////////////////////////////////////////////////////////// // create an RTR solver // leftmost or rightmost? bool leftMost = true; if (whch_ == "LR" || whch_ == "LM") { leftMost = false; } pl_.set<bool>("Leftmost",leftMost); Teuchos::RCP<RTRBase<ScalarType,MV,OP> > rtr_solver; if (skinny_ == false) { // "hefty" IRTR rtr_solver = Teuchos::rcp( new IRTR<ScalarType,MV,OP>(problem_,sorter,printer_,outputtest,ortho,pl_) ); } else { // "skinny" IRTR rtr_solver = Teuchos::rcp( new SIRTR<ScalarType,MV,OP>(problem_,sorter,printer_,outputtest,ortho,pl_) ); } // set any auxiliary vectors defined in the problem Teuchos::RCP< const MV > probauxvecs = problem_->getAuxVecs(); if (probauxvecs != Teuchos::null) { rtr_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) ); } TEUCHOS_TEST_FOR_EXCEPTION(rtr_solver->getBlockSize() < problem_->getNEV(),std::logic_error, "Anasazi::RTRSolMgr requires block size >= requested number of eigenvalues."); int numfound = 0; Teuchos::RCP<MV> foundvecs; std::vector<MagnitudeType> foundvals; // tell the solver to iterate try { #ifdef ANASAZI_TEUCHOS_TIME_MONITOR Teuchos::TimeMonitor slvtimer(*_timerSolve); #endif rtr_solver->iterate(); numIters_ = rtr_solver->getNumIters(); } catch (const std::exception &e) { // we are a simple solver manager. we don't catch exceptions. set solution empty, then rethrow. printer_->stream(Anasazi::Errors) << "Exception: " << e.what() << endl; Eigensolution<ScalarType,MV> sol; sol.numVecs = 0; problem_->setSolution(sol); throw; } // check the status tests if (convtest->getStatus() == Passed || (maxtest != Teuchos::null && maxtest->getStatus() == Passed)) { int num = convtest->howMany(); if (num > 0) { std::vector<int> ind = convtest->whichVecs(); // copy the converged eigenvectors foundvecs = MVT::CloneCopy(*rtr_solver->getRitzVectors(),ind); // copy the converged eigenvalues foundvals.resize(num); std::vector<Value<ScalarType> > all = rtr_solver->getRitzValues(); for (int i=0; i<num; i++) { foundvals[i] = all[ind[i]].realpart; } numfound = num; } } else { TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Anasazi::RTRSolMgr::solve(): solver returned without satisfy status test."); } // create contiguous storage for all eigenvectors, eigenvalues Eigensolution<ScalarType,MV> sol; sol.numVecs = numfound; sol.Evecs = foundvecs; sol.Espace = sol.Evecs; sol.Evals.resize(sol.numVecs); for (int i=0; i<sol.numVecs; i++) { sol.Evals[i].realpart = foundvals[i]; } // all real eigenvalues: set index vectors [0,...,numfound-1] sol.index.resize(numfound,0); // print final summary rtr_solver->currentStatus(printer_->stream(FinalSummary)); // print timing information #ifdef ANASAZI_TEUCHOS_TIME_MONITOR if ( printer_->isVerbosity( TimingDetails ) ) { Teuchos::TimeMonitor::summarize( printer_->stream( TimingDetails ) ); } #endif // send the solution to the eigenproblem problem_->setSolution(sol); printer_->stream(Debug) << "Returning " << sol.numVecs << " eigenpairs to eigenproblem." << endl; // return from SolMgr::solve() if (sol.numVecs < nev) return Unconverged; return Converged; }
void Export<LocalOrdinal,GlobalOrdinal,Node>:: setupSamePermuteExport (Teuchos::Array<GlobalOrdinal>& exportGIDs) { using Teuchos::arcp; using Teuchos::Array; using Teuchos::ArrayRCP; using Teuchos::ArrayView; using Teuchos::as; using Teuchos::null; typedef LocalOrdinal LO; typedef GlobalOrdinal GO; typedef typename ArrayView<const GO>::size_type size_type; const Map<LO,GO,Node>& source = * (getSourceMap ()); const Map<LO,GO,Node>& target = * (getTargetMap ()); ArrayView<const GO> sourceGIDs = source.getNodeElementList (); ArrayView<const GO> targetGIDs = target.getNodeElementList (); #ifdef HAVE_TPETRA_DEBUG ArrayView<const GO> rawSrcGids = sourceGIDs; ArrayView<const GO> rawTgtGids = targetGIDs; #else const GO* const rawSrcGids = sourceGIDs.getRawPtr (); const GO* const rawTgtGids = targetGIDs.getRawPtr (); #endif // HAVE_TPETRA_DEBUG const size_type numSrcGids = sourceGIDs.size (); const size_type numTgtGids = targetGIDs.size (); const size_type numGids = std::min (numSrcGids, numTgtGids); // Compute numSameIDs_: the number of initial GIDs that are the // same (and occur in the same order) in both Maps. The point of // numSameIDs_ is for the common case of an Export where all the // overlapping GIDs are at the end of the source Map, but // otherwise the source and target Maps are the same. This allows // a fast contiguous copy for the initial "same IDs." size_type numSameGids = 0; for ( ; numSameGids < numGids && rawSrcGids[numSameGids] == rawTgtGids[numSameGids]; ++numSameGids) {} // third clause of 'for' does everything ExportData_->numSameIDs_ = numSameGids; // Compute permuteToLIDs_, permuteFromLIDs_, exportGIDs, and // exportLIDs_. The first two arrays are IDs to be permuted, and // the latter two arrays are IDs to sent out ("exported"), called // "export" IDs. // // IDs to permute are in both the source and target Maps, which // means we don't have to send or receive them, but we do have to // rearrange (permute) them in general. IDs to send are in the // source Map, but not in the target Map. exportGIDs.resize (0); Array<LO>& permuteToLIDs = ExportData_->permuteToLIDs_; Array<LO>& permuteFromLIDs = ExportData_->permuteFromLIDs_; Array<LO>& exportLIDs = ExportData_->exportLIDs_; const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid (); const LO numSrcLids = as<LO> (numSrcGids); // Iterate over the source Map's LIDs, since we only need to do // GID -> LID lookups for the target Map. for (LO srcLid = numSameGids; srcLid < numSrcLids; ++srcLid) { const GO curSrcGid = rawSrcGids[srcLid]; // getLocalElement() returns LINVALID if the GID isn't in the target Map. // This saves us a lookup (which isNodeGlobalElement() would do). const LO tgtLid = target.getLocalElement (curSrcGid); if (tgtLid != LINVALID) { // if target.isNodeGlobalElement (curSrcGid) permuteToLIDs.push_back (tgtLid); permuteFromLIDs.push_back (srcLid); } else { exportGIDs.push_back (curSrcGid); exportLIDs.push_back (srcLid); } } // exportLIDs_ is the list of this process' LIDs that it has to // send out. Since this is an Export, and therefore the target // Map is nonoverlapping, we know that each export LID only needs // to be sent to one process. However, the source Map may be // overlapping, so multiple processes might send to the same LID // on a receiving process. TPETRA_ABUSE_WARNING( getNumExportIDs() > 0 && ! source.isDistributed(), std::runtime_error, "::setupSamePermuteExport(): Source has export LIDs but Source is not " "distributed globally." << std::endl << "Exporting to a submap of the target map."); // Compute exportPIDs_ ("outgoing" process IDs). // // For each GID in exportGIDs (GIDs to which this process must // send), find its corresponding owning process (a.k.a. "image") // ID in the target Map. Store these process IDs in // exportPIDs_. These are the process IDs to which the Export // needs to send data. // // We only need to do this if the source Map is distributed; // otherwise, the Export doesn't have to perform any // communication. if (source.isDistributed ()) { ExportData_->exportPIDs_.resize(exportGIDs.size ()); // This call will assign any GID in the target Map with no // corresponding process ID a fake process ID of -1. We'll use // this below to remove exports for processses that don't exist. const LookupStatus lookup = target.getRemoteIndexList (exportGIDs(), ExportData_->exportPIDs_ ()); TPETRA_ABUSE_WARNING( lookup == IDNotPresent, std::runtime_error, "::setupSamePermuteExport(): The source Map has GIDs not found " "in the target Map."); // Get rid of process IDs not in the target Map. This prevents // exporting to GIDs which don't belong to any process in the // target Map. if (lookup == IDNotPresent) { const size_type numInvalidExports = std::count_if (ExportData_->exportPIDs_().begin(), ExportData_->exportPIDs_().end(), std::bind1st (std::equal_to<int>(), -1)); // count number of valid and total number of exports const size_type totalNumExports = ExportData_->exportPIDs_.size(); if (numInvalidExports == totalNumExports) { // all exports are invalid; we have no exports; we can delete all exports exportGIDs.resize(0); ExportData_->exportLIDs_.resize(0); ExportData_->exportPIDs_.resize(0); } else { // some exports are valid; we need to keep the valid exports // pack and resize size_type numValidExports = 0; for (size_type e = 0; e < totalNumExports; ++e) { if (ExportData_->exportPIDs_[e] != -1) { exportGIDs[numValidExports] = exportGIDs[e]; ExportData_->exportLIDs_[numValidExports] = ExportData_->exportLIDs_[e]; ExportData_->exportPIDs_[numValidExports] = ExportData_->exportPIDs_[e]; ++numValidExports; } } exportGIDs.resize (numValidExports); ExportData_->exportLIDs_.resize (numValidExports); ExportData_->exportPIDs_.resize (numValidExports); } } } } // setupSamePermuteExport()
void blockCrsMatrixWriter(BlockCrsMatrix<Scalar,LO,GO,Node> const &A, std::ostream &os, Teuchos::ParameterList const ¶ms) { using Teuchos::RCP; using Teuchos::rcp; typedef Teuchos::OrdinalTraits<GO> TOT; typedef BlockCrsMatrix<Scalar, LO, GO, Node> block_crs_matrix_type; typedef Tpetra::Import<LO, GO, Node> import_type; typedef Tpetra::Map<LO, GO, Node> map_type; typedef Tpetra::MultiVector<GO, LO, GO, Node> mv_type; typedef Tpetra::CrsGraph<LO, GO, Node> crs_graph_type; RCP<const map_type> const rowMap = A.getRowMap(); //"mesh" map RCP<const Teuchos::Comm<int> > comm = rowMap->getComm(); const int myRank = comm->getRank(); const size_t numProcs = comm->getSize(); // If true, force use of the import strip-mining infrastructure. This is useful for debugging on one process. bool alwaysUseParallelAlgorithm = false; if (params.isParameter("always use parallel algorithm")) alwaysUseParallelAlgorithm = params.get<bool>("always use parallel algorithm"); bool printMatrixMarketHeader = true; if (params.isParameter("print MatrixMarket header")) printMatrixMarketHeader = params.get<bool>("print MatrixMarket header"); if (printMatrixMarketHeader && myRank==0) { std::time_t now = std::time(NULL); const std::string dataTypeStr = Teuchos::ScalarTraits<Scalar>::isComplex ? "complex" : "real"; // Explanation of first line of file: // - "%%MatrixMarket" is the tag for Matrix Market format. // - "matrix" is what we're printing. // - "coordinate" means sparse (triplet format), rather than dense. // - "real" / "complex" is the type (in an output format sense, // not in a C++ sense) of each value of the matrix. (The // other two possibilities are "integer" (not really necessary // here) and "pattern" (no values, just graph).) os << "%%MatrixMarket matrix coordinate " << dataTypeStr << " general" << std::endl; os << "% time stamp: " << ctime(&now); os << "% written from " << numProcs << " processes" << std::endl; os << "% point representation of Tpetra::Experimental::BlockCrsMatrix" << std::endl; size_t numRows = A.getGlobalNumRows(); size_t numCols = A.getGlobalNumCols(); os << "% " << numRows << " block rows, " << numCols << " block columns" << std::endl; const LO blockSize = A.getBlockSize(); os << "% block size " << blockSize << std::endl; os << numRows*blockSize << " " << numCols*blockSize << " " << A.getGlobalNumEntries()*blockSize*blockSize << std::endl; } if (numProcs==1 && !alwaysUseParallelAlgorithm) { writeMatrixStrip(A,os,params); } else { size_t numRows = rowMap->getNodeNumElements(); //Create source map RCP<const map_type> allMeshGidsMap = rcp(new map_type(TOT::invalid(), numRows, A.getIndexBase(), comm)); //Create and populate vector of mesh GIDs corresponding to this pid's rows. //This vector will be imported one pid's worth of information at a time to pid 0. mv_type allMeshGids(allMeshGidsMap,1); Teuchos::ArrayRCP<GO> allMeshGidsData = allMeshGids.getDataNonConst(0); for (size_t i=0; i<numRows; i++) allMeshGidsData[i] = rowMap->getGlobalElement(i); allMeshGidsData = Teuchos::null; // Now construct a RowMatrix on PE 0 by strip-mining the rows of the input matrix A. size_t stripSize = allMeshGids.getGlobalLength() / numProcs; size_t remainder = allMeshGids.getGlobalLength() % numProcs; size_t curStart = 0; size_t curStripSize = 0; Teuchos::Array<GO> importMeshGidList; for (size_t i=0; i<numProcs; i++) { if (myRank==0) { // Only PE 0 does this part curStripSize = stripSize; if (i<remainder) curStripSize++; // handle leftovers importMeshGidList.resize(curStripSize); // Set size of vector to max needed for (size_t j=0; j<curStripSize; j++) importMeshGidList[j] = j + curStart + A.getIndexBase(); curStart += curStripSize; } // The following import map should be non-trivial only on PE 0. TEUCHOS_TEST_FOR_EXCEPTION(myRank>0 && curStripSize!=0, std::runtime_error, "Tpetra::Experimental::blockCrsMatrixWriter: (pid " << myRank << ") map size should be zero, but is " << curStripSize); RCP<map_type> importMeshGidMap = rcp(new map_type(TOT::invalid(), importMeshGidList(), A.getIndexBase(), comm)); import_type gidImporter(allMeshGidsMap, importMeshGidMap); mv_type importMeshGids(importMeshGidMap, 1); importMeshGids.doImport(allMeshGids, gidImporter, INSERT); // importMeshGids now has a list of GIDs for the current strip of matrix rows. // Use these values to build another importer that will get rows of the matrix. // The following import map will be non-trivial only on PE 0. Teuchos::ArrayRCP<const GO> importMeshGidsData = importMeshGids.getData(0); Teuchos::Array<GO> importMeshGidsGO; importMeshGidsGO.reserve(importMeshGidsData.size()); for (typename Teuchos::ArrayRCP<const GO>::size_type j=0; j<importMeshGidsData.size(); ++j) importMeshGidsGO.push_back(importMeshGidsData[j]); RCP<const map_type> importMap = rcp(new map_type(TOT::invalid(), importMeshGidsGO(), rowMap->getIndexBase(), comm) ); import_type importer(rowMap,importMap ); size_t numEntriesPerRow = A.getCrsGraph().getGlobalMaxNumRowEntries(); RCP<crs_graph_type> graph = createCrsGraph(importMap,numEntriesPerRow); RCP<const map_type> domainMap = A.getCrsGraph().getDomainMap(); graph->doImport(A.getCrsGraph(), importer, INSERT); graph->fillComplete(domainMap, importMap); block_crs_matrix_type importA(*graph, A.getBlockSize()); importA.doImport(A, importer, INSERT); // Finally we are ready to write this strip of the matrix writeMatrixStrip(importA, os, params); } } }
/*! @brief replace set of global ids by new global ids * @param input Overlapping input map. @param nonOvlInput Non-overlapping map containing GIDs corresponding to "input". Think of it is the corresponding domain map associated with the column map "input" @param nonOvlReferenceInput Non-overlapping reference map containing new GIDs. @return Overlapping map compatible to "input" using the GIDs as defined by "nonOvlReferenceInput" Example: input = { 0, 1, 2, 3 }; on proc 0 input = { 2, 3, 4, 5 }; on proc 1 nonOvlInput = { 0, 1, 2 }; on proc 0 nonOvlInput = { 3, 4, 5 }: on proc 1 nonOvlReferenceInput = { 33, 44, 55 }; on proc 0 nonOvlReferenceInput = { 101, 102, 103 }; on proc 1 result = { 33, 44, 55, 101 }; on proc 0 result = { 55, 101, 102, 103}; on proc 1 */ static Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > transformThyra2XpetraGIDs( const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>& input, const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>& nonOvlInput, const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>& nonOvlReferenceInput) { //TEUCHOS_TEST_FOR_EXCEPTION(nonOvlInput.getNodeNumElements() > input.getNodeNumElements(), Xpetra::Exceptions::Incompatible, "Xpetra::MatrixUtils::transformThyra2XpetraGIDs: the non-overlapping map must not have more local ids than the overlapping map."); TEUCHOS_TEST_FOR_EXCEPTION(nonOvlInput.getNodeNumElements() != nonOvlReferenceInput.getNodeNumElements(), Xpetra::Exceptions::Incompatible, "Xpetra::MatrixUtils::transformThyra2XpetraGIDs: the number of local Xpetra reference GIDs and local Thyra GIDs of the non-overlapping maps must be the same!"); //TEUCHOS_TEST_FOR_EXCEPTION(nonOvlInput.getMaxAllGlobalIndex() != input.getMaxAllGlobalIndex(), Xpetra::Exceptions::Incompatible, "Xpetra::MatrixUtils::transformThyra2XpetraGIDs: the maximum GIDs of the overlapping and non-overlapping maps must be the same. nonOvlInput.getMaxAllGlobalIndex() = " << nonOvlInput.getMaxAllGlobalIndex() << " ovlInput.getMaxAllGlobalIndex() = " << input.getMaxAllGlobalIndex()); RCP< const Teuchos::Comm<int> > comm = input.getComm(); // fill translation map as far as possible std::map<const GlobalOrdinal, GlobalOrdinal> thyra2xpetraGID; for(size_t i = 0; i < nonOvlInput.getNodeNumElements(); i++) { thyra2xpetraGID[nonOvlInput.getGlobalElement(i)] = nonOvlReferenceInput.getGlobalElement(i); } // find all GIDs of the overlapping Thyra map which are not owned by this proc Teuchos::Array<GlobalOrdinal> ovlUnknownStatusGids; // loop over global column map of A and find all GIDs where it is not sure, whether they are special or not for(size_t i = 0; i<input.getNodeNumElements(); i++) { GlobalOrdinal gcid = input.getGlobalElement(i); if( nonOvlInput.isNodeGlobalElement(gcid) == false) { ovlUnknownStatusGids.push_back(gcid); } } // Communicate the number of DOFs on each processor std::vector<int> myUnknownDofGIDs(comm->getSize(),0); std::vector<int> numUnknownDofGIDs(comm->getSize(),0); myUnknownDofGIDs[comm->getRank()] = ovlUnknownStatusGids.size(); Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,comm->getSize(),&myUnknownDofGIDs[0],&numUnknownDofGIDs[0]); // create array containing all DOF GIDs size_t cntUnknownDofGIDs = 0; for(int p = 0; p < comm->getSize(); p++) cntUnknownDofGIDs += numUnknownDofGIDs[p]; std::vector<GlobalOrdinal> lUnknownDofGIDs(cntUnknownDofGIDs,0); // local version to be filled std::vector<GlobalOrdinal> gUnknownDofGIDs(cntUnknownDofGIDs,0); // global version after communication // calculate the offset and fill chunk of memory with local data on each processor size_t cntUnknownOffset = 0; for(int p = 0; p < comm->getRank(); p++) cntUnknownOffset += numUnknownDofGIDs[p]; for(size_t k=0; k < Teuchos::as<size_t>(ovlUnknownStatusGids.size()); k++) { lUnknownDofGIDs[k+cntUnknownOffset] = ovlUnknownStatusGids[k]; } if(cntUnknownDofGIDs > 0) // only perform communication if there are unknown DOF GIDs Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,Teuchos::as<int>(cntUnknownDofGIDs),&lUnknownDofGIDs[0],&gUnknownDofGIDs[0]); std::vector<GlobalOrdinal> lTranslatedDofGIDs(cntUnknownDofGIDs,0); // local version to be filled std::vector<GlobalOrdinal> gTranslatedDofGIDs(cntUnknownDofGIDs,0); // global version after communication // loop through all GIDs with unknown status for(size_t k=0; k < gUnknownDofGIDs.size(); k++) { GlobalOrdinal curgid = gUnknownDofGIDs[k]; if(nonOvlInput.isNodeGlobalElement(curgid)) { lTranslatedDofGIDs[k] = thyra2xpetraGID[curgid]; } } if(cntUnknownDofGIDs > 0) // only perform communication if there are unknown DOF GIDs Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,Teuchos::as<int>(cntUnknownDofGIDs),&lTranslatedDofGIDs[0],&gTranslatedDofGIDs[0]); for(size_t k=0; k < Teuchos::as<size_t>(ovlUnknownStatusGids.size()); k++) { thyra2xpetraGID[ovlUnknownStatusGids[k]] = gTranslatedDofGIDs[k+cntUnknownOffset]; } Teuchos::Array<GlobalOrdinal> ovlDomainMapArray; for(size_t i = 0; i<input.getNodeNumElements(); i++) { GlobalOrdinal gcid = input.getGlobalElement(i); ovlDomainMapArray.push_back(thyra2xpetraGID[gcid]); } RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > ovlDomainMap = Xpetra::MapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build (nonOvlInput.lib(),Teuchos::OrdinalTraits<GlobalOrdinal>::invalid(),ovlDomainMapArray(),0,comm); TEUCHOS_TEST_FOR_EXCEPTION(input.getNodeNumElements() != ovlDomainMap->getNodeNumElements(), Xpetra::Exceptions::Incompatible, "Xpetra::MatrixUtils::transformThyra2XpetraGIDs: the number of local Thyra reference GIDs (overlapping) and local Xpetra GIDs (overlapping) must be the same!"); //TEUCHOS_TEST_FOR_EXCEPTION(nonOvlReferenceInput.getMaxAllGlobalIndex() != ovlDomainMap->getMaxAllGlobalIndex(), Xpetra::Exceptions::Incompatible, "Xpetra::MatrixUtils::transformThyra2XpetraGIDs: the maximum GIDs of the overlapping and non-overlapping Xpetra maps must be the same."); return ovlDomainMap; }
/*! @brief Helper function to shrink the GIDs and generate a standard map whith GIDs starting at 0 * @param input Input map (may be overlapping) containing all GIDs. Think of it as a column map. @param nonOvlInput Non-overlapping version of "input" map. Think of it is the corresponding domain map associated with the column map "input" @return New map with unique continuous global ids starting with GID 0 This helper routine may be useful for the transformation of MapExtractors in Xpetra-style GID ordering to the Thyra-style ordering. Example: input = { 10, 15, 26, 37, 48 }; on proc 0 input = { 37, 48, 59, 60, 70 }; on proc 1 nonOvlInput = { 10, 15, 26, 37 }; on proc 0 nonOvlInput = { 48, 59, 60, 70 }: on proc 1 result = { 0, 1, 2, 3, 4 }; on proc 0 result = { 3, 4, 5, 6, 7 }; on proc 1 */ static Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > shrinkMapGIDs( const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>& input, const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>& nonOvlInput ) { TEUCHOS_TEST_FOR_EXCEPTION(nonOvlInput.getNodeNumElements() > input.getNodeNumElements(), Xpetra::Exceptions::Incompatible, "Xpetra::MatrixUtils::shrinkMapGIDs: the non-overlapping map must not have more local ids than the overlapping map.") TEUCHOS_TEST_FOR_EXCEPTION(nonOvlInput.getMaxAllGlobalIndex() != input.getMaxAllGlobalIndex(), Xpetra::Exceptions::Incompatible, "Xpetra::MatrixUtils::shrinkMapGIDs: the maximum GIDs of the overlapping and non-overlapping maps must be the same.") RCP< const Teuchos::Comm<int> > comm = input.getComm(); // we expect input to be the potentially overlapping map associated with nonOvlInput as the non-overlapping // map with the same GIDs over all processors (e.g. column map and domain map). We use the nonOvlInput map // to determine which GIDs are owned by which processor. // calculate offset for new global Ids std::vector<int> myGIDs(comm->getSize(),0); std::vector<int> numGIDs(comm->getSize(),0); myGIDs[comm->getRank()] = nonOvlInput.getNodeNumElements(); Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,comm->getSize(),&myGIDs[0],&numGIDs[0]); size_t gidOffset = 0; for(int p = 0; p < comm->getRank(); p++) gidOffset += numGIDs[p]; // we use nonOvlInput to assign the globally unique shrinked GIDs and communicate them to input. std::map<const GlobalOrdinal, GlobalOrdinal> origGID2newGID; for(size_t i = 0; i < nonOvlInput.getNodeNumElements(); i++) { origGID2newGID[nonOvlInput.getGlobalElement(i)] = Teuchos::as<GlobalOrdinal>(i) + Teuchos::as<GlobalOrdinal>(gidOffset); } // build an overlapping version of mySpecialMap Teuchos::Array<GlobalOrdinal> ovlUnknownStatusGids; Teuchos::Array<GlobalOrdinal> ovlFoundStatusGids; // loop over global column map of A and find all GIDs where it is not sure, whether they are special or not for(size_t i = 0; i<input.getNodeNumElements(); i++) { GlobalOrdinal gcid = input.getGlobalElement(i); if( nonOvlInput.isNodeGlobalElement(gcid) == false) { ovlUnknownStatusGids.push_back(gcid); } } // Communicate the number of DOFs on each processor std::vector<int> myUnknownDofGIDs(comm->getSize(),0); std::vector<int> numUnknownDofGIDs(comm->getSize(),0); myUnknownDofGIDs[comm->getRank()] = ovlUnknownStatusGids.size(); Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,comm->getSize(),&myUnknownDofGIDs[0],&numUnknownDofGIDs[0]); // create array containing all DOF GIDs size_t cntUnknownDofGIDs = 0; for(int p = 0; p < comm->getSize(); p++) cntUnknownDofGIDs += numUnknownDofGIDs[p]; std::vector<GlobalOrdinal> lUnknownDofGIDs(cntUnknownDofGIDs,0); // local version to be filled std::vector<GlobalOrdinal> gUnknownDofGIDs(cntUnknownDofGIDs,0); // global version after communication // calculate the offset and fill chunk of memory with local data on each processor size_t cntUnknownOffset = 0; for(int p = 0; p < comm->getRank(); p++) cntUnknownOffset += numUnknownDofGIDs[p]; for(size_t k=0; k < Teuchos::as<size_t>(ovlUnknownStatusGids.size()); k++) { lUnknownDofGIDs[k+cntUnknownOffset] = ovlUnknownStatusGids[k]; } if(cntUnknownDofGIDs > 0) // only perform communication if there are unknown DOF GIDs Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,Teuchos::as<int>(cntUnknownDofGIDs),&lUnknownDofGIDs[0],&gUnknownDofGIDs[0]); std::vector<GlobalOrdinal> lTranslatedDofGIDs(cntUnknownDofGIDs,0); // local version to be filled std::vector<GlobalOrdinal> gTranslatedDofGIDs(cntUnknownDofGIDs,0); // global version after communication // loop through all GIDs with unknown status for(size_t k=0; k < gUnknownDofGIDs.size(); k++) { GlobalOrdinal curgid = gUnknownDofGIDs[k]; if(nonOvlInput.isNodeGlobalElement(curgid)) { lTranslatedDofGIDs[k] = origGID2newGID[curgid]; // curgid is in special map (on this processor) } } if(cntUnknownDofGIDs > 0) // only perform communication if there are unknown DOF GIDs Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,Teuchos::as<int>(cntUnknownDofGIDs),&lTranslatedDofGIDs[0],&gTranslatedDofGIDs[0]); for(size_t k=0; k < Teuchos::as<size_t>(ovlUnknownStatusGids.size()); k++) { origGID2newGID[ovlUnknownStatusGids[k]] = gTranslatedDofGIDs[k+cntUnknownOffset]; } Teuchos::Array<GlobalOrdinal> ovlDomainMapArray; for(size_t i = 0; i<input.getNodeNumElements(); i++) { GlobalOrdinal gcid = input.getGlobalElement(i); ovlDomainMapArray.push_back(origGID2newGID[gcid]); } RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > ovlDomainMap = Xpetra::MapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build (nonOvlInput.lib(),Teuchos::OrdinalTraits<GlobalOrdinal>::invalid(),ovlDomainMapArray(),0,comm); return ovlDomainMap; }
void Albany::ResponseFactory:: createResponseFunction( const std::string& name, Teuchos::ParameterList& responseParams, Teuchos::Array< Teuchos::RCP<AbstractResponseFunction> >& responses) const { using std::string; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::ParameterList; using Teuchos::Array; RCP<const Teuchos_Comm> comm = app->getComm(); if (name == "Solution Average") { responses.push_back(rcp(new Albany::SolutionAverageResponseFunction(comm))); } else if (name == "Solution Two Norm") { responses.push_back(rcp(new Albany::SolutionTwoNormResponseFunction(comm))); } else if (name == "Solution Values") { responses.push_back(rcp(new Albany::SolutionValuesResponseFunction(app, responseParams))); } else if (name == "Solution Max Value") { int eq = responseParams.get("Equation", 0); int neq = responseParams.get("Num Equations", 1); bool inor = responseParams.get("Interleaved Ordering", true); responses.push_back( rcp(new Albany::SolutionMaxValueResponseFunction(comm, neq, eq, inor))); } else if (name == "Solution Two Norm File") { responses.push_back( rcp(new Albany::SolutionFileResponseFunction<Albany::NormTwo>(comm))); } else if (name == "Solution Inf Norm File") { responses.push_back( rcp(new Albany::SolutionFileResponseFunction<Albany::NormInf>(comm))); } else if (name == "OBC Functional") { #ifdef ALBANY_PERIDIGM #ifdef ALBANY_EPETRA responses.push_back(rcp(new Albany::AlbanyPeridigmOBCFunctional(comm))); #endif #endif } else if (name == "Aggregated") { int num_aggregate_responses = responseParams.get<int>("Number"); Array< RCP<AbstractResponseFunction> > aggregated_responses; Array< RCP<ScalarResponseFunction> > scalar_responses; for (int i=0; i<num_aggregate_responses; i++) { std::string id = Albany::strint("Response",i); std::string name = responseParams.get<std::string>(id); std::string sublist_name = Albany::strint("ResponseParams",i); createResponseFunction(name, responseParams.sublist(sublist_name), aggregated_responses); } scalar_responses.resize(aggregated_responses.size()); for (int i=0; i<aggregated_responses.size(); i++) { TEUCHOS_TEST_FOR_EXCEPTION( aggregated_responses[i]->isScalarResponse() != true, std::logic_error, "Response function " << i << " is not a scalar response function." << std::endl << "The aggregated response can only aggregate scalar response " << "functions!"); scalar_responses[i] = Teuchos::rcp_dynamic_cast<ScalarResponseFunction>( aggregated_responses[i]); } responses.push_back( rcp(new Albany::AggregateScalarResponseFunction(comm, scalar_responses))); } else if (name == "Field Integral" || name == "Field Value" || name == "Field Average" || name == "Surface Velocity Mismatch" || name == "Aeras Shallow Water L2 Error" || name == "Aeras Total Volume" || name == "Center Of Mass" || name == "Save Field" || name == "Region Boundary" || name == "Element Size Field" || name == "Save Nodal Fields" || name == "Stiffness Objective" || name == "Internal Energy Objective" || name == "Tensor PNorm Objective" || name == "Homogenized Constants Response" || name == "Modal Objective" || name == "PHAL Field Integral" || name == "PHAL Field IntegralT") { responseParams.set("Name", name); for (int i=0; i<meshSpecs.size(); i++) { #if defined(ALBANY_LCM) // Skip if dealing with interface block //if (meshSpecs[i]->ebName == "Surface Element") continue; #endif responses.push_back( rcp(new Albany::FieldManagerScalarResponseFunction( app, prob, meshSpecs[i], stateMgr, responseParams))); } } else if (name == "IP to Nodal Field" || name == "Project IP to Nodal Field") { responseParams.set("Name", name); for (int i=0; i<meshSpecs.size(); i++) { #if defined(ALBANY_LCM) // Skip if dealing with interface block //if (meshSpecs[i]->ebName == "Surface Element") continue; #endif // For these RFs, default to true for this parm. const char* reb_parm = "Restrict to Element Block"; if ( ! responseParams.isType<bool>(reb_parm) && (name == "IP to Nodal Field" || name == "Project IP to Nodal Field")) responseParams.set<bool>(reb_parm, true); responses.push_back( rcp(new Albany::FieldManagerResidualOnlyResponseFunction( app, prob, meshSpecs[i], stateMgr, responseParams))); } } else if (name == "Solution") { #if defined(ALBANY_EPETRA) responses.push_back( rcp(new Albany::SolutionResponseFunction(app, responseParams))); #endif } else if (name == "KL") { Array< RCP<AbstractResponseFunction> > base_responses; std::string name = responseParams.get<std::string>("Response"); createResponseFunction(name, responseParams.sublist("ResponseParams"), base_responses); for (int i=0; i<base_responses.size(); i++) responses.push_back( rcp(new Albany::KLResponseFunction(base_responses[i], responseParams))); } #ifdef ALBANY_QCAD #if defined(ALBANY_EPETRA) else if (name == "Saddle Value") { responseParams.set("Name", name); for (int i=0; i<meshSpecs.size(); i++) { responses.push_back( rcp(new QCAD::SaddleValueResponseFunction( app, prob, meshSpecs[i], stateMgr, responseParams))); } } #endif #endif else { TEUCHOS_TEST_FOR_EXCEPTION( true, Teuchos::Exceptions::InvalidParameter, std::endl << "Error! Unknown response function " << name << "!" << std::endl << "Supplied parameter list is " << std::endl << responseParams); } }
//Neumann BCs void Tsunami::Boussinesq::constructNeumannEvaluators(const Teuchos::RCP<Albany::MeshSpecsStruct>& meshSpecs) { // Note: we only enter this function if sidesets are defined in the mesh file // i.e. meshSpecs.ssNames.size() > 0 Albany::BCUtils<Albany::NeumannTraits> nbcUtils; // Check to make sure that Neumann BCs are given in the input file if(!nbcUtils.haveBCSpecified(this->params)) { return; } // Construct BC evaluators for all side sets and names // Note that the string index sets up the equation offset, so ordering is important // // Currently we aren't exactly doing this right. I think to do this // correctly we need different neumann evaluators for each DOF (velocity, // pressure, temperature, flux) since velocity is a vector and the // others are scalars. The dof_names stuff is only used // for robin conditions, so at this point, as long as we don't enable // robin conditions, this should work. std::vector<std::string> nbcNames; Teuchos::RCP< Teuchos::Array<std::string> > dof_names = Teuchos::rcp(new Teuchos::Array<std::string>); Teuchos::Array<Teuchos::Array<int> > offsets; int idx = 0; nbcNames.push_back("eta"); offsets.push_back(Teuchos::Array<int>(1,idx++)); nbcNames.push_back("ualpha"); offsets.push_back(Teuchos::Array<int>(1,idx++)); if (numDim > 1) { nbcNames.push_back("valpha"); offsets.push_back(Teuchos::Array<int>(1,idx++)); } nbcNames.push_back("E1"); offsets.push_back(Teuchos::Array<int>(1,idx++)); if (numDim > 1) { nbcNames.push_back("E2"); offsets.push_back(Teuchos::Array<int>(1,idx++)); } // Construct BC evaluators for all possible names of conditions // Should only specify flux vector components (dudx, dudy, dudz), or dudn, not both std::vector<std::string> condNames(3); //dudx, dudy, dudz, dudn, basal // Note that sidesets are only supported for two and 3D currently // //IKT, FIXME: the following needs to be changed for Tsunami problem! if(numDim == 2) condNames[0] = "(dudx, dudy)"; else TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter, std::endl << "Error: Sidesets only supported in 2 and 3D." << std::endl); condNames[1] = "dudn"; condNames[2] = "basal"; nfm.resize(1); nfm[0] = nbcUtils.constructBCEvaluators(meshSpecs, nbcNames, Teuchos::arcp(dof_names), true, 0, condNames, offsets, dl, this->params, this->paramLib); }
void Albany::ResponseFactory:: createResponseFunction( const std::string& name, Teuchos::ParameterList& responseParams, Teuchos::Array< Teuchos::RCP<AbstractResponseFunction> >& responses) const { using std::string; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::ParameterList; using Teuchos::Array; RCP<const Epetra_Comm> comm = app->getComm(); if (name == "Solution Average") { responses.push_back(rcp(new Albany::SolutionAverageResponseFunction(comm))); } else if (name == "Solution Two Norm") { responses.push_back(rcp(new Albany::SolutionTwoNormResponseFunction(comm))); } else if (name == "Solution Values") { responses.push_back(rcp(new Albany::SolutionValuesResponseFunction(app, responseParams))); } else if (name == "Solution Max Value") { int eq = responseParams.get("Equation", 0); int neq = responseParams.get("Num Equations", 1); bool inor = responseParams.get("Interleaved Ordering", true); responses.push_back( rcp(new Albany::SolutionMaxValueResponseFunction(comm, neq, eq, inor))); } else if (name == "Solution Two Norm File") { responses.push_back( rcp(new Albany::SolutionFileResponseFunction<Albany::NormTwo>(comm))); } else if (name == "Solution Inf Norm File") { responses.push_back( rcp(new Albany::SolutionFileResponseFunction<Albany::NormInf>(comm))); } else if (name == "Aggregated") { int num_aggregate_responses = responseParams.get<int>("Number"); Array< RCP<AbstractResponseFunction> > aggregated_responses; Array< RCP<ScalarResponseFunction> > scalar_responses; for (int i=0; i<num_aggregate_responses; i++) { std::string id = Albany::strint("Response",i); std::string name = responseParams.get<std::string>(id); std::string sublist_name = Albany::strint("ResponseParams",i); createResponseFunction(name, responseParams.sublist(sublist_name), aggregated_responses); } scalar_responses.resize(aggregated_responses.size()); for (int i=0; i<aggregated_responses.size(); i++) { TEUCHOS_TEST_FOR_EXCEPTION( aggregated_responses[i]->isScalarResponse() != true, std::logic_error, "Response function " << i << " is not a scalar response function." << std::endl << "The aggregated response can only aggregate scalar response " << "functions!"); scalar_responses[i] = Teuchos::rcp_dynamic_cast<ScalarResponseFunction>( aggregated_responses[i]); } responses.push_back( rcp(new Albany::AggregateScalarResponseFunction(comm, scalar_responses))); } else if (name == "Field Integral" || name == "Field Value" || name == "Field Average" || name == "Surface Velocity Mismatch" || name == "Center Of Mass" || name == "Save Field" || name == "Region Boundary" || name == "Element Size Field" || name == "IP to Nodal Field" || name == "Save Nodal Fields" || name == "PHAL Field Integral") { responseParams.set("Name", name); for (int i=0; i<meshSpecs.size(); i++) { responses.push_back( rcp(new Albany::FieldManagerScalarResponseFunction( app, prob, meshSpecs[i], stateMgr, responseParams))); } } else if (name == "Solution") { responses.push_back( rcp(new Albany::SolutionResponseFunction(app, responseParams))); } else if (name == "KL") { Array< RCP<AbstractResponseFunction> > base_responses; std::string name = responseParams.get<std::string>("Response"); createResponseFunction(name, responseParams.sublist("ResponseParams"), base_responses); for (int i=0; i<base_responses.size(); i++) responses.push_back( rcp(new Albany::KLResponseFunction(base_responses[i], responseParams))); } #ifdef ALBANY_QCAD else if (name == "Saddle Value") { responseParams.set("Name", name); for (int i=0; i<meshSpecs.size(); i++) { responses.push_back( rcp(new QCAD::SaddleValueResponseFunction( app, prob, meshSpecs[i], stateMgr, responseParams))); } } #endif else { TEUCHOS_TEST_FOR_EXCEPTION( true, Teuchos::Exceptions::InvalidParameter, std::endl << "Error! Unknown response function " << name << "!" << std::endl << "Supplied parameter list is " << std::endl << responseParams); } }