Go to the documentation of this file.00001
00002
00003
00004
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
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
00081 const RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
00082
00083
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
00092 const RCP<Teuchos::ParameterList> topLevelParams = Teuchos::createParameterList("Albany Parameters");
00093 Teuchos::updateParametersFromXmlFileAndBroadcast(inputFileName, topLevelParams.ptr(), *teuchosComm);
00094
00095
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", 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, 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
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, 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
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
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
00164 (void) Teuchos::sublist(rbgenParams, "Reduced Basis Method")->get("Basis Size", modifiedSnapshots->NumVectors());
00165
00166
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
00176
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
00187 {
00188
00189 const Epetra_Map outputMap = *baseDisc->getOverlapMap();
00190 const Epetra_Import outputImport(outputMap, snapshotSource.vectorMap());
00191 Epetra_Vector outputVector(outputMap, false);
00192
00193 if (nonzeroOrigin) {
00194 const double stamp = -1.0;
00195 outputVector.Import(*origin, outputImport, Insert);
00196 baseDisc->writeSolution(outputVector, stamp, 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, true);
00203 }
00204 for (int i = 0; i < basis->NumVectors(); ++i) {
00205 const double stamp = -discardedEnergyFractions[i];
00206 const Epetra_Vector vec(View, *basis, i);
00207 outputVector.Import(vec, outputImport, Insert);
00208 baseDisc->writeSolution(outputVector, stamp, true);
00209 }
00210 }
00211 }