33 #include <Thyra_LinearOpWithSolveBase.hpp>
34 #include <Thyra_VectorBase.hpp>
35 #include <Thyra_SolveSupportTypes.hpp>
38 #include <Stratimikos_LinearSolverBuilder.hpp>
39 #include <Stratimikos_InternalConfig.h>
42 #include <Xpetra_Parameters.hpp>
43 #include <Xpetra_ThyraUtils.hpp>
46 #include <Galeri_XpetraParameters.hpp>
47 #include <Galeri_XpetraProblemFactory.hpp>
48 #include <Galeri_XpetraUtils.hpp>
49 #include <Galeri_XpetraMaps.hpp>
52 template <
class Scalar>
56 typedef map_type::local_ordinal_type LocalOrdinal;
57 typedef map_type::global_ordinal_type GlobalOrdinal;
58 typedef map_type::node_type Node;
63 #include <Xpetra_UseShortNames.hpp>
79 Galeri::Xpetra::Parameters<GlobalOrdinal> galeriParameters(clp, 100, 100, 100,
"Laplace2D");
81 Xpetra::Parameters xpetraParameters(clp);
84 std::string xmlFileName =
"stratimikos_ParameterList.xml"; clp.
setOption(
"xml", &xmlFileName,
"read parameters from an xml file");
85 std::string yamlFileName =
""; clp.
setOption(
"yaml", &yamlFileName,
"read parameters from a yaml file");
86 bool printTimings =
false; clp.
setOption(
"timings",
"notimings", &printTimings,
"print timings to screen");
87 bool use_stacked_timer =
false; clp.
setOption(
"stacked-timer",
"no-stacked-timer", &use_stacked_timer,
"Run with or without stacked timer output");
88 std::string timingsFormat =
"table-fixed"; clp.
setOption(
"time-format", &timingsFormat,
"timings format (table-fixed | table-scientific | yaml)");
89 int numVectors = 1; clp.
setOption(
"multivector", &numVectors,
"number of rhs to solve simultaneously");
90 int numSolves = 1; clp.
setOption(
"numSolves", &numSolves,
"number of times the system should be solved");
92 switch (clp.
parse(argc,argv)) {
99 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
105 if (use_stacked_timer)
107 TimeMonitor::setStackedTimer(stacked_timer);
111 "Need to provide xml or yaml input file");
112 RCP<ParameterList> paramList =
rcp(
new ParameterList(
"params"));
113 if (yamlFileName !=
"")
114 Teuchos::updateParametersFromYamlFileAndBroadcast(yamlFileName, paramList.ptr(), *comm);
116 Teuchos::updateParametersFromXmlFileAndBroadcast(xmlFileName, paramList.ptr(), *comm);
124 RCP<MultiVector> X,
B;
126 std::ostringstream galeriStream;
128 galeriStream <<
"========================================================\n" << xpetraParameters;
129 galeriStream << galeriParameters;
140 std::string matrixType = galeriParameters.GetMatrixType();
143 if (matrixType ==
"Laplace1D") {
144 map = Galeri::Xpetra::CreateMap<LO, GO, Node>(xpetraParameters.GetLib(),
"Cartesian1D", comm, galeriList);
146 }
else if (matrixType ==
"Laplace2D" || matrixType ==
"Star2D" ||
147 matrixType ==
"BigStar2D" || matrixType ==
"AnisotropicDiffusion" || matrixType ==
"Elasticity2D") {
148 map = Galeri::Xpetra::CreateMap<LO, GO, Node>(xpetraParameters.GetLib(),
"Cartesian2D", comm, galeriList);
150 }
else if (matrixType ==
"Laplace3D" || matrixType ==
"Brick3D" || matrixType ==
"Elasticity3D") {
151 map = Galeri::Xpetra::CreateMap<LO, GO, Node>(xpetraParameters.GetLib(),
"Cartesian3D", comm, galeriList);
155 if (matrixType ==
"Elasticity2D")
156 map = Xpetra::MapFactory<LO,GO,Node>::Build(map, 2);
157 if (matrixType ==
"Elasticity3D")
158 map = Xpetra::MapFactory<LO,GO,Node>::Build(map, 3);
160 galeriStream <<
"Processor subdomains in x direction: " << galeriList.
get<
GO>(
"mx") << std::endl
161 <<
"Processor subdomains in y direction: " << galeriList.
get<
GO>(
"my") << std::endl
162 <<
"Processor subdomains in z direction: " << galeriList.
get<
GO>(
"mz") << std::endl
163 <<
"========================================================" << std::endl;
165 if (matrixType ==
"Elasticity2D" || matrixType ==
"Elasticity3D") {
167 galeriList.
set(
"right boundary" ,
"Neumann");
168 galeriList.
set(
"bottom boundary",
"Neumann");
169 galeriList.
set(
"top boundary" ,
"Neumann");
170 galeriList.
set(
"front boundary" ,
"Neumann");
171 galeriList.
set(
"back boundary" ,
"Neumann");
174 RCP<Galeri::Xpetra::Problem<Map,CrsMatrixWrap,MultiVector> > Pr =
175 Galeri::Xpetra::BuildProblem<SC,LO,GO,Map,CrsMatrixWrap,MultiVector>(galeriParameters.GetMatrixType(), map, galeriList);
176 A = Pr->BuildMatrix();
178 if (matrixType ==
"Elasticity2D" ||
179 matrixType ==
"Elasticity3D") {
180 A->SetFixedBlockSize((galeriParameters.GetMatrixType() ==
"Elasticity2D") ? 2 : 3);
183 out << galeriStream.str();
184 X = MultiVectorFactory::Build(map, numVectors);
185 B = MultiVectorFactory::Build(map, numVectors);
193 RCP<const Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node> > xpCrsA = Teuchos::rcp_dynamic_cast<
const Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(A);
195 RCP<const Thyra::LinearOpBase<Scalar> > thyraA = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpCrsA->getCrsMatrix());
196 RCP< Thyra::MultiVectorBase<Scalar> > thyraX = Teuchos::rcp_const_cast<Thyra::MultiVectorBase<Scalar> >(Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyraMultiVector(X));
197 RCP<const Thyra::MultiVectorBase<Scalar> > thyraB = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyraMultiVector(B);
210 RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > solverFactory = Thyra::createLinearSolveStrategy(linearSolverBuilder);
211 auto precFactory = solverFactory->getPreconditionerFactory();
212 RCP<Thyra::PreconditionerBase<Scalar> > prec;
214 if (!precFactory.is_null()) {
215 prec = precFactory->createPrec();
218 Thyra::initializePrec<Scalar>(*precFactory, thyraA, prec.ptr());
219 thyraInverseA = solverFactory->createOp();
220 Thyra::initializePreconditionedOp<Scalar>(*solverFactory, thyraA, prec, thyraInverseA.ptr());
222 thyraInverseA = Thyra::linearOpWithSolve(*solverFactory, thyraA);
226 Thyra::SolveStatus<Scalar> status = Thyra::solve<Scalar>(*thyraInverseA, Thyra::NOTRANS, *thyraB, thyraX.
ptr());
228 success = (status.solveStatus == Thyra::SOLVE_STATUS_CONVERGED);
230 for (
int solveno = 1; solveno < numSolves; solveno++) {
231 if (!precFactory.is_null())
232 Thyra::initializePrec<Scalar>(*precFactory, thyraA, prec.ptr());
235 status = Thyra::solve<Scalar>(*thyraInverseA, Thyra::NOTRANS, *thyraB, thyraX.ptr());
237 success = success && (status.solveStatus == Thyra::SOLVE_STATUS_CONVERGED);
242 if (use_stacked_timer) {
243 stacked_timer->
stop(
"Main");
246 stacked_timer->
report(out, comm, options);
248 RCP<ParameterList> reportParams =
rcp(
new ParameterList);
249 if (timingsFormat ==
"yaml") {
250 reportParams->set(
"Report format",
"YAML");
251 reportParams->set(
"YAML style",
"compact");
253 reportParams->set(
"How to merge timer sets",
"Union");
254 reportParams->set(
"alwaysWriteLocal",
false);
255 reportParams->set(
"writeGlobalStats",
true);
256 reportParams->set(
"writeZeroTimers",
false);
258 const std::string filter =
"";
260 std::ios_base::fmtflags ff(out.flags());
261 if (timingsFormat ==
"table-fixed") out << std::fixed;
262 else out << std::scientific;
263 TimeMonitor::report(comm.ptr(), out, filter, reportParams);
264 out << std::setiosflags(ff);
268 TimeMonitor::clearCounters();
274 return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
291 std::vector<const char*> availableScalarTypeStrings;
292 std::vector<scalarType> availableScalarTypes;
293 #ifdef HAVE_TPETRA_INST_DOUBLE
294 availableScalarTypeStrings.push_back(
"double");
295 availableScalarTypes.push_back(
DOUBLE);
297 #ifdef HAVE_TPETRA_INST_FLOAT
298 availableScalarTypeStrings.push_back(
"float");
299 availableScalarTypes.push_back(
FLOAT);
301 #ifdef HAVE_TPETRA_INST_COMPLEX_DOUBLE
302 availableScalarTypeStrings.push_back(
"complex<double>");
305 #ifdef HAVE_TPETRA_INST_COMPLEX_FLOAT
306 availableScalarTypeStrings.push_back(
"complex<float>");
309 clp.
setOption(
"scalarType", &scalar, availableScalarTypes.size(), availableScalarTypes.data(), availableScalarTypeStrings.data(),
"scalar type");
311 switch (clp.
parse(argc, argv, NULL)) {
318 #ifdef HAVE_TPETRA_INST_DOUBLE
320 return main_<double>(argc, argv, clp);
322 #ifdef HAVE_TPETRA_INST_FLOAT
324 return main_<float>(argc, argv, clp);
326 #ifdef HAVE_TPETRA_INST_COMPLEX_DOUBLE
328 return main_<std::complex<double> >(argc, argv, clp);
330 #ifdef HAVE_TPETRA_INST_COMPLEX_FLOAT
332 return main_<std::complex<float> >(argc, argv, clp);
int main(int argc, char *argv[])
void stop(const std::string &name, const bool pop_kokkos_profiling_region=true)
Tpetra::Map< int, int > map_type
void recogniseAllOptions(const bool &recogniseAllOptions)
T & get(ParameterList &l, const std::string &name)
int main_(int argc, char *argv[], Teuchos::CommandLineProcessor &clp)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void setParameterList(RCP< ParameterList > const ¶mList)
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
void report(std::ostream &os)
Concrete subclass of Thyra::LinearSolverBuilderBase for creating Thyra::LinearOpWithSolveFactoryBase ...
map_type::global_ordinal_type GO