• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Main_RBGen.cpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include "Albany_DataTypes.hpp"
00008 #include "Albany_Utils.hpp"
00009 
00010 #include "Albany_DiscretizationFactory.hpp"
00011 #include "Albany_STKDiscretization.hpp"
00012 
00013 #include "Albany_MORDiscretizationUtils.hpp"
00014 #include "Albany_StkEpetraMVSource.hpp"
00015 
00016 #include "MOR_EpetraMVSource.hpp"
00017 #include "MOR_ConcatenatedEpetraMVSource.hpp"
00018 #include "MOR_SnapshotPreprocessor.hpp"
00019 #include "MOR_SnapshotPreprocessorFactory.hpp"
00020 #include "MOR_SnapshotBlockingUtils.hpp"
00021 #include "MOR_SingularValuesHelpers.hpp"
00022 
00023 #include "RBGen_EpetraMVMethodFactory.h"
00024 #include "RBGen_PODMethod.hpp"
00025 
00026 #include "Epetra_Comm.h"
00027 #include "Epetra_MultiVector.h"
00028 #include "Epetra_Import.h"
00029 
00030 #include "Teuchos_Ptr.hpp"
00031 #include "Teuchos_RCP.hpp"
00032 #include "Teuchos_ArrayRCP.hpp"
00033 #include "Teuchos_Array.hpp"
00034 #include "Teuchos_GlobalMPISession.hpp"
00035 #include "Teuchos_Comm.hpp"
00036 #include "Teuchos_FancyOStream.hpp"
00037 #include "Teuchos_VerboseObject.hpp"
00038 #include "Teuchos_ParameterList.hpp"
00039 #include "Teuchos_XMLParameterListHelpers.hpp"
00040 
00041 #include <string>
00042 #include <limits>
00043 
00044 
00045 Teuchos::Array<int> getMyBlockLIDs(
00046     const Teuchos::ParameterList &blockingParams,
00047     const Albany::AbstractDiscretization &disc)
00048 {
00049   Teuchos::Array<int> result;
00050 
00051   const std::string nodeSetLabel = blockingParams.get<std::string>("Node Set");
00052   const int dofRank = blockingParams.get<int>("Dof");
00053 
00054   const Albany::NodeSetList &nodeSets = disc.getNodeSets();
00055   const Albany::NodeSetList::const_iterator it = nodeSets.find(nodeSetLabel);
00056   TEUCHOS_TEST_FOR_EXCEPT(it == nodeSets.end());
00057   {
00058     typedef Albany::NodeSetList::mapped_type NodeSetEntryList;
00059     const NodeSetEntryList &nodeEntries = it->second;
00060 
00061     for (NodeSetEntryList::const_iterator jt = nodeEntries.begin(); jt != nodeEntries.end(); ++jt) {
00062       typedef NodeSetEntryList::value_type NodeEntryList;
00063       const NodeEntryList &entries = *jt;
00064       result.push_back(entries[dofRank]);
00065     }
00066   }
00067 
00068   return result;
00069 }
00070 
00071 int main(int argc, char *argv[]) {
00072   using Teuchos::RCP;
00073 
00074   // Communicators
00075   Teuchos::GlobalMPISession mpiSession(&argc, &argv);
00076   const Albany_MPI_Comm nativeComm = Albany_MPI_COMM_WORLD;
00077   const RCP<const Teuchos::Comm<int> > teuchosComm = Albany::createTeuchosCommFromMpiComm(nativeComm);
00078   const RCP<const Epetra_Comm> epetraComm = Albany::createEpetraCommFromMpiComm(nativeComm);
00079 
00080   // Standard output
00081   const RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
00082 
00083   // Parse command-line argument for input file
00084   const std::string firstArg = (argc > 1) ? argv[1] : "";
00085   if (firstArg.empty() || firstArg == "--help") {
00086     *out << "AlbanyRBGen input-file-path\n";
00087     return 0;
00088   }
00089   const std::string inputFileName = argv[1];
00090 
00091   // Parse XML input file
00092   const RCP<Teuchos::ParameterList> topLevelParams = Teuchos::createParameterList("Albany Parameters");
00093   Teuchos::updateParametersFromXmlFileAndBroadcast(inputFileName, topLevelParams.ptr(), *teuchosComm);
00094 
00095   // Create base discretization, used to retrieve the snapshot map and output the basis
00096   const Teuchos::RCP<Teuchos::ParameterList> baseTopLevelParams(new Teuchos::ParameterList(*topLevelParams));
00097   const RCP<Albany::AbstractDiscretization> baseDisc = Albany::discretizationNew(baseTopLevelParams, epetraComm);
00098 
00099   const RCP<Teuchos::ParameterList> rbgenParams =
00100     Teuchos::sublist(topLevelParams, "Reduced Basis", /*sublistMustExist =*/ true);
00101 
00102   typedef Teuchos::Array<std::string> FileNameList;
00103   FileNameList snapshotFiles;
00104   {
00105     const RCP<Teuchos::ParameterList> snapshotSourceParams = Teuchos::sublist(rbgenParams, "Snapshot Sources");
00106     snapshotFiles = snapshotSourceParams->get("File Names", snapshotFiles);
00107   }
00108 
00109   typedef Teuchos::Array<RCP<Albany::STKDiscretization> > DiscretizationList;
00110   DiscretizationList discretizations;
00111   if (snapshotFiles.empty()) {
00112     discretizations.push_back(Teuchos::rcp_dynamic_cast<Albany::STKDiscretization>(baseDisc, /*throw_on_fail =*/ true));
00113   } else {
00114     discretizations.reserve(snapshotFiles.size());
00115     for (FileNameList::const_iterator it = snapshotFiles.begin(), it_end = snapshotFiles.end(); it != it_end; ++it) {
00116       const Teuchos::RCP<Teuchos::ParameterList> localTopLevelParams(new Teuchos::ParameterList(*topLevelParams));
00117       {
00118         // Replace discretization parameters to read snapshot file
00119         Teuchos::ParameterList localDiscParams;
00120         localDiscParams.set("Method", "Ioss");
00121         localDiscParams.set("Exodus Input File Name", *it);
00122         localTopLevelParams->set("Discretization", localDiscParams);
00123       }
00124       const RCP<Albany::AbstractDiscretization> disc = Albany::discretizationNew(localTopLevelParams, epetraComm);
00125       discretizations.push_back(Teuchos::rcp_dynamic_cast<Albany::STKDiscretization>(disc, /*throw_on_fail =*/ true));
00126     }
00127   }
00128 
00129   typedef Teuchos::Array<RCP<MOR::EpetraMVSource> > SnapshotSourceList;
00130   SnapshotSourceList snapshotSources;
00131   for (DiscretizationList::const_iterator it = discretizations.begin(), it_end = discretizations.end(); it != it_end; ++it) {
00132     snapshotSources.push_back(Teuchos::rcp(new Albany::StkEpetraMVSource(*it)));
00133   }
00134 
00135   MOR::ConcatenatedEpetraMVSource snapshotSource(*baseDisc->getMap(), snapshotSources);
00136   *out << "Total snapshot count = " << snapshotSource.vectorCount() << "\n";
00137   const Teuchos::RCP<Epetra_MultiVector> rawSnapshots = snapshotSource.multiVectorNew();
00138 
00139   // Isolate Dirichlet BC
00140   RCP<const Epetra_Vector> blockVector;
00141   if (rbgenParams->isSublist("Blocking")) {
00142     const RCP<const Teuchos::ParameterList> blockingParams = Teuchos::sublist(rbgenParams, "Blocking");
00143     const Teuchos::Array<int> mySelectedLIDs = getMyBlockLIDs(*blockingParams, *baseDisc);
00144     *out << "Selected LIDs = " << mySelectedLIDs << "\n";
00145 
00146     blockVector = MOR::isolateUniformBlock(mySelectedLIDs, *rawSnapshots);
00147   }
00148 
00149   // Preprocess raw snapshots
00150   const RCP<Teuchos::ParameterList> preprocessingParams = Teuchos::sublist(rbgenParams, "Snapshot Preprocessing");
00151 
00152   MOR::SnapshotPreprocessorFactory preprocessorFactory;
00153   const Teuchos::RCP<MOR::SnapshotPreprocessor> snapshotPreprocessor = preprocessorFactory.instanceNew(preprocessingParams);
00154   snapshotPreprocessor->rawSnapshotSetIs(rawSnapshots);
00155   const RCP<const Epetra_MultiVector> modifiedSnapshots = snapshotPreprocessor->modifiedSnapshotSet();
00156 
00157   const RCP<const Epetra_Vector> origin = snapshotPreprocessor->origin();
00158   const bool nonzeroOrigin = Teuchos::nonnull(origin);
00159 
00160   *out << "After preprocessing, " << modifiedSnapshots->NumVectors() << " snapshot vectors and "
00161     << static_cast<int>(nonzeroOrigin) << " origin\n";
00162 
00163   // By default, compute as many basis vectors as snapshots
00164   (void) Teuchos::sublist(rbgenParams, "Reduced Basis Method")->get("Basis Size", modifiedSnapshots->NumVectors());
00165 
00166   // Compute reduced basis
00167   RBGen::EpetraMVMethodFactory methodFactory;
00168   const RCP<RBGen::Method<Epetra_MultiVector, Epetra_Operator> > method = methodFactory.create(*rbgenParams);
00169   method->Initialize(rbgenParams, modifiedSnapshots);
00170   method->computeBasis();
00171   const RCP<const Epetra_MultiVector> basis = method->getBasis();
00172 
00173   *out << "Computed " << basis->NumVectors() << " left-singular vectors\n";
00174 
00175   // Compute discarded energy fraction for each left-singular vector
00176   // (relative residual energy corresponding to a basis truncation after current vector)
00177   const RCP<const RBGen::PODMethod<double> > pod_method = Teuchos::rcp_dynamic_cast<RBGen::PODMethod<double> >(method);
00178   const Teuchos::Array<double> singularValues = pod_method->getSingularValues();
00179 
00180   *out << "Singular values: " << singularValues << "\n";
00181 
00182   const Teuchos::Array<double> discardedEnergyFractions = MOR::computeDiscardedEnergyFractions(singularValues);
00183 
00184   *out << "Discarded energy fractions: " << discardedEnergyFractions << "\n";
00185 
00186   // Output results
00187   {
00188     // Setup overlapping map and vector
00189     const Epetra_Map outputMap = *baseDisc->getOverlapMap();
00190     const Epetra_Import outputImport(outputMap, snapshotSource.vectorMap());
00191     Epetra_Vector outputVector(outputMap, /*zeroOut =*/ false);
00192 
00193     if (nonzeroOrigin) {
00194       const double stamp = -1.0; // Stamps must be increasing
00195       outputVector.Import(*origin, outputImport, Insert);
00196       baseDisc->writeSolution(outputVector, stamp, /*overlapped =*/ true);
00197     }
00198     if (Teuchos::nonnull(blockVector)) {
00199       const double stamp = -1.0 + std::numeric_limits<double>::epsilon();
00200       TEUCHOS_ASSERT(stamp != -1.0);
00201       outputVector.Import(*blockVector, outputImport, Insert);
00202       baseDisc->writeSolution(outputVector, stamp, /*overlapped =*/ true);
00203     }
00204     for (int i = 0; i < basis->NumVectors(); ++i) {
00205       const double stamp = -discardedEnergyFractions[i]; // Stamps must be increasing
00206       const Epetra_Vector vec(View, *basis, i);
00207       outputVector.Import(vec, outputImport, Insert);
00208       baseDisc->writeSolution(outputVector, stamp, /*overlapped =*/ true);
00209     }
00210   }
00211 }

Generated on Wed Mar 26 2014 18:36:39 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1