From 9ae0e5d62c3b913edd5dad1aeaffce12381bcd64 Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Tue, 16 Jan 2024 13:34:04 -0700 Subject: [PATCH] Teko: clang-format --- .github/workflows/clang_format.yml | 2 +- packages/teko/.clang-format | 8 + .../teko/examples/AddMultiplyPrecs/Driver.cpp | 184 +- .../inverse-factory-operator.cpp | 162 +- .../BasicExamples/stratimikos-solve.cpp | 108 +- .../example-driver-belos.cpp | 251 +- .../BuildPreconditioner/example-driver.cpp | 137 +- .../step1/ExamplePreconditionerFactory.cpp | 138 +- .../step1/example-test.cpp | 143 +- .../step2/ExamplePreconditionerFactory.cpp | 198 +- .../examples/ML-Teko-Coupling/ml_teko.cpp | 139 +- .../ML-Teko-Coupling/ml_teko_single.cpp | 68 +- .../ML-Teko-Coupling/teko_ml_prec.cpp | 170 +- .../examples/StridedSolve/strided_solve.cpp | 164 +- .../src/Epetra/Teko_BasicMappingStrategy.cpp | 72 +- .../src/Epetra/Teko_BasicMappingStrategy.hpp | 193 +- .../src/Epetra/Teko_BlockedEpetraOperator.cpp | 245 +- .../src/Epetra/Teko_BlockedEpetraOperator.hpp | 209 +- .../Epetra/Teko_BlockedMappingStrategy.cpp | 225 +- .../Epetra/Teko_BlockedMappingStrategy.hpp | 323 +- .../teko/src/Epetra/Teko_BlockingEpetra.cpp | 531 +- .../teko/src/Epetra/Teko_BlockingEpetra.hpp | 215 +- .../Epetra/Teko_EpetraBlockPreconditioner.cpp | 533 +- .../Epetra/Teko_EpetraBlockPreconditioner.hpp | 284 +- .../teko/src/Epetra/Teko_EpetraHelpers.cpp | 331 +- .../teko/src/Epetra/Teko_EpetraHelpers.hpp | 197 +- .../Epetra/Teko_EpetraInverseOpWrapper.cpp | 42 +- .../Epetra/Teko_EpetraInverseOpWrapper.hpp | 64 +- .../src/Epetra/Teko_EpetraOperatorWrapper.cpp | 377 +- .../src/Epetra/Teko_EpetraOperatorWrapper.hpp | 416 +- .../src/Epetra/Teko_EpetraThyraConverter.cpp | 371 +- .../src/Epetra/Teko_EpetraThyraConverter.hpp | 112 +- .../teko/src/Epetra/Teko_InterlacedEpetra.cpp | 708 +-- .../teko/src/Epetra/Teko_InterlacedEpetra.hpp | 246 +- .../Epetra/Teko_InverseFactoryOperator.cpp | 284 +- .../Epetra/Teko_InverseFactoryOperator.hpp | 257 +- .../Epetra/Teko_ReorderedMappingStrategy.cpp | 79 +- .../Epetra/Teko_ReorderedMappingStrategy.hpp | 199 +- .../src/Epetra/Teko_StridedEpetraOperator.cpp | 334 +- .../src/Epetra/Teko_StridedEpetraOperator.hpp | 152 +- .../Epetra/Teko_StridedMappingStrategy.cpp | 210 +- .../Epetra/Teko_StridedMappingStrategy.hpp | 324 +- packages/teko/src/NS/Teko_ALOperator.cpp | 339 +- packages/teko/src/NS/Teko_ALOperator.hpp | 321 +- packages/teko/src/NS/Teko_InvLSCStrategy.cpp | 898 ++-- packages/teko/src/NS/Teko_InvLSCStrategy.hpp | 442 +- .../teko/src/NS/Teko_InvModALStrategy.cpp | 549 +- .../teko/src/NS/Teko_InvModALStrategy.hpp | 247 +- .../src/NS/Teko_LSCPreconditionerFactory.cpp | 389 +- .../src/NS/Teko_LSCPreconditionerFactory.hpp | 273 +- .../teko/src/NS/Teko_LSCSIMPLECStrategy.cpp | 328 +- .../teko/src/NS/Teko_LSCSIMPLECStrategy.hpp | 297 +- packages/teko/src/NS/Teko_LSCStrategy.hpp | 361 +- .../NS/Teko_ModALPreconditionerFactory.cpp | 201 +- .../NS/Teko_ModALPreconditionerFactory.hpp | 169 +- .../NS/Teko_NavierStokesPreconditioners.hpp | 28 +- packages/teko/src/NS/Teko_PCDStrategy.cpp | 495 +- packages/teko/src/NS/Teko_PCDStrategy.hpp | 276 +- .../src/NS/Teko_PresLaplaceLSCStrategy.cpp | 541 +- .../src/NS/Teko_PresLaplaceLSCStrategy.hpp | 363 +- .../NS/Teko_SIMPLEPreconditionerFactory.cpp | 524 +- .../NS/Teko_SIMPLEPreconditionerFactory.hpp | 124 +- .../teko/src/NS/Teko_StaticLSCStrategy.cpp | 27 +- .../teko/src/NS/Teko_StaticLSCStrategy.hpp | 267 +- ...eko_TimingsSIMPLEPreconditionerFactory.cpp | 643 ++- ...eko_TimingsSIMPLEPreconditionerFactory.hpp | 151 +- .../src/Teko_AddPreconditionerFactory.cpp | 130 +- .../src/Teko_AddPreconditionerFactory.hpp | 90 +- .../teko/src/Teko_BlockImplicitLinearOp.cpp | 89 +- .../teko/src/Teko_BlockImplicitLinearOp.hpp | 136 +- .../src/Teko_BlockInvDiagonalStrategy.cpp | 119 +- .../src/Teko_BlockInvDiagonalStrategy.hpp | 218 +- .../teko/src/Teko_BlockLowerTriInverseOp.cpp | 232 +- .../teko/src/Teko_BlockLowerTriInverseOp.hpp | 182 +- .../src/Teko_BlockPreconditionerFactory.cpp | 55 +- .../src/Teko_BlockPreconditionerFactory.hpp | 171 +- .../teko/src/Teko_BlockUpperTriInverseOp.cpp | 297 +- .../teko/src/Teko_BlockUpperTriInverseOp.hpp | 212 +- packages/teko/src/Teko_BlockedReordering.cpp | 1100 ++-- packages/teko/src/Teko_BlockedReordering.hpp | 695 +-- packages/teko/src/Teko_CloneFactory.hpp | 275 +- packages/teko/src/Teko_ConfigDefs.hpp | 2 +- packages/teko/src/Teko_DiagnosticLinearOp.cpp | 207 +- packages/teko/src/Teko_DiagnosticLinearOp.hpp | 311 +- .../Teko_DiagnosticPreconditionerFactory.cpp | 339 +- .../Teko_DiagnosticPreconditionerFactory.hpp | 218 +- .../Teko_DiagonalPreconditionerFactory.cpp | 87 +- .../Teko_DiagonalPreconditionerFactory.hpp | 66 +- .../src/Teko_DiagonalPreconditionerOp.cpp | 105 +- .../src/Teko_DiagonalPreconditionerOp.hpp | 93 +- ..._DiagonallyScaledPreconditionerFactory.cpp | 182 +- ..._DiagonallyScaledPreconditionerFactory.hpp | 145 +- .../Teko_GaussSeidelPreconditionerFactory.cpp | 213 +- .../Teko_GaussSeidelPreconditionerFactory.hpp | 115 +- .../Teko_IdentityPreconditionerFactory.cpp | 64 +- .../Teko_IdentityPreconditionerFactory.hpp | 70 +- packages/teko/src/Teko_ImplicitLinearOp.cpp | 63 +- packages/teko/src/Teko_ImplicitLinearOp.hpp | 102 +- packages/teko/src/Teko_InverseFactory.cpp | 364 +- packages/teko/src/Teko_InverseFactory.hpp | 556 +- packages/teko/src/Teko_InverseLibrary.cpp | 1112 ++-- packages/teko/src/Teko_InverseLibrary.hpp | 269 +- .../Teko_IterativePreconditionerFactory.cpp | 195 +- .../Teko_IterativePreconditionerFactory.hpp | 230 +- .../src/Teko_JacobiPreconditionerFactory.cpp | 228 +- .../src/Teko_JacobiPreconditionerFactory.hpp | 115 +- .../teko/src/Teko_LU2x2DiagonalStrategy.cpp | 310 +- .../teko/src/Teko_LU2x2DiagonalStrategy.hpp | 153 +- packages/teko/src/Teko_LU2x2InverseOp.cpp | 273 +- packages/teko/src/Teko_LU2x2InverseOp.hpp | 318 +- .../src/Teko_LU2x2PreconditionerFactory.cpp | 342 +- .../src/Teko_LU2x2PreconditionerFactory.hpp | 341 +- packages/teko/src/Teko_LU2x2Strategy.hpp | 278 +- .../src/Teko_MultPreconditionerFactory.cpp | 195 +- .../src/Teko_MultPreconditionerFactory.hpp | 175 +- ...eko_NeumannSeriesPreconditionerFactory.hpp | 256 +- ...NeumannSeriesPreconditionerFactoryDecl.hpp | 181 +- packages/teko/src/Teko_Preconditioner.hpp | 142 +- .../teko/src/Teko_PreconditionerFactory.cpp | 353 +- .../teko/src/Teko_PreconditionerFactory.hpp | 466 +- .../src/Teko_PreconditionerInverseFactory.cpp | 549 +- .../src/Teko_PreconditionerInverseFactory.hpp | 345 +- .../teko/src/Teko_PreconditionerLinearOp.hpp | 169 +- .../src/Teko_PreconditionerLinearOpDecl.hpp | 139 +- .../teko/src/Teko_PreconditionerState.cpp | 87 +- .../teko/src/Teko_PreconditionerState.hpp | 246 +- .../src/Teko_ProbingPreconditionerFactory.cpp | 129 +- .../src/Teko_ProbingPreconditionerFactory.hpp | 66 +- packages/teko/src/Teko_ReorderedLinearOp.cpp | 100 +- packages/teko/src/Teko_ReorderedLinearOp.hpp | 102 +- packages/teko/src/Teko_RequestCallback.hpp | 112 +- packages/teko/src/Teko_RequestHandler.cpp | 38 +- packages/teko/src/Teko_RequestHandler.hpp | 158 +- .../teko/src/Teko_RequestHandlerContainer.hpp | 48 +- .../teko/src/Teko_RequestHandler_impl.hpp | 99 +- packages/teko/src/Teko_RequestMesg.hpp | 141 +- .../teko/src/Teko_SolveInverseFactory.cpp | 237 +- .../teko/src/Teko_SolveInverseFactory.hpp | 226 +- .../teko/src/Teko_StaticRequestCallback.hpp | 83 +- packages/teko/src/Teko_StratimikosFactory.cpp | 740 ++- packages/teko/src/Teko_StratimikosFactory.hpp | 164 +- packages/teko/src/Teko_Utilities.cpp | 4571 +++++++++-------- packages/teko/src/Teko_Utilities.hpp | 1207 ++--- .../src/Tpetra/Teko_BlockedTpetraOperator.cpp | 255 +- .../src/Tpetra/Teko_BlockedTpetraOperator.hpp | 214 +- .../teko/src/Tpetra/Teko_BlockingTpetra.cpp | 666 +-- .../teko/src/Tpetra/Teko_BlockingTpetra.hpp | 220 +- .../teko/src/Tpetra/Teko_InterlacedTpetra.cpp | 849 +-- .../teko/src/Tpetra/Teko_InterlacedTpetra.hpp | 246 +- .../src/Tpetra/Teko_StridedTpetraOperator.cpp | 353 +- .../src/Tpetra/Teko_StridedTpetraOperator.hpp | 156 +- .../Teko_TpetraBasicMappingStrategy.cpp | 78 +- .../Teko_TpetraBasicMappingStrategy.hpp | 194 +- .../Tpetra/Teko_TpetraBlockPreconditioner.cpp | 537 +- .../Tpetra/Teko_TpetraBlockPreconditioner.hpp | 287 +- .../Teko_TpetraBlockedMappingStrategy.cpp | 241 +- .../Teko_TpetraBlockedMappingStrategy.hpp | 325 +- .../teko/src/Tpetra/Teko_TpetraHelpers.cpp | 526 +- .../teko/src/Tpetra/Teko_TpetraHelpers.hpp | 282 +- .../Teko_TpetraInverseFactoryOperator.cpp | 289 +- .../Teko_TpetraInverseFactoryOperator.hpp | 263 +- .../Tpetra/Teko_TpetraInverseOpWrapper.cpp | 46 +- .../Tpetra/Teko_TpetraInverseOpWrapper.hpp | 72 +- .../src/Tpetra/Teko_TpetraOperatorWrapper.cpp | 387 +- .../src/Tpetra/Teko_TpetraOperatorWrapper.hpp | 428 +- .../Teko_TpetraReorderedMappingStrategy.cpp | 80 +- .../Teko_TpetraReorderedMappingStrategy.hpp | 199 +- .../Teko_TpetraStridedMappingStrategy.cpp | 214 +- .../Teko_TpetraStridedMappingStrategy.hpp | 326 +- .../src/Tpetra/Teko_TpetraThyraConverter.cpp | 373 +- .../src/Tpetra/Teko_TpetraThyraConverter.hpp | 113 +- packages/teko/src/mlutils/Teko_MLLinearOp.cpp | 172 +- packages/teko/src/mlutils/Teko_MLLinearOp.hpp | 103 +- .../mlutils/Teko_MLPreconditionerFactory.cpp | 236 +- .../mlutils/Teko_MLPreconditionerFactory.hpp | 124 +- .../Teko_SmootherPreconditionerFactory.cpp | 382 +- .../Teko_SmootherPreconditionerFactory.hpp | 257 +- packages/teko/src/mlutils/Teko_mlutils.cpp | 278 +- packages/teko/src/mlutils/Teko_mlutils.hpp | 37 +- packages/teko/tests/Teko_UnitTestMain.cpp | 5 +- packages/teko/tests/Test_Utils.cpp | 608 ++- packages/teko/tests/Test_Utils.hpp | 189 +- .../src/Epetra/tBlockedEpetraOperator.cpp | 596 ++- .../src/Epetra/tBlockedEpetraOperator.hpp | 52 +- .../teko/tests/src/Epetra/tBlockingEpetra.cpp | 705 ++- .../teko/tests/src/Epetra/tBlockingEpetra.hpp | 54 +- .../src/Epetra/tEpetraOperatorWrapper.cpp | 438 +- .../src/Epetra/tEpetraOperatorWrapper.hpp | 44 +- .../src/Epetra/tEpetraThyraConverter.cpp | 609 +-- .../src/Epetra/tEpetraThyraConverter.hpp | 52 +- .../tests/src/Epetra/tInterlacedEpetra.cpp | 921 ++-- .../tests/src/Epetra/tInterlacedEpetra.hpp | 56 +- .../src/Epetra/tStridedEpetraOperator.cpp | 757 ++- .../src/Epetra/tStridedEpetraOperator.hpp | 52 +- .../src/Tpetra/tBlockedTpetraOperator.cpp | 545 +- .../src/Tpetra/tBlockedTpetraOperator.hpp | 53 +- .../teko/tests/src/Tpetra/tBlockingTpetra.cpp | 678 ++- .../teko/tests/src/Tpetra/tBlockingTpetra.hpp | 54 +- .../tests/src/Tpetra/tInterlacedTpetra.cpp | 898 ++-- .../tests/src/Tpetra/tInterlacedTpetra.hpp | 56 +- .../src/Tpetra/tStridedTpetraOperator.cpp | 725 ++- .../src/Tpetra/tStridedTpetraOperator.hpp | 52 +- .../src/Tpetra/tTpetraOperatorWrapper.cpp | 463 +- .../src/Tpetra/tTpetraOperatorWrapper.hpp | 45 +- .../src/Tpetra/tTpetraThyraConverter.cpp | 548 +- .../src/Tpetra/tTpetraThyraConverter.hpp | 52 +- packages/teko/tests/src/tAbsRowSum.cpp | 302 +- packages/teko/tests/src/tAbsRowSum.hpp | 50 +- packages/teko/tests/src/tAbsRowSum_tpetra.cpp | 290 +- packages/teko/tests/src/tAbsRowSum_tpetra.hpp | 50 +- .../src/tBlockJacobiPreconditionerFactory.cpp | 439 +- .../src/tBlockJacobiPreconditionerFactory.hpp | 58 +- ...lockJacobiPreconditionerFactory_tpetra.cpp | 480 +- ...lockJacobiPreconditionerFactory_tpetra.hpp | 30 +- .../tests/src/tBlockLowerTriInverseOp.cpp | 371 +- .../tests/src/tBlockLowerTriInverseOp.hpp | 56 +- .../src/tBlockLowerTriInverseOp_tpetra.cpp | 349 +- .../src/tBlockLowerTriInverseOp_tpetra.hpp | 56 +- .../tests/src/tBlockUpperTriInverseOp.cpp | 437 +- .../tests/src/tBlockUpperTriInverseOp.hpp | 58 +- .../src/tBlockUpperTriInverseOp_tpetra.cpp | 361 +- .../src/tBlockUpperTriInverseOp_tpetra.hpp | 56 +- .../src/tDiagonalPreconditionerFactory.cpp | 232 +- .../src/tDiagonalPreconditionerFactory.hpp | 71 +- .../tDiagonalPreconditionerFactory_tpetra.cpp | 250 +- .../tDiagonalPreconditionerFactory_tpetra.hpp | 43 +- packages/teko/tests/src/tExplicitOps.cpp | 636 ++- packages/teko/tests/src/tExplicitOps.hpp | 64 +- .../teko/tests/src/tExplicitOps_tpetra.cpp | 826 +-- .../teko/tests/src/tExplicitOps_tpetra.hpp | 66 +- packages/teko/tests/src/tGraphLaplacian.cpp | 354 +- packages/teko/tests/src/tGraphLaplacian.hpp | 53 +- .../teko/tests/src/tGraphLaplacian_tpetra.cpp | 368 +- .../teko/tests/src/tGraphLaplacian_tpetra.hpp | 53 +- .../src/tJacobi2x2PreconditionerFactory.cpp | 1250 +++-- .../src/tJacobi2x2PreconditionerFactory.hpp | 82 +- ...tJacobi2x2PreconditionerFactory_tpetra.cpp | 1279 ++--- ...tJacobi2x2PreconditionerFactory_tpetra.hpp | 82 +- .../teko/tests/src/tLSCHIntegrationTest.cpp | 300 +- .../teko/tests/src/tLSCHIntegrationTest.hpp | 48 +- .../tests/src/tLSCHIntegrationTest_tpetra.cpp | 288 +- .../tests/src/tLSCHIntegrationTest_tpetra.hpp | 48 +- .../teko/tests/src/tLSCIntegrationTest.cpp | 637 +-- .../teko/tests/src/tLSCIntegrationTest.hpp | 80 +- .../tests/src/tLSCIntegrationTest_tpetra.cpp | 619 ++- .../tests/src/tLSCIntegrationTest_tpetra.hpp | 80 +- packages/teko/tests/src/tLSCStabilized.cpp | 938 ++-- packages/teko/tests/src/tLSCStabilized.hpp | 58 +- .../teko/tests/src/tLSCStabilized_tpetra.cpp | 974 ++-- .../teko/tests/src/tLSCStabilized_tpetra.hpp | 58 +- .../src/tLSCStablePreconditionerFactory.cpp | 1170 +++-- .../src/tLSCStablePreconditionerFactory.hpp | 52 +- ...tLSCStablePreconditionerFactory_tpetra.cpp | 1252 ++--- ...tLSCStablePreconditionerFactory_tpetra.hpp | 52 +- .../tests/src/tLU2x2PreconditionerFactory.cpp | 1461 +++--- .../tests/src/tLU2x2PreconditionerFactory.hpp | 80 +- .../tLU2x2PreconditionerFactory_tpetra.cpp | 1585 +++--- .../tLU2x2PreconditionerFactory_tpetra.hpp | 80 +- packages/teko/tests/src/tLumping.cpp | 301 +- packages/teko/tests/src/tLumping.hpp | 50 +- packages/teko/tests/src/tLumping_tpetra.cpp | 290 +- packages/teko/tests/src/tLumping_tpetra.hpp | 50 +- packages/teko/tests/src/tNeumannSeries.cpp | 388 +- packages/teko/tests/src/tNeumannSeries.hpp | 50 +- .../teko/tests/src/tNeumannSeries_tpetra.cpp | 377 +- .../teko/tests/src/tNeumannSeries_tpetra.hpp | 50 +- packages/teko/tests/src/tPCDStrategy.cpp | 391 +- packages/teko/tests/src/tPCDStrategy.hpp | 48 +- .../teko/tests/src/tPCDStrategy_tpetra.cpp | 379 +- .../teko/tests/src/tPCDStrategy_tpetra.hpp | 48 +- packages/teko/tests/src/tParallelInverse.cpp | 181 +- packages/teko/tests/src/tParallelInverse.hpp | 58 +- .../tests/src/tParallelInverse_tpetra.cpp | 158 +- .../tests/src/tParallelInverse_tpetra.hpp | 58 +- .../src/tSIMPLEPreconditionerFactory.cpp | 1398 ++--- .../src/tSIMPLEPreconditionerFactory.hpp | 100 +- .../tSIMPLEPreconditionerFactory_tpetra.cpp | 991 ++-- .../tSIMPLEPreconditionerFactory_tpetra.hpp | 100 +- packages/teko/tests/testdriver.cpp | 221 +- packages/teko/tests/testdriver_tpetra.cpp | 206 +- .../teko/tests/unit_tests/tALOperator.cpp | 180 +- .../tests/unit_tests/tDiagnosticLinearOp.cpp | 715 +-- .../tDiagonalPreconditionerFactory.cpp | 291 +- .../tDiagonallyScaledPreconditioner.cpp | 668 ++- .../teko/tests/unit_tests/tExplicitOps.cpp | 103 +- .../unit_tests/tInverseFactoryOperator.cpp | 606 +-- .../tIterativePreconditionerFactory.cpp | 697 +-- .../teko/tests/unit_tests/tLU2x2InverseOp.cpp | 264 +- .../tests/unit_tests/tModALPreconditioner.cpp | 236 +- .../teko/tests/unit_tests/tProbingFactory.cpp | 368 +- .../tests/unit_tests/tReorderBlocking.cpp | 284 +- .../tests/unit_tests/tRequestInterface.cpp | 350 +- .../tests/unit_tests/tStratimikosFactory.cpp | 663 +-- .../unit_tests/tStridedEpetraOperator.cpp | 630 +-- .../teko/tests/unit_tests/tUtilitiesTests.cpp | 155 +- 295 files changed, 46060 insertions(+), 44819 deletions(-) create mode 100644 packages/teko/.clang-format diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml index a1673683bafd..95ec174a8123 100644 --- a/.github/workflows/clang_format.yml +++ b/.github/workflows/clang_format.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: DoozyX/clang-format-lint-action@v0.16.2 with: - source: './packages/muelu ./packages/tempus ./packages/xpetra' + source: './packages/muelu ./packages/tempus ./packages/teko ./packages/xpetra' exclude: './packages/tempus/examples' extensions: 'cpp,hpp' clangFormatVersion: 14 diff --git a/packages/teko/.clang-format b/packages/teko/.clang-format new file mode 100644 index 000000000000..37d0679d14dc --- /dev/null +++ b/packages/teko/.clang-format @@ -0,0 +1,8 @@ +#Official Tool: clang-format version 14.0.0 +#Kokkos options +BasedOnStyle: google +SortIncludes: false +AlignConsecutiveAssignments: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: true +ColumnLimit: 100 diff --git a/packages/teko/examples/AddMultiplyPrecs/Driver.cpp b/packages/teko/examples/AddMultiplyPrecs/Driver.cpp index d79140b93fc9..04a816446f9c 100644 --- a/packages/teko/examples/AddMultiplyPrecs/Driver.cpp +++ b/packages/teko/examples/AddMultiplyPrecs/Driver.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -63,10 +63,10 @@ // include basic Epetra information #ifdef HAVE_MPI - #include "Epetra_MpiComm.h" - #include "mpi.h" +#include "Epetra_MpiComm.h" +#include "mpi.h" #else - #include "Epetra_SerialComm.h" +#include "Epetra_SerialComm.h" #endif #include "Epetra_Map.h" #include "Epetra_CrsMatrix.h" @@ -74,7 +74,7 @@ #include "Epetra_LinearProblem.h" #include "Epetra_Export.h" -// EpetraExt +// EpetraExt #include "EpetraExt_CrsMatrixIn.h" #include "EpetraExt_VectorIn.h" #include "EpetraExt_VectorOut.h" @@ -110,83 +110,87 @@ #include #include +using Teuchos::null; +using Teuchos::ParameterList; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcp_dynamic_cast; -using Teuchos::null; -using Teuchos::ParameterList; // -// Exercise the use of additive and multiplicative preconditioners +// Exercise the use of additive and multiplicative preconditioners // using AddPreconditionerFactory and MultPreconditionerFactory // -int main(int argc,char * argv[]) -{ - // calls MPI_Init and MPI_Finalize - Teuchos::GlobalMPISession mpiSession(&argc,&argv); - - // Handles some I/O to the output screen - RCP out = Teuchos::VerboseObjectBase::getDefaultOStream(); - - #ifdef HAVE_MPI - Epetra_MpiComm Comm(MPI_COMM_WORLD); - #else - Epetra_SerialComm Comm; - #endif - - // get process information - int numProc = Comm.NumProc(); - int myPID = Comm.MyPID(); - - // output garbage - *out << "Approaching Barrier: proc = " << numProc << ", pid = " << myPID << std::endl; - Comm.Barrier(); - - RCP paramList = Teuchos::getParametersFromXmlFile("solverparams.xml"); - - Epetra_Map map(15444,0,Comm); - Epetra_CrsMatrix * ptrA = 0; - Epetra_Vector * ptrf = 0; - Epetra_Vector * ptrx = 0; - - std::cout << "Reading matrix market file" << std::endl; - EpetraExt::MatrixMarketFileToCrsMatrix("./modified.mm",map,map,map,ptrA); - EpetraExt::MatrixMarketFileToVector("./rhs_test.mm",map,ptrf); - EpetraExt::MatrixMarketFileToVector("./lhs_test.mm",map,ptrx); - - RCP A = rcp(ptrA); - RCP b = rcp(ptrf); - RCP x = rcp(ptrx); - - std::cout << "Building strided operator" << std::endl; - std::vector vec(2); vec[0] = 2; vec[1] = 1; - Teuchos::RCP sA - = Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(vec,A)); - - RCP inverse = Teko::invFactoryFromParamList(*paramList,"Amesos"); - RCP strategy = rcp(new Teko::InvFactoryDiagStrategy(inverse)); - - RCP GSFactory = rcp(new Teko::GaussSeidelPreconditionerFactory( - Teko::GS_UseLowerTriangle,strategy)); - RCP JacobiFactory = rcp(new Teko::JacobiPreconditionerFactory(strategy)); - #ifdef ADD_PREC - RCP MasterFactory = rcp(new Teko::AddPreconditionerFactory(GSFactory,JacobiFactory)); - #else - RCP MasterFactory = rcp(new Teko::MultPreconditionerFactory(GSFactory,JacobiFactory)); - #endif - - Teko::Epetra::EpetraBlockPreconditioner MyPreconditioner(MasterFactory); - MyPreconditioner.buildPreconditioner(sA); - Epetra_LinearProblem problem(&*A,&*x,&*b); - - // build solver - AztecOO solver(problem); - solver.SetAztecOption(AZ_solver,AZ_gmres); - solver.SetAztecOption(AZ_precond,AZ_none); - solver.SetAztecOption(AZ_kspace,50); - solver.SetAztecOption(AZ_output,10); - solver.SetPrecOperator(&MyPreconditioner); - solver.Iterate(100,1e-5); - - return 0; +int main(int argc, char* argv[]) { + // calls MPI_Init and MPI_Finalize + Teuchos::GlobalMPISession mpiSession(&argc, &argv); + + // Handles some I/O to the output screen + RCP out = Teuchos::VerboseObjectBase::getDefaultOStream(); + +#ifdef HAVE_MPI + Epetra_MpiComm Comm(MPI_COMM_WORLD); +#else + Epetra_SerialComm Comm; +#endif + + // get process information + int numProc = Comm.NumProc(); + int myPID = Comm.MyPID(); + + // output garbage + *out << "Approaching Barrier: proc = " << numProc << ", pid = " << myPID << std::endl; + Comm.Barrier(); + + RCP paramList = Teuchos::getParametersFromXmlFile("solverparams.xml"); + + Epetra_Map map(15444, 0, Comm); + Epetra_CrsMatrix* ptrA = 0; + Epetra_Vector* ptrf = 0; + Epetra_Vector* ptrx = 0; + + std::cout << "Reading matrix market file" << std::endl; + EpetraExt::MatrixMarketFileToCrsMatrix("./modified.mm", map, map, map, ptrA); + EpetraExt::MatrixMarketFileToVector("./rhs_test.mm", map, ptrf); + EpetraExt::MatrixMarketFileToVector("./lhs_test.mm", map, ptrx); + + RCP A = rcp(ptrA); + RCP b = rcp(ptrf); + RCP x = rcp(ptrx); + + std::cout << "Building strided operator" << std::endl; + std::vector vec(2); + vec[0] = 2; + vec[1] = 1; + Teuchos::RCP sA = + Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(vec, A)); + + RCP inverse = Teko::invFactoryFromParamList(*paramList, "Amesos"); + RCP strategy = rcp(new Teko::InvFactoryDiagStrategy(inverse)); + + RCP GSFactory = + rcp(new Teko::GaussSeidelPreconditionerFactory(Teko::GS_UseLowerTriangle, strategy)); + RCP JacobiFactory = + rcp(new Teko::JacobiPreconditionerFactory(strategy)); +#ifdef ADD_PREC + RCP MasterFactory = + rcp(new Teko::AddPreconditionerFactory(GSFactory, JacobiFactory)); +#else + RCP MasterFactory = + rcp(new Teko::MultPreconditionerFactory(GSFactory, JacobiFactory)); +#endif + + Teko::Epetra::EpetraBlockPreconditioner MyPreconditioner(MasterFactory); + MyPreconditioner.buildPreconditioner(sA); + Epetra_LinearProblem problem(&*A, &*x, &*b); + + // build solver + AztecOO solver(problem); + solver.SetAztecOption(AZ_solver, AZ_gmres); + solver.SetAztecOption(AZ_precond, AZ_none); + solver.SetAztecOption(AZ_kspace, 50); + solver.SetAztecOption(AZ_output, 10); + solver.SetPrecOperator(&MyPreconditioner); + solver.Iterate(100, 1e-5); + + return 0; } diff --git a/packages/teko/examples/BasicExamples/inverse-factory-operator.cpp b/packages/teko/examples/BasicExamples/inverse-factory-operator.cpp index b8e4a4eea969..4773d1f826f4 100644 --- a/packages/teko/examples/BasicExamples/inverse-factory-operator.cpp +++ b/packages/teko/examples/BasicExamples/inverse-factory-operator.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,10 +52,10 @@ // Epetra includes #ifdef HAVE_MPI - #include "mpi.h" - #include "Epetra_MpiComm.h" +#include "mpi.h" +#include "Epetra_MpiComm.h" #else - #include "Epetra_SerialComm.h" +#include "Epetra_SerialComm.h" #endif #include "Epetra_CrsMatrix.h" #include "Epetra_Vector.h" @@ -82,74 +82,74 @@ using Teuchos::RCP; using Teuchos::rcp; -int main(int argc,char * argv[]) -{ - // calls MPI_Init and MPI_Finalize - Teuchos::GlobalMPISession mpiSession(&argc,&argv); +int main(int argc, char* argv[]) { + // calls MPI_Init and MPI_Finalize + Teuchos::GlobalMPISession mpiSession(&argc, &argv); - // read in parameter list - Teuchos::RCP paramList = Teuchos::getParametersFromXmlFile("simple_example.xml"); + // read in parameter list + Teuchos::RCP paramList = + Teuchos::getParametersFromXmlFile("simple_example.xml"); - // build global communicator + // build global communicator #ifdef HAVE_MPI - Epetra_MpiComm Comm(MPI_COMM_WORLD); + Epetra_MpiComm Comm(MPI_COMM_WORLD); #else - Epetra_SerialComm Comm; + Epetra_SerialComm Comm; #endif - // Read in the matrix, store pointer as an RCP - Epetra_CrsMatrix * ptrA = 0; - EpetraExt::MatrixMarketFileToCrsMatrix("../data/nsjac.mm",Comm,ptrA); - RCP A = rcp(ptrA); - - // read in the RHS vector - Epetra_Vector * ptrb = 0; - EpetraExt::MatrixMarketFileToVector("../data/nsrhs_test.mm",A->OperatorRangeMap(),ptrb); - RCP b = rcp(ptrb); - - // allocate vectors - RCP x = rcp(new Epetra_Vector(A->OperatorDomainMap())); - x->PutScalar(0.0); - - // Break apart the strided linear system - ///////////////////////////////////////////////////////// - - // Block the linear system using a strided epetra operator - std::vector vec(2); vec[0] = 2; vec[1] = 1; /*@ \label{lned:define-strided} @*/ - Teuchos::RCP strided_A - = Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(vec,A)); - - // Build the preconditioner /*@ \label{lned:construct-prec} @*/ - ///////////////////////////////////////////////////////// - - // build an InverseLibrary and inverse factory - RCP invLib - = Teko::InverseLibrary::buildFromParameterList(*paramList); - RCP inverse - = invLib->getInverseFactory("SIMPLE"); - - // Create the initial preconditioner, and build it from strided_A - RCP prec_A - = rcp(new Teko::Epetra::InverseFactoryOperator(inverse)); - prec_A->initInverse(); - prec_A->rebuildInverseOperator(strided_A.getConst()); - - // Build and solve the linear system - ///////////////////////////////////////////////////////// - - // Setup the linear solve: notice A is used directly - Epetra_LinearProblem problem(&*A,&*x,&*b); /*@ \label{lned:aztec-solve} @*/ - - // build the solver - AztecOO solver(problem); - solver.SetAztecOption(AZ_solver,AZ_gmres); - solver.SetAztecOption(AZ_precond,AZ_none); - solver.SetAztecOption(AZ_kspace,1000); - solver.SetAztecOption(AZ_output,10); - solver.SetPrecOperator(&*prec_A); - - // solve the linear system - solver.Iterate(1000,1e-5); - - return 0; + // Read in the matrix, store pointer as an RCP + Epetra_CrsMatrix* ptrA = 0; + EpetraExt::MatrixMarketFileToCrsMatrix("../data/nsjac.mm", Comm, ptrA); + RCP A = rcp(ptrA); + + // read in the RHS vector + Epetra_Vector* ptrb = 0; + EpetraExt::MatrixMarketFileToVector("../data/nsrhs_test.mm", A->OperatorRangeMap(), ptrb); + RCP b = rcp(ptrb); + + // allocate vectors + RCP x = rcp(new Epetra_Vector(A->OperatorDomainMap())); + x->PutScalar(0.0); + + // Break apart the strided linear system + ///////////////////////////////////////////////////////// + + // Block the linear system using a strided epetra operator + std::vector vec(2); + vec[0] = 2; + vec[1] = 1; /*@ \label{lned:define-strided} @*/ + Teuchos::RCP strided_A = + Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(vec, A)); + + // Build the preconditioner /*@ \label{lned:construct-prec} @*/ + ///////////////////////////////////////////////////////// + + // build an InverseLibrary and inverse factory + RCP invLib = Teko::InverseLibrary::buildFromParameterList(*paramList); + RCP inverse = invLib->getInverseFactory("SIMPLE"); + + // Create the initial preconditioner, and build it from strided_A + RCP prec_A = + rcp(new Teko::Epetra::InverseFactoryOperator(inverse)); + prec_A->initInverse(); + prec_A->rebuildInverseOperator(strided_A.getConst()); + + // Build and solve the linear system + ///////////////////////////////////////////////////////// + + // Setup the linear solve: notice A is used directly + Epetra_LinearProblem problem(&*A, &*x, &*b); /*@ \label{lned:aztec-solve} @*/ + + // build the solver + AztecOO solver(problem); + solver.SetAztecOption(AZ_solver, AZ_gmres); + solver.SetAztecOption(AZ_precond, AZ_none); + solver.SetAztecOption(AZ_kspace, 1000); + solver.SetAztecOption(AZ_output, 10); + solver.SetPrecOperator(&*prec_A); + + // solve the linear system + solver.Iterate(1000, 1e-5); + + return 0; } diff --git a/packages/teko/examples/BasicExamples/stratimikos-solve.cpp b/packages/teko/examples/BasicExamples/stratimikos-solve.cpp index 2730c94c715b..d12d7d23a7f9 100644 --- a/packages/teko/examples/BasicExamples/stratimikos-solve.cpp +++ b/packages/teko/examples/BasicExamples/stratimikos-solve.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,10 +52,10 @@ // Epetra includes #ifdef HAVE_MPI - #include "mpi.h" - #include "Epetra_MpiComm.h" +#include "mpi.h" +#include "Epetra_MpiComm.h" #else - #include "Epetra_SerialComm.h" +#include "Epetra_SerialComm.h" #endif #include "Epetra_CrsMatrix.h" #include "Epetra_Vector.h" @@ -77,57 +77,57 @@ using Teuchos::RCP; using Teuchos::rcp; -int main(int argc,char * argv[]) -{ - // calls MPI_Init and MPI_Finalize - Teuchos::GlobalMPISession mpiSession(&argc,&argv); +int main(int argc, char* argv[]) { + // calls MPI_Init and MPI_Finalize + Teuchos::GlobalMPISession mpiSession(&argc, &argv); - // read in parameter list - Teuchos::RCP paramList = Teuchos::getParametersFromXmlFile("strat_example.xml"); + // read in parameter list + Teuchos::RCP paramList = + Teuchos::getParametersFromXmlFile("strat_example.xml"); - // build global communicator + // build global communicator #ifdef HAVE_MPI - Epetra_MpiComm Comm(MPI_COMM_WORLD); + Epetra_MpiComm Comm(MPI_COMM_WORLD); #else - Epetra_SerialComm Comm; + Epetra_SerialComm Comm; #endif - // Read in the matrix, store pointer as an RCP - Epetra_CrsMatrix * ptrA = 0; - EpetraExt::MatrixMarketFileToCrsMatrix("../data/nsjac.mm",Comm,ptrA); - RCP A = rcp(ptrA); + // Read in the matrix, store pointer as an RCP + Epetra_CrsMatrix* ptrA = 0; + EpetraExt::MatrixMarketFileToCrsMatrix("../data/nsjac.mm", Comm, ptrA); + RCP A = rcp(ptrA); - // read in the RHS vector - Epetra_Vector * ptrb = 0; - EpetraExt::MatrixMarketFileToVector("../data/nsrhs_test.mm",A->OperatorRangeMap(),ptrb); - RCP b = rcp(ptrb); + // read in the RHS vector + Epetra_Vector* ptrb = 0; + EpetraExt::MatrixMarketFileToVector("../data/nsrhs_test.mm", A->OperatorRangeMap(), ptrb); + RCP b = rcp(ptrb); - // allocate vectors - RCP x = rcp(new Epetra_Vector(A->OperatorDomainMap())); - x->PutScalar(0.0); + // allocate vectors + RCP x = rcp(new Epetra_Vector(A->OperatorDomainMap())); + x->PutScalar(0.0); - // Build Thyra linear algebra objects - RCP > th_A = Thyra::epetraLinearOp(A); - RCP > th_b = Thyra::create_Vector(b,th_A->range()); - RCP > th_x = Thyra::create_Vector(x,th_A->domain()); + // Build Thyra linear algebra objects + RCP > th_A = Thyra::epetraLinearOp(A); + RCP > th_b = Thyra::create_Vector(b, th_A->range()); + RCP > th_x = Thyra::create_Vector(x, th_A->domain()); - // Build stratimikos solver - ///////////////////////////////////////////////////////// + // Build stratimikos solver + ///////////////////////////////////////////////////////// - Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder; + Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder; - Teko::addTekoToStratimikosBuilder(linearSolverBuilder); - linearSolverBuilder.setParameterList(paramList); + Teko::addTekoToStratimikosBuilder(linearSolverBuilder); + linearSolverBuilder.setParameterList(paramList); - RCP > lowsFactory - = Thyra::createLinearSolveStrategy(linearSolverBuilder); + RCP > lowsFactory = + Thyra::createLinearSolveStrategy(linearSolverBuilder); - Teuchos::RCP > th_invA - = Thyra::linearOpWithSolve(*lowsFactory, th_A); + Teuchos::RCP > th_invA = + Thyra::linearOpWithSolve(*lowsFactory, th_A); - Thyra::assign(th_x.ptr(), 0.0); - Thyra::SolveStatus status - = Thyra::solve(*th_invA, Thyra::NOTRANS, *th_b, th_x.ptr()); + Thyra::assign(th_x.ptr(), 0.0); + Thyra::SolveStatus status = + Thyra::solve(*th_invA, Thyra::NOTRANS, *th_b, th_x.ptr()); - return 0; + return 0; } diff --git a/packages/teko/examples/BuildPreconditioner/example-driver-belos.cpp b/packages/teko/examples/BuildPreconditioner/example-driver-belos.cpp index 9f16011f3daa..6fffa87aea42 100644 --- a/packages/teko/examples/BuildPreconditioner/example-driver-belos.cpp +++ b/packages/teko/examples/BuildPreconditioner/example-driver-belos.cpp @@ -75,7 +75,7 @@ #include "BelosConfigDefs.hpp" #include "BelosLinearProblem.hpp" #include "BelosBlockGmresSolMgr.hpp" -#include "BelosThyraAdapter.hpp" // Requires Stratimikos... +#include "BelosThyraAdapter.hpp" // Requires Stratimikos... #include /*@ \label{lned:end-includes} @*/ @@ -86,126 +86,137 @@ using Teuchos::rcpFromRef; RCP buildLibPL(); -int main(int argc,char * argv[]) -{ - typedef double ST; - typedef Thyra::MultiVectorBase MV; - typedef Thyra::LinearOpBase OP; - - typedef Tpetra::Vector TP_Vec; - typedef Tpetra::CrsMatrix TP_Crs; - typedef Tpetra::Operator TP_Op; - - typedef TP_Vec::local_ordinal_type LO; - typedef TP_Vec::global_ordinal_type GO; - typedef TP_Vec::node_type NT; - - // calls MPI_Init and MPI_Finalize - Teuchos::GlobalMPISession mpiSession(&argc,&argv); - - RCP linearSolverBuilder = Teuchos::rcp(new Stratimikos::DefaultLinearSolverBuilder); - - // Build the Tpetra matrices and vectors - ///////////////////////////////////////////////////////// - - // read in the CRS matrix - RCP crsMat = Tpetra::MatrixMarket::Reader::readSparseFile("../data/nsjac.mm", Tpetra::getDefaultComm()); - - RCP zeroCrsMat = rcp(new TP_Crs(*crsMat, Teuchos::Copy)); - zeroCrsMat->setAllToScalar(0.0); - - RCP Mat = crsMat; - RCP zeroMat = zeroCrsMat; - - // Allocate some right handside vectors - RCP x0_tp = rcp(new TP_Vec(Mat->getDomainMap())); - RCP x1_tp = rcp(new TP_Vec(Mat->getDomainMap())); - RCP b0_tp = rcp(new TP_Vec(Mat->getRangeMap())); - RCP b1_tp = rcp(new TP_Vec(Mat->getRangeMap())); - b0_tp->randomize(); - b1_tp->randomize(); - - RCP > domain = Thyra::tpetraVectorSpace(Mat->getDomainMap()); - RCP > range = Thyra::tpetraVectorSpace(Mat->getRangeMap()); - - // Build Teko compatible matrices and vectors - ///////////////////////////////////////////////////////// - - // convert them to teko compatible sub vectors - Teko::MultiVector x0_th = Thyra::tpetraVector(domain, x0_tp); - Teko::MultiVector x1_th = Thyra::tpetraVector(domain, x1_tp); - Teko::MultiVector b0_th = Thyra::tpetraVector( range, b0_tp); - Teko::MultiVector b1_th = Thyra::tpetraVector( range, b1_tp); - std::vector x_vec; x_vec.push_back(x0_th); x_vec.push_back(x1_th); - std::vector b_vec; b_vec.push_back(b0_th); b_vec.push_back(b1_th); - - Teko::MultiVector x = Teko::buildBlockedMultiVector(x_vec); // these will be used in the Teko solve - Teko::MultiVector b = Teko::buildBlockedMultiVector(b_vec); - - // Build the Teko compatible linear system - Teko::LinearOp thMat = Thyra::tpetraLinearOp(range,domain,Mat); - Teko::LinearOp thZero = Thyra::tpetraLinearOp(range,domain,zeroMat); - Teko::LinearOp A = Thyra::block2x2(thMat,thZero,thZero,thMat); // build an upper triangular 2x2 - - // Build the preconditioner - ///////////////////////////////////////////////////////// - - // build an InverseLibrary - RCP invLib = Teko::InverseLibrary::buildFromParameterList(*buildLibPL(),linearSolverBuilder); - - // build the inverse factory needed by the example preconditioner - RCP inverse = invLib->getInverseFactory("Gauss-Seidel"); - - // build the preconditioner from the jacobian - Teko::LinearOp prec = Teko::buildInverse(*inverse,A); - - // Setup the Belos solver - ///////////////////////////////////////////////////////// - - Teuchos::ParameterList belosList; - belosList.set( "Num Blocks", 200 ); // Maximum number of blocks in Krylov factorization - belosList.set( "Block Size",1 ); // Blocksize to be used by iterative solver - belosList.set( "Maximum Iterations", 200 ); // Maximum number of iterations allowed - belosList.set( "Maximum Restarts", 1 ); // Maximum number of restarts allowed - belosList.set( "Convergence Tolerance", 1e-5 ); // Relative convergence tolerance requested - belosList.set( "Verbosity", 33);//Belos::Errors + Belos::Warnings + Belos::TimingDetails + Belos::StatusTestDetails ); - belosList.set( "Output Frequency", 1 ); - belosList.set( "Output Style", 1 ); - - RCP > problem = rcp(new Belos::LinearProblem( A, x, b ) ); - problem->setLeftPrec(prec); - problem->setProblem(); // should check the return type!!! - - RCP > solver - = rcp(new Belos::BlockGmresSolMgr(problem, rcpFromRef(belosList))); - - // - // Perform solve - // - Belos::ReturnType ret = solver->solve(); +int main(int argc, char* argv[]) { + typedef double ST; + typedef Thyra::MultiVectorBase MV; + typedef Thyra::LinearOpBase OP; + + typedef Tpetra::Vector TP_Vec; + typedef Tpetra::CrsMatrix TP_Crs; + typedef Tpetra::Operator TP_Op; + + typedef TP_Vec::local_ordinal_type LO; + typedef TP_Vec::global_ordinal_type GO; + typedef TP_Vec::node_type NT; + + // calls MPI_Init and MPI_Finalize + Teuchos::GlobalMPISession mpiSession(&argc, &argv); + + RCP linearSolverBuilder = + Teuchos::rcp(new Stratimikos::DefaultLinearSolverBuilder); + + // Build the Tpetra matrices and vectors + ///////////////////////////////////////////////////////// + + // read in the CRS matrix + RCP crsMat = Tpetra::MatrixMarket::Reader::readSparseFile( + "../data/nsjac.mm", Tpetra::getDefaultComm()); + + RCP zeroCrsMat = rcp(new TP_Crs(*crsMat, Teuchos::Copy)); + zeroCrsMat->setAllToScalar(0.0); + + RCP Mat = crsMat; + RCP zeroMat = zeroCrsMat; + + // Allocate some right handside vectors + RCP x0_tp = rcp(new TP_Vec(Mat->getDomainMap())); + RCP x1_tp = rcp(new TP_Vec(Mat->getDomainMap())); + RCP b0_tp = rcp(new TP_Vec(Mat->getRangeMap())); + RCP b1_tp = rcp(new TP_Vec(Mat->getRangeMap())); + b0_tp->randomize(); + b1_tp->randomize(); + + RCP > domain = + Thyra::tpetraVectorSpace(Mat->getDomainMap()); + RCP > range = + Thyra::tpetraVectorSpace(Mat->getRangeMap()); + + // Build Teko compatible matrices and vectors + ///////////////////////////////////////////////////////// + + // convert them to teko compatible sub vectors + Teko::MultiVector x0_th = Thyra::tpetraVector(domain, x0_tp); + Teko::MultiVector x1_th = Thyra::tpetraVector(domain, x1_tp); + Teko::MultiVector b0_th = Thyra::tpetraVector(range, b0_tp); + Teko::MultiVector b1_th = Thyra::tpetraVector(range, b1_tp); + std::vector x_vec; + x_vec.push_back(x0_th); + x_vec.push_back(x1_th); + std::vector b_vec; + b_vec.push_back(b0_th); + b_vec.push_back(b1_th); + + Teko::MultiVector x = + Teko::buildBlockedMultiVector(x_vec); // these will be used in the Teko solve + Teko::MultiVector b = Teko::buildBlockedMultiVector(b_vec); + + // Build the Teko compatible linear system + Teko::LinearOp thMat = Thyra::tpetraLinearOp(range, domain, Mat); + Teko::LinearOp thZero = Thyra::tpetraLinearOp(range, domain, zeroMat); + Teko::LinearOp A = + Thyra::block2x2(thMat, thZero, thZero, thMat); // build an upper triangular 2x2 + + // Build the preconditioner + ///////////////////////////////////////////////////////// + + // build an InverseLibrary + RCP invLib = + Teko::InverseLibrary::buildFromParameterList(*buildLibPL(), linearSolverBuilder); + + // build the inverse factory needed by the example preconditioner + RCP inverse = invLib->getInverseFactory("Gauss-Seidel"); + + // build the preconditioner from the jacobian + Teko::LinearOp prec = Teko::buildInverse(*inverse, A); + + // Setup the Belos solver + ///////////////////////////////////////////////////////// + + Teuchos::ParameterList belosList; + belosList.set("Num Blocks", 200); // Maximum number of blocks in Krylov factorization + belosList.set("Block Size", 1); // Blocksize to be used by iterative solver + belosList.set("Maximum Iterations", 200); // Maximum number of iterations allowed + belosList.set("Maximum Restarts", 1); // Maximum number of restarts allowed + belosList.set("Convergence Tolerance", 1e-5); // Relative convergence tolerance requested + belosList.set( + "Verbosity", + 33); // Belos::Errors + Belos::Warnings + Belos::TimingDetails + Belos::StatusTestDetails ); + belosList.set("Output Frequency", 1); + belosList.set("Output Style", 1); + + RCP > problem = + rcp(new Belos::LinearProblem(A, x, b)); + problem->setLeftPrec(prec); + problem->setProblem(); // should check the return type!!! + + RCP > solver = + rcp(new Belos::BlockGmresSolMgr(problem, rcpFromRef(belosList))); + + // + // Perform solve + // + Belos::ReturnType ret = solver->solve(); + + if (ret != Belos::Converged) { + std::cout << std::endl << "ERROR: Belos did not converge!" << std::endl; + return -1; + } + + return 0; +} - if (ret!=Belos::Converged) { - std::cout << std::endl << "ERROR: Belos did not converge!" << std::endl; - return -1; - } +RCP buildLibPL() { + RCP pl = rcp(new Teuchos::ParameterList()); - return 0; -} + { + Teuchos::ParameterList& sub_jac = pl->sublist("Jacobi"); + sub_jac.set("Type", "Block Jacobi"); + sub_jac.set("Inverse Type", "Ifpack2"); -RCP buildLibPL() -{ - RCP pl = rcp(new Teuchos::ParameterList()); - - { - Teuchos::ParameterList & sub_jac = pl->sublist("Jacobi"); - sub_jac.set("Type","Block Jacobi"); - sub_jac.set("Inverse Type","Ifpack2"); - - Teuchos::ParameterList & sub_gs = pl->sublist("Gauss-Seidel"); - sub_gs.set("Type","Block Gauss-Seidel"); - sub_gs.set("Use Upper Triangle",true); - sub_gs.set("Inverse Type","Ifpack2"); - } - return pl; + Teuchos::ParameterList& sub_gs = pl->sublist("Gauss-Seidel"); + sub_gs.set("Type", "Block Gauss-Seidel"); + sub_gs.set("Use Upper Triangle", true); + sub_gs.set("Inverse Type", "Ifpack2"); + } + return pl; } - diff --git a/packages/teko/examples/BuildPreconditioner/example-driver.cpp b/packages/teko/examples/BuildPreconditioner/example-driver.cpp index b4b6ddc143fa..f0190f1416da 100644 --- a/packages/teko/examples/BuildPreconditioner/example-driver.cpp +++ b/packages/teko/examples/BuildPreconditioner/example-driver.cpp @@ -81,71 +81,74 @@ using Teuchos::RCP; using Teuchos::rcp; -int main(int argc,char * argv[]) -{ - // calls MPI_Init and MPI_Finalize - Teuchos::GlobalMPISession mpiSession(&argc,&argv); - - // build global communicator - Epetra_MpiComm Comm(MPI_COMM_WORLD); - - // Read in the matrix, store pointer as an RCP - Epetra_CrsMatrix * ptrA = 0; - EpetraExt::MatrixMarketFileToCrsMatrix("../data/nsjac.mm",Comm,ptrA); - RCP A = rcp(ptrA); - - // read in the RHS vector - Epetra_Vector * ptrb = 0; - EpetraExt::MatrixMarketFileToVector("../data/nsrhs_test.mm",A->OperatorRangeMap(),ptrb); - RCP b = rcp(ptrb); - - // allocate vectors - RCP x = rcp(new Epetra_Vector(A->OperatorDomainMap())); - x->PutScalar(0.0); - - // Break apart the strided linear system - ///////////////////////////////////////////////////////// - - // Block the linear system using a strided epetra operator - std::vector vec(2); vec[0] = 2; vec[1] = 1; /*@ \label{lned:define-strided} @*/ - Teuchos::RCP sA - = Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(vec,A)); - - // Build the preconditioner /*@ \label{lned:construct-prec} @*/ - ///////////////////////////////////////////////////////// - - // build an InverseLibrary - RCP invLib = Teko::InverseLibrary::buildFromStratimikos(); /*@ \label{lned:define-inv-params} @*/ - - // build the inverse factory needed by the example preconditioner - RCP inverse /*@ \label{lned:define-inv-fact} @*/ - = invLib->getInverseFactory("Amesos"); - - // build the preconditioner factory - RCP strategy = rcp(new Teko::NS::InvLSCStrategy(inverse,true)); /*@ \label{lned:const-prec-strategy} @*/ - RCP precFact /*@ \label{lned:const-prec-fact} @*/ - = rcp(new Teko::NS::LSCPreconditionerFactory(strategy)); - - // using the preconditioner factory construct an Epetra_Operator - Teko::Epetra::EpetraBlockPreconditioner prec(precFact); /*@ \label{lned:const-epetra-prec} @*/ - prec.buildPreconditioner(sA); // fill epetra preconditioner using the strided operator - - // Build and solve the linear system - ///////////////////////////////////////////////////////// - - // Setup the linear solve: notice A is used directly - Epetra_LinearProblem problem(&*A,&*x,&*b); /*@ \label{lned:aztec-solve} @*/ - - // build the solver - AztecOO solver(problem); - solver.SetAztecOption(AZ_solver,AZ_gmres); - solver.SetAztecOption(AZ_precond,AZ_none); - solver.SetAztecOption(AZ_kspace,1000); - solver.SetAztecOption(AZ_output,10); - solver.SetPrecOperator(&prec); - - // solve the linear system - solver.Iterate(1000,1e-5); - - return 0; +int main(int argc, char* argv[]) { + // calls MPI_Init and MPI_Finalize + Teuchos::GlobalMPISession mpiSession(&argc, &argv); + + // build global communicator + Epetra_MpiComm Comm(MPI_COMM_WORLD); + + // Read in the matrix, store pointer as an RCP + Epetra_CrsMatrix* ptrA = 0; + EpetraExt::MatrixMarketFileToCrsMatrix("../data/nsjac.mm", Comm, ptrA); + RCP A = rcp(ptrA); + + // read in the RHS vector + Epetra_Vector* ptrb = 0; + EpetraExt::MatrixMarketFileToVector("../data/nsrhs_test.mm", A->OperatorRangeMap(), ptrb); + RCP b = rcp(ptrb); + + // allocate vectors + RCP x = rcp(new Epetra_Vector(A->OperatorDomainMap())); + x->PutScalar(0.0); + + // Break apart the strided linear system + ///////////////////////////////////////////////////////// + + // Block the linear system using a strided epetra operator + std::vector vec(2); + vec[0] = 2; + vec[1] = 1; /*@ \label{lned:define-strided} @*/ + Teuchos::RCP sA = + Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(vec, A)); + + // Build the preconditioner /*@ \label{lned:construct-prec} @*/ + ///////////////////////////////////////////////////////// + + // build an InverseLibrary + RCP invLib = + Teko::InverseLibrary::buildFromStratimikos(); /*@ \label{lned:define-inv-params} @*/ + + // build the inverse factory needed by the example preconditioner + RCP inverse /*@ \label{lned:define-inv-fact} @*/ + = invLib->getInverseFactory("Amesos"); + + // build the preconditioner factory + RCP strategy = + rcp(new Teko::NS::InvLSCStrategy(inverse, true)); /*@ \label{lned:const-prec-strategy} @*/ + RCP precFact /*@ \label{lned:const-prec-fact} @*/ + = rcp(new Teko::NS::LSCPreconditionerFactory(strategy)); + + // using the preconditioner factory construct an Epetra_Operator + Teko::Epetra::EpetraBlockPreconditioner prec(precFact); /*@ \label{lned:const-epetra-prec} @*/ + prec.buildPreconditioner(sA); // fill epetra preconditioner using the strided operator + + // Build and solve the linear system + ///////////////////////////////////////////////////////// + + // Setup the linear solve: notice A is used directly + Epetra_LinearProblem problem(&*A, &*x, &*b); /*@ \label{lned:aztec-solve} @*/ + + // build the solver + AztecOO solver(problem); + solver.SetAztecOption(AZ_solver, AZ_gmres); + solver.SetAztecOption(AZ_precond, AZ_none); + solver.SetAztecOption(AZ_kspace, 1000); + solver.SetAztecOption(AZ_output, 10); + solver.SetPrecOperator(&prec); + + // solve the linear system + solver.Iterate(1000, 1e-5); + + return 0; } diff --git a/packages/teko/examples/BuildPreconditioner/step1/ExamplePreconditionerFactory.cpp b/packages/teko/examples/BuildPreconditioner/step1/ExamplePreconditionerFactory.cpp index 5f10514f90d2..5ed6f816e1ec 100644 --- a/packages/teko/examples/BuildPreconditioner/step1/ExamplePreconditionerFactory.cpp +++ b/packages/teko/examples/BuildPreconditioner/step1/ExamplePreconditionerFactory.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -54,65 +54,65 @@ using Teuchos::RCP; // Declaration of the preconditioner factory class ExamplePreconditionerFactory /*@ \label{lne1:begin-decl} @*/ - : public Teko::BlockPreconditionerFactory { -public: - // Constructor - ExamplePreconditionerFactory(const RCP & inverse, - double alpha); - - // Function inherited from Teko::BlockPreconditionerFactory - Teko::LinearOp buildPreconditionerOperator(Teko::BlockedLinearOp & blo, - Teko::BlockPreconditionerState & state) const; - -protected: - // class members - RCP inverse_; - double alpha_; - -};/*@ \label{lne1:end-decl} @*/ + : public Teko::BlockPreconditionerFactory { + public: + // Constructor + ExamplePreconditionerFactory(const RCP& inverse, double alpha); + + // Function inherited from Teko::BlockPreconditionerFactory + Teko::LinearOp buildPreconditionerOperator(Teko::BlockedLinearOp& blo, + Teko::BlockPreconditionerState& state) const; + + protected: + // class members + RCP inverse_; + double alpha_; + +}; /*@ \label{lne1:end-decl} @*/ // Constructor definition ExamplePreconditionerFactory /*@ \label{lne1:begin-constructor} @*/ - ::ExamplePreconditionerFactory(const RCP & inverse, - double alpha) - : inverse_(inverse), alpha_(alpha) -{ } /*@ \label{lne1:end-constructor} @*/ + ::ExamplePreconditionerFactory(const RCP& inverse, double alpha) + : inverse_(inverse), alpha_(alpha) {} /*@ \label{lne1:end-constructor} @*/ // Use the factory to build the preconditioner (this is where the work goes) Teko::LinearOp ExamplePreconditionerFactory /*@ \label{lne1:begin-bpo} @*/ - ::buildPreconditionerOperator(Teko::BlockedLinearOp & blockOp, - Teko::BlockPreconditionerState & state) const -{ - int rows = Teko::blockRowCount(blockOp); /*@ \label{lne1:begin-extraction} @*/ - int cols = Teko::blockColCount(blockOp); - - TEUCHOS_ASSERT(rows==2); // sanity checks - TEUCHOS_ASSERT(cols==2); - - // extract subblocks - const Teko::LinearOp A_00 = Teko::getBlock(0,0,blockOp); - const Teko::LinearOp A_01 = Teko::getBlock(0,1,blockOp); - const Teko::LinearOp A_10 = Teko::getBlock(1,0,blockOp); - const Teko::LinearOp A_11 = Teko::getBlock(1,1,blockOp); /*@ \label{lne1:end-extraction} @*/ - - // get inverse of diag(A11) - const Teko::LinearOp invH = Teko::getInvDiagonalOp(A_11); /*@ \label{lne1:invH} @*/ - - // build 0,0 block in the preconditioner - const Teko::LinearOp P = Teko::explicitAdd(A_00, Teko::scale(alpha_,A_01)); /*@ \label{lne1:P} @*/ - const Teko::LinearOp invP = Teko::buildInverse(*inverse_,P); // build inverse P /*@ \label{lne1:invP} @*/ - - // build lower triangular inverse matrix - Teko::BlockedLinearOp L = Teko::zeroBlockedOp(blockOp); /*@ \label{lne1:begin-trisolve} @*/ - Teko::setBlock(1,0,L,A_10); - Teko::endBlockFill(L); - - std::vector invDiag(2); // vector storing inverses /*@ \label{lne1:begin-invdiags} @*/ - invDiag[0] = invP; - invDiag[1] = invH; /*@ \label{lne1:end-invdiags} @*/ - - Teko::LinearOp invTildeA = Teko::createBlockLowerTriInverseOp(L,invDiag); /*@ \label{lne1:invLower} @*/ - - // return fully constructed preconditioner - return invTildeA; /*@ \label{lne1:end-trisolve} @*/ + ::buildPreconditionerOperator(Teko::BlockedLinearOp& blockOp, + Teko::BlockPreconditionerState& state) const { + int rows = Teko::blockRowCount(blockOp); /*@ \label{lne1:begin-extraction} @*/ + int cols = Teko::blockColCount(blockOp); + + TEUCHOS_ASSERT(rows == 2); // sanity checks + TEUCHOS_ASSERT(cols == 2); + + // extract subblocks + const Teko::LinearOp A_00 = Teko::getBlock(0, 0, blockOp); + const Teko::LinearOp A_01 = Teko::getBlock(0, 1, blockOp); + const Teko::LinearOp A_10 = Teko::getBlock(1, 0, blockOp); + const Teko::LinearOp A_11 = Teko::getBlock(1, 1, blockOp); /*@ \label{lne1:end-extraction} @*/ + + // get inverse of diag(A11) + const Teko::LinearOp invH = Teko::getInvDiagonalOp(A_11); /*@ \label{lne1:invH} @*/ + + // build 0,0 block in the preconditioner + const Teko::LinearOp P = + Teko::explicitAdd(A_00, Teko::scale(alpha_, A_01)); /*@ \label{lne1:P} @*/ + const Teko::LinearOp invP = + Teko::buildInverse(*inverse_, P); // build inverse P /*@ \label{lne1:invP} @*/ + + // build lower triangular inverse matrix + Teko::BlockedLinearOp L = Teko::zeroBlockedOp(blockOp); /*@ \label{lne1:begin-trisolve} @*/ + Teko::setBlock(1, 0, L, A_10); + Teko::endBlockFill(L); + + std::vector invDiag( + 2); // vector storing inverses /*@ \label{lne1:begin-invdiags} @*/ + invDiag[0] = invP; + invDiag[1] = invH; /*@ \label{lne1:end-invdiags} @*/ + + Teko::LinearOp invTildeA = + Teko::createBlockLowerTriInverseOp(L, invDiag); /*@ \label{lne1:invLower} @*/ + + // return fully constructed preconditioner + return invTildeA; /*@ \label{lne1:end-trisolve} @*/ } /*@ \label{lne1:end-bpo} @*/ diff --git a/packages/teko/examples/BuildPreconditioner/step1/example-test.cpp b/packages/teko/examples/BuildPreconditioner/step1/example-test.cpp index 23f9c635c24b..680816a05834 100644 --- a/packages/teko/examples/BuildPreconditioner/step1/example-test.cpp +++ b/packages/teko/examples/BuildPreconditioner/step1/example-test.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -76,81 +76,80 @@ using Teuchos::RCP; using Teuchos::rcp; // utility function to construct Epetra operators -RCP build2x2(double a,double b,double c,double d,Epetra_Comm & Comm) -{ - RCP map = rcp(new Epetra_Map(2,0,Comm)); - RCP matrix = rcp(new Epetra_CrsMatrix(Copy,*map,2)); +RCP build2x2(double a, double b, double c, double d, Epetra_Comm& Comm) { + RCP map = rcp(new Epetra_Map(2, 0, Comm)); + RCP matrix = rcp(new Epetra_CrsMatrix(Copy, *map, 2)); - int indicies[2] = { 0, 1 }; - double values[2]; + int indicies[2] = {0, 1}; + double values[2]; - // build first row - values[0] = a; - values[1] = b; - matrix->InsertGlobalValues(0,2,values,indicies); + // build first row + values[0] = a; + values[1] = b; + matrix->InsertGlobalValues(0, 2, values, indicies); - // build second row - values[0] = c; - values[1] = d; - matrix->InsertGlobalValues(1,2,values,indicies); + // build second row + values[0] = c; + values[1] = d; + matrix->InsertGlobalValues(1, 2, values, indicies); - // pack it up - matrix->FillComplete(); + // pack it up + matrix->FillComplete(); - return matrix; + return matrix; } -int main(int argc,char * argv[]) -{ - // calls MPI_Init and MPI_Finalize - Teuchos::GlobalMPISession mpiSession(&argc,&argv); +int main(int argc, char* argv[]) { + // calls MPI_Init and MPI_Finalize + Teuchos::GlobalMPISession mpiSession(&argc, &argv); - // build global communicator - Epetra_MpiComm Comm(MPI_COMM_WORLD); + // build global communicator + Epetra_MpiComm Comm(MPI_COMM_WORLD); - // build the sub blocks - Teko::LinearOp A_00 = Thyra::epetraLinearOp(build2x2(1,2,2,1,Comm)); - Teko::LinearOp A_01 = Thyra::epetraLinearOp(build2x2(0,-1,3,4,Comm)); - Teko::LinearOp A_10 = Thyra::epetraLinearOp(build2x2(1,6,-3,2,Comm)); - Teko::LinearOp A_11 = Thyra::epetraLinearOp(build2x2(2,1,1,2,Comm)); + // build the sub blocks + Teko::LinearOp A_00 = Thyra::epetraLinearOp(build2x2(1, 2, 2, 1, Comm)); + Teko::LinearOp A_01 = Thyra::epetraLinearOp(build2x2(0, -1, 3, 4, Comm)); + Teko::LinearOp A_10 = Thyra::epetraLinearOp(build2x2(1, 6, -3, 2, Comm)); + Teko::LinearOp A_11 = Thyra::epetraLinearOp(build2x2(2, 1, 1, 2, Comm)); - // build the Epetra operator - Teuchos::RCP A - = Teuchos::rcp(new Teko::Epetra::EpetraOperatorWrapper(Teko::block2x2(A_00,A_01,A_10,A_11))); + // build the Epetra operator + Teuchos::RCP A = + Teuchos::rcp(new Teko::Epetra::EpetraOperatorWrapper(Teko::block2x2(A_00, A_01, A_10, A_11))); - // build the Epetra vector - Epetra_Vector b(A->OperatorRangeMap()); - Epetra_Vector x(A->OperatorDomainMap()); - x.PutScalar(0.0); + // build the Epetra vector + Epetra_Vector b(A->OperatorRangeMap()); + Epetra_Vector x(A->OperatorDomainMap()); + x.PutScalar(0.0); - // build the RHS vector - b[0] = 1; - b[1] = 2; - b[2] = 3; - b[3] = 4; + // build the RHS vector + b[0] = 1; + b[1] = 2; + b[2] = 3; + b[3] = 4; - // Build the preconditioner /*@ \label{lnet:construct-prec} @*/ - ///////////////////////////////////////////////////////// + // Build the preconditioner /*@ \label{lnet:construct-prec} @*/ + ///////////////////////////////////////////////////////// - // build an InverseLibrary - RCP invLib = Teko::InverseLibrary::buildFromStratimikos(); /*@ \label{lnet:define-inv-params} @*/ - - // build the inverse factory needed by the example preconditioner - RCP inverse /*@ \label{lnet:define-inv-fact} @*/ - = invLib->getInverseFactory("Amesos"); + // build an InverseLibrary + RCP invLib = + Teko::InverseLibrary::buildFromStratimikos(); /*@ \label{lnet:define-inv-params} @*/ - // build the preconditioner factory - RCP precFact /*@ \label{lnet:const-prec-fact} @*/ - = rcp(new ExamplePreconditionerFactory(inverse,0.9)); + // build the inverse factory needed by the example preconditioner + RCP inverse /*@ \label{lnet:define-inv-fact} @*/ + = invLib->getInverseFactory("Amesos"); - // using the preconditioner factory construct an Epetra_Operator - Teko::Epetra::EpetraBlockPreconditioner prec(precFact); /*@ \label{lnet:const-epetra-prec} @*/ - prec.buildPreconditioner(A); // fill epetra preconditioner using the strided operator + // build the preconditioner factory + RCP precFact /*@ \label{lnet:const-prec-fact} @*/ + = rcp(new ExamplePreconditionerFactory(inverse, 0.9)); - // apply the preconditioner - prec.ApplyInverse(b,x); + // using the preconditioner factory construct an Epetra_Operator + Teko::Epetra::EpetraBlockPreconditioner prec(precFact); /*@ \label{lnet:const-epetra-prec} @*/ + prec.buildPreconditioner(A); // fill epetra preconditioner using the strided operator - x.Print(std::cout); + // apply the preconditioner + prec.ApplyInverse(b, x); - return 0; + x.Print(std::cout); + + return 0; } diff --git a/packages/teko/examples/BuildPreconditioner/step2/ExamplePreconditionerFactory.cpp b/packages/teko/examples/BuildPreconditioner/step2/ExamplePreconditionerFactory.cpp index 7985d232edeb..d43338c9268f 100644 --- a/packages/teko/examples/BuildPreconditioner/step2/ExamplePreconditionerFactory.cpp +++ b/packages/teko/examples/BuildPreconditioner/step2/ExamplePreconditionerFactory.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -54,107 +54,103 @@ using Teuchos::RCP; // Declaration of the example preconditioner state class ExamplePreconditionerState /*@ \label{lne2:begin-decl-state} @*/ - : public Teko::BlockPreconditionerState { -public: - // Default constructor - ExamplePreconditionerState() - : Teko::BlockPreconditionerState() {} - - // class members - Teko::LinearOp P_; // store P = A_00+\alpha A_01 - + : public Teko::BlockPreconditionerState { + public: + // Default constructor + ExamplePreconditionerState() : Teko::BlockPreconditionerState() {} + + // class members + Teko::LinearOp P_; // store P = A_00+\alpha A_01 + }; /*@ \label{lne2:end-decl-state} @*/ // Declaration of the preconditioner factory class ExamplePreconditionerFactory /*@ \label{lne2:begin-decl} @*/ - : public Teko::BlockPreconditionerFactory { -public: - // Constructor - ExamplePreconditionerFactory(const RCP & inverse, - double alpha); - - // Function inherited from Teko::BlockPreconditionerFactory - Teko::LinearOp buildPreconditionerOperator(Teko::BlockedLinearOp & blo, - Teko::BlockPreconditionerState & state) const; - - // Function that returns the correct type of state object - virtual RCP buildPreconditionerState() const; - -protected: - // class members - RCP inverse_; - double alpha_; - std::string invP_str_; - -};/*@ \label{lne2:end-decl} @*/ + : public Teko::BlockPreconditionerFactory { + public: + // Constructor + ExamplePreconditionerFactory(const RCP &inverse, double alpha); + + // Function inherited from Teko::BlockPreconditionerFactory + Teko::LinearOp buildPreconditionerOperator(Teko::BlockedLinearOp &blo, + Teko::BlockPreconditionerState &state) const; + + // Function that returns the correct type of state object + virtual RCP buildPreconditionerState() const; + + protected: + // class members + RCP inverse_; + double alpha_; + std::string invP_str_; + +}; /*@ \label{lne2:end-decl} @*/ // Constructor definition ExamplePreconditionerFactory /*@ \label{lne2:begin-constructor} @*/ - ::ExamplePreconditionerFactory(const RCP & inverse, - double alpha) - : inverse_(inverse), alpha_(alpha) -{ - // store the string name for retrieving the inverse - invP_str_ = "invP"; + ::ExamplePreconditionerFactory(const RCP &inverse, double alpha) + : inverse_(inverse), alpha_(alpha) { + // store the string name for retrieving the inverse + invP_str_ = "invP"; } /*@ \label{lne2:end-constructor} @*/ // Use the factory to build the preconditioner (this is where the work goes) Teko::LinearOp ExamplePreconditionerFactory /*@ \label{lne2:begin-bpo} @*/ - ::buildPreconditionerOperator(Teko::BlockedLinearOp & blockOp, - Teko::BlockPreconditionerState & state) const -{ - int rows = Teko::blockRowCount(blockOp); /*@ \label{lne2:begin-extraction} @*/ - int cols = Teko::blockColCount(blockOp); - - TEUCHOS_ASSERT(rows==2); // sanity checks - TEUCHOS_ASSERT(cols==2); - - // get the casted version of the state object - ExamplePreconditionerState & exampleState /*@ \label{lne2:state-cast} @*/ - = dynamic_cast(state); - - // extract subblocks - const Teko::LinearOp A_00 = Teko::getBlock(0,0,blockOp); - const Teko::LinearOp A_01 = Teko::getBlock(0,1,blockOp); - const Teko::LinearOp A_10 = Teko::getBlock(1,0,blockOp); - const Teko::LinearOp A_11 = Teko::getBlock(1,1,blockOp); /*@ \label{lne2:end-extraction} @*/ - - // get inverse of diag(A11) - const Teko::LinearOp invH = Teko::getInvDiagonalOp(A_11); /*@ \label{lne2:invH} @*/ - - // build or rebuild inverse P /*@ \label{lne2:invP} @*/ - Teko::InverseLinearOp invP = exampleState.getInverse(invP_str_); - if(invP==Teuchos::null) { - // build 0,0 block in the preconditioner - exampleState.P_ = Teko::explicitAdd(A_00, Teko::scale(alpha_,A_01)); /*@ \label{lne2:P} @*/ - - invP = Teko::buildInverse(*inverse_,exampleState.P_); // build inverse P - exampleState.addInverse(invP_str_,invP); // add inverse operator to state - } - - // build lower triangular inverse matrix - Teko::BlockedLinearOp L = Teko::zeroBlockedOp(blockOp); /*@ \label{lne2:begin-trisolve} @*/ - Teko::setBlock(1,0,L,A_10); - Teko::endBlockFill(L); - - std::vector invDiag(2); // vector storing inverses /*@ \label{lne2:begin-invdiags} @*/ - invDiag[0] = invP; - invDiag[1] = invH; /*@ \label{lne2:end-invdiags} @*/ - - Teko::LinearOp invTildeA = Teko::createBlockLowerTriInverseOp(L,invDiag); /*@ \label{lne2:invLower} @*/ - - // tell the state object it has been initialized for this operator - exampleState.setInitialized(true); - - // return fully constructed preconditioner - return invTildeA; /*@ \label{lne2:end-trisolve} @*/ + ::buildPreconditionerOperator(Teko::BlockedLinearOp &blockOp, + Teko::BlockPreconditionerState &state) const { + int rows = Teko::blockRowCount(blockOp); /*@ \label{lne2:begin-extraction} @*/ + int cols = Teko::blockColCount(blockOp); + + TEUCHOS_ASSERT(rows == 2); // sanity checks + TEUCHOS_ASSERT(cols == 2); + + // get the casted version of the state object + ExamplePreconditionerState &exampleState /*@ \label{lne2:state-cast} @*/ + = dynamic_cast(state); + + // extract subblocks + const Teko::LinearOp A_00 = Teko::getBlock(0, 0, blockOp); + const Teko::LinearOp A_01 = Teko::getBlock(0, 1, blockOp); + const Teko::LinearOp A_10 = Teko::getBlock(1, 0, blockOp); + const Teko::LinearOp A_11 = Teko::getBlock(1, 1, blockOp); /*@ \label{lne2:end-extraction} @*/ + + // get inverse of diag(A11) + const Teko::LinearOp invH = Teko::getInvDiagonalOp(A_11); /*@ \label{lne2:invH} @*/ + + // build or rebuild inverse P /*@ \label{lne2:invP} @*/ + Teko::InverseLinearOp invP = exampleState.getInverse(invP_str_); + if (invP == Teuchos::null) { + // build 0,0 block in the preconditioner + exampleState.P_ = Teko::explicitAdd(A_00, Teko::scale(alpha_, A_01)); /*@ \label{lne2:P} @*/ + + invP = Teko::buildInverse(*inverse_, exampleState.P_); // build inverse P + exampleState.addInverse(invP_str_, invP); // add inverse operator to state + } + + // build lower triangular inverse matrix + Teko::BlockedLinearOp L = Teko::zeroBlockedOp(blockOp); /*@ \label{lne2:begin-trisolve} @*/ + Teko::setBlock(1, 0, L, A_10); + Teko::endBlockFill(L); + + std::vector invDiag( + 2); // vector storing inverses /*@ \label{lne2:begin-invdiags} @*/ + invDiag[0] = invP; + invDiag[1] = invH; /*@ \label{lne2:end-invdiags} @*/ + + Teko::LinearOp invTildeA = + Teko::createBlockLowerTriInverseOp(L, invDiag); /*@ \label{lne2:invLower} @*/ + + // tell the state object it has been initialized for this operator + exampleState.setInitialized(true); + + // return fully constructed preconditioner + return invTildeA; /*@ \label{lne2:end-trisolve} @*/ } /*@ \label{lne2:end-bpo} @*/ // Function that returns the correct type of state object RCP ExamplePreconditionerFactory /*@ \label{lne2:begin-bps} @*/ - ::buildPreconditionerState() const -{ - // build the state object - return Teuchos::rcp(new ExamplePreconditionerState()); + ::buildPreconditionerState() const { + // build the state object + return Teuchos::rcp(new ExamplePreconditionerState()); } /*@ \label{lne2:end-bps} @*/ diff --git a/packages/teko/examples/ML-Teko-Coupling/ml_teko.cpp b/packages/teko/examples/ML-Teko-Coupling/ml_teko.cpp index dbc02c32d9f2..d417369b452a 100644 --- a/packages/teko/examples/ML-Teko-Coupling/ml_teko.cpp +++ b/packages/teko/examples/ML-Teko-Coupling/ml_teko.cpp @@ -46,17 +46,16 @@ using namespace Teuchos; EpetraExt::CrsMatrix_SolverMap RowMatrixColMapTrans_; -ML_Operator * readNS(ML_Comm * ml_comm,Epetra_Comm & Comm); +ML_Operator *readNS(ML_Comm *ml_comm, Epetra_Comm &Comm); -int main(int argc, char *argv[]) -{ - int *idummy1, *idummy2; +int main(int argc, char *argv[]) { + int *idummy1, *idummy2; double *ddummy; int MyPID = 0; - Epetra_RowMatrix* A[2]; + Epetra_RowMatrix *A[2]; #ifdef HAVE_MPI - MPI_Init(&argc,&argv); + MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); MyPID = Comm.MyPID(); #else @@ -65,43 +64,44 @@ int main(int argc, char *argv[]) ML_Comm *ml_comm; ML_Comm_Create(&ml_comm); - Teuchos::RCP tekoPL = Teuchos::getParametersFromXmlFile("ml_teko.xml"); - bool cForPressure = tekoPL->get("Use C For Pressure"); + Teuchos::RCP tekoPL = Teuchos::getParametersFromXmlFile("ml_teko.xml"); + bool cForPressure = tekoPL->get("Use C For Pressure"); /***********************************************/ /* Read in BlkMatrix, set A[0] to BlkMat(0,0), */ /* and then read BBt into A[1]. */ /***********************************************/ - ML_Operator* BlkMat = readNS(ml_comm, Comm); - ML_Operator *tmpF = ML_Operator_BlkMatExtract(BlkMat,0,0); - ML_Operator *tmpC = ML_Operator_BlkMatExtract(BlkMat,1,1); + ML_Operator *BlkMat = readNS(ml_comm, Comm); + ML_Operator *tmpF = ML_Operator_BlkMatExtract(BlkMat, 0, 0); + ML_Operator *tmpC = ML_Operator_BlkMatExtract(BlkMat, 1, 1); // CRS or ROW matrix? - if (Epetra_ML_GetCrsDataptrs(tmpF, &ddummy, &idummy1,&idummy2)) - A[0] = (Epetra_RowMatrix *) tmpF->data; - else A[0] = dynamic_cast((Epetra_CrsMatrix *) tmpF->data); + if (Epetra_ML_GetCrsDataptrs(tmpF, &ddummy, &idummy1, &idummy2)) + A[0] = (Epetra_RowMatrix *)tmpF->data; + else + A[0] = dynamic_cast((Epetra_CrsMatrix *)tmpF->data); Teko::ModifiableLinearOp BBt; - if(cForPressure) { - std::cout << "Using C for SA" << std::endl; - if (Epetra_ML_GetCrsDataptrs(tmpC, &ddummy, &idummy1,&idummy2)) - A[1] = (Epetra_RowMatrix *) tmpC->data; - else A[1] = dynamic_cast((Epetra_CrsMatrix *) tmpC->data); - } - else { - std::cout << "Using approximate Schur Complement for SA" << std::endl; - ML_Operator * tmpBt = ML_Operator_BlkMatExtract(BlkMat,0,1); - ML_Operator * tmpB = ML_Operator_BlkMatExtract(BlkMat,1,0); - - Teko::LinearOp Bt = Thyra::epetraLinearOp(Teuchos::rcp((Epetra_CrsMatrix*) tmpBt->data,false)); - Teko::LinearOp B = Thyra::epetraLinearOp(Teuchos::rcp((Epetra_CrsMatrix*) tmpB->data,false)); - Teko::LinearOp F = Thyra::epetraLinearOp(Teuchos::rcp((Epetra_CrsMatrix*) tmpF->data,false)); - Teko::LinearOp C = Thyra::epetraLinearOp(Teuchos::rcp((Epetra_CrsMatrix*) tmpC->data,false)); - Teko::LinearOp idF = Teko::getInvDiagonalOp(F,Teko::AbsRowSum); - - BBt = Teko::explicitAdd(C,Teko::scale(-1.0,Teko::explicitMultiply(B,idF,Bt)),BBt); - A[1] = &*Teuchos::rcp_dynamic_cast(Thyra::get_Epetra_Operator(*BBt)); + if (cForPressure) { + std::cout << "Using C for SA" << std::endl; + if (Epetra_ML_GetCrsDataptrs(tmpC, &ddummy, &idummy1, &idummy2)) + A[1] = (Epetra_RowMatrix *)tmpC->data; + else + A[1] = dynamic_cast((Epetra_CrsMatrix *)tmpC->data); + } else { + std::cout << "Using approximate Schur Complement for SA" << std::endl; + ML_Operator *tmpBt = ML_Operator_BlkMatExtract(BlkMat, 0, 1); + ML_Operator *tmpB = ML_Operator_BlkMatExtract(BlkMat, 1, 0); + + Teko::LinearOp Bt = Thyra::epetraLinearOp(Teuchos::rcp((Epetra_CrsMatrix *)tmpBt->data, false)); + Teko::LinearOp B = Thyra::epetraLinearOp(Teuchos::rcp((Epetra_CrsMatrix *)tmpB->data, false)); + Teko::LinearOp F = Thyra::epetraLinearOp(Teuchos::rcp((Epetra_CrsMatrix *)tmpF->data, false)); + Teko::LinearOp C = Thyra::epetraLinearOp(Teuchos::rcp((Epetra_CrsMatrix *)tmpC->data, false)); + Teko::LinearOp idF = Teko::getInvDiagonalOp(F, Teko::AbsRowSum); + + BBt = Teko::explicitAdd(C, Teko::scale(-1.0, Teko::explicitMultiply(B, idF, Bt)), BBt); + A[1] = &*Teuchos::rcp_dynamic_cast(Thyra::get_Epetra_Operator(*BBt)); } /**************************************************/ @@ -109,50 +109,52 @@ int main(int argc, char *argv[]) /* block 2x2 system. */ /**************************************************/ - Teuchos::RCP invLibPL = Teuchos::rcpFromRef(tekoPL->sublist("Inverse Library")); - int maxAztecIters = tekoPL->get("Max Aztec Iters",100); - double aztecTols = tekoPL->get("Aztec Tolerance",1e-8); + Teuchos::RCP invLibPL = + Teuchos::rcpFromRef(tekoPL->sublist("Inverse Library")); + int maxAztecIters = tekoPL->get("Max Aztec Iters", 100); + double aztecTols = tekoPL->get("Aztec Tolerance", 1e-8); - Teuchos::ParameterList MLMainList; + Teuchos::ParameterList MLMainList; Teuchos::ParameterList MLList[2]; - ML_Epetra::SetDefaults("SA",MLMainList); - ML_Epetra::SetDefaults("SA",MLList[0]); - ML_Epetra::SetDefaults("SA",MLList[1]); + ML_Epetra::SetDefaults("SA", MLMainList); + ML_Epetra::SetDefaults("SA", MLList[0]); + ML_Epetra::SetDefaults("SA", MLList[1]); MLMainList.setParameters(tekoPL->sublist("Main ML List")); MLList[0].setParameters(tekoPL->sublist("u ML List")); MLList[1].setParameters(tekoPL->sublist("p ML List")); - MLMainList.set("smoother: teko parameter list",invLibPL); + MLMainList.set("smoother: teko parameter list", invLibPL); /*********************************************************/ - /* Constructor for composite AMG. Does AMG on A[k] using */ + /* Constructor for composite AMG. Does AMG on A[k] using */ /* corresponding parameter lists. Then, builds a new AMG */ /* hierarchy with block diagonal grid transfers. The */ /* (k,k)th diagonal block is obtained by extracting the */ /* grid transfers associated with AMG on A[k]. */ /*********************************************************/ - ML_Epetra::MultiLevelPreconditioner* MLPre = + ML_Epetra::MultiLevelPreconditioner *MLPre = new ML_Epetra::MultiLevelPreconditioner(BlkMat, MLMainList, A, MLList, 2); // ML * mlptr = const_cast(MLPre->GetML()); // ML_Operator_Print(&(mlptr->Pmat[1]),"CompP1"); // ML_Operator_Print(&(mlptr->Rmat[0]),"CompR0"); /* convert BlkMat to an Epetra BlkMat */ - ML_Epetra::RowMatrix EBlkMat(BlkMat,&Comm); + ML_Epetra::RowMatrix EBlkMat(BlkMat, &Comm); /* read in rhs */ Teuchos::RCP RHS = Teuchos::rcp(new Epetra_Vector(EBlkMat.OperatorRangeMap())); RHS->PutScalar(7.0); Teuchos::RCP srcRHS = Teuchos::rcp(new Epetra_Vector(*RHS)); - EBlkMat.Apply(*srcRHS,*RHS); + EBlkMat.Apply(*srcRHS, *RHS); /* set initial guess */ - Epetra_Vector LHS(EBlkMat.OperatorDomainMap()); LHS.PutScalar(0.0); + Epetra_Vector LHS(EBlkMat.OperatorDomainMap()); + LHS.PutScalar(0.0); Epetra_LinearProblem Problem(&EBlkMat, &LHS, &*RHS); AztecOO solver(Problem); - + solver.SetPrecOperator(MLPre); solver.SetAztecOption(AZ_solver, AZ_gmres); solver.SetAztecOption(AZ_output, 1); @@ -166,7 +168,7 @@ int main(int argc, char *argv[]) MPI_Finalize(); #endif - return(EXIT_SUCCESS); + return (EXIT_SUCCESS); } /***********************************************************/ @@ -175,34 +177,31 @@ int main(int argc, char *argv[]) /* ML matrix. */ /***********************************************************/ -ML_Operator * convertToSubOp(ML_Comm * ml_comm,Epetra_Comm & Comm,const std::string & fileName) -{ - ML_Operator * tmp = 0; - const char * str = fileName.c_str(); - Epetra_RowMatrix *EMat = 0; - Epetra_CrsMatrix * crsMat = 0; +ML_Operator *convertToSubOp(ML_Comm *ml_comm, Epetra_Comm &Comm, const std::string &fileName) { + ML_Operator *tmp = 0; + const char *str = fileName.c_str(); + Epetra_RowMatrix *EMat = 0; + Epetra_CrsMatrix *crsMat = 0; - int finfo = EpetraExt::MatrixMarketFileToCrsMatrix(str, Comm, crsMat); + int finfo = EpetraExt::MatrixMarketFileToCrsMatrix(str, Comm, crsMat); - if (finfo==0) { - EMat = ML_Epetra::ModifyEpetraMatrixColMap(*crsMat,RowMatrixColMapTrans_, str); - tmp = ML_Operator_Create(ml_comm); - ML_Operator_WrapEpetraMatrix(EMat, tmp); - } - else - TEUCHOS_ASSERT(false); + if (finfo == 0) { + EMat = ML_Epetra::ModifyEpetraMatrixColMap(*crsMat, RowMatrixColMapTrans_, str); + tmp = ML_Operator_Create(ml_comm); + ML_Operator_WrapEpetraMatrix(EMat, tmp); + } else + TEUCHOS_ASSERT(false); - return tmp; + return tmp; } -ML_Operator * readNS(ML_Comm * ml_comm,Epetra_Comm & Comm) -{ - ML_Operator* BlkMat = ML_Operator_Create(ml_comm); +ML_Operator *readNS(ML_Comm *ml_comm, Epetra_Comm &Comm) { + ML_Operator *BlkMat = ML_Operator_Create(ml_comm); ML_Operator_BlkMatInit(BlkMat, ml_comm, 2, 2, ML_DESTROY_EVERYTHING); - ML_Operator_BlkMatInsert(BlkMat, convertToSubOp(ml_comm,Comm,"data/F.mm"), 0, 0); - ML_Operator_BlkMatInsert(BlkMat, convertToSubOp(ml_comm,Comm,"data/C.mm"), 1, 1); - ML_Operator_BlkMatInsert(BlkMat, convertToSubOp(ml_comm,Comm,"data/Bt.mm"), 0, 1); - ML_Operator_BlkMatInsert(BlkMat, convertToSubOp(ml_comm,Comm,"data/B.mm"), 1, 0); + ML_Operator_BlkMatInsert(BlkMat, convertToSubOp(ml_comm, Comm, "data/F.mm"), 0, 0); + ML_Operator_BlkMatInsert(BlkMat, convertToSubOp(ml_comm, Comm, "data/C.mm"), 1, 1); + ML_Operator_BlkMatInsert(BlkMat, convertToSubOp(ml_comm, Comm, "data/Bt.mm"), 0, 1); + ML_Operator_BlkMatInsert(BlkMat, convertToSubOp(ml_comm, Comm, "data/B.mm"), 1, 0); ML_Operator_BlkMatFinalize(BlkMat); return BlkMat; diff --git a/packages/teko/examples/ML-Teko-Coupling/ml_teko_single.cpp b/packages/teko/examples/ML-Teko-Coupling/ml_teko_single.cpp index 97ce97de33eb..e99ec428191a 100644 --- a/packages/teko/examples/ML-Teko-Coupling/ml_teko_single.cpp +++ b/packages/teko/examples/ML-Teko-Coupling/ml_teko_single.cpp @@ -39,13 +39,12 @@ using namespace Teuchos; -int main(int argc, char *argv[]) -{ +int main(int argc, char* argv[]) { int MyPID = 0; - Epetra_CrsMatrix* A; + Epetra_CrsMatrix* A; #ifdef HAVE_MPI - MPI_Init(&argc,&argv); + MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); MyPID = Comm.MyPID(); #else @@ -57,56 +56,57 @@ int main(int argc, char *argv[]) ParameterList MLMainList; - ML_Epetra::SetDefaults("SA",MLMainList); + ML_Epetra::SetDefaults("SA", MLMainList); - #define ML_OUT_LEVEL 0 +#define ML_OUT_LEVEL 0 - Teuchos::RCP tekoPL = Teuchos::getParametersFromXmlFile("ml_teko.xml"); - Teuchos::RCP invLibPL = Teuchos::rcpFromRef(tekoPL->sublist("Inverse Library")); + Teuchos::RCP tekoPL = Teuchos::getParametersFromXmlFile("ml_teko.xml"); + Teuchos::RCP invLibPL = + Teuchos::rcpFromRef(tekoPL->sublist("Inverse Library")); // big outer parameter list - MLMainList.set("ML output", 8); - MLMainList.set("ML print initial list", -2); - MLMainList.set("ML print final list", -2); + MLMainList.set("ML output", 8); + MLMainList.set("ML print initial list", -2); + MLMainList.set("ML print final list", -2); MLMainList.set("ML label", "1x1 system"); - MLMainList.set("max levels",3); - MLMainList.set("PDE equations",1); - MLMainList.set("smoother: pre or post","both"); - MLMainList.set("smoother: sweeps",2); - if(argc==2) { - MLMainList.set("smoother: type","Gauss-Seidel"); - MLMainList.set("coarse: type","Amesos-KLU"); - std::cout << " *** ML GS SMOOTHER *** " << std::endl; - } - else { - MLMainList.set("smoother: type","teko"); - MLMainList.set("coarse: type","teko"); - MLMainList.set("coarse: teko inverse",std::string("Amesos")); - MLMainList.set("smoother: teko parameter list",invLibPL); - MLMainList.set("smoother: teko inverse",std::string("GS-Single")); - MLMainList.set("smoother: teko is blocked",0); - std::cout << " *** Teko GS SMOOTHER *** " << std::endl; + MLMainList.set("max levels", 3); + MLMainList.set("PDE equations", 1); + MLMainList.set("smoother: pre or post", "both"); + MLMainList.set("smoother: sweeps", 2); + if (argc == 2) { + MLMainList.set("smoother: type", "Gauss-Seidel"); + MLMainList.set("coarse: type", "Amesos-KLU"); + std::cout << " *** ML GS SMOOTHER *** " << std::endl; + } else { + MLMainList.set("smoother: type", "teko"); + MLMainList.set("coarse: type", "teko"); + MLMainList.set("coarse: teko inverse", std::string("Amesos")); + MLMainList.set("smoother: teko parameter list", invLibPL); + MLMainList.set("smoother: teko inverse", std::string("GS-Single")); + MLMainList.set("smoother: teko is blocked", 0); + std::cout << " *** Teko GS SMOOTHER *** " << std::endl; } /*********************************************************/ - /* Constructor for composite AMG. Does AMG on A[k] using */ + /* Constructor for composite AMG. Does AMG on A[k] using */ /* corresponding parameter lists. Then, builds a new AMG */ /* hierarchy with block diagonal grid transfers. The */ /* (k,k)th diagonal block is obtained by extracting the */ /* grid transfers associated with AMG on A[k]. */ /*********************************************************/ - ML_Epetra::MultiLevelPreconditioner* MLPre = - new ML_Epetra::MultiLevelPreconditioner(*A, MLMainList,true); + ML_Epetra::MultiLevelPreconditioner* MLPre = + new ML_Epetra::MultiLevelPreconditioner(*A, MLMainList, true); /* read in rhs */ Epetra_Vector* RHS = new Epetra_Vector(A->OperatorRangeMap()); RHS->PutScalar(7.0); /* set initial guess */ - Epetra_Vector LHS(A->OperatorDomainMap()); LHS.PutScalar(0.0); + Epetra_Vector LHS(A->OperatorDomainMap()); + LHS.PutScalar(0.0); Epetra_LinearProblem Problem(A, &LHS, RHS); AztecOO solver(Problem); - + solver.SetPrecOperator(MLPre); solver.SetAztecOption(AZ_solver, AZ_gmres); solver.SetAztecOption(AZ_conv, AZ_noscaled); @@ -119,5 +119,5 @@ int main(int argc, char *argv[]) MPI_Finalize(); #endif - return(EXIT_SUCCESS); + return (EXIT_SUCCESS); } diff --git a/packages/teko/examples/ML-Teko-Coupling/teko_ml_prec.cpp b/packages/teko/examples/ML-Teko-Coupling/teko_ml_prec.cpp index 73f73f8c4d4e..0d1262cfae59 100644 --- a/packages/teko/examples/ML-Teko-Coupling/teko_ml_prec.cpp +++ b/packages/teko/examples/ML-Teko-Coupling/teko_ml_prec.cpp @@ -1,4 +1,4 @@ -// Teuchos includes +// Teuchos includes #include "Teuchos_ConfigDefs.hpp" #include "Teuchos_GlobalMPISession.hpp" #include "Teuchos_RCP.hpp" @@ -32,99 +32,97 @@ using Teuchos::RCP; using Teuchos::rcp; -Teko::LinearOp readNS(Epetra_Comm & Comm); - -int main(int argc,char * argv[]) -{ - // calls MPI_Init and MPI_Finalize - Teuchos::GlobalMPISession mpiSession(&argc,&argv); - - // build global communicator - Epetra_MpiComm Comm(MPI_COMM_WORLD); - - Teko::LinearOp A = readNS(Comm); - - // Build the preconditioner - ///////////////////////////////////////////////////////// - - Teuchos::RCP tekoPL = Teuchos::getParametersFromXmlFile("ml_teko.xml"); - Teuchos::RCP invLibPL = Teuchos::rcpFromRef(tekoPL->sublist("Inverse Library")); - - // build an InverseLibrary - RCP invLib = Teko::InverseLibrary::buildFromParameterList(*invLibPL); - RCP inverse = invLib->getInverseFactory("ML-Teko"); - Teko::LinearOp invA = Teko::buildInverse(*inverse,A); - std::cout << "INV(A) = " << Teuchos::describe(*invA) << std::endl; - - // build epetra operators - ///////////////////////////////////// - - Teuchos::RCP eA = Teuchos::rcp(new Teko::Epetra::EpetraOperatorWrapper(A)); - Teuchos::RCP eInvA = Teuchos::rcp(new Teko::Epetra::EpetraInverseOpWrapper(invA)); - - RCP x = rcp(new Epetra_Vector(eA->OperatorDomainMap())); - RCP b = rcp(new Epetra_Vector(eA->OperatorRangeMap())); - RCP r = rcp(new Epetra_Vector(eA->OperatorRangeMap())); - - // form a resonable right hand side - x->Random(); - b->PutScalar(0.0); - eA->Apply(*x,*b); - x->PutScalar(0.0); - r->PutScalar(0.0); - - // Build and solve the linear system - ///////////////////////////////////////////////////////// - - // Setup the linear solve: notice A is used directly - Epetra_LinearProblem problem(&*eA,&*x,&*b); /*@ \label{lned:aztec-solve} @*/ - - // build the solver - AztecOO solver(problem); - solver.SetAztecOption(AZ_solver,AZ_gmres); - solver.SetAztecOption(AZ_precond,AZ_none); - solver.SetAztecOption(AZ_kspace,1000); - solver.SetAztecOption(AZ_output,1); - solver.SetPrecOperator(&*eInvA); - - // solve the linear system - solver.Iterate(1000,1e-5); - - eA->Apply(*x,*r); - r->Update(1.0,*b,-1.0); - double norm; - r->Norm2(&norm); - std::cout << "norm = " << norm << std::endl; - - return 0; +Teko::LinearOp readNS(Epetra_Comm& Comm); + +int main(int argc, char* argv[]) { + // calls MPI_Init and MPI_Finalize + Teuchos::GlobalMPISession mpiSession(&argc, &argv); + + // build global communicator + Epetra_MpiComm Comm(MPI_COMM_WORLD); + + Teko::LinearOp A = readNS(Comm); + + // Build the preconditioner + ///////////////////////////////////////////////////////// + + Teuchos::RCP tekoPL = Teuchos::getParametersFromXmlFile("ml_teko.xml"); + Teuchos::RCP invLibPL = + Teuchos::rcpFromRef(tekoPL->sublist("Inverse Library")); + + // build an InverseLibrary + RCP invLib = Teko::InverseLibrary::buildFromParameterList(*invLibPL); + RCP inverse = invLib->getInverseFactory("ML-Teko"); + Teko::LinearOp invA = Teko::buildInverse(*inverse, A); + std::cout << "INV(A) = " << Teuchos::describe(*invA) << std::endl; + + // build epetra operators + ///////////////////////////////////// + + Teuchos::RCP eA = Teuchos::rcp(new Teko::Epetra::EpetraOperatorWrapper(A)); + Teuchos::RCP eInvA = + Teuchos::rcp(new Teko::Epetra::EpetraInverseOpWrapper(invA)); + + RCP x = rcp(new Epetra_Vector(eA->OperatorDomainMap())); + RCP b = rcp(new Epetra_Vector(eA->OperatorRangeMap())); + RCP r = rcp(new Epetra_Vector(eA->OperatorRangeMap())); + + // form a resonable right hand side + x->Random(); + b->PutScalar(0.0); + eA->Apply(*x, *b); + x->PutScalar(0.0); + r->PutScalar(0.0); + + // Build and solve the linear system + ///////////////////////////////////////////////////////// + + // Setup the linear solve: notice A is used directly + Epetra_LinearProblem problem(&*eA, &*x, &*b); /*@ \label{lned:aztec-solve} @*/ + + // build the solver + AztecOO solver(problem); + solver.SetAztecOption(AZ_solver, AZ_gmres); + solver.SetAztecOption(AZ_precond, AZ_none); + solver.SetAztecOption(AZ_kspace, 1000); + solver.SetAztecOption(AZ_output, 1); + solver.SetPrecOperator(&*eInvA); + + // solve the linear system + solver.Iterate(1000, 1e-5); + + eA->Apply(*x, *r); + r->Update(1.0, *b, -1.0); + double norm; + r->Norm2(&norm); + std::cout << "norm = " << norm << std::endl; + + return 0; } -Teko::ModifiableLinearOp readOp(Epetra_Comm & Comm,const std::string & fileName) -{ - Epetra_CrsMatrix * crsMat = 0; - Teko::ModifiableLinearOp output; +Teko::ModifiableLinearOp readOp(Epetra_Comm& Comm, const std::string& fileName) { + Epetra_CrsMatrix* crsMat = 0; + Teko::ModifiableLinearOp output; - int finfo = EpetraExt::MatrixMarketFileToCrsMatrix(fileName.c_str(), Comm, crsMat); + int finfo = EpetraExt::MatrixMarketFileToCrsMatrix(fileName.c_str(), Comm, crsMat); - if(finfo==0) { - output = Thyra::nonconstEpetraLinearOp(Teuchos::rcp(crsMat)); - } - else { - delete crsMat; - TEUCHOS_ASSERT(false); - } + if (finfo == 0) { + output = Thyra::nonconstEpetraLinearOp(Teuchos::rcp(crsMat)); + } else { + delete crsMat; + TEUCHOS_ASSERT(false); + } - return output; + return output; } -Teko::LinearOp readNS(Epetra_Comm & Comm) -{ +Teko::LinearOp readNS(Epetra_Comm& Comm) { Teko::BlockedLinearOp blo = Teko::createBlockedOp(); - Teko::beginBlockFill(blo,2,2); - blo->setNonconstBlock(0,0,readOp(Comm,"data/F.mm")); - blo->setNonconstBlock(1,1,readOp(Comm,"data/C.mm")); - blo->setNonconstBlock(0,1,readOp(Comm,"data/Bt.mm")); - blo->setNonconstBlock(1,0,readOp(Comm,"data/B.mm")); + Teko::beginBlockFill(blo, 2, 2); + blo->setNonconstBlock(0, 0, readOp(Comm, "data/F.mm")); + blo->setNonconstBlock(1, 1, readOp(Comm, "data/C.mm")); + blo->setNonconstBlock(0, 1, readOp(Comm, "data/Bt.mm")); + blo->setNonconstBlock(1, 0, readOp(Comm, "data/B.mm")); Teko::endBlockFill(blo); return blo; diff --git a/packages/teko/examples/StridedSolve/strided_solve.cpp b/packages/teko/examples/StridedSolve/strided_solve.cpp index 0ec10c7cc789..2476d74cc610 100644 --- a/packages/teko/examples/StridedSolve/strided_solve.cpp +++ b/packages/teko/examples/StridedSolve/strided_solve.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -66,10 +66,10 @@ // include basic Epetra information #ifdef HAVE_MPI - #include "Epetra_MpiComm.h" - #include "mpi.h" +#include "Epetra_MpiComm.h" +#include "mpi.h" #else - #include "Epetra_SerialComm.h" +#include "Epetra_SerialComm.h" #endif #include "Epetra_Map.h" #include "Epetra_CrsMatrix.h" @@ -77,7 +77,7 @@ #include "Epetra_LinearProblem.h" #include "Epetra_Export.h" -// EpetraExt +// EpetraExt #include "EpetraExt_CrsMatrixIn.h" #include "EpetraExt_VectorIn.h" #include "EpetraExt_VectorOut.h" @@ -108,94 +108,94 @@ #include #include +using Teuchos::null; +using Teuchos::ParameterList; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcp_dynamic_cast; -using Teuchos::null; -using Teuchos::ParameterList; -int main(int argc,char * argv[]) -{ - // calls MPI_Init and MPI_Finalize - Teuchos::GlobalMPISession mpiSession(&argc,&argv); +int main(int argc, char* argv[]) { + // calls MPI_Init and MPI_Finalize + Teuchos::GlobalMPISession mpiSession(&argc, &argv); - // Handles some I/O to the output screen - RCP out = Teuchos::VerboseObjectBase::getDefaultOStream(); + // Handles some I/O to the output screen + RCP out = Teuchos::VerboseObjectBase::getDefaultOStream(); - // build global (or serial communicator - #ifdef HAVE_MPI - Epetra_MpiComm Comm(MPI_COMM_WORLD); - #else - Epetra_SerialComm Comm; - #endif +// build global (or serial communicator +#ifdef HAVE_MPI + Epetra_MpiComm Comm(MPI_COMM_WORLD); +#else + Epetra_SerialComm Comm; +#endif + std::string solveName = "Amesos"; + if (argc > 1) solveName = argv[1]; - std::string solveName = "Amesos"; - if(argc>1) - solveName = argv[1]; + std::cout << "Using \"" << solveName << "\" for approximate solve" << std::endl; - std::cout << "Using \"" << solveName << "\" for approximate solve" << std::endl; - - // get process information - int numProc = Comm.NumProc(); - int myPID = Comm.MyPID(); + // get process information + int numProc = Comm.NumProc(); + int myPID = Comm.MyPID(); - std::cout << "MPI_PID = " << myPID << ", UNIX_PID = " << getpid() << std::endl; + std::cout << "MPI_PID = " << myPID << ", UNIX_PID = " << getpid() << std::endl; - // output garbage - *out << "Approaching Barrier: proc = " << numProc << ", pid = " << myPID << std::endl; - Comm.Barrier(); + // output garbage + *out << "Approaching Barrier: proc = " << numProc << ", pid = " << myPID << std::endl; + Comm.Barrier(); - RCP paramList = Teuchos::getParametersFromXmlFile("solverparams.xml"); + RCP paramList = Teuchos::getParametersFromXmlFile("solverparams.xml"); - Epetra_Map map(15444,0,Comm); - Epetra_CrsMatrix * ptrA = 0; - Epetra_Vector * ptrf = 0; - Epetra_Vector * ptrx = 0; + Epetra_Map map(15444, 0, Comm); + Epetra_CrsMatrix* ptrA = 0; + Epetra_Vector* ptrf = 0; + Epetra_Vector* ptrx = 0; - std::cout << "Reading matrix market file" << std::endl; - EpetraExt::MatrixMarketFileToCrsMatrix("../data/nsjac.mm",map,map,map,ptrA); - EpetraExt::MatrixMarketFileToVector("../data/nsrhs_test.mm",map,ptrf); - EpetraExt::MatrixMarketFileToVector("../data/nslhs_test.mm",map,ptrx); + std::cout << "Reading matrix market file" << std::endl; + EpetraExt::MatrixMarketFileToCrsMatrix("../data/nsjac.mm", map, map, map, ptrA); + EpetraExt::MatrixMarketFileToVector("../data/nsrhs_test.mm", map, ptrf); + EpetraExt::MatrixMarketFileToVector("../data/nslhs_test.mm", map, ptrx); - RCP A = rcp(ptrA); - RCP b = rcp(ptrf); - RCP x = rcp(ptrx); + RCP A = rcp(ptrA); + RCP b = rcp(ptrf); + RCP x = rcp(ptrx); - std::cout << "Building strided operator" << std::endl; - std::vector vec(2); vec[0] = 2; vec[1] = 1; - Teuchos::RCP sA - = Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(vec,A)); + std::cout << "Building strided operator" << std::endl; + std::vector vec(2); + vec[0] = 2; + vec[1] = 1; + Teuchos::RCP sA = + Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(vec, A)); - double alpha = 0.9; - RCP inverse = Teko::invFactoryFromParamList(*paramList,solveName); + double alpha = 0.9; + RCP inverse = Teko::invFactoryFromParamList(*paramList, solveName); #if 1 - RCP precFact - = rcp(new Teko::NS::SIMPLEPreconditionerFactory(inverse,alpha)); + RCP precFact = + rcp(new Teko::NS::SIMPLEPreconditionerFactory(inverse, alpha)); #else - RCP precStrat = rcp(new Teko::NS::InvLSCStrategy(inverse)); - RCP precFact = rcp(new Teko::NS::LSCPreconditionerFactory(precStrat)); + RCP precStrat = rcp(new Teko::NS::InvLSCStrategy(inverse)); + RCP precFact = + rcp(new Teko::NS::LSCPreconditionerFactory(precStrat)); #endif - std::cout << "Preconditioner factory built" << std::endl; - Teko::Epetra::EpetraBlockPreconditioner prec(precFact); - prec.buildPreconditioner(sA); + std::cout << "Preconditioner factory built" << std::endl; + Teko::Epetra::EpetraBlockPreconditioner prec(precFact); + prec.buildPreconditioner(sA); - std::cout << "Preconditioner built" << std::endl; + std::cout << "Preconditioner built" << std::endl; - Epetra_LinearProblem problem(&*A,&*x,&*b); + Epetra_LinearProblem problem(&*A, &*x, &*b); - // build solver - std::cout << "Setting solver parameters" << std::endl; - AztecOO solver(problem); - solver.SetAztecOption(AZ_solver,AZ_gmres); - solver.SetAztecOption(AZ_precond,AZ_none); - solver.SetAztecOption(AZ_kspace,50); - solver.SetAztecOption(AZ_output,10); - solver.SetPrecOperator(&prec); + // build solver + std::cout << "Setting solver parameters" << std::endl; + AztecOO solver(problem); + solver.SetAztecOption(AZ_solver, AZ_gmres); + solver.SetAztecOption(AZ_precond, AZ_none); + solver.SetAztecOption(AZ_kspace, 50); + solver.SetAztecOption(AZ_output, 10); + solver.SetPrecOperator(&prec); - std::cout << "Solving" << std::endl; - solver.Iterate(1000,1e-5); + std::cout << "Solving" << std::endl; + solver.Iterate(1000, 1e-5); - return 0; + return 0; } diff --git a/packages/teko/src/Epetra/Teko_BasicMappingStrategy.cpp b/packages/teko/src/Epetra/Teko_BasicMappingStrategy.cpp index 0a7d6735a0ef..ef2fc7e0240c 100644 --- a/packages/teko/src/Epetra/Teko_BasicMappingStrategy.cpp +++ b/packages/teko/src/Epetra/Teko_BasicMappingStrategy.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -62,16 +62,16 @@ namespace Epetra { // in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current // implimentation only supports a fixed number of variables // -// arguments: -// vars - Number of different variables +// arguments: +// vars - Number of different variables // map - original Epetra_Map to be broken up // comm - Epetra_Comm object related to the map // -BasicMappingStrategy::BasicMappingStrategy(const Teuchos::RCP & rMap, - const Teuchos::RCP & dMap, const Epetra_Comm & /* comm */) -{ - rangeMap_ = rMap; - domainMap_ = dMap; +BasicMappingStrategy::BasicMappingStrategy(const Teuchos::RCP& rMap, + const Teuchos::RCP& dMap, + const Epetra_Comm& /* comm */) { + rangeMap_ = rMap; + domainMap_ = dMap; } // Virtual function defined in MappingStrategy. This copies @@ -82,14 +82,15 @@ BasicMappingStrategy::BasicMappingStrategy(const Teuchos::RCP // X - source Epetra_MultiVector // thyra_X - destination Thyra::MultiVectorBase // -void BasicMappingStrategy::copyEpetraIntoThyra(const Epetra_MultiVector& X, - const Teuchos::Ptr > & thyra_X) const -{ - // perform a simple copy - RCP > vec - = rcp_dynamic_cast >(Teuchos::rcpFromRef(*thyra_X)); - Teuchos::RCP ptrX = Teuchos::rcp_const_cast(Teuchos::rcpFromRef(X)); - fillDefaultSpmdMultiVector(vec,ptrX); +void BasicMappingStrategy::copyEpetraIntoThyra( + const Epetra_MultiVector& X, + const Teuchos::Ptr >& thyra_X) const { + // perform a simple copy + RCP > vec = + rcp_dynamic_cast >(Teuchos::rcpFromRef(*thyra_X)); + Teuchos::RCP ptrX = + Teuchos::rcp_const_cast(Teuchos::rcpFromRef(X)); + fillDefaultSpmdMultiVector(vec, ptrX); } // Virtual function defined in MappingStrategy. This copies @@ -100,13 +101,12 @@ void BasicMappingStrategy::copyEpetraIntoThyra(const Epetra_MultiVector& X, // thyra_Y - source Thyra::MultiVectorBase // Y - destination Epetra_MultiVector // -void BasicMappingStrategy::copyThyraIntoEpetra(const RCP > & thyra_Y, - Epetra_MultiVector& Y) const -{ - RCP eSrc = Thyra::get_Epetra_MultiVector(*rangeMap(),thyra_Y); +void BasicMappingStrategy::copyThyraIntoEpetra( + const RCP >& thyra_Y, Epetra_MultiVector& Y) const { + RCP eSrc = Thyra::get_Epetra_MultiVector(*rangeMap(), thyra_Y); - Y = *eSrc; + Y = *eSrc; } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_BasicMappingStrategy.hpp b/packages/teko/src/Epetra/Teko_BasicMappingStrategy.hpp index 712fcfbfc31d..990a89965bda 100644 --- a/packages/teko/src/Epetra/Teko_BasicMappingStrategy.hpp +++ b/packages/teko/src/Epetra/Teko_BasicMappingStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -68,90 +68,89 @@ namespace Teko { namespace Epetra { class BasicMappingStrategy : public MappingStrategy { -public: - //! \name Constructors - //@{ - - /** Creates a strided mapping strategy. This class is useful - * for breaking up nodally ordered matrices (i.e. the unknowns - * in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current - * implimentation only supports a fixed number of variables - * - * \param[in] rMap Range map - * \param[in] dMap Domain map - * \param[in] comm Epetra_Comm object related to the map - */ - BasicMappingStrategy(const Teuchos::RCP & rMap, - const Teuchos::RCP & dMap, const Epetra_Comm & comm); - //@} - - //!\name Member functions inherited from Teko::Epetra::MappingStrategy - //@{ - - /** Virtual function defined in MappingStrategy. This copies - * an Epetra_MultiVector into a Thyra::MultiVectorBase with - * blocking handled by the strides defined in the constructor. - * - * \param[in] epetra_X source Epetra_MultiVector - * \param[in,out] thyra_X destination Thyra::MultiVectorBase - * \param[in] eow Operator that defines the transition - */ - virtual void copyEpetraIntoThyra(const Epetra_MultiVector& epetra_X, - const Teuchos::Ptr > & thyra_X) const; - // const Teko::Epetra::EpetraOperatorWrapper & eow) const; - - /** Virtual function defined in MappingStrategy. This copies - * an Epetra_MultiVector into a Thyra::MultiVectorBase with - * blocking handled by the strides defined in the constructor. - * - * \param[in] thyra_Y source Thyra::MultiVectorBase - * \param[in,out] epetra_Y destination Epetra_MultiVector - * \param[in] eow Operator that defines the transition - */ - virtual void copyThyraIntoEpetra(const Teuchos::RCP > & thyra_Y, - Epetra_MultiVector& epetra_Y) const; - // const Teko::Epetra::EpetraOperatorWrapper & eow) const; - - /** Returns the domain and range maps used by this class. - * This faciliates building an Epetra_Operator around this - * class with its core functionality being a Thyra::LinearOpBase - * operator - * - * \returns Range map corresponding to this class - */ - virtual const Teuchos::RCP domainMap() const - { return domainMap_; } - - /** Returns the domain and range maps used by this class. - * This faciliates building an Epetra_Operator around this - * class with its core functionality being a Thyra::LinearOpBase - * operator - * - * \returns Range map corresponding to this class - */ - virtual const Teuchos::RCP rangeMap() const - { return rangeMap_; } - - /** A function for my sanity - * - * \returns String with description of this class - */ - virtual std::string toString() const - { return std::string("BasicMappingStrategy"); } - - //@} - -protected: - // member variables - - //! \name storage for sanity - //@{ - Teuchos::RCP domainMap_; - Teuchos::RCP rangeMap_; - //@} + public: + //! \name Constructors + //@{ + + /** Creates a strided mapping strategy. This class is useful + * for breaking up nodally ordered matrices (i.e. the unknowns + * in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current + * implimentation only supports a fixed number of variables + * + * \param[in] rMap Range map + * \param[in] dMap Domain map + * \param[in] comm Epetra_Comm object related to the map + */ + BasicMappingStrategy(const Teuchos::RCP& rMap, + const Teuchos::RCP& dMap, const Epetra_Comm& comm); + //@} + + //!\name Member functions inherited from Teko::Epetra::MappingStrategy + //@{ + + /** Virtual function defined in MappingStrategy. This copies + * an Epetra_MultiVector into a Thyra::MultiVectorBase with + * blocking handled by the strides defined in the constructor. + * + * \param[in] epetra_X source Epetra_MultiVector + * \param[in,out] thyra_X destination Thyra::MultiVectorBase + * \param[in] eow Operator that defines the transition + */ + virtual void copyEpetraIntoThyra( + const Epetra_MultiVector& epetra_X, + const Teuchos::Ptr >& thyra_X) const; + // const Teko::Epetra::EpetraOperatorWrapper & eow) const; + + /** Virtual function defined in MappingStrategy. This copies + * an Epetra_MultiVector into a Thyra::MultiVectorBase with + * blocking handled by the strides defined in the constructor. + * + * \param[in] thyra_Y source Thyra::MultiVectorBase + * \param[in,out] epetra_Y destination Epetra_MultiVector + * \param[in] eow Operator that defines the transition + */ + virtual void copyThyraIntoEpetra( + const Teuchos::RCP >& thyra_Y, + Epetra_MultiVector& epetra_Y) const; + // const Teko::Epetra::EpetraOperatorWrapper & eow) const; + + /** Returns the domain and range maps used by this class. + * This faciliates building an Epetra_Operator around this + * class with its core functionality being a Thyra::LinearOpBase + * operator + * + * \returns Range map corresponding to this class + */ + virtual const Teuchos::RCP domainMap() const { return domainMap_; } + + /** Returns the domain and range maps used by this class. + * This faciliates building an Epetra_Operator around this + * class with its core functionality being a Thyra::LinearOpBase + * operator + * + * \returns Range map corresponding to this class + */ + virtual const Teuchos::RCP rangeMap() const { return rangeMap_; } + + /** A function for my sanity + * + * \returns String with description of this class + */ + virtual std::string toString() const { return std::string("BasicMappingStrategy"); } + + //@} + + protected: + // member variables + + //! \name storage for sanity + //@{ + Teuchos::RCP domainMap_; + Teuchos::RCP rangeMap_; + //@} }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_BlockedEpetraOperator.cpp b/packages/teko/src/Epetra/Teko_BlockedEpetraOperator.cpp index 637757fa4287..0b07d2d4602a 100644 --- a/packages/teko/src/Epetra/Teko_BlockedEpetraOperator.cpp +++ b/packages/teko/src/Epetra/Teko_BlockedEpetraOperator.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -70,137 +70,128 @@ using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcp_dynamic_cast; -BlockedEpetraOperator::BlockedEpetraOperator(const std::vector > & vars, - const Teuchos::RCP & content, - const std::string & label) - : Teko::Epetra::EpetraOperatorWrapper(), label_(label) -{ - SetContent(vars,content); +BlockedEpetraOperator::BlockedEpetraOperator(const std::vector >& vars, + const Teuchos::RCP& content, + const std::string& label) + : Teko::Epetra::EpetraOperatorWrapper(), label_(label) { + SetContent(vars, content); } -void BlockedEpetraOperator::SetContent(const std::vector > & vars, - const Teuchos::RCP & content) -{ - fullContent_ = content; - blockedMapping_ = rcp(new BlockedMappingStrategy(vars,Teuchos::rcpFromRef(fullContent_->OperatorDomainMap()), - fullContent_->Comm())); - SetMapStrategy(blockedMapping_); +void BlockedEpetraOperator::SetContent(const std::vector >& vars, + const Teuchos::RCP& content) { + fullContent_ = content; + blockedMapping_ = rcp(new BlockedMappingStrategy( + vars, Teuchos::rcpFromRef(fullContent_->OperatorDomainMap()), fullContent_->Comm())); + SetMapStrategy(blockedMapping_); - // build thyra operator - BuildBlockedOperator(); + // build thyra operator + BuildBlockedOperator(); } -void BlockedEpetraOperator::BuildBlockedOperator() -{ - TEUCHOS_ASSERT(blockedMapping_!=Teuchos::null); - - // get a CRS matrix - const RCP crsContent - = rcp_dynamic_cast(fullContent_); - - // ask the strategy to build the Thyra operator for you - if(blockedOperator_==Teuchos::null) { - blockedOperator_ = blockedMapping_->buildBlockedThyraOp(crsContent,label_); - } - else { - const RCP > blkOp - = rcp_dynamic_cast >(blockedOperator_,true); - blockedMapping_->rebuildBlockedThyraOp(crsContent,blkOp); - } - - // set whatever is returned - SetOperator(blockedOperator_,false); - - // reorder if neccessary - if(reorderManager_!=Teuchos::null) - Reorder(*reorderManager_); +void BlockedEpetraOperator::BuildBlockedOperator() { + TEUCHOS_ASSERT(blockedMapping_ != Teuchos::null); + + // get a CRS matrix + const RCP crsContent = + rcp_dynamic_cast(fullContent_); + + // ask the strategy to build the Thyra operator for you + if (blockedOperator_ == Teuchos::null) { + blockedOperator_ = blockedMapping_->buildBlockedThyraOp(crsContent, label_); + } else { + const RCP > blkOp = + rcp_dynamic_cast >(blockedOperator_, true); + blockedMapping_->rebuildBlockedThyraOp(crsContent, blkOp); + } + + // set whatever is returned + SetOperator(blockedOperator_, false); + + // reorder if neccessary + if (reorderManager_ != Teuchos::null) Reorder(*reorderManager_); } -const Teuchos::RCP BlockedEpetraOperator::GetBlock(int i,int j) const -{ - const RCP > blkOp - = Teuchos::rcp_dynamic_cast >(getThyraOp()); +const Teuchos::RCP BlockedEpetraOperator::GetBlock(int i, int j) const { + const RCP > blkOp = + Teuchos::rcp_dynamic_cast >(getThyraOp()); - return Thyra::get_Epetra_Operator(*blkOp->getBlock(i,j)); + return Thyra::get_Epetra_Operator(*blkOp->getBlock(i, j)); } /** Use a reorder manager to block this operator as desired. - * Multiple calls to the function reorder only the underlying object. - */ -void BlockedEpetraOperator::Reorder(const BlockReorderManager & brm) -{ - reorderManager_ = rcp(new BlockReorderManager(brm)); - - // build reordered objects - RCP reorderMapping = rcp(new ReorderedMappingStrategy(*reorderManager_,blockedMapping_)); - RCP > blockOp - = rcp_dynamic_cast >(blockedOperator_); - - RCP > A = buildReorderedLinearOp(*reorderManager_,blockOp); - - // set them as working values - SetMapStrategy(reorderMapping); - SetOperator(A,false); + * Multiple calls to the function reorder only the underlying object. + */ +void BlockedEpetraOperator::Reorder(const BlockReorderManager& brm) { + reorderManager_ = rcp(new BlockReorderManager(brm)); + + // build reordered objects + RCP reorderMapping = + rcp(new ReorderedMappingStrategy(*reorderManager_, blockedMapping_)); + RCP > blockOp = + rcp_dynamic_cast >(blockedOperator_); + + RCP > A = buildReorderedLinearOp(*reorderManager_, blockOp); + + // set them as working values + SetMapStrategy(reorderMapping); + SetOperator(A, false); } //! Remove any reordering on this object -void BlockedEpetraOperator::RemoveReording() -{ - SetMapStrategy(blockedMapping_); - SetOperator(blockedOperator_,false); - reorderManager_ = Teuchos::null; +void BlockedEpetraOperator::RemoveReording() { + SetMapStrategy(blockedMapping_); + SetOperator(blockedOperator_, false); + reorderManager_ = Teuchos::null; } /** Write out this operator to matrix market files - */ -void BlockedEpetraOperator::WriteBlocks(const std::string & prefix) const -{ - RCP > blockOp - = rcp_dynamic_cast >(blockedOperator_); - - // get size of blocked block operator - int rows = Teko::blockRowCount(blockOp); - - for(int i=0;i mat - = Teuchos::rcp_dynamic_cast(Thyra::get_Epetra_Operator(*blockOp->getBlock(i,j))); - - // write to file - EpetraExt::RowMatrixToMatrixMarketFile(formatBlockName(prefix,i,j,rows).c_str(),*mat); - } - } + */ +void BlockedEpetraOperator::WriteBlocks(const std::string& prefix) const { + RCP > blockOp = + rcp_dynamic_cast >(blockedOperator_); + + // get size of blocked block operator + int rows = Teko::blockRowCount(blockOp); + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < rows; j++) { + // get the row matrix object + RCP mat = Teuchos::rcp_dynamic_cast( + Thyra::get_Epetra_Operator(*blockOp->getBlock(i, j))); + + // write to file + EpetraExt::RowMatrixToMatrixMarketFile(formatBlockName(prefix, i, j, rows).c_str(), *mat); + } + } } -bool BlockedEpetraOperator::testAgainstFullOperator(int count,double tol) const -{ - Epetra_Vector xf(OperatorRangeMap()); - Epetra_Vector xs(OperatorRangeMap()); - Epetra_Vector y(OperatorDomainMap()); - - // test operator many times - bool result = true; - double diffNorm=0.0,trueNorm=0.0; - for(int i=0;iApply(y,xf); // xf = A*y - - // compute norms - xs.Update(-1.0,xf,1.0); - xs.Norm2(&diffNorm); - xf.Norm2(&trueNorm); - - // check result - result &= (diffNorm/trueNorm < tol); - } - return result; +bool BlockedEpetraOperator::testAgainstFullOperator(int count, double tol) const { + Epetra_Vector xf(OperatorRangeMap()); + Epetra_Vector xs(OperatorRangeMap()); + Epetra_Vector y(OperatorDomainMap()); + + // test operator many times + bool result = true; + double diffNorm = 0.0, trueNorm = 0.0; + for (int i = 0; i < count; i++) { + xf.PutScalar(0.0); + xs.PutScalar(0.0); + y.Random(); + + // apply operator + Apply(y, xs); // xs = A*y + fullContent_->Apply(y, xf); // xf = A*y + + // compute norms + xs.Update(-1.0, xf, 1.0); + xs.Norm2(&diffNorm); + xf.Norm2(&trueNorm); + + // check result + result &= (diffNorm / trueNorm < tol); + } + return result; } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_BlockedEpetraOperator.hpp b/packages/teko/src/Epetra/Teko_BlockedEpetraOperator.hpp index 87305f64d75d..9fa6fc71f845 100644 --- a/packages/teko/src/Epetra/Teko_BlockedEpetraOperator.hpp +++ b/packages/teko/src/Epetra/Teko_BlockedEpetraOperator.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -64,99 +64,98 @@ namespace Teko { namespace Epetra { /** \brief Tear about a user specified Epetra_Operator (CrsMatrix) - * using a vector of vectors of GIDs for each block. - */ + * using a vector of vectors of GIDs for each block. + */ class BlockedEpetraOperator : public EpetraOperatorWrapper { -public: - - /** Build a blocked operator based on a vector of vector - * of global IDs. - * - * \param[in] vars Vector of vectors of global ids specifying - * how the operator is to be blocked. - * \param[in] content Operator to be blocked - * \param[in] label Label for name the operator - */ - BlockedEpetraOperator(const std::vector > & vars, - const Teuchos::RCP & content, - const std::string & label=""); - - /** Build a blocked operator based on a vector of vector - * of global IDs. This function basically sets up the mapping - * strategy used by this operator. - * - * \param[in] vars Vector of vectors of global ids specifying - * how the operator is to be blocked. - * \param[in] content Operator to be blocked - */ - virtual void SetContent(const std::vector > & vars, - const Teuchos::RCP & content); - - /** Force a rebuild of the blocked operator from the stored - * content operator. - */ - virtual void RebuildOps() - { BuildBlockedOperator(); } - - virtual const Teuchos::RCP GetContent() const - { return fullContent_; } - - virtual const Teuchos::RCP GetContent() - { return fullContent_; } - - const Teuchos::RCP GetBlock(int i,int j) const; - - /** Use a reorder manager to block this operator as desired. - * Multiple calls to the function reorder only the underlying object. - */ - void Reorder(const BlockReorderManager & brm); - - //! Remove any reordering on this object - void RemoveReording(); - - /** Write out this operator to matrix market files - */ - virtual void WriteBlocks(const std::string & prefix) const; - - // functions overloading Epetra_Operator - //////////////////////////////////////////////// - - // destructor - virtual ~BlockedEpetraOperator() {} - - // attribute set methods - - // don't use transpose...ever! - virtual int SetUseTranspose(bool /* useTranspose */) - { return -1; } - - virtual int ApplyInverse(const Epetra_MultiVector &/* X */, Epetra_MultiVector &/* Y */) const - { TEUCHOS_ASSERT(false); return -1; } - - virtual double NormInf() const - { TEUCHOS_ASSERT(false); return 0.0; } - - // attribute access functions - virtual bool UseTranspose() const { return false; } - virtual bool HasNormInf() const { return false; } - virtual const Epetra_Comm & Comm() const { return fullContent_->Comm(); } - - //! Helps perform sanity checks - bool testAgainstFullOperator(int count,double tol) const; - -protected: - // gooey center of this shell - Teuchos::RCP fullContent_; - Teuchos::RCP blockedMapping_; - Teuchos::RCP > blockedOperator_; - Teuchos::RCP reorderManager_; - - std::string label_; - - void BuildBlockedOperator(); + public: + /** Build a blocked operator based on a vector of vector + * of global IDs. + * + * \param[in] vars Vector of vectors of global ids specifying + * how the operator is to be blocked. + * \param[in] content Operator to be blocked + * \param[in] label Label for name the operator + */ + BlockedEpetraOperator(const std::vector > &vars, + const Teuchos::RCP &content, + const std::string &label = ""); + + /** Build a blocked operator based on a vector of vector + * of global IDs. This function basically sets up the mapping + * strategy used by this operator. + * + * \param[in] vars Vector of vectors of global ids specifying + * how the operator is to be blocked. + * \param[in] content Operator to be blocked + */ + virtual void SetContent(const std::vector > &vars, + const Teuchos::RCP &content); + + /** Force a rebuild of the blocked operator from the stored + * content operator. + */ + virtual void RebuildOps() { BuildBlockedOperator(); } + + virtual const Teuchos::RCP GetContent() const { return fullContent_; } + + virtual const Teuchos::RCP GetContent() { return fullContent_; } + + const Teuchos::RCP GetBlock(int i, int j) const; + + /** Use a reorder manager to block this operator as desired. + * Multiple calls to the function reorder only the underlying object. + */ + void Reorder(const BlockReorderManager &brm); + + //! Remove any reordering on this object + void RemoveReording(); + + /** Write out this operator to matrix market files + */ + virtual void WriteBlocks(const std::string &prefix) const; + + // functions overloading Epetra_Operator + //////////////////////////////////////////////// + + // destructor + virtual ~BlockedEpetraOperator() {} + + // attribute set methods + + // don't use transpose...ever! + virtual int SetUseTranspose(bool /* useTranspose */) { return -1; } + + virtual int ApplyInverse(const Epetra_MultiVector & /* X */, Epetra_MultiVector & /* Y */) const { + TEUCHOS_ASSERT(false); + return -1; + } + + virtual double NormInf() const { + TEUCHOS_ASSERT(false); + return 0.0; + } + + // attribute access functions + virtual bool UseTranspose() const { return false; } + virtual bool HasNormInf() const { return false; } + virtual const Epetra_Comm &Comm() const { return fullContent_->Comm(); } + + //! Helps perform sanity checks + bool testAgainstFullOperator(int count, double tol) const; + + protected: + // gooey center of this shell + Teuchos::RCP fullContent_; + Teuchos::RCP blockedMapping_; + Teuchos::RCP > blockedOperator_; + Teuchos::RCP reorderManager_; + + std::string label_; + + void BuildBlockedOperator(); }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_BlockedMappingStrategy.cpp b/packages/teko/src/Epetra/Teko_BlockedMappingStrategy.cpp index d49bb2c53e48..a3c2da8293db 100644 --- a/packages/teko/src/Epetra/Teko_BlockedMappingStrategy.cpp +++ b/packages/teko/src/Epetra/Teko_BlockedMappingStrategy.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -67,17 +67,17 @@ namespace Epetra { // in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current // implimentation only supports a fixed number of variables // -// arguments: -// vars - Number of different variables +// arguments: +// vars - Number of different variables // map - original Epetra_Map to be broken up // comm - Epetra_Comm object related to the map // -BlockedMappingStrategy::BlockedMappingStrategy(const std::vector > & vars, - const Teuchos::RCP & map, const Epetra_Comm & comm) -{ - rangeMap_ = map; - domainMap_ = map; - buildBlockTransferData(vars, rangeMap_,comm); +BlockedMappingStrategy::BlockedMappingStrategy(const std::vector >& vars, + const Teuchos::RCP& map, + const Epetra_Comm& comm) { + rangeMap_ = map; + domainMap_ = map; + buildBlockTransferData(vars, rangeMap_, comm); } // Virtual function defined in MappingStrategy. This copies @@ -88,28 +88,29 @@ BlockedMappingStrategy::BlockedMappingStrategy(const std::vector > & thyra_X) const -{ - int count = X.NumVectors(); - - std::vector > subX; - - // allocate vectors to copy into - Blocking::buildSubVectors(blockMaps_,subX,count); - - // copy source vector to X vector - Blocking::one2many(subX,X,blockImport_); - - // convert subX to an array of multi vectors - Teuchos::Array > > thyra_subX; - Teuchos::Ptr > prod_X - = Teuchos::ptr_dynamic_cast >(thyra_X); - for(unsigned int i=0;i > vec - = rcp_dynamic_cast >(prod_X->getNonconstMultiVectorBlock(i)); - fillDefaultSpmdMultiVector(vec,subX[i]); - } +void BlockedMappingStrategy::copyEpetraIntoThyra( + const Epetra_MultiVector& X, + const Teuchos::Ptr >& thyra_X) const { + int count = X.NumVectors(); + + std::vector > subX; + + // allocate vectors to copy into + Blocking::buildSubVectors(blockMaps_, subX, count); + + // copy source vector to X vector + Blocking::one2many(subX, X, blockImport_); + + // convert subX to an array of multi vectors + Teuchos::Array > > thyra_subX; + Teuchos::Ptr > prod_X = + Teuchos::ptr_dynamic_cast >(thyra_X); + for (unsigned int i = 0; i < blockMaps_.size(); i++) { + RCP > vec = + rcp_dynamic_cast >( + prod_X->getNonconstMultiVectorBlock(i)); + fillDefaultSpmdMultiVector(vec, subX[i]); + } } // Virtual function defined in MappingStrategy. This copies @@ -120,22 +121,22 @@ void BlockedMappingStrategy::copyEpetraIntoThyra(const Epetra_MultiVector& X, // thyra_Y - source Thyra::MultiVectorBase // Y - destination Epetra_MultiVector // -void BlockedMappingStrategy::copyThyraIntoEpetra(const RCP > & thyra_Y, - Epetra_MultiVector& Y) const -{ - std::vector > subY; - RCP > prod_Y - = rcp_dynamic_cast >(thyra_Y); - - // convert thyra product vector to subY - for(unsigned int i=0;igetMultiVectorBlock(i))); - - // endow the subVectors with required information about the maps - // Blocking::associateSubVectors(blockMaps_,subY); - - // copy solution vectors to Y vector - Blocking::many2one(Y,subY,blockExport_); +void BlockedMappingStrategy::copyThyraIntoEpetra( + const RCP >& thyra_Y, Epetra_MultiVector& Y) const { + std::vector > subY; + RCP > prod_Y = + rcp_dynamic_cast >(thyra_Y); + + // convert thyra product vector to subY + for (unsigned int i = 0; i < blockMaps_.size(); i++) + subY.push_back( + Thyra::get_Epetra_MultiVector(*blockMaps_[i].second, prod_Y->getMultiVectorBlock(i))); + + // endow the subVectors with required information about the maps + // Blocking::associateSubVectors(blockMaps_,subY); + + // copy solution vectors to Y vector + Blocking::many2one(Y, subY, blockExport_); } // this is the core routine that builds the maps @@ -150,19 +151,19 @@ void BlockedMappingStrategy::copyThyraIntoEpetra(const RCP > & vars, - const Teuchos::RCP & baseMap, const Epetra_Comm & comm) -{ - // build block for each vector - for(std::size_t i=0;i >& vars, + const Teuchos::RCP& baseMap, + const Epetra_Comm& comm) { + // build block for each vector + for (std::size_t i = 0; i < vars.size(); i++) { + // build maps and exporters/importers + Blocking::MapPair mapPair = Blocking::buildSubMap(vars[i], comm); + Blocking::ImExPair iePair = Blocking::buildExportImport(*baseMap, mapPair); + + blockMaps_.push_back(mapPair); + blockImport_.push_back(iePair.first); + blockExport_.push_back(iePair.second); + } } // Builds a blocked Thyra operator that uses the strided @@ -175,28 +176,27 @@ void BlockedMappingStrategy::buildBlockTransferData(const std::vector > -BlockedMappingStrategy::buildBlockedThyraOp(const RCP & crsContent,const std::string & label) const -{ - int dim = blockMaps_.size(); - - RCP > A = Thyra::defaultBlockedLinearOp(); - - A->beginBlockFill(dim,dim); - for(int i=0;i blk = Blocking::buildSubBlock(i,j,*crsContent,blockMaps_); - A->setNonconstBlock(i,j,Thyra::nonconstEpetraLinearOp(blk,ss.str())); - } - } // end for i - A->endBlockFill(); - - return A; +const Teuchos::RCP > BlockedMappingStrategy::buildBlockedThyraOp( + const RCP& crsContent, const std::string& label) const { + int dim = blockMaps_.size(); + + RCP > A = Thyra::defaultBlockedLinearOp(); + + A->beginBlockFill(dim, dim); + for (int i = 0; i < dim; i++) { + for (int j = 0; j < dim; j++) { + // label block correctly + std::stringstream ss; + ss << label << "_" << i << "," << j; + + // build the blocks and place it the right location + RCP blk = Blocking::buildSubBlock(i, j, *crsContent, blockMaps_); + A->setNonconstBlock(i, j, Thyra::nonconstEpetraLinearOp(blk, ss.str())); + } + } // end for i + A->endBlockFill(); + + return A; } // Rebuilds a blocked Thyra operator that uses the strided @@ -209,22 +209,23 @@ BlockedMappingStrategy::buildBlockedThyraOp(const RCP & // A - Destination block linear op composed of blocks of // Epetra_CrsMatrix at all relevant locations // -void BlockedMappingStrategy::rebuildBlockedThyraOp(const RCP & crsContent, - const RCP > & A) const -{ - int dim = blockMaps_.size(); - - for(int i=0;i > Aij = A->getNonconstBlock(i,j); - RCP eAij = rcp_dynamic_cast(Thyra::get_Epetra_Operator(*Aij),true); - - // rebuild the blocks and place it the right location - Blocking::rebuildSubBlock(i,j,*crsContent,blockMaps_,*eAij); - } - } // end for i +void BlockedMappingStrategy::rebuildBlockedThyraOp( + const RCP& crsContent, + const RCP >& A) const { + int dim = blockMaps_.size(); + + for (int i = 0; i < dim; i++) { + for (int j = 0; j < dim; j++) { + // get Epetra version of desired block + RCP > Aij = A->getNonconstBlock(i, j); + RCP eAij = + rcp_dynamic_cast(Thyra::get_Epetra_Operator(*Aij), true); + + // rebuild the blocks and place it the right location + Blocking::rebuildSubBlock(i, j, *crsContent, blockMaps_, *eAij); + } + } // end for i } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_BlockedMappingStrategy.hpp b/packages/teko/src/Epetra/Teko_BlockedMappingStrategy.hpp index d5cf5ee8bb2b..34bc7fe97bcc 100644 --- a/packages/teko/src/Epetra/Teko_BlockedMappingStrategy.hpp +++ b/packages/teko/src/Epetra/Teko_BlockedMappingStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -74,155 +74,154 @@ namespace Teko { namespace Epetra { class BlockedMappingStrategy : public MappingStrategy { -public: - //! \name Constructors - //@{ - - /** Creates a strided mapping strategy. This class is useful - * for breaking up nodally ordered matrices (i.e. the unknowns - * in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current - * implimentation only supports a fixed number of variables - * - * \param[in] vars Vector describing the blocking of variables - * \param[in] baseMap original Epetra_Map to be broken up - * \param[in] comm Epetra_Comm object related to the map - */ - BlockedMappingStrategy(const std::vector > & vars, - const Teuchos::RCP & baseMap, const Epetra_Comm & comm); - //@} - - //!\name Member functions inherited from Teko::Epetra::MappingStrategy - //@{ - - /** Virtual function defined in MappingStrategy. This copies - * an Epetra_MultiVector into a Thyra::MultiVectorBase with - * blocking handled by the strides defined in the constructor. - * - * \param[in] epetra_X source Epetra_MultiVector - * \param[in,out] thyra_X destination Thyra::MultiVectorBase - */ - virtual void copyEpetraIntoThyra(const Epetra_MultiVector& epetra_X, - const Teuchos::Ptr > & thyra_X) const; - - /** Virtual function defined in MappingStrategy. This copies - * an Epetra_MultiVector into a Thyra::MultiVectorBase with - * blocking handled by the strides defined in the constructor. - * - * \param[in] thyra_Y source Thyra::MultiVectorBase - * \param[in,out] epetra_Y destination Epetra_MultiVector - */ - virtual void copyThyraIntoEpetra(const Teuchos::RCP > & thyra_Y, - Epetra_MultiVector& epetra_Y) const; - - /** Returns the domain and range maps used by this class. - * This faciliates building an Epetra_Operator around this - * class with its core functionality being a Thyra::LinearOpBase - * operator - * - * \returns Range map corresponding to this class - */ - virtual const Teuchos::RCP domainMap() const - { return domainMap_; } - - /** Returns the domain and range maps used by this class. - * This faciliates building an Epetra_Operator around this - * class with its core functionality being a Thyra::LinearOpBase - * operator - * - * \returns Range map corresponding to this class - */ - virtual const Teuchos::RCP rangeMap() const - { return rangeMap_; } - - /** A function for my sanity - * - * \returns String with description of this class - */ - virtual std::string toString() const - { return std::string("BlockedMappingStrategy"); } - - //@} - - //! \name Locally useful functions - //@{ - - /** \brief This is the core routine that builds the maps - * and importers/exporters. - * - * This is the core routine that builds the maps - * and importers/exporters neccessary for all the - * transfers. Currently it simply calls out to the - * interlaced epetra functions. (Comment: this - * routine should probably be private or protected - * ... it is basically the meat of the constructor) - * - * \param[in] vars Vector describing the blocking of variables - * \param[in] baseMap basic map to use in the transfers - * \param[in] comm Epetra_Comm object - */ - void buildBlockTransferData(const std::vector > & vars, - const Teuchos::RCP & baseMap, const Epetra_Comm & comm); - - /** \brief Get the individual block maps underlying that - * make up a strided vector/operator. - * - * Get the individual block maps underlying that - * make up a strided vector/operator. These are - * useful if you want to tear something ... i.e. - * a matrix ... apart. - * - * \returns Return a vector of block maps - * created for this strided operator - */ - const std::vector & getMaps() const - { return blockMaps_; } - - /** Builds a blocked Thyra operator that uses the strided - * mapping strategy to define sub blocks. - * - * \param[in] mat Epetra_CrsMatrix with FillComplete called, this - * matrix is assumed to be square, with the same - * range and domain maps - * \param[in] label String to be used to prefix the sub block's labels - * - * \returns Blocked Thyra linear operator with sub blocks - * defined by this mapping strategy - */ - const Teuchos::RCP > - buildBlockedThyraOp(const Teuchos::RCP & mat,const std::string & label="") const; - - /** Rebuilds a block Thyra operator using the strided mapping - * strategy to define sub blocks. - * - * \param[in] mat Epetra_CrsMatrix with FillComplete called, this - * matrix is assumed to be square, with the same - * range and domain maps - * \param[in] A Destination block linear op composed of blocks of - * Epetra_CrsMatrix at all relevant locations - */ - void rebuildBlockedThyraOp(const RCP & mat, - const RCP > & A) const; - - //@} - -protected: - // member variables - - //! \name storage for sanity - //@{ - Teuchos::RCP domainMap_; - Teuchos::RCP rangeMap_; - //@} - - //! \name block transfer data - //@{ - std::vector blockMaps_; - std::vector > blockImport_; - std::vector > blockExport_; - //@} + public: + //! \name Constructors + //@{ + + /** Creates a strided mapping strategy. This class is useful + * for breaking up nodally ordered matrices (i.e. the unknowns + * in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current + * implimentation only supports a fixed number of variables + * + * \param[in] vars Vector describing the blocking of variables + * \param[in] baseMap original Epetra_Map to be broken up + * \param[in] comm Epetra_Comm object related to the map + */ + BlockedMappingStrategy(const std::vector >& vars, + const Teuchos::RCP& baseMap, const Epetra_Comm& comm); + //@} + + //!\name Member functions inherited from Teko::Epetra::MappingStrategy + //@{ + + /** Virtual function defined in MappingStrategy. This copies + * an Epetra_MultiVector into a Thyra::MultiVectorBase with + * blocking handled by the strides defined in the constructor. + * + * \param[in] epetra_X source Epetra_MultiVector + * \param[in,out] thyra_X destination Thyra::MultiVectorBase + */ + virtual void copyEpetraIntoThyra( + const Epetra_MultiVector& epetra_X, + const Teuchos::Ptr >& thyra_X) const; + + /** Virtual function defined in MappingStrategy. This copies + * an Epetra_MultiVector into a Thyra::MultiVectorBase with + * blocking handled by the strides defined in the constructor. + * + * \param[in] thyra_Y source Thyra::MultiVectorBase + * \param[in,out] epetra_Y destination Epetra_MultiVector + */ + virtual void copyThyraIntoEpetra( + const Teuchos::RCP >& thyra_Y, + Epetra_MultiVector& epetra_Y) const; + + /** Returns the domain and range maps used by this class. + * This faciliates building an Epetra_Operator around this + * class with its core functionality being a Thyra::LinearOpBase + * operator + * + * \returns Range map corresponding to this class + */ + virtual const Teuchos::RCP domainMap() const { return domainMap_; } + + /** Returns the domain and range maps used by this class. + * This faciliates building an Epetra_Operator around this + * class with its core functionality being a Thyra::LinearOpBase + * operator + * + * \returns Range map corresponding to this class + */ + virtual const Teuchos::RCP rangeMap() const { return rangeMap_; } + + /** A function for my sanity + * + * \returns String with description of this class + */ + virtual std::string toString() const { return std::string("BlockedMappingStrategy"); } + + //@} + + //! \name Locally useful functions + //@{ + + /** \brief This is the core routine that builds the maps + * and importers/exporters. + * + * This is the core routine that builds the maps + * and importers/exporters neccessary for all the + * transfers. Currently it simply calls out to the + * interlaced epetra functions. (Comment: this + * routine should probably be private or protected + * ... it is basically the meat of the constructor) + * + * \param[in] vars Vector describing the blocking of variables + * \param[in] baseMap basic map to use in the transfers + * \param[in] comm Epetra_Comm object + */ + void buildBlockTransferData(const std::vector >& vars, + const Teuchos::RCP& baseMap, + const Epetra_Comm& comm); + + /** \brief Get the individual block maps underlying that + * make up a strided vector/operator. + * + * Get the individual block maps underlying that + * make up a strided vector/operator. These are + * useful if you want to tear something ... i.e. + * a matrix ... apart. + * + * \returns Return a vector of block maps + * created for this strided operator + */ + const std::vector& getMaps() const { return blockMaps_; } + + /** Builds a blocked Thyra operator that uses the strided + * mapping strategy to define sub blocks. + * + * \param[in] mat Epetra_CrsMatrix with FillComplete called, this + * matrix is assumed to be square, with the same + * range and domain maps + * \param[in] label String to be used to prefix the sub block's labels + * + * \returns Blocked Thyra linear operator with sub blocks + * defined by this mapping strategy + */ + const Teuchos::RCP > buildBlockedThyraOp( + const Teuchos::RCP& mat, const std::string& label = "") const; + + /** Rebuilds a block Thyra operator using the strided mapping + * strategy to define sub blocks. + * + * \param[in] mat Epetra_CrsMatrix with FillComplete called, this + * matrix is assumed to be square, with the same + * range and domain maps + * \param[in] A Destination block linear op composed of blocks of + * Epetra_CrsMatrix at all relevant locations + */ + void rebuildBlockedThyraOp(const RCP& mat, + const RCP >& A) const; + + //@} + + protected: + // member variables + + //! \name storage for sanity + //@{ + Teuchos::RCP domainMap_; + Teuchos::RCP rangeMap_; + //@} + + //! \name block transfer data + //@{ + std::vector blockMaps_; + std::vector > blockImport_; + std::vector > blockExport_; + //@} }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_BlockingEpetra.cpp b/packages/teko/src/Epetra/Teko_BlockingEpetra.cpp index 1b4dd85b63dc..6baea3feb941 100644 --- a/packages/teko/src/Epetra/Teko_BlockingEpetra.cpp +++ b/packages/teko/src/Epetra/Teko_BlockingEpetra.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -56,277 +56,274 @@ namespace Teko { namespace Epetra { namespace Blocking { -/** Build maps to make other conversions. This function builds a map - * using a vector of global ids local to this processor. It also builds - * a seperate map that (globally) starts from zero. For instance if the following - * GIDs are passed in PID = 0, GID = [0 2 4 6 8] and PID = 1, GID = [10 12 14] - * the the two maps created are - * Global Map = [(PID=0,GID=[0 2 4 6 8]), (PID=1,GID=[10 12 14])] - * Contiguous Map = [(PID=0,GID=[0 1 2 3 4]), (PID=1,GID=[5 6 7])] - * - * \param[in] gid Local global IDs to use - * \param[in] comm Communicator to use in construction of the maps - * - * \returns A pair of maps: (Global Map, Contiguous Map) - */ -const MapPair buildSubMap(const std::vector< int > & gid, const Epetra_Comm &comm) -{ - Teuchos::RCP gidMap = rcp(new Epetra_Map(-1,gid.size(),&gid[0],0,comm)); - Teuchos::RCP contigMap = rcp(new Epetra_Map(-1,gid.size(),0,comm)); - - return std::make_pair(gidMap,contigMap); +/** Build maps to make other conversions. This function builds a map + * using a vector of global ids local to this processor. It also builds + * a seperate map that (globally) starts from zero. For instance if the following + * GIDs are passed in PID = 0, GID = [0 2 4 6 8] and PID = 1, GID = [10 12 14] + * the the two maps created are + * Global Map = [(PID=0,GID=[0 2 4 6 8]), (PID=1,GID=[10 12 14])] + * Contiguous Map = [(PID=0,GID=[0 1 2 3 4]), (PID=1,GID=[5 6 7])] + * + * \param[in] gid Local global IDs to use + * \param[in] comm Communicator to use in construction of the maps + * + * \returns A pair of maps: (Global Map, Contiguous Map) + */ +const MapPair buildSubMap(const std::vector &gid, const Epetra_Comm &comm) { + Teuchos::RCP gidMap = rcp(new Epetra_Map(-1, gid.size(), &gid[0], 0, comm)); + Teuchos::RCP contigMap = rcp(new Epetra_Map(-1, gid.size(), 0, comm)); + + return std::make_pair(gidMap, contigMap); } -/** Build the Export/Import objects that take the single vector global map and - * build individual sub maps. - * - * \param[in] baseMap Single global vector map. - * \param[in] maps Pair of maps containing the global sub map and the contiguous sub map. - * These come directly from buildSubMap. - * - * \returns A pair containing pointers to the Import/Export objects. - */ -const ImExPair buildExportImport(const Epetra_Map & baseMap,const MapPair & maps) -{ - return std::make_pair(rcp(new Epetra_Import(*maps.first,baseMap)), - rcp(new Epetra_Export(*maps.first,baseMap))); +/** Build the Export/Import objects that take the single vector global map and + * build individual sub maps. + * + * \param[in] baseMap Single global vector map. + * \param[in] maps Pair of maps containing the global sub map and the contiguous sub map. + * These come directly from buildSubMap. + * + * \returns A pair containing pointers to the Import/Export objects. + */ +const ImExPair buildExportImport(const Epetra_Map &baseMap, const MapPair &maps) { + return std::make_pair(rcp(new Epetra_Import(*maps.first, baseMap)), + rcp(new Epetra_Export(*maps.first, baseMap))); } /** Using a list of map pairs created by buildSubMap, buidl the corresponding - * multi-vector objects. - * - * \param[in] maps Map pairs created by buildSubMap - * \param[in,out] vectors Vector objects created using the Contiguous maps - * \param[in] count Number of multivectors to build. - */ -void buildSubVectors(const std::vector & maps, - std::vector > & vectors,int count) -{ - std::vector::const_iterator mapItr; - - // loop over all maps - for(mapItr=maps.begin();mapItr!=maps.end();mapItr++) { - // add new elements to vectors - RCP mv = rcp(new Epetra_MultiVector(*(*mapItr).second,count)); - vectors.push_back(mv); - } + * multi-vector objects. + * + * \param[in] maps Map pairs created by buildSubMap + * \param[in,out] vectors Vector objects created using the Contiguous maps + * \param[in] count Number of multivectors to build. + */ +void buildSubVectors(const std::vector &maps, + std::vector > &vectors, int count) { + std::vector::const_iterator mapItr; + + // loop over all maps + for (mapItr = maps.begin(); mapItr != maps.end(); mapItr++) { + // add new elements to vectors + RCP mv = rcp(new Epetra_MultiVector(*(*mapItr).second, count)); + vectors.push_back(mv); + } } -/** Copy the contents of a global vector into many sub-vectors created by buildSubVectors. - * - * \param[in,out] many Sub-vector to be filled by this operation created by buildSubVectors. - * \param[in] one The source vector. - * \param[in] subImport A list of import objects to use in copying. - */ -void one2many(std::vector > & many, const Epetra_MultiVector & single, - const std::vector > & subImport) -{ - // std::vector >::const_iterator vecItr; - std::vector >::const_iterator vecItr; - std::vector >::const_iterator impItr; - - // using Importers fill the sub vectors from the mama vector - for(vecItr=many.begin(),impItr=subImport.begin(); - vecItr!=many.end();++vecItr,++impItr) { - // for ease of access to the destination - RCP destVec = *vecItr; - - // extract the map with global indicies from the current vector - const Epetra_BlockMap & globalMap = (*impItr)->TargetMap(); - - // build the import vector as a view on the destination - Epetra_MultiVector importVector(View,globalMap,destVec->Values(),destVec->Stride(),destVec->NumVectors()); - - // perform the import - importVector.Import(single,**impItr,Insert); - } +/** Copy the contents of a global vector into many sub-vectors created by + * buildSubVectors. + * + * \param[in,out] many Sub-vector to be filled by this operation created by + * buildSubVectors. \param[in] one The source vector. \param[in] subImport A list of + * import objects to use in copying. + */ +void one2many(std::vector > &many, const Epetra_MultiVector &single, + const std::vector > &subImport) { + // std::vector >::const_iterator vecItr; + std::vector >::const_iterator vecItr; + std::vector >::const_iterator impItr; + + // using Importers fill the sub vectors from the mama vector + for (vecItr = many.begin(), impItr = subImport.begin(); vecItr != many.end(); + ++vecItr, ++impItr) { + // for ease of access to the destination + RCP destVec = *vecItr; + + // extract the map with global indicies from the current vector + const Epetra_BlockMap &globalMap = (*impItr)->TargetMap(); + + // build the import vector as a view on the destination + Epetra_MultiVector importVector(View, globalMap, destVec->Values(), destVec->Stride(), + destVec->NumVectors()); + + // perform the import + importVector.Import(single, **impItr, Insert); + } } /** Copy the contents of many sub vectors (created from a contigous sub maps) to a single global - * vector. This should have the map used to create the Export/Import objects in the buildExportImport - * function. If more then one sub vector contains values for a particular GID in the single vector - * then the value in the final vector will be that of the last sub vector (in the list many). - * - * \param[in,out] one The single vector to be filled by this operation. - * \param[in] many Sub-vectors created by buildSubVectors used to fill one. - * \param[in] subExport A list of export objects to use in copying. - */ -void many2one(Epetra_MultiVector & one, const std::vector > & many, - const std::vector > & subExport) -{ - // std::vector >::const_iterator vecItr; - std::vector >::const_iterator vecItr; - std::vector >::const_iterator expItr; - - // using Exporters fill the empty vector from the sub-vectors - for(vecItr=many.begin(),expItr=subExport.begin(); - vecItr!=many.end();++vecItr,++expItr) { - - // for ease of access to the source - RCP srcVec = *vecItr; - - // extract the map with global indicies from the current vector - const Epetra_BlockMap & globalMap = (*expItr)->SourceMap(); - - // build the export vector as a view of the destination - Epetra_MultiVector exportVector(View,globalMap,srcVec->Values(),srcVec->Stride(),srcVec->NumVectors()); - one.Export(exportVector,**expItr,Insert); - } + * vector. This should have the map used to create the Export/Import objects in the + * buildExportImport function. If more then one sub vector contains values for a + * particular GID in the single vector then the value in the final vector will be that of the last + * sub vector (in the list many). + * + * \param[in,out] one The single vector to be filled by this operation. + * \param[in] many Sub-vectors created by buildSubVectors used to fill + * one. \param[in] subExport A list of export objects to use in copying. + */ +void many2one(Epetra_MultiVector &one, const std::vector > &many, + const std::vector > &subExport) { + // std::vector >::const_iterator vecItr; + std::vector >::const_iterator vecItr; + std::vector >::const_iterator expItr; + + // using Exporters fill the empty vector from the sub-vectors + for (vecItr = many.begin(), expItr = subExport.begin(); vecItr != many.end(); + ++vecItr, ++expItr) { + // for ease of access to the source + RCP srcVec = *vecItr; + + // extract the map with global indicies from the current vector + const Epetra_BlockMap &globalMap = (*expItr)->SourceMap(); + + // build the export vector as a view of the destination + Epetra_MultiVector exportVector(View, globalMap, srcVec->Values(), srcVec->Stride(), + srcVec->NumVectors()); + one.Export(exportVector, **expItr, Insert); + } } /** This function will return an IntVector that is constructed with a column map. - * The vector will be filled with -1 if there is not a corresponding entry in the - * sub-block row map. The other columns will be filled with the contiguous row map - * values. - */ -RCP getSubBlockColumnGIDs(const Epetra_CrsMatrix & A,const MapPair & mapPair) -{ - RCP blkGIDMap = mapPair.first; - RCP blkContigMap = mapPair.second; - - // fill index vector for rows - Epetra_IntVector rIndex(A.RowMap(),true); - for(int i=0;iLID(A.GRID(i)); // this LID makes me nervous - if(lid>-1) - rIndex[i] = blkContigMap->GID(lid); - else - rIndex[i] = -1; - } - - // get relavant column indices - Epetra_Import import(A.ColMap(),A.RowMap()); - RCP cIndex = rcp(new Epetra_IntVector(A.ColMap(),true)); - cIndex->Import(rIndex,import,Insert); - - return cIndex; + * The vector will be filled with -1 if there is not a corresponding entry in the + * sub-block row map. The other columns will be filled with the contiguous row map + * values. + */ +RCP getSubBlockColumnGIDs(const Epetra_CrsMatrix &A, const MapPair &mapPair) { + RCP blkGIDMap = mapPair.first; + RCP blkContigMap = mapPair.second; + + // fill index vector for rows + Epetra_IntVector rIndex(A.RowMap(), true); + for (int i = 0; i < A.NumMyRows(); i++) { + // LID is need to get to contiguous map + int lid = blkGIDMap->LID(A.GRID(i)); // this LID makes me nervous + if (lid > -1) + rIndex[i] = blkContigMap->GID(lid); + else + rIndex[i] = -1; + } + + // get relavant column indices + Epetra_Import import(A.ColMap(), A.RowMap()); + RCP cIndex = rcp(new Epetra_IntVector(A.ColMap(), true)); + cIndex->Import(rIndex, import, Insert); + + return cIndex; } // build a single subblock Epetra_CrsMatrix -RCP buildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector & subMaps) -{ - // get the number of variables families - int numVarFamily = subMaps.size(); - - TEUCHOS_ASSERT(i>=0 && i=0 && j plocal2ContigGIDs = getSubBlockColumnGIDs(A,subMaps[j]); - Epetra_IntVector & local2ContigGIDs = *plocal2ContigGIDs; - - RCP mat = rcp(new Epetra_CrsMatrix(Copy,rowMap,0)); - - // get entry information - int numMyRows = rowMap.NumMyElements(); - int maxNumEntries = A.MaxNumEntries(); - - // for extraction - std::vector indices(maxNumEntries); - std::vector values(maxNumEntries); - - // for insertion - std::vector colIndices(maxNumEntries); - std::vector colValues(maxNumEntries); - - // insert each row into subblock - // let FillComplete handle column distribution - for(int localRow=0;localRow-1); - - int err = A.ExtractMyRowCopy(lid, maxNumEntries, numEntries, &values[0], &indices[0]); - TEUCHOS_ASSERT(err==0); - - int numOwnedCols = 0; - for(int localCol=0;localCol-1); - - // if global id is not owned by this column - int gid = local2ContigGIDs[indices[localCol]]; - if(gid==-1) continue; // in contiguous row - - colIndices[numOwnedCols] = gid; - colValues[numOwnedCols] = values[localCol]; - numOwnedCols++; - } - - // insert it into the new matrix - mat->InsertGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]); - } - - // fill it and automagically optimize the storage - mat->FillComplete(colMap,rowMap); - - return mat; +RCP buildSubBlock(int i, int j, const Epetra_CrsMatrix &A, + const std::vector &subMaps) { + // get the number of variables families + int numVarFamily = subMaps.size(); + + TEUCHOS_ASSERT(i >= 0 && i < numVarFamily); + TEUCHOS_ASSERT(j >= 0 && j < numVarFamily); + + const Epetra_Map &gRowMap = *subMaps[i].first; // new GIDs + const Epetra_Map &rowMap = *subMaps[i].second; // contiguous GIDs + const Epetra_Map &colMap = *subMaps[j].second; + + const RCP plocal2ContigGIDs = getSubBlockColumnGIDs(A, subMaps[j]); + Epetra_IntVector &local2ContigGIDs = *plocal2ContigGIDs; + + RCP mat = rcp(new Epetra_CrsMatrix(Copy, rowMap, 0)); + + // get entry information + int numMyRows = rowMap.NumMyElements(); + int maxNumEntries = A.MaxNumEntries(); + + // for extraction + std::vector indices(maxNumEntries); + std::vector values(maxNumEntries); + + // for insertion + std::vector colIndices(maxNumEntries); + std::vector colValues(maxNumEntries); + + // insert each row into subblock + // let FillComplete handle column distribution + for (int localRow = 0; localRow < numMyRows; localRow++) { + int numEntries = -1; + int globalRow = gRowMap.GID(localRow); + int lid = A.RowMap().LID(globalRow); + int contigRow = rowMap.GID(localRow); + TEUCHOS_ASSERT(lid > -1); + + int err = A.ExtractMyRowCopy(lid, maxNumEntries, numEntries, &values[0], &indices[0]); + TEUCHOS_ASSERT(err == 0); + + int numOwnedCols = 0; + for (int localCol = 0; localCol < numEntries; localCol++) { + TEUCHOS_ASSERT(indices[localCol] > -1); + + // if global id is not owned by this column + int gid = local2ContigGIDs[indices[localCol]]; + if (gid == -1) continue; // in contiguous row + + colIndices[numOwnedCols] = gid; + colValues[numOwnedCols] = values[localCol]; + numOwnedCols++; + } + + // insert it into the new matrix + mat->InsertGlobalValues(contigRow, numOwnedCols, &colValues[0], &colIndices[0]); + } + + // fill it and automagically optimize the storage + mat->FillComplete(colMap, rowMap); + + return mat; } // build a single subblock Epetra_CrsMatrix -void rebuildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector & subMaps,Epetra_CrsMatrix & mat) -{ - // get the number of variables families - int numVarFamily = subMaps.size(); - - TEUCHOS_ASSERT(i>=0 && i=0 && j plocal2ContigGIDs = getSubBlockColumnGIDs(A,subMaps[j]); - Epetra_IntVector & local2ContigGIDs = *plocal2ContigGIDs; - - mat.PutScalar(0.0); - - // get entry information - int numMyRows = rowMap.NumMyElements(); - int maxNumEntries = A.MaxNumEntries(); - - // for extraction - std::vector indices(maxNumEntries); - std::vector values(maxNumEntries); - - // for insertion - std::vector colIndices(maxNumEntries); - std::vector colValues(maxNumEntries); - - // insert each row into subblock - // let FillComplete handle column distribution - for(int localRow=0;localRow-1); - - int err = A.ExtractMyRowCopy(lid, maxNumEntries, numEntries, &values[0], &indices[0]); - TEUCHOS_ASSERT(err==0); - - int numOwnedCols = 0; - for(int localCol=0;localCol-1); - - // if global id is not owned by this column - int gid = local2ContigGIDs[indices[localCol]]; - if(gid==-1) continue; // in contiguous row - - colIndices[numOwnedCols] = gid; - colValues[numOwnedCols] = values[localCol]; - numOwnedCols++; - } - - // insert it into the new matrix - mat.SumIntoGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]); - } +void rebuildSubBlock(int i, int j, const Epetra_CrsMatrix &A, const std::vector &subMaps, + Epetra_CrsMatrix &mat) { + // get the number of variables families + int numVarFamily = subMaps.size(); + + TEUCHOS_ASSERT(i >= 0 && i < numVarFamily); + TEUCHOS_ASSERT(j >= 0 && j < numVarFamily); + + const Epetra_Map &gRowMap = *subMaps[i].first; // new GIDs + const Epetra_Map &rowMap = *subMaps[i].second; // contiguous GIDs + + const RCP plocal2ContigGIDs = getSubBlockColumnGIDs(A, subMaps[j]); + Epetra_IntVector &local2ContigGIDs = *plocal2ContigGIDs; + + mat.PutScalar(0.0); + + // get entry information + int numMyRows = rowMap.NumMyElements(); + int maxNumEntries = A.MaxNumEntries(); + + // for extraction + std::vector indices(maxNumEntries); + std::vector values(maxNumEntries); + + // for insertion + std::vector colIndices(maxNumEntries); + std::vector colValues(maxNumEntries); + + // insert each row into subblock + // let FillComplete handle column distribution + for (int localRow = 0; localRow < numMyRows; localRow++) { + int numEntries = -1; + int globalRow = gRowMap.GID(localRow); + int lid = A.RowMap().LID(globalRow); + int contigRow = rowMap.GID(localRow); + TEUCHOS_ASSERT(lid > -1); + + int err = A.ExtractMyRowCopy(lid, maxNumEntries, numEntries, &values[0], &indices[0]); + TEUCHOS_ASSERT(err == 0); + + int numOwnedCols = 0; + for (int localCol = 0; localCol < numEntries; localCol++) { + TEUCHOS_ASSERT(indices[localCol] > -1); + + // if global id is not owned by this column + int gid = local2ContigGIDs[indices[localCol]]; + if (gid == -1) continue; // in contiguous row + + colIndices[numOwnedCols] = gid; + colValues[numOwnedCols] = values[localCol]; + numOwnedCols++; + } + + // insert it into the new matrix + mat.SumIntoGlobalValues(contigRow, numOwnedCols, &colValues[0], &colIndices[0]); + } } -} // end Blocking -} // end Epetra -} // end Teko +} // namespace Blocking +} // namespace Epetra +} // namespace Teko diff --git a/packages/teko/src/Epetra/Teko_BlockingEpetra.hpp b/packages/teko/src/Epetra/Teko_BlockingEpetra.hpp index 005578353c63..7f6e8c3497c5 100644 --- a/packages/teko/src/Epetra/Teko_BlockingEpetra.hpp +++ b/packages/teko/src/Epetra/Teko_BlockingEpetra.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -65,105 +65,112 @@ namespace Teko { namespace Epetra { namespace Blocking { -typedef std::pair,Teuchos::RCP > MapPair; -typedef std::pair,Teuchos::RCP > ImExPair; - -/** Build maps to make other conversions. This function builds a map - * using a vector of global ids local to this processor. It also builds - * a seperate map that (globally) starts from zero. For instance if the following - * GIDs are passed in PID = 0, GID = [0 2 4 6 8] and PID = 1, GID = [10 12 14] - * the the two maps created are - * Global Map = [(PID=0,GID=[0 2 4 6 8]), (PID=1,GID=[10 12 14])] - * Contiguous Map = [(PID=0,GID=[0 1 2 3 4]), (PID=1,GID=[5 6 7])] - * - * \param[in] gid Local global IDs to use - * \param[in] comm Communicator to use in construction of the maps - * - * \returns A pair of maps: (Global Map, Contiguous Map) - */ -const MapPair buildSubMap(const std::vector< int > & gid, const Epetra_Comm &comm); - -/** Build the Export/Import objects that take the single vector global map and - * build individual sub maps. - * - * \param[in] baseMap Single global vector map. - * \param[in] maps Pair of maps containing the global sub map and the contiguous sub map. - * These come directly from buildSubMap. - * - * \returns A pair containing pointers to the Import/Export objects. - */ -const ImExPair buildExportImport(const Epetra_Map & baseMap,const MapPair & maps); +typedef std::pair, Teuchos::RCP > MapPair; +typedef std::pair, Teuchos::RCP > ImExPair; + +/** Build maps to make other conversions. This function builds a map + * using a vector of global ids local to this processor. It also builds + * a seperate map that (globally) starts from zero. For instance if the following + * GIDs are passed in PID = 0, GID = [0 2 4 6 8] and PID = 1, GID = [10 12 14] + * the the two maps created are + * Global Map = [(PID=0,GID=[0 2 4 6 8]), (PID=1,GID=[10 12 14])] + * Contiguous Map = [(PID=0,GID=[0 1 2 3 4]), (PID=1,GID=[5 6 7])] + * + * \param[in] gid Local global IDs to use + * \param[in] comm Communicator to use in construction of the maps + * + * \returns A pair of maps: (Global Map, Contiguous Map) + */ +const MapPair buildSubMap(const std::vector &gid, const Epetra_Comm &comm); + +/** Build the Export/Import objects that take the single vector global map and + * build individual sub maps. + * + * \param[in] baseMap Single global vector map. + * \param[in] maps Pair of maps containing the global sub map and the contiguous sub map. + * These come directly from buildSubMap. + * + * \returns A pair containing pointers to the Import/Export objects. + */ +const ImExPair buildExportImport(const Epetra_Map &baseMap, const MapPair &maps); /** Copy the contents of many sub vectors (created from a contigous sub maps) to a single global - * vector. This should have the map used to create the Export/Import objects in the buildExportImport - * function. If more then one sub vector contains values for a particular GID in the single vector - * then the value in the final vector will be that of the last sub vector (in the list many). - * - * \param[in,out] one The single vector to be filled by this operation. - * \param[in] many Sub-vectors created by buildSubVectors used to fill one. - * \param[in] subExport A list of export objects to use in copying. - */ -void many2one(Epetra_MultiVector & one, const std::vector > & many, - const std::vector > & subExport); - -/** Copy the contents of a global vector into many sub-vectors created by buildSubVectors. - * - * \param[in,out] many Sub-vector to be filled by this operation created by buildSubVectors. - * \param[in] single The source vector. - * \param[in] subImport A list of import objects to use in copying. - */ -void one2many(std::vector > & many, const Epetra_MultiVector & single, - const std::vector > & subImport); + * vector. This should have the map used to create the Export/Import objects in the + * buildExportImport function. If more then one sub vector contains values for a + * particular GID in the single vector then the value in the final vector will be that of the last + * sub vector (in the list many). + * + * \param[in,out] one The single vector to be filled by this operation. + * \param[in] many Sub-vectors created by buildSubVectors used to fill + * one. \param[in] subExport A list of export objects to use in copying. + */ +void many2one(Epetra_MultiVector &one, + const std::vector > &many, + const std::vector > &subExport); + +/** Copy the contents of a global vector into many sub-vectors created by + * buildSubVectors. + * + * \param[in,out] many Sub-vector to be filled by this operation created by + * buildSubVectors. \param[in] single The source vector. \param[in] subImport A list of + * import objects to use in copying. + */ +void one2many(std::vector > &many, + const Epetra_MultiVector &single, + const std::vector > &subImport); /** Using a list of map pairs created by buildSubMap, buidl the corresponding - * multi-vector objects. - * - * \param[in] maps Map pairs created by buildSubMap - * \param[in,out] vectors Vector objects created using the Contiguous maps - * \param[in] count Number of multivectors to build. - */ -void buildSubVectors(const std::vector & maps, - std::vector > & vectors,int count); + * multi-vector objects. + * + * \param[in] maps Map pairs created by buildSubMap + * \param[in,out] vectors Vector objects created using the Contiguous maps + * \param[in] count Number of multivectors to build. + */ +void buildSubVectors(const std::vector &maps, + std::vector > &vectors, int count); /** This function will return an IntVector that is constructed with a column map. - * The vector will be filled with -1 if there is not a corresponding entry in the - * sub-block row map. The other columns will be filled with the contiguous row map - * values. - */ -Teuchos::RCP getSubBlockColumnGIDs(const Epetra_CrsMatrix & A,const MapPair & mapPair); + * The vector will be filled with -1 if there is not a corresponding entry in the + * sub-block row map. The other columns will be filled with the contiguous row map + * values. + */ +Teuchos::RCP getSubBlockColumnGIDs(const Epetra_CrsMatrix &A, + const MapPair &mapPair); /** Extract the (i,j) sub block described by a vector of map pair objects from - * a CRS matrix. The first of map in the ith pair describes the rows to be extracted, - * while the second pair defines GID numbering of the new block. Similarly with the - * jth pair (except for columns). - * - * \param[in] i Index of the map to use to define the row space - * \param[in] j Index of the map to use to define the columns space - * \param[in] A Source CRS matrix - * \param[in] subMaps Vector of maps created by the buildSubMap routine. - * - * \returns A CRS matrix containing a subset of the rows and columns as described - * by the vector of maps. - */ -Teuchos::RCP buildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector & subMaps); + * a CRS matrix. The first of map in the ith pair describes the rows to be extracted, + * while the second pair defines GID numbering of the new block. Similarly with the + * jth pair (except for columns). + * + * \param[in] i Index of the map to use to define the row space + * \param[in] j Index of the map to use to define the columns space + * \param[in] A Source CRS matrix + * \param[in] subMaps Vector of maps created by the buildSubMap routine. + * + * \returns A CRS matrix containing a subset of the rows and columns as described + * by the vector of maps. + */ +Teuchos::RCP buildSubBlock(int i, int j, const Epetra_CrsMatrix &A, + const std::vector &subMaps); /** Extract the (i,j) sub block described by a vector of map pair objects from - * a CRS matrix. The first of map in the ith pair describes the rows to be extracted, - * while the second pair defines GID numbering of the new block. Similarly with the - * jth pair (except for columns). This "refills" an operator already created by - * buildSubBlock. This only replaces the sparsity pattern of the matrix. - * - * \param[in] i Index of the map to use to define the row space - * \param[in] j Index of the map to use to define the columns space - * \param[in] A Source CRS matrix - * \param[in] subMaps Vector of maps created by the buildSubMap routine. - * \param[in,out] mat Destination matrix with a fixed nonzero pattern. Most likely - * this operator would come from the buildSubBlock routine. - */ -void rebuildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector & subMaps,Epetra_CrsMatrix & mat); - -} // end Blocking -} // end Epetra -} // end Teko + * a CRS matrix. The first of map in the ith pair describes the rows to be extracted, + * while the second pair defines GID numbering of the new block. Similarly with the + * jth pair (except for columns). This "refills" an operator already created by + * buildSubBlock. This only replaces the sparsity pattern of the matrix. + * + * \param[in] i Index of the map to use to define the row space + * \param[in] j Index of the map to use to define the columns space + * \param[in] A Source CRS matrix + * \param[in] subMaps Vector of maps created by the buildSubMap routine. + * \param[in,out] mat Destination matrix with a fixed nonzero pattern. Most likely + * this operator would come from the buildSubBlock routine. + */ +void rebuildSubBlock(int i, int j, const Epetra_CrsMatrix &A, const std::vector &subMaps, + Epetra_CrsMatrix &mat); + +} // namespace Blocking +} // namespace Epetra +} // namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_EpetraBlockPreconditioner.cpp b/packages/teko/src/Epetra/Teko_EpetraBlockPreconditioner.cpp index 81e08a20a8d9..aaed023e2d95 100644 --- a/packages/teko/src/Epetra/Teko_EpetraBlockPreconditioner.cpp +++ b/packages/teko/src/Epetra/Teko_EpetraBlockPreconditioner.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -62,282 +62,279 @@ namespace Epetra { using Teuchos::RCP; using Teuchos::rcp; -using Teuchos::rcpFromRef; using Teuchos::rcp_dynamic_cast; +using Teuchos::rcpFromRef; /** \brief Constructor that takes the BlockPreconditionerFactory that will - * build the preconditioner. - * - * Constructor that takes the BlockPreconditionerFactory that will - * build the preconditioner. - */ -EpetraBlockPreconditioner::EpetraBlockPreconditioner(const Teuchos::RCP & bfp) - : preconFactory_(bfp), firstBuildComplete_(false) -{ -} - -void EpetraBlockPreconditioner::initPreconditioner(bool clearOld) -{ - if((not clearOld) && preconObj_!=Teuchos::null) - return; - preconObj_ = preconFactory_->createPrec(); + * build the preconditioner. + * + * Constructor that takes the BlockPreconditionerFactory that will + * build the preconditioner. + */ +EpetraBlockPreconditioner::EpetraBlockPreconditioner( + const Teuchos::RCP& bfp) + : preconFactory_(bfp), firstBuildComplete_(false) {} + +void EpetraBlockPreconditioner::initPreconditioner(bool clearOld) { + if ((not clearOld) && preconObj_ != Teuchos::null) return; + preconObj_ = preconFactory_->createPrec(); } -/** \brief Build this preconditioner from an Epetra_Operator - * passed in to this object. It is assume that this Epetra_Operator - * - * Build this preconditioner from an Epetra_Operator - * passed in to this object. It is assume that this Epetra_Operator - * will be a EpetraOperatorWrapper object, so the block Thyra components - * can be easily extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - * - * \note This will clear any internal state stored by the state object - */ -void EpetraBlockPreconditioner::buildPreconditioner(const Teuchos::RCP & A,bool clear) -{ - Teko_DEBUG_SCOPE("EBP::buildPreconditioner",10); - - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - RCP > thyraA = extractLinearOp(A); - - // set the mapping strategy - // SetMapStrategy(rcp(new InverseMappingStrategy(eow->getMapStrategy()))); - SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A)))); - - // build preconObj_ - initPreconditioner(clear); - - // actually build the preconditioner - RCP > lOpSrc = Thyra::defaultLinearOpSource(thyraA); - preconFactory_->initializePrec(lOpSrc,&*preconObj_,Thyra::SUPPORT_SOLVE_UNSPECIFIED); - - // extract preconditioner operator - RCP > preconditioner = preconObj_->getUnspecifiedPrecOp(); - - SetOperator(preconditioner,false); - - firstBuildComplete_ = true; - - TEUCHOS_ASSERT(preconObj_!=Teuchos::null); - TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null); - TEUCHOS_ASSERT(getMapStrategy()!=Teuchos::null); - TEUCHOS_ASSERT(firstBuildComplete_==true); +/** \brief Build this preconditioner from an Epetra_Operator + * passed in to this object. It is assume that this Epetra_Operator + * + * Build this preconditioner from an Epetra_Operator + * passed in to this object. It is assume that this Epetra_Operator + * will be a EpetraOperatorWrapper object, so the block Thyra components + * can be easily extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + * + * \note This will clear any internal state stored by the state object + */ +void EpetraBlockPreconditioner::buildPreconditioner(const Teuchos::RCP& A, + bool clear) { + Teko_DEBUG_SCOPE("EBP::buildPreconditioner", 10); + + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + RCP > thyraA = extractLinearOp(A); + + // set the mapping strategy + // SetMapStrategy(rcp(new InverseMappingStrategy(eow->getMapStrategy()))); + SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A)))); + + // build preconObj_ + initPreconditioner(clear); + + // actually build the preconditioner + RCP > lOpSrc = Thyra::defaultLinearOpSource(thyraA); + preconFactory_->initializePrec(lOpSrc, &*preconObj_, Thyra::SUPPORT_SOLVE_UNSPECIFIED); + + // extract preconditioner operator + RCP > preconditioner = preconObj_->getUnspecifiedPrecOp(); + + SetOperator(preconditioner, false); + + firstBuildComplete_ = true; + + TEUCHOS_ASSERT(preconObj_ != Teuchos::null); + TEUCHOS_ASSERT(getThyraOp() != Teuchos::null); + TEUCHOS_ASSERT(getMapStrategy() != Teuchos::null); + TEUCHOS_ASSERT(firstBuildComplete_ == true); } -/** \brief Build this preconditioner from an Epetra_Operator - * passed in to this object. It is assume that this Epetra_Operator - * - * Build this preconditioner from an Epetra_Operator - * passed in to this object. It is assume that this Epetra_Operator - * will be a EpetraOperatorWrapper object, so the block Thyra components - * can be easily extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - * \param[in] src A vector that was used to build the source operator. - * - * \note This will clear any internal state stored by the state object - */ -void EpetraBlockPreconditioner::buildPreconditioner(const Teuchos::RCP & A,const Epetra_MultiVector & epetra_mv,bool clear) -{ - Teko_DEBUG_SCOPE("EBP::buildPreconditioner - with solution",10); - - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - RCP > thyraA = extractLinearOp(A); - - // set the mapping strategy - SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A)))); - - TEUCHOS_ASSERT(getMapStrategy()!=Teuchos::null); - - // build the thyra version of the source multivector - RCP > thyra_mv = Thyra::createMembers(thyraA->range(),epetra_mv.NumVectors()); - getMapStrategy()->copyEpetraIntoThyra(epetra_mv,thyra_mv.ptr()); - - // build preconObj_ - initPreconditioner(clear); - - // actually build the preconditioner - preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA),thyra_mv,&*preconObj_,Thyra::SUPPORT_SOLVE_UNSPECIFIED); - RCP > preconditioner = preconObj_->getUnspecifiedPrecOp(); - - SetOperator(preconditioner,false); - - firstBuildComplete_ = true; - - TEUCHOS_ASSERT(preconObj_!=Teuchos::null); - TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null); - TEUCHOS_ASSERT(getMapStrategy()!=Teuchos::null); - TEUCHOS_ASSERT(firstBuildComplete_==true); +/** \brief Build this preconditioner from an Epetra_Operator + * passed in to this object. It is assume that this Epetra_Operator + * + * Build this preconditioner from an Epetra_Operator + * passed in to this object. It is assume that this Epetra_Operator + * will be a EpetraOperatorWrapper object, so the block Thyra components + * can be easily extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + * \param[in] src A vector that was used to build the source operator. + * + * \note This will clear any internal state stored by the state object + */ +void EpetraBlockPreconditioner::buildPreconditioner(const Teuchos::RCP& A, + const Epetra_MultiVector& epetra_mv, + bool clear) { + Teko_DEBUG_SCOPE("EBP::buildPreconditioner - with solution", 10); + + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + RCP > thyraA = extractLinearOp(A); + + // set the mapping strategy + SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A)))); + + TEUCHOS_ASSERT(getMapStrategy() != Teuchos::null); + + // build the thyra version of the source multivector + RCP > thyra_mv = + Thyra::createMembers(thyraA->range(), epetra_mv.NumVectors()); + getMapStrategy()->copyEpetraIntoThyra(epetra_mv, thyra_mv.ptr()); + + // build preconObj_ + initPreconditioner(clear); + + // actually build the preconditioner + preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA), thyra_mv, &*preconObj_, + Thyra::SUPPORT_SOLVE_UNSPECIFIED); + RCP > preconditioner = preconObj_->getUnspecifiedPrecOp(); + + SetOperator(preconditioner, false); + + firstBuildComplete_ = true; + + TEUCHOS_ASSERT(preconObj_ != Teuchos::null); + TEUCHOS_ASSERT(getThyraOp() != Teuchos::null); + TEUCHOS_ASSERT(getMapStrategy() != Teuchos::null); + TEUCHOS_ASSERT(firstBuildComplete_ == true); } /** \brief Rebuild this preconditioner from an Epetra_Operator passed - * in this to object. - * - * Rebuild this preconditioner from an Epetra_Operator passed - * in this to object. If buildPreconditioner has not been called - * the preconditioner will be built instead. Otherwise efforts are taken - * to only rebuild what is neccessary. Also, it is assumed that this Epetra_Operator - * will be an EpetraOperatorWrapper object, so the block Thyra components - * can be easily extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - * \param[in] mv A vector that was used to build the source operator. - */ -void EpetraBlockPreconditioner::rebuildPreconditioner(const Teuchos::RCP & A) -{ - Teko_DEBUG_SCOPE("EBP::rebuildPreconditioner",10); - - // if the preconditioner hasn't been built yet, rebuild from scratch - if(not firstBuildComplete_) { - buildPreconditioner(A,false); - return; - } - Teko_DEBUG_EXPR(Teuchos::Time timer("")); - - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - Teko_DEBUG_EXPR(timer.start(true)); - RCP > thyraA = extractLinearOp(A); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("EBP::rebuild get thyraop time = " << timer.totalElapsedTime(),2); - - // reinitialize the preconditioner - Teko_DEBUG_EXPR(timer.start(true)); - preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA),&*preconObj_,Thyra::SUPPORT_SOLVE_UNSPECIFIED); - RCP > preconditioner = preconObj_->getUnspecifiedPrecOp(); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("EBP::rebuild initialize prec time = " << timer.totalElapsedTime(),2); - - Teko_DEBUG_EXPR(timer.start(true)); - SetOperator(preconditioner,false); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("EBP::rebuild set operator time = " << timer.totalElapsedTime(),2); - - TEUCHOS_ASSERT(preconObj_!=Teuchos::null); - TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null); - TEUCHOS_ASSERT(firstBuildComplete_==true); + * in this to object. + * + * Rebuild this preconditioner from an Epetra_Operator passed + * in this to object. If buildPreconditioner has not been called + * the preconditioner will be built instead. Otherwise efforts are taken + * to only rebuild what is neccessary. Also, it is assumed that this Epetra_Operator + * will be an EpetraOperatorWrapper object, so the block Thyra components + * can be easily extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + * \param[in] mv A vector that was used to build the source operator. + */ +void EpetraBlockPreconditioner::rebuildPreconditioner( + const Teuchos::RCP& A) { + Teko_DEBUG_SCOPE("EBP::rebuildPreconditioner", 10); + + // if the preconditioner hasn't been built yet, rebuild from scratch + if (not firstBuildComplete_) { + buildPreconditioner(A, false); + return; + } + Teko_DEBUG_EXPR(Teuchos::Time timer("")); + + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + Teko_DEBUG_EXPR(timer.start(true)); + RCP > thyraA = extractLinearOp(A); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("EBP::rebuild get thyraop time = " << timer.totalElapsedTime(), 2); + + // reinitialize the preconditioner + Teko_DEBUG_EXPR(timer.start(true)); + preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA), &*preconObj_, + Thyra::SUPPORT_SOLVE_UNSPECIFIED); + RCP > preconditioner = preconObj_->getUnspecifiedPrecOp(); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("EBP::rebuild initialize prec time = " << timer.totalElapsedTime(), 2); + + Teko_DEBUG_EXPR(timer.start(true)); + SetOperator(preconditioner, false); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("EBP::rebuild set operator time = " << timer.totalElapsedTime(), 2); + + TEUCHOS_ASSERT(preconObj_ != Teuchos::null); + TEUCHOS_ASSERT(getThyraOp() != Teuchos::null); + TEUCHOS_ASSERT(firstBuildComplete_ == true); } /** \brief Rebuild this preconditioner from an Epetra_Operator passed - * in this to object. - * - * Rebuild this preconditioner from an Epetra_Operator passed - * in this to object. If buildPreconditioner has not been called - * the preconditioner will be built instead. Otherwise efforts are taken - * to only rebuild what is neccessary. Also, it is assumed that this Epetra_Operator - * will be an EpetraOperatorWrapper object, so the block Thyra components - * can be easily extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - * \param[in] mv A vector that was used to build the source operator. - */ -void EpetraBlockPreconditioner::rebuildPreconditioner(const Teuchos::RCP & A,const Epetra_MultiVector & epetra_mv) -{ - Teko_DEBUG_SCOPE("EBP::rebuildPreconditioner - with solution",10); - - // if the preconditioner hasn't been built yet, rebuild from scratch - if(not firstBuildComplete_) { - buildPreconditioner(A,epetra_mv,false); - return; - } - Teko_DEBUG_EXPR(Teuchos::Time timer("")); - - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - Teko_DEBUG_EXPR(timer.start(true)); - RCP > thyraA = extractLinearOp(A); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("EBP::rebuild get thyraop time = " << timer.totalElapsedTime(),2); - - // build the thyra version of the source multivector - Teko_DEBUG_EXPR(timer.start(true)); - RCP > thyra_mv = Thyra::createMembers(thyraA->range(),epetra_mv.NumVectors()); - getMapStrategy()->copyEpetraIntoThyra(epetra_mv,thyra_mv.ptr()); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("EBP::rebuild vector copy time = " << timer.totalElapsedTime(),2); - - // reinitialize the preconditioner - Teko_DEBUG_EXPR(timer.start(true)); - preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA),thyra_mv,&*preconObj_,Thyra::SUPPORT_SOLVE_UNSPECIFIED); - RCP > preconditioner = preconObj_->getUnspecifiedPrecOp(); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("EBP::rebuild initialize prec time = " << timer.totalElapsedTime(),2); - - Teko_DEBUG_EXPR(timer.start(true)); - SetOperator(preconditioner,false); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("EBP::rebuild set operator time = " << timer.totalElapsedTime(),2); - - TEUCHOS_ASSERT(preconObj_!=Teuchos::null); - TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null); - TEUCHOS_ASSERT(firstBuildComplete_==true); + * in this to object. + * + * Rebuild this preconditioner from an Epetra_Operator passed + * in this to object. If buildPreconditioner has not been called + * the preconditioner will be built instead. Otherwise efforts are taken + * to only rebuild what is neccessary. Also, it is assumed that this Epetra_Operator + * will be an EpetraOperatorWrapper object, so the block Thyra components + * can be easily extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + * \param[in] mv A vector that was used to build the source operator. + */ +void EpetraBlockPreconditioner::rebuildPreconditioner(const Teuchos::RCP& A, + const Epetra_MultiVector& epetra_mv) { + Teko_DEBUG_SCOPE("EBP::rebuildPreconditioner - with solution", 10); + + // if the preconditioner hasn't been built yet, rebuild from scratch + if (not firstBuildComplete_) { + buildPreconditioner(A, epetra_mv, false); + return; + } + Teko_DEBUG_EXPR(Teuchos::Time timer("")); + + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + Teko_DEBUG_EXPR(timer.start(true)); + RCP > thyraA = extractLinearOp(A); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("EBP::rebuild get thyraop time = " << timer.totalElapsedTime(), 2); + + // build the thyra version of the source multivector + Teko_DEBUG_EXPR(timer.start(true)); + RCP > thyra_mv = + Thyra::createMembers(thyraA->range(), epetra_mv.NumVectors()); + getMapStrategy()->copyEpetraIntoThyra(epetra_mv, thyra_mv.ptr()); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("EBP::rebuild vector copy time = " << timer.totalElapsedTime(), 2); + + // reinitialize the preconditioner + Teko_DEBUG_EXPR(timer.start(true)); + preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA), thyra_mv, &*preconObj_, + Thyra::SUPPORT_SOLVE_UNSPECIFIED); + RCP > preconditioner = preconObj_->getUnspecifiedPrecOp(); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("EBP::rebuild initialize prec time = " << timer.totalElapsedTime(), 2); + + Teko_DEBUG_EXPR(timer.start(true)); + SetOperator(preconditioner, false); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("EBP::rebuild set operator time = " << timer.totalElapsedTime(), 2); + + TEUCHOS_ASSERT(preconObj_ != Teuchos::null); + TEUCHOS_ASSERT(getThyraOp() != Teuchos::null); + TEUCHOS_ASSERT(firstBuildComplete_ == true); } /** Try to get a Teko::PreconditionerState object. This method - * attempts to cast its internal representation of a preconditioner - * object to a Teko::BlockPreconditioner object. If it suceeds a - * state object is returned. Otherwise, Teuchos::null is returned. - * - * \returns Get the state object associated with this preconditioner. - * If it doesn't exist for this type of preconditioner factory - * this method returns null. - */ -Teuchos::RCP EpetraBlockPreconditioner::getPreconditionerState() -{ - Teuchos::RCP bp = rcp_dynamic_cast(preconObj_); - - if(bp!=Teuchos::null) - return bp->getStateObject(); - - return Teuchos::null; + * attempts to cast its internal representation of a preconditioner + * object to a Teko::BlockPreconditioner object. If it suceeds a + * state object is returned. Otherwise, Teuchos::null is returned. + * + * \returns Get the state object associated with this preconditioner. + * If it doesn't exist for this type of preconditioner factory + * this method returns null. + */ +Teuchos::RCP EpetraBlockPreconditioner::getPreconditionerState() { + Teuchos::RCP bp = rcp_dynamic_cast(preconObj_); + + if (bp != Teuchos::null) return bp->getStateObject(); + + return Teuchos::null; } /** Try to get a Teko::PreconditionerState object. This method - * attempts to cast its internal representation of a preconditioner - * object to a Teko::Preconditioner object. If it suceeds a - * state object is returned. Otherwise, Teuchos::null is returned. - * - * \returns Get the state object associated with this preconditioner. - * If it doesn't exist for this type of preconditioner factory - * this method returns null. - */ -Teuchos::RCP EpetraBlockPreconditioner::getPreconditionerState() const -{ - Teuchos::RCP bp = rcp_dynamic_cast(preconObj_); - - if(bp!=Teuchos::null) - return bp->getStateObject(); - - return Teuchos::null; + * attempts to cast its internal representation of a preconditioner + * object to a Teko::Preconditioner object. If it suceeds a + * state object is returned. Otherwise, Teuchos::null is returned. + * + * \returns Get the state object associated with this preconditioner. + * If it doesn't exist for this type of preconditioner factory + * this method returns null. + */ +Teuchos::RCP EpetraBlockPreconditioner::getPreconditionerState() const { + Teuchos::RCP bp = rcp_dynamic_cast(preconObj_); + + if (bp != Teuchos::null) return bp->getStateObject(); + + return Teuchos::null; } -Teuchos::RCP > EpetraBlockPreconditioner::extractLinearOp(const Teuchos::RCP & A) const -{ - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - const RCP & eow = rcp_dynamic_cast(A); - - // if it is an EpetraOperatorWrapper, then get the Thyra operator - if(eow!=Teuchos::null) - return eow->getThyraOp(); - - // otherwise wrap it up as a thyra operator - return Thyra::epetraLinearOp(A); +Teuchos::RCP > EpetraBlockPreconditioner::extractLinearOp( + const Teuchos::RCP& A) const { + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + const RCP& eow = rcp_dynamic_cast(A); + + // if it is an EpetraOperatorWrapper, then get the Thyra operator + if (eow != Teuchos::null) return eow->getThyraOp(); + + // otherwise wrap it up as a thyra operator + return Thyra::epetraLinearOp(A); } -Teuchos::RCP EpetraBlockPreconditioner::extractMappingStrategy(const Teuchos::RCP & A) const -{ - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - const RCP & eow = rcp_dynamic_cast(A); - - // if it is an EpetraOperatorWrapper, then get the Thyra operator - if(eow!=Teuchos::null) - return eow->getMapStrategy(); - - // otherwise wrap it up as a thyra operator - RCP range = rcpFromRef(A->OperatorRangeMap()); - RCP domain = rcpFromRef(A->OperatorDomainMap()); - return rcp(new BasicMappingStrategy(range,domain,A->Comm())); +Teuchos::RCP EpetraBlockPreconditioner::extractMappingStrategy( + const Teuchos::RCP& A) const { + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + const RCP& eow = rcp_dynamic_cast(A); + + // if it is an EpetraOperatorWrapper, then get the Thyra operator + if (eow != Teuchos::null) return eow->getMapStrategy(); + + // otherwise wrap it up as a thyra operator + RCP range = rcpFromRef(A->OperatorRangeMap()); + RCP domain = rcpFromRef(A->OperatorDomainMap()); + return rcp(new BasicMappingStrategy(range, domain, A->Comm())); } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_EpetraBlockPreconditioner.hpp b/packages/teko/src/Epetra/Teko_EpetraBlockPreconditioner.hpp index 7cd44a74d576..57c3174585a2 100644 --- a/packages/teko/src/Epetra/Teko_EpetraBlockPreconditioner.hpp +++ b/packages/teko/src/Epetra/Teko_EpetraBlockPreconditioner.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -55,134 +55,138 @@ namespace Teko { namespace Epetra { /** \brief A single Epetra wrapper for all the BlockPreconditioners. - * - * This class uses the Thyra based preconditioner factories to - * build an Epetra_Operator that behaves like a preconditioner. - * This is done by using the BlockPreconditionerFactory, and letting - * it build whatever preconditioner is neccessary. Thus the Epetra - * "layer" is just a single class that handles any generic - * BlockPreconditionerFactory. - */ + * + * This class uses the Thyra based preconditioner factories to + * build an Epetra_Operator that behaves like a preconditioner. + * This is done by using the BlockPreconditionerFactory, and letting + * it build whatever preconditioner is neccessary. Thus the Epetra + * "layer" is just a single class that handles any generic + * BlockPreconditionerFactory. + */ class EpetraBlockPreconditioner : public EpetraInverseOpWrapper { -public: - /** \brief Constructor that takes the BlockPreconditionerFactory that will - * build the preconditioner. - * - * Constructor that takes the BlockPreconditionerFactory that will - * build the preconditioner. - */ - EpetraBlockPreconditioner(const Teuchos::RCP & bfp); - - /** \brief Build the underlying data structure for the preconditioner. - * - * Build the underlying data structure for the preconditioner. This - * permits the manipulation of the state object for a preconditioner. - * and is useful in that case some extra data needs to fill the - * preconditioner state. - * - * \param[in] clearOld If true any previously constructed - * preconditioner will be wiped out and - * a new one created. If false, a preconditioner - * will be create only if the current one is - * empty (i.e. initPreconditioner - * had not been called). - */ - virtual void initPreconditioner(bool clearOld=false); - - /** \brief Build this preconditioner from an Epetra_Operator - * passed in to this object. - * - * Build this preconditioner from an Epetra_Operator - * passed in to this object. It is assumed that this Epetra_Operator - * will be a EpetraOperatorWrapper object, so the block Thyra components - * can be easily extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - * \param[in] clear If true, than any previous state saved by the preconditioner - * is discarded. - */ - virtual void buildPreconditioner(const Teuchos::RCP & A,bool clear=true); - - /** \brief Build this preconditioner from an Epetra_Operator - * passed in to this object. It is assumed that this Epetra_Operator - * - * Build this preconditioner from an Epetra_Operator - * passed in to this object. It is assumed that this Epetra_Operator - * will be a EpetraOperatorWrapper object, so the block Thyra components - * can be easily extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - * \param[in] mv A vector that was used to build the source operator. - * \param[in] clear If true, than any previous state saved by the preconditioner - * is discarded. - */ - virtual void buildPreconditioner(const Teuchos::RCP & A,const Epetra_MultiVector & mv,bool clear=true); - - /** \brief Rebuild this preconditioner from an Epetra_Operator passed - * in this to object. - * - * Rebuild this preconditioner from an Epetra_Operator passed - * in this to object. If buildPreconditioner has not been called - * the preconditioner will be built instead. Otherwise efforts are taken - * to only rebuild what is neccessary. Also, it is assumed that this Epetra_Operator - * will be an EpetraOperatorWrapper object, so the block Thyra components - * can be easily extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - */ - virtual void rebuildPreconditioner(const Teuchos::RCP & A); - - /** \brief Rebuild this preconditioner from an Epetra_Operator passed - * in this to object. - * - * Rebuild this preconditioner from an Epetra_Operator passed - * in this to object. If buildPreconditioner has not been called - * the preconditioner will be built instead. Otherwise efforts are taken - * to only rebuild what is neccessary. Also, it is assumed that this Epetra_Operator - * will be an EpetraOperatorWrapper object, so the block Thyra components - * can be easily extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - * \param[in] mv A vector that was used to build the source operator. - */ - virtual void rebuildPreconditioner(const Teuchos::RCP & A,const Epetra_MultiVector & mv); - - /** Try to get a Teko::PreconditionerState object. This method - * attempts to cast its internal representation of a preconditioner - * object to a Teko::BlockPreconditioner object. If it suceeds a - * state object is returned. Otherwise, Teuchos::null is returned. - * - * \returns Get the state object associated with this preconditioner. - * If it doesn't exist for this type of preconditioner factory - * this method returns null. - */ - virtual Teuchos::RCP getPreconditionerState(); - - /** Try to get a Teko::PreconditionerState object. This method - * attempts to cast its internal representation of a preconditioner - * object to a Teko::BlockPreconditioner object. If it suceeds a - * state object is returned. Otherwise, Teuchos::null is returned. - * - * \returns Get the state object associated with this preconditioner. - * If it doesn't exist for this type of preconditioner factory - * this method returns null. - */ - virtual Teuchos::RCP getPreconditionerState() const; - -protected: - Teuchos::RCP > extractLinearOp(const Teuchos::RCP & A) const; - Teuchos::RCP extractMappingStrategy(const Teuchos::RCP & A) const; - - EpetraBlockPreconditioner(); - EpetraBlockPreconditioner(const EpetraBlockPreconditioner &); - - // Teuchos::RCP preconFactory_; - Teuchos::RCP preconFactory_; - Teuchos::RCP > preconObj_; - bool firstBuildComplete_; + public: + /** \brief Constructor that takes the BlockPreconditionerFactory that will + * build the preconditioner. + * + * Constructor that takes the BlockPreconditionerFactory that will + * build the preconditioner. + */ + EpetraBlockPreconditioner(const Teuchos::RCP &bfp); + + /** \brief Build the underlying data structure for the preconditioner. + * + * Build the underlying data structure for the preconditioner. This + * permits the manipulation of the state object for a preconditioner. + * and is useful in that case some extra data needs to fill the + * preconditioner state. + * + * \param[in] clearOld If true any previously constructed + * preconditioner will be wiped out and + * a new one created. If false, a preconditioner + * will be create only if the current one is + * empty (i.e. initPreconditioner + * had not been called). + */ + virtual void initPreconditioner(bool clearOld = false); + + /** \brief Build this preconditioner from an Epetra_Operator + * passed in to this object. + * + * Build this preconditioner from an Epetra_Operator + * passed in to this object. It is assumed that this Epetra_Operator + * will be a EpetraOperatorWrapper object, so the block Thyra components + * can be easily extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + * \param[in] clear If true, than any previous state saved by the preconditioner + * is discarded. + */ + virtual void buildPreconditioner(const Teuchos::RCP &A, bool clear = true); + + /** \brief Build this preconditioner from an Epetra_Operator + * passed in to this object. It is assumed that this Epetra_Operator + * + * Build this preconditioner from an Epetra_Operator + * passed in to this object. It is assumed that this Epetra_Operator + * will be a EpetraOperatorWrapper object, so the block Thyra components + * can be easily extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + * \param[in] mv A vector that was used to build the source operator. + * \param[in] clear If true, than any previous state saved by the preconditioner + * is discarded. + */ + virtual void buildPreconditioner(const Teuchos::RCP &A, + const Epetra_MultiVector &mv, bool clear = true); + + /** \brief Rebuild this preconditioner from an Epetra_Operator passed + * in this to object. + * + * Rebuild this preconditioner from an Epetra_Operator passed + * in this to object. If buildPreconditioner has not been called + * the preconditioner will be built instead. Otherwise efforts are taken + * to only rebuild what is neccessary. Also, it is assumed that this Epetra_Operator + * will be an EpetraOperatorWrapper object, so the block Thyra components + * can be easily extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + */ + virtual void rebuildPreconditioner(const Teuchos::RCP &A); + + /** \brief Rebuild this preconditioner from an Epetra_Operator passed + * in this to object. + * + * Rebuild this preconditioner from an Epetra_Operator passed + * in this to object. If buildPreconditioner has not been called + * the preconditioner will be built instead. Otherwise efforts are taken + * to only rebuild what is neccessary. Also, it is assumed that this Epetra_Operator + * will be an EpetraOperatorWrapper object, so the block Thyra components + * can be easily extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + * \param[in] mv A vector that was used to build the source operator. + */ + virtual void rebuildPreconditioner(const Teuchos::RCP &A, + const Epetra_MultiVector &mv); + + /** Try to get a Teko::PreconditionerState object. This method + * attempts to cast its internal representation of a preconditioner + * object to a Teko::BlockPreconditioner object. If it suceeds a + * state object is returned. Otherwise, Teuchos::null is returned. + * + * \returns Get the state object associated with this preconditioner. + * If it doesn't exist for this type of preconditioner factory + * this method returns null. + */ + virtual Teuchos::RCP getPreconditionerState(); + + /** Try to get a Teko::PreconditionerState object. This method + * attempts to cast its internal representation of a preconditioner + * object to a Teko::BlockPreconditioner object. If it suceeds a + * state object is returned. Otherwise, Teuchos::null is returned. + * + * \returns Get the state object associated with this preconditioner. + * If it doesn't exist for this type of preconditioner factory + * this method returns null. + */ + virtual Teuchos::RCP getPreconditionerState() const; + + protected: + Teuchos::RCP > extractLinearOp( + const Teuchos::RCP &A) const; + Teuchos::RCP extractMappingStrategy( + const Teuchos::RCP &A) const; + + EpetraBlockPreconditioner(); + EpetraBlockPreconditioner(const EpetraBlockPreconditioner &); + + // Teuchos::RCP preconFactory_; + Teuchos::RCP preconFactory_; + Teuchos::RCP > preconObj_; + bool firstBuildComplete_; }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_EpetraHelpers.cpp b/packages/teko/src/Epetra/Teko_EpetraHelpers.cpp index d11fd021d297..acd75d1314c2 100644 --- a/packages/teko/src/Epetra/Teko_EpetraHelpers.cpp +++ b/packages/teko/src/Epetra/Teko_EpetraHelpers.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -69,189 +69,184 @@ #include "Teko_EpetraOperatorWrapper.hpp" #include "Teko_Utilities.hpp" +using Teuchos::null; using Teuchos::RCP; using Teuchos::rcp; -using Teuchos::rcpFromRef; using Teuchos::rcp_dynamic_cast; -using Teuchos::null; +using Teuchos::rcpFromRef; namespace Teko { namespace Epetra { /** \brief Convert an Epetra_Vector into a diagonal linear operator. - * - * Convert an Epetra_Vector into a diagonal linear operator. - * - * \param[in] ev Epetra_Vector to use as the diagonal - * \param[in] map Map related to the Epetra_Vector - * \param[in] lbl String to easily label the operator - * - * \returns A diagonal linear operator using the vector - */ -const Teuchos::RCP > thyraDiagOp(const RCP & ev,const Epetra_Map & map, - const std::string & lbl) -{ - const RCP > thyraVec // need a Thyra::VectorBase object - = Thyra::create_Vector(ev,Thyra::create_VectorSpace(rcpFromRef(map))); - Teuchos::RCP > op - = Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp(thyraVec)); - op->setObjectLabel(lbl); - return op; + * + * Convert an Epetra_Vector into a diagonal linear operator. + * + * \param[in] ev Epetra_Vector to use as the diagonal + * \param[in] map Map related to the Epetra_Vector + * \param[in] lbl String to easily label the operator + * + * \returns A diagonal linear operator using the vector + */ +const Teuchos::RCP > thyraDiagOp( + const RCP& ev, const Epetra_Map& map, const std::string& lbl) { + const RCP > thyraVec // need a Thyra::VectorBase object + = Thyra::create_Vector(ev, Thyra::create_VectorSpace(rcpFromRef(map))); + Teuchos::RCP > op = + Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp(thyraVec)); + op->setObjectLabel(lbl); + return op; } /** \brief Convert an Epetra_Vector into a diagonal linear operator. - * - * Convert an Epetra_Vector into a diagonal linear operator. - * - * \param[in] ev Epetra_Vector to use as the diagonal - * \param[in] map Map related to the Epetra_Vector - * \param[in] lbl String to easily label the operator - * - * \returns A diagonal linear operator using the vector - */ -const Teuchos::RCP > thyraDiagOp(const RCP & ev,const Epetra_Map & map, - const std::string & lbl) -{ - const RCP > thyraVec // need a Thyra::VectorBase object - = Thyra::create_Vector(ev,Thyra::create_VectorSpace(rcpFromRef(map))); - Teuchos::RCP > op - = Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp(thyraVec)); - op->setObjectLabel(lbl); - return op; + * + * Convert an Epetra_Vector into a diagonal linear operator. + * + * \param[in] ev Epetra_Vector to use as the diagonal + * \param[in] map Map related to the Epetra_Vector + * \param[in] lbl String to easily label the operator + * + * \returns A diagonal linear operator using the vector + */ +const Teuchos::RCP > thyraDiagOp(const RCP& ev, + const Epetra_Map& map, + const std::string& lbl) { + const RCP > thyraVec // need a Thyra::VectorBase object + = Thyra::create_Vector(ev, Thyra::create_VectorSpace(rcpFromRef(map))); + Teuchos::RCP > op = + Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp(thyraVec)); + op->setObjectLabel(lbl); + return op; } /** \brief Fill a Thyra vector with the contents of an epetra vector. This prevents the - * - * Fill a Thyra vector with the contents of an epetra vector. This prevents the need - * to reallocate memory using a create_MultiVector routine. It also allows an aritrary - * Thyra vector to be filled. - * - * \param[in,out] spmdMV Multi-vector to be filled. - * \param[in] mv Epetra multi-vector to be used in filling the Thyra vector. - */ -void fillDefaultSpmdMultiVector(Teuchos::RCP > & spmdMV, - Teuchos::RCP & epetraMV) -{ - // first get desired range and domain - const RCP > range = spmdMV->spmdSpace(); - const RCP > domain - = rcp_dynamic_cast >(spmdMV->domain()); - - TEUCHOS_ASSERT(domain->dim()==epetraMV->NumVectors()); - - // New local view of raw data - double *localValues; int leadingDim; - if(epetraMV->ConstantStride() ) - epetraMV->ExtractView( &localValues, &leadingDim ); - else - TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement views of non-contiguous mult-vectors! - - // Build the MultiVector - spmdMV->initialize(range, domain, - Teuchos::arcp(localValues,0,leadingDim*epetraMV->NumVectors(),false), + * + * Fill a Thyra vector with the contents of an epetra vector. This prevents the need + * to reallocate memory using a create_MultiVector routine. It also allows an aritrary + * Thyra vector to be filled. + * + * \param[in,out] spmdMV Multi-vector to be filled. + * \param[in] mv Epetra multi-vector to be used in filling the Thyra vector. + */ +void fillDefaultSpmdMultiVector(Teuchos::RCP >& spmdMV, + Teuchos::RCP& epetraMV) { + // first get desired range and domain + const RCP > range = spmdMV->spmdSpace(); + const RCP > domain = + rcp_dynamic_cast >(spmdMV->domain()); + + TEUCHOS_ASSERT(domain->dim() == epetraMV->NumVectors()); + + // New local view of raw data + double* localValues; + int leadingDim; + if (epetraMV->ConstantStride()) + epetraMV->ExtractView(&localValues, &leadingDim); + else + TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement views of non-contiguous mult-vectors! + + // Build the MultiVector + spmdMV->initialize(range, domain, + Teuchos::arcp(localValues, 0, leadingDim * epetraMV->NumVectors(), false), leadingDim); - // make sure the Epetra_MultiVector doesn't disappear prematurely - Teuchos::set_extra_data >(epetraMV,"Epetra_MultiVector",Teuchos::outArg(spmdMV)); + // make sure the Epetra_MultiVector doesn't disappear prematurely + Teuchos::set_extra_data >(epetraMV, "Epetra_MultiVector", + Teuchos::outArg(spmdMV)); } -/** \brief Build a vector of the dirchlet row indices. - * - * Build a vector of the dirchlet row indices. That is, record the global - * index of any row that is all zeros except for $1$ on the diagonal. - * - * \param[in] rowMap Map specifying which global indices this process examines - * \param[in] mat Matrix to be examined - * \param[in,out] indices Output list of indices corresponding to dirchlet rows (GIDs). - */ -void identityRowIndices(const Epetra_Map & rowMap, const Epetra_CrsMatrix & mat,std::vector & outIndices) -{ - int maxSz = mat.GlobalMaxNumEntries(); - std::vector values(maxSz); - std::vector indices(maxSz); - - // loop over elements owned by this processor - for(int i=0;i& outIndices) { + int maxSz = mat.GlobalMaxNumEntries(); + std::vector values(maxSz); + std::vector indices(maxSz); + + // loop over elements owned by this processor + for (int i = 0; i < rowMap.NumMyElements(); i++) { + bool rowIsIdentity = true; + int sz = 0; + int rowGID = rowMap.GID(i); + mat.ExtractGlobalRowCopy(rowGID, maxSz, sz, &values[0], &indices[0]); + + // loop over the columns of this row + for (int j = 0; j < sz; j++) { + int colGID = indices[j]; + + // look at row entries + if (colGID == rowGID) + rowIsIdentity &= values[j] == 1.0; + else + rowIsIdentity &= values[j] == 0.0; + + // not a dirchlet row...quit + if (not rowIsIdentity) break; + } + + // save a row that is dirchlet + if (rowIsIdentity) outIndices.push_back(rowGID); + } } /** \brief Zero out the value of a vector on the specified - * set of global indices. - * - * Zero out the value of a vector on the specified set of global - * indices. The indices here are assumed to belong to the calling - * process (i.e. zeroIndices $\in$ mv.Map()). - * - * \param[in,out] mv Vector whose entries will be zeroed - * \param[in] zeroIndices Indices local to this process that need to be zeroed - */ -void zeroMultiVectorRowIndices(Epetra_MultiVector & mv,const std::vector & zeroIndices) -{ - int colCnt = mv.NumVectors(); - std::vector::const_iterator itr; - - // loop over the indices to zero - for(itr=zeroIndices.begin();itr!=zeroIndices.end();++itr) { - - // loop over columns - for(int j=0;j& zeroIndices) { + int colCnt = mv.NumVectors(); + std::vector::const_iterator itr; + + // loop over the indices to zero + for (itr = zeroIndices.begin(); itr != zeroIndices.end(); ++itr) { + // loop over columns + for (int j = 0; j < colCnt; j++) TEUCHOS_TEST_FOR_EXCEPT(mv.ReplaceGlobalValue(*itr, j, 0.0)); + } } /** \brief Constructor for a ZeroedOperator. - * - * Build a ZeroedOperator based on a particular Epetra_Operator and - * a set of indices to zero out. These indices must be local to this - * processor as specified by RowMap(). - * - * \param[in] zeroIndices Set of indices to zero out (must be local). - * \param[in] op Underlying epetra operator to use. - */ -ZeroedOperator::ZeroedOperator(const std::vector & zeroIndices, - const Teuchos::RCP & op) - : zeroIndices_(zeroIndices), epetraOp_(op) -{ - label_ = "zeroed( "+std::string(epetraOp_->Label())+" )"; + * + * Build a ZeroedOperator based on a particular Epetra_Operator and + * a set of indices to zero out. These indices must be local to this + * processor as specified by RowMap(). + * + * \param[in] zeroIndices Set of indices to zero out (must be local). + * \param[in] op Underlying epetra operator to use. + */ +ZeroedOperator::ZeroedOperator(const std::vector& zeroIndices, + const Teuchos::RCP& op) + : zeroIndices_(zeroIndices), epetraOp_(op) { + label_ = "zeroed( " + std::string(epetraOp_->Label()) + " )"; } //! Perform a matrix-vector product with certain rows zeroed out -int ZeroedOperator::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const -{ -/* - Epetra_MultiVector temp(X); - zeroMultiVectorRowIndices(temp,zeroIndices_); - int result = epetraOp_->Apply(temp,Y); -*/ +int ZeroedOperator::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { + /* + Epetra_MultiVector temp(X); + zeroMultiVectorRowIndices(temp,zeroIndices_); + int result = epetraOp_->Apply(temp,Y); + */ - int result = epetraOp_->Apply(X,Y); + int result = epetraOp_->Apply(X, Y); - // zero a few of the rows - zeroMultiVectorRowIndices(Y,zeroIndices_); + // zero a few of the rows + zeroMultiVectorRowIndices(Y, zeroIndices_); - return result; + return result; } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_EpetraHelpers.hpp b/packages/teko/src/Epetra/Teko_EpetraHelpers.hpp index fc1a77c7883b..3f616cdb2ae2 100644 --- a/packages/teko/src/Epetra/Teko_EpetraHelpers.hpp +++ b/packages/teko/src/Epetra/Teko_EpetraHelpers.hpp @@ -67,128 +67,133 @@ namespace Teko { namespace Epetra { /** \brief Fill a Thyra vector with the contents of an epetra vector. This prevents the - * - * Fill a Thyra vector with the contents of an epetra vector. This prevents the need - * to reallocate memory using a create_MultiVector routine. It also allows an aritrary - * Thyra vector to be filled. - * - * \param[in,out] spmdMV Multi-vector to be filled. - * \param[in] epetraMV Epetra multi-vector to be used in filling the Thyra vector. - */ -void fillDefaultSpmdMultiVector(Teuchos::RCP > & spmdMV, - Teuchos::RCP & epetraMV); + * + * Fill a Thyra vector with the contents of an epetra vector. This prevents the need + * to reallocate memory using a create_MultiVector routine. It also allows an aritrary + * Thyra vector to be filled. + * + * \param[in,out] spmdMV Multi-vector to be filled. + * \param[in] epetraMV Epetra multi-vector to be used in filling the Thyra vector. + */ +void fillDefaultSpmdMultiVector(Teuchos::RCP >& spmdMV, + Teuchos::RCP& epetraMV); /** \brief Convert an Epetra_Vector into a diagonal linear operator. - * - * Convert an Epetra_Vector into a diagonal linear operator. - * - * \param[in] ev Epetra_Vector to use as the diagonal - * \param[in] map Map related to the Epetra_Vector - * \param[in] lbl String to easily label the operator - * - * \returns A diagonal linear operator using the vector - */ -const Teuchos::RCP > thyraDiagOp(const Teuchos::RCP & ev, - const Epetra_Map & map,const std::string & lbl="ANYM"); + * + * Convert an Epetra_Vector into a diagonal linear operator. + * + * \param[in] ev Epetra_Vector to use as the diagonal + * \param[in] map Map related to the Epetra_Vector + * \param[in] lbl String to easily label the operator + * + * \returns A diagonal linear operator using the vector + */ +const Teuchos::RCP > thyraDiagOp( + const Teuchos::RCP& ev, const Epetra_Map& map, + const std::string& lbl = "ANYM"); /** \brief Convert an Epetra_Vector into a diagonal linear operator. - * - * Convert an Epetra_Vector into a diagonal linear operator. - * - * \param[in] ev Epetra_Vector to use as the diagonal - * \param[in] map Map related to the Epetra_Vector - * \param[in] lbl String to easily label the operator - * - * \returns A diagonal linear operator using the vector - */ -const Teuchos::RCP > thyraDiagOp(const Teuchos::RCP & ev, - const Epetra_Map & map,const std::string & lbl="ANYM"); + * + * Convert an Epetra_Vector into a diagonal linear operator. + * + * \param[in] ev Epetra_Vector to use as the diagonal + * \param[in] map Map related to the Epetra_Vector + * \param[in] lbl String to easily label the operator + * + * \returns A diagonal linear operator using the vector + */ +const Teuchos::RCP > thyraDiagOp(const Teuchos::RCP& ev, + const Epetra_Map& map, + const std::string& lbl = "ANYM"); /** \brief Build a vector of the dirchlet row indices. - * - * Build a vector of the dirchlet row indices. That is, record the global - * index of any row that is all zeros except for $1$ on the diagonal. - * - * \param[in] rowMap Map specifying which global indices this process examines - * \param[in] mat Matrix to be examined - * \param[in,out] outIndices Output list of indices corresponding to dirchlet rows. - */ -void identityRowIndices(const Epetra_Map & rowMap, const Epetra_CrsMatrix & mat,std::vector & outIndices); + * + * Build a vector of the dirchlet row indices. That is, record the global + * index of any row that is all zeros except for $1$ on the diagonal. + * + * \param[in] rowMap Map specifying which global indices this process examines + * \param[in] mat Matrix to be examined + * \param[in,out] outIndices Output list of indices corresponding to dirchlet rows. + */ +void identityRowIndices(const Epetra_Map& rowMap, const Epetra_CrsMatrix& mat, + std::vector& outIndices); /** \brief Zero out the value of a vector on the specified - * set of global indices. - * - * Zero out the value of a vector on the specified set of global - * indices. The indices here are assumed to belong to the calling - * process (i.e. zeroIndices \f$\in\f$ mv.Map()). - * - * \param[in,out] mv Vector whose entries will be zeroed - * \param[in] zeroIndices Indices local to this process that need to be zeroed - */ -void zeroMultiVectorRowIndices(Epetra_MultiVector & mv,const std::vector & zeroIndices); + * set of global indices. + * + * Zero out the value of a vector on the specified set of global + * indices. The indices here are assumed to belong to the calling + * process (i.e. zeroIndices \f$\in\f$ mv.Map()). + * + * \param[in,out] mv Vector whose entries will be zeroed + * \param[in] zeroIndices Indices local to this process that need to be zeroed + */ +void zeroMultiVectorRowIndices(Epetra_MultiVector& mv, const std::vector& zeroIndices); /** A class that zeros out chosen rows of a matrix-vector - * product. - */ + * product. + */ class ZeroedOperator : public Epetra_Operator { -public: - /** \brief Constructor for a ZeroedOperator. - * - * Build a ZeroedOperator based on a particular Epetra_Operator and - * a set of indices to zero out. These indices must be local to this - * processor as specified by RowMap(). - * - * \param[in] zeroIndices Set of indices to zero out (must be local). - * \param[in] op Underlying epetra operator to use. - */ - ZeroedOperator(const std::vector & zeroIndices,const Teuchos::RCP & op); + public: + /** \brief Constructor for a ZeroedOperator. + * + * Build a ZeroedOperator based on a particular Epetra_Operator and + * a set of indices to zero out. These indices must be local to this + * processor as specified by RowMap(). + * + * \param[in] zeroIndices Set of indices to zero out (must be local). + * \param[in] op Underlying epetra operator to use. + */ + ZeroedOperator(const std::vector& zeroIndices, + const Teuchos::RCP& op); - //! \name Functions required by Epetra_Operator - //@{ + //! \name Functions required by Epetra_Operator + //@{ - //! Do nothing destructor - virtual ~ZeroedOperator() {} + //! Do nothing destructor + virtual ~ZeroedOperator() {} - //! Can't transpose a ZeroedOperator - int SetUseTranspose(bool /* useTranspose */ ) { return -1;} + //! Can't transpose a ZeroedOperator + int SetUseTranspose(bool /* useTranspose */) { return -1; } - //! Perform a matrix-vector product with certain rows zeroed out - int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; + //! Perform a matrix-vector product with certain rows zeroed out + int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; - //! Can't call ApplyInverse on a zeroed operator - int ApplyInverse(const Epetra_MultiVector& /* X */, Epetra_MultiVector& /* Y */) const - { return -1; } + //! Can't call ApplyInverse on a zeroed operator + int ApplyInverse(const Epetra_MultiVector& /* X */, Epetra_MultiVector& /* Y */) const { + return -1; + } - //! - double NormInf() const { return -1.0; } + //! + double NormInf() const { return -1.0; } - //! - const char* Label() const {return label_.c_str();} + //! + const char* Label() const { return label_.c_str(); } - //! - bool UseTranspose() const {return false;} + //! + bool UseTranspose() const { return false; } - //! - bool HasNormInf() const {return false;} + //! + bool HasNormInf() const { return false; } - //! - const Epetra_Comm & Comm() const {return epetraOp_->Comm(); } + //! + const Epetra_Comm& Comm() const { return epetraOp_->Comm(); } - //! - const Epetra_Map& OperatorDomainMap() const {return epetraOp_->OperatorDomainMap(); } + //! + const Epetra_Map& OperatorDomainMap() const { return epetraOp_->OperatorDomainMap(); } - //! - const Epetra_Map& OperatorRangeMap() const {return epetraOp_->OperatorRangeMap(); } + //! + const Epetra_Map& OperatorRangeMap() const { return epetraOp_->OperatorRangeMap(); } - //@} + //@} -protected: - std::vector zeroIndices_; - const Teuchos::RCP epetraOp_; - std::string label_; + protected: + std::vector zeroIndices_; + const Teuchos::RCP epetraOp_; + std::string label_; }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_EpetraInverseOpWrapper.cpp b/packages/teko/src/Epetra/Teko_EpetraInverseOpWrapper.cpp index c0b90240359c..b79fb8900048 100644 --- a/packages/teko/src/Epetra/Teko_EpetraInverseOpWrapper.cpp +++ b/packages/teko/src/Epetra/Teko_EpetraInverseOpWrapper.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -51,11 +51,13 @@ using namespace Teuchos; namespace Teko { namespace Epetra { -int EpetraInverseOpWrapper::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const -{ return EpetraOperatorWrapper::ApplyInverse(X,Y);} +int EpetraInverseOpWrapper::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { + return EpetraOperatorWrapper::ApplyInverse(X, Y); +} -int EpetraInverseOpWrapper::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const -{ return EpetraOperatorWrapper::Apply(X,Y);} +int EpetraInverseOpWrapper::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { + return EpetraOperatorWrapper::Apply(X, Y); +} -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_EpetraInverseOpWrapper.hpp b/packages/teko/src/Epetra/Teko_EpetraInverseOpWrapper.hpp index 2ec2b2806a05..cde71f0eb4a0 100644 --- a/packages/teko/src/Epetra/Teko_EpetraInverseOpWrapper.hpp +++ b/packages/teko/src/Epetra/Teko_EpetraInverseOpWrapper.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -53,29 +53,29 @@ namespace Teko { namespace Epetra { class EpetraInverseOpWrapper : public EpetraOperatorWrapper { -public: - EpetraInverseOpWrapper(const RCP & forwardMaps) - : EpetraOperatorWrapper(forwardMaps) {} + public: + EpetraInverseOpWrapper(const RCP& forwardMaps) + : EpetraOperatorWrapper(forwardMaps) {} - EpetraInverseOpWrapper(const RCP > & thyraOp) - : EpetraOperatorWrapper(thyraOp) {} + EpetraInverseOpWrapper(const RCP >& thyraOp) + : EpetraOperatorWrapper(thyraOp) {} - /** */ - virtual int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; + /** */ + virtual int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; - /** */ - virtual int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; + /** */ + virtual int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; -// /** */ -// virtual const Epetra_Map& OperatorDomainMap() const; -// -// /** */ -// virtual const Epetra_Map& OperatorRangeMap() const; -protected: - EpetraInverseOpWrapper() {} + // /** */ + // virtual const Epetra_Map& OperatorDomainMap() const; + // + // /** */ + // virtual const Epetra_Map& OperatorRangeMap() const; + protected: + EpetraInverseOpWrapper() {} }; -} // end Epetra -} // end Teko +} // namespace Epetra +} // namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_EpetraOperatorWrapper.cpp b/packages/teko/src/Epetra/Teko_EpetraOperatorWrapper.cpp index fba6fe7c0a91..6bb66eabc6f6 100644 --- a/packages/teko/src/Epetra/Teko_EpetraOperatorWrapper.cpp +++ b/packages/teko/src/Epetra/Teko_EpetraOperatorWrapper.cpp @@ -1,28 +1,28 @@ // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -31,17 +31,16 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER - #include "Teko_EpetraOperatorWrapper.hpp" #include "Thyra_SpmdVectorBase.hpp" #include "Thyra_MultiVectorStdOps.hpp" @@ -65,239 +64,223 @@ #include "Teko_EpetraThyraConverter.hpp" #include "Teuchos_Ptr.hpp" - -namespace Teko { -namespace Epetra { - +namespace Teko { +namespace Epetra { using namespace Teuchos; using namespace Thyra; -DefaultMappingStrategy::DefaultMappingStrategy(const RCP > & thyraOp,const Epetra_Comm & comm) -{ - RCP newComm = rcp(comm.Clone()); +DefaultMappingStrategy::DefaultMappingStrategy( + const RCP >& thyraOp, const Epetra_Comm& comm) { + RCP newComm = rcp(comm.Clone()); - // extract vector spaces from linear operator - domainSpace_ = thyraOp->domain(); - rangeSpace_ = thyraOp->range(); + // extract vector spaces from linear operator + domainSpace_ = thyraOp->domain(); + rangeSpace_ = thyraOp->range(); - domainMap_ = Teko::Epetra::thyraVSToEpetraMap(*domainSpace_,newComm); - rangeMap_ = Teko::Epetra::thyraVSToEpetraMap(*rangeSpace_,newComm); + domainMap_ = Teko::Epetra::thyraVSToEpetraMap(*domainSpace_, newComm); + rangeMap_ = Teko::Epetra::thyraVSToEpetraMap(*rangeSpace_, newComm); } -void DefaultMappingStrategy::copyEpetraIntoThyra(const Epetra_MultiVector& x, const Ptr > & thyraVec) const -{ - Teko::Epetra::blockEpetraToThyra(x,thyraVec); +void DefaultMappingStrategy::copyEpetraIntoThyra( + const Epetra_MultiVector& x, const Ptr >& thyraVec) const { + Teko::Epetra::blockEpetraToThyra(x, thyraVec); } -void DefaultMappingStrategy::copyThyraIntoEpetra(const RCP > & thyraVec, Epetra_MultiVector& v) const -{ - Teko::Epetra::blockThyraToEpetra(thyraVec,v); +void DefaultMappingStrategy::copyThyraIntoEpetra( + const RCP >& thyraVec, Epetra_MultiVector& v) const { + Teko::Epetra::blockThyraToEpetra(thyraVec, v); } -EpetraOperatorWrapper::EpetraOperatorWrapper() -{ - useTranspose_ = false; - mapStrategy_ = Teuchos::null; - thyraOp_ = Teuchos::null; - comm_ = Teuchos::null; - label_ = Teuchos::null; +EpetraOperatorWrapper::EpetraOperatorWrapper() { + useTranspose_ = false; + mapStrategy_ = Teuchos::null; + thyraOp_ = Teuchos::null; + comm_ = Teuchos::null; + label_ = Teuchos::null; } -EpetraOperatorWrapper::EpetraOperatorWrapper(const RCP > & thyraOp) -{ - SetOperator(thyraOp); +EpetraOperatorWrapper::EpetraOperatorWrapper( + const RCP >& thyraOp) { + SetOperator(thyraOp); } -EpetraOperatorWrapper::EpetraOperatorWrapper(const RCP > & thyraOp,const RCP & mapStrategy) - : mapStrategy_(mapStrategy) -{ - SetOperator(thyraOp); +EpetraOperatorWrapper::EpetraOperatorWrapper(const RCP >& thyraOp, + const RCP& mapStrategy) + : mapStrategy_(mapStrategy) { + SetOperator(thyraOp); } -EpetraOperatorWrapper::EpetraOperatorWrapper(const RCP & mapStrategy) - : mapStrategy_(mapStrategy) -{ - useTranspose_ = false; - thyraOp_ = Teuchos::null; - comm_ = Teuchos::null; - label_ = Teuchos::null; +EpetraOperatorWrapper::EpetraOperatorWrapper(const RCP& mapStrategy) + : mapStrategy_(mapStrategy) { + useTranspose_ = false; + thyraOp_ = Teuchos::null; + comm_ = Teuchos::null; + label_ = Teuchos::null; } -void EpetraOperatorWrapper::SetOperator(const RCP > & thyraOp,bool buildMap) -{ - useTranspose_ = false; - thyraOp_ = thyraOp; - comm_ = getEpetraComm(*thyraOp); - label_ = thyraOp_->description(); - if(mapStrategy_==Teuchos::null && buildMap) - mapStrategy_ = Teuchos::rcp(new DefaultMappingStrategy(thyraOp,*comm_)); +void EpetraOperatorWrapper::SetOperator(const RCP >& thyraOp, + bool buildMap) { + useTranspose_ = false; + thyraOp_ = thyraOp; + comm_ = getEpetraComm(*thyraOp); + label_ = thyraOp_->description(); + if (mapStrategy_ == Teuchos::null && buildMap) + mapStrategy_ = Teuchos::rcp(new DefaultMappingStrategy(thyraOp, *comm_)); } -double EpetraOperatorWrapper::NormInf() const -{ +double EpetraOperatorWrapper::NormInf() const { TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, - "EpetraOperatorWrapper::NormInf not implemated"); + "EpetraOperatorWrapper::NormInf not implemated"); return 1.0; } -int EpetraOperatorWrapper::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const -{ - if (!useTranspose_) - { - // allocate space for each vector - RCP > tX; - RCP > tY; - - tX = Thyra::createMembers(thyraOp_->domain(),X.NumVectors()); - tY = Thyra::createMembers(thyraOp_->range(),X.NumVectors()); - - Thyra::assign(tX.ptr(),0.0); - Thyra::assign(tY.ptr(),0.0); - - // copy epetra X into thyra X - mapStrategy_->copyEpetraIntoThyra(X, tX.ptr()); - mapStrategy_->copyEpetraIntoThyra(Y, tY.ptr()); // if this matrix isn't block square, this probably won't work! - - // perform matrix vector multiplication - thyraOp_->apply(Thyra::NOTRANS,*tX,tY.ptr(),1.0,0.0); - - // copy thyra Y into epetra Y - mapStrategy_->copyThyraIntoEpetra(tY, Y); - } - else - { - TEUCHOS_ASSERT(false); - } - - return 0; -} +int EpetraOperatorWrapper::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { + if (!useTranspose_) { + // allocate space for each vector + RCP > tX; + RCP > tY; + tX = Thyra::createMembers(thyraOp_->domain(), X.NumVectors()); + tY = Thyra::createMembers(thyraOp_->range(), X.NumVectors()); -int EpetraOperatorWrapper::ApplyInverse(const Epetra_MultiVector& /* X */, - Epetra_MultiVector& /* Y */) const -{ - TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, - "EpetraOperatorWrapper::ApplyInverse not implemented"); - return 1; -} + Thyra::assign(tX.ptr(), 0.0); + Thyra::assign(tY.ptr(), 0.0); + // copy epetra X into thyra X + mapStrategy_->copyEpetraIntoThyra(X, tX.ptr()); + mapStrategy_->copyEpetraIntoThyra( + Y, tY.ptr()); // if this matrix isn't block square, this probably won't work! -RCP -EpetraOperatorWrapper::getEpetraComm(const Thyra::LinearOpBase& inOp) const -{ - RCP > vs = inOp.domain(); + // perform matrix vector multiplication + thyraOp_->apply(Thyra::NOTRANS, *tX, tY.ptr(), 1.0, 0.0); - RCP > spmd; - RCP > current = vs; - while(current!=Teuchos::null) { - // try to cast to a product vector space first - RCP > prod - = rcp_dynamic_cast >(current); - - // figure out what type it is - if(prod==Teuchos::null) { - // hopfully this is a SPMD vector space - spmd = rcp_dynamic_cast >(current); - - break; - } - else // get first convenient vector space - current = prod->getBlock(0); + // copy thyra Y into epetra Y + mapStrategy_->copyThyraIntoEpetra(tY, Y); + } else { + TEUCHOS_ASSERT(false); } - TEUCHOS_TEST_FOR_EXCEPTION(spmd==Teuchos::null, std::runtime_error, - "EpetraOperatorWrapper requires std::vector space " - "blocks to be SPMD std::vector spaces"); + return 0; +} - return Thyra::get_Epetra_Comm(*spmd->getComm()); -/* - const Thyra::ConstLinearOperator thyraOp = rcpFromRef(inOp); +int EpetraOperatorWrapper::ApplyInverse(const Epetra_MultiVector& /* X */, + Epetra_MultiVector& /* Y */) const { + TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, + "EpetraOperatorWrapper::ApplyInverse not implemented"); + return 1; +} - RCP rtn; - // VectorSpace vs = thyraOp.domain().getBlock(0); - RCP > vs = thyraOp.domain().getBlock(0).constPtr(); +RCP EpetraOperatorWrapper::getEpetraComm( + const Thyra::LinearOpBase& inOp) const { + RCP > vs = inOp.domain(); - // search for an SpmdVectorSpaceBase object RCP > spmd; RCP > current = vs; - while(current!=Teuchos::null) { - // try to cast to a product vector space first - RCP > prod - = rcp_dynamic_cast >(current); - - // figure out what type it is - if(prod==Teuchos::null) { - // hopfully this is a SPMD vector space - spmd = rcp_dynamic_cast >(current); - - break; - } - else { - // get first convenient vector space - current = prod->getBlock(0); - } + while (current != Teuchos::null) { + // try to cast to a product vector space first + RCP > prod = + rcp_dynamic_cast >(current); + + // figure out what type it is + if (prod == Teuchos::null) { + // hopfully this is a SPMD vector space + spmd = rcp_dynamic_cast >(current); + + break; + } else // get first convenient vector space + current = prod->getBlock(0); } - TEUCHOS_TEST_FOR_EXCEPTION(spmd==Teuchos::null, std::runtime_error, - "EpetraOperatorWrapper requires std::vector space " - "blocks to be SPMD std::vector spaces"); - - const SerialComm* serialComm - = dynamic_cast*>(spmd->getComm().get()); + TEUCHOS_TEST_FOR_EXCEPTION(spmd == Teuchos::null, std::runtime_error, + "EpetraOperatorWrapper requires std::vector space " + "blocks to be SPMD std::vector spaces"); -#ifdef HAVE_MPI - const MpiComm* mpiComm - = dynamic_cast*>(spmd->getComm().get()); - - TEUCHOS_TEST_FOR_EXCEPTION(mpiComm==0 && serialComm==0, std::runtime_error, - "SPMD std::vector space has a communicator that is " - "neither a serial comm nor an MPI comm"); - - if (mpiComm != 0) - { - rtn = rcp(new Epetra_MpiComm(MPI_COMM_WORLD)); - } - else - { - rtn = rcp(new Epetra_SerialComm()); + return Thyra::get_Epetra_Comm(*spmd->getComm()); + /* + const Thyra::ConstLinearOperator thyraOp = rcpFromRef(inOp); + + RCP rtn; + // VectorSpace vs = thyraOp.domain().getBlock(0); + RCP > vs = thyraOp.domain().getBlock(0).constPtr(); + + // search for an SpmdVectorSpaceBase object + RCP > spmd; + RCP > current = vs; + while(current!=Teuchos::null) { + // try to cast to a product vector space first + RCP > prod + = rcp_dynamic_cast >(current); + + // figure out what type it is + if(prod==Teuchos::null) { + // hopfully this is a SPMD vector space + spmd = rcp_dynamic_cast >(current); + + break; + } + else { + // get first convenient vector space + current = prod->getBlock(0); + } } -#else - TEUCHOS_TEST_FOR_EXCEPTION(serialComm==0, std::runtime_error, - "SPMD std::vector space has a communicator that is " - "neither a serial comm nor an MPI comm"); - rtn = rcp(new Epetra_SerialComm()); - -#endif - TEUCHOS_TEST_FOR_EXCEPTION(rtn.get()==0, std::runtime_error, "null communicator created"); - return rtn; -*/ + TEUCHOS_TEST_FOR_EXCEPTION(spmd==Teuchos::null, std::runtime_error, + "EpetraOperatorWrapper requires std::vector space " + "blocks to be SPMD std::vector spaces"); + + const SerialComm* serialComm + = dynamic_cast*>(spmd->getComm().get()); + + #ifdef HAVE_MPI + const MpiComm* mpiComm + = dynamic_cast*>(spmd->getComm().get()); + + TEUCHOS_TEST_FOR_EXCEPTION(mpiComm==0 && serialComm==0, std::runtime_error, + "SPMD std::vector space has a communicator that is " + "neither a serial comm nor an MPI comm"); + + if (mpiComm != 0) + { + rtn = rcp(new Epetra_MpiComm(MPI_COMM_WORLD)); + } + else + { + rtn = rcp(new Epetra_SerialComm()); + } + #else + TEUCHOS_TEST_FOR_EXCEPTION(serialComm==0, std::runtime_error, + "SPMD std::vector space has a communicator that is " + "neither a serial comm nor an MPI comm"); + rtn = rcp(new Epetra_SerialComm()); + + #endif + + TEUCHOS_TEST_FOR_EXCEPTION(rtn.get()==0, std::runtime_error, "null communicator created"); + return rtn; + */ } -int EpetraOperatorWrapper::GetBlockRowCount() -{ - const RCP > blkOp - = Teuchos::rcp_dynamic_cast >(getThyraOp()); +int EpetraOperatorWrapper::GetBlockRowCount() { + const RCP > blkOp = + Teuchos::rcp_dynamic_cast >(getThyraOp()); - return blkOp->productRange()->numBlocks(); + return blkOp->productRange()->numBlocks(); } -int EpetraOperatorWrapper::GetBlockColCount() -{ - const RCP > blkOp - = Teuchos::rcp_dynamic_cast >(getThyraOp()); +int EpetraOperatorWrapper::GetBlockColCount() { + const RCP > blkOp = + Teuchos::rcp_dynamic_cast >(getThyraOp()); - return blkOp->productDomain()->numBlocks(); + return blkOp->productDomain()->numBlocks(); } -Teuchos::RCP EpetraOperatorWrapper::GetBlock(int i,int j) const -{ - const RCP > blkOp - = Teuchos::rcp_dynamic_cast >(getThyraOp()); +Teuchos::RCP EpetraOperatorWrapper::GetBlock(int i, int j) const { + const RCP > blkOp = + Teuchos::rcp_dynamic_cast >(getThyraOp()); - return Thyra::get_Epetra_Operator(*blkOp->getBlock(i,j)); + return Thyra::get_Epetra_Operator(*blkOp->getBlock(i, j)); } -} // namespace Epetra -} // namespace Teko +} // namespace Epetra +} // namespace Teko diff --git a/packages/teko/src/Epetra/Teko_EpetraOperatorWrapper.hpp b/packages/teko/src/Epetra/Teko_EpetraOperatorWrapper.hpp index 0492a020e218..9814369e7968 100644 --- a/packages/teko/src/Epetra/Teko_EpetraOperatorWrapper.hpp +++ b/packages/teko/src/Epetra/Teko_EpetraOperatorWrapper.hpp @@ -55,242 +55,242 @@ #include - namespace Teko { namespace Epetra { - using Teuchos::RCP; - - class EpetraOperatorWrapper; - - /// Abstract Mapping strategy for an EpetraOperatorWrapper - class MappingStrategy { - public: - virtual ~MappingStrategy() {} - - /** \brief Copy an Epetra_MultiVector into a Thyra::MultiVectorBase - * - * Copy an Epetra_MultiVector into a Thyra::MultiVectorBase. The exact - * method for copying is specified by the concrete implementations. - * - * \param[in] epetraX Vector to be copied into the Thyra object - * \param[in,out] thyraX Destination Thyra object - */ - virtual void copyEpetraIntoThyra(const Epetra_MultiVector& epetraX, - const Teuchos::Ptr > & thyraX) const = 0; - // const EpetraOperatorWrapper & eow) const = 0; - - /** \brief Copy an Thyra::MultiVectorBase into a Epetra_MultiVector - * - * Copy an Thyra::MultiVectorBase into an Epetra_MultiVector. The exact - * method for copying is specified by the concrete implementations. - * - * \param[in] thyraX Source Thyra object - * \param[in,out] epetraX Destination Epetra object - */ - virtual void copyThyraIntoEpetra(const RCP > & thyraX, - Epetra_MultiVector& epetraX) const = 0; - // const EpetraOperatorWrapper & eow) const = 0; - - /** \brief Domain map for this strategy */ - virtual const RCP domainMap() const = 0; - - /** \brief Range map for this strategy */ - virtual const RCP rangeMap() const = 0; - - /** \brief Identifier string */ - virtual std::string toString() const = 0; - }; - - /// Flip a mapping strategy object around to give the "inverse" mapping strategy. - class InverseMappingStrategy : public MappingStrategy { - public: - /** \brief Constructor to build a inverse MappingStrategy from - * a forward map. - */ - InverseMappingStrategy(const RCP & forward) - : forwardStrategy_(forward) - { } - - virtual ~InverseMappingStrategy() {} - - virtual void copyEpetraIntoThyra(const Epetra_MultiVector& epetraX, - const Teuchos::Ptr > & thyraX) const - // const EpetraOperatorWrapper & eow) const - { forwardStrategy_->copyEpetraIntoThyra(epetraX,thyraX); } - - virtual void copyThyraIntoEpetra(const RCP > & thyraX, - Epetra_MultiVector& epetraX) const - // const EpetraOperatorWrapper & eow) const - { forwardStrategy_->copyThyraIntoEpetra(thyraX,epetraX); } - - /** \brief Domain map for this strategy */ - virtual const RCP domainMap() const - { return forwardStrategy_->rangeMap(); } - - /** \brief Range map for this strategy */ - virtual const RCP rangeMap() const - { return forwardStrategy_->domainMap(); } - - /** \brief Identifier string */ - virtual std::string toString() const - { return std::string("InverseMapping(")+forwardStrategy_->toString()+std::string(")"); } - protected: - /** \brief Forward mapping strategy object */ - const RCP forwardStrategy_; - - private: - InverseMappingStrategy(); - InverseMappingStrategy(const InverseMappingStrategy &); - }; - - /// default mapping strategy for the basic EpetraOperatorWrapper - class DefaultMappingStrategy : public MappingStrategy { - public: - /** */ - DefaultMappingStrategy(const RCP > & thyraOp,const Epetra_Comm & comm); - - virtual ~DefaultMappingStrategy() {} - - /** \brief Copy an Epetra_MultiVector into a Thyra::MultiVectorBase - * - * Copy an Epetra_MultiVector into a Thyra::MultiVectorBase. The exact - * method for copying is specified by the concrete implementations. - * - * \param[in] epetraX Vector to be copied into the Thyra object - * \param[in,out] thyraX Destination Thyra object - */ - virtual void copyEpetraIntoThyra(const Epetra_MultiVector& epetraX, - const Teuchos::Ptr > & thyraX) const; - // const EpetraOperatorWrapper & eow) const; - - /** \brief Copy an Thyra::MultiVectorBase into a Epetra_MultiVector - * - * Copy an Thyra::MultiVectorBase into an Epetra_MultiVector. The exact - * method for copying is specified by the concrete implementations. - * - * \param[in] thyraX Source Thyra object - * \param[in,out] epetraX Destination Epetra object - */ - virtual void copyThyraIntoEpetra(const RCP > & thyraX, - Epetra_MultiVector& epetraX) const; - // const EpetraOperatorWrapper & eow) const; - - /** \brief Domain map for this strategy */ - virtual const RCP domainMap() const { return domainMap_; } - - /** \brief Range map for this strategy */ - virtual const RCP rangeMap() const { return rangeMap_; } - - /** \brief Identifier string */ - virtual std::string toString() const - { return std::string("DefaultMappingStrategy"); } - - protected: - RCP > domainSpace_; ///< Domain space object - RCP > rangeSpace_; ///< Range space object - - RCP domainMap_; ///< Pointer to the constructed domain map - RCP rangeMap_; ///< Pointer to the constructed range map - }; - - /** \brief - * Implements the Epetra_Operator interface with a Thyra LinearOperator. This - * enables the use of absrtact Thyra operators in AztecOO as preconditioners and - * operators, without being rendered into concrete Epetra matrices. This is my own - * modified version that was originally in Thyra. +using Teuchos::RCP; + +class EpetraOperatorWrapper; + +/// Abstract Mapping strategy for an EpetraOperatorWrapper +class MappingStrategy { + public: + virtual ~MappingStrategy() {} + + /** \brief Copy an Epetra_MultiVector into a Thyra::MultiVectorBase + * + * Copy an Epetra_MultiVector into a Thyra::MultiVectorBase. The exact + * method for copying is specified by the concrete implementations. + * + * \param[in] epetraX Vector to be copied into the Thyra object + * \param[in,out] thyraX Destination Thyra object + */ + virtual void copyEpetraIntoThyra( + const Epetra_MultiVector& epetraX, + const Teuchos::Ptr >& thyraX) const = 0; + // const EpetraOperatorWrapper & eow) const = 0; + + /** \brief Copy an Thyra::MultiVectorBase into a Epetra_MultiVector + * + * Copy an Thyra::MultiVectorBase into an Epetra_MultiVector. The exact + * method for copying is specified by the concrete implementations. + * + * \param[in] thyraX Source Thyra object + * \param[in,out] epetraX Destination Epetra object + */ + virtual void copyThyraIntoEpetra(const RCP >& thyraX, + Epetra_MultiVector& epetraX) const = 0; + // const EpetraOperatorWrapper & eow) const = 0; + + /** \brief Domain map for this strategy */ + virtual const RCP domainMap() const = 0; + + /** \brief Range map for this strategy */ + virtual const RCP rangeMap() const = 0; + + /** \brief Identifier string */ + virtual std::string toString() const = 0; +}; + +/// Flip a mapping strategy object around to give the "inverse" mapping strategy. +class InverseMappingStrategy : public MappingStrategy { + public: + /** \brief Constructor to build a inverse MappingStrategy from + * a forward map. */ - class EpetraOperatorWrapper : public Epetra_Operator + InverseMappingStrategy(const RCP& forward) : forwardStrategy_(forward) {} + + virtual ~InverseMappingStrategy() {} + + virtual void copyEpetraIntoThyra( + const Epetra_MultiVector& epetraX, + const Teuchos::Ptr >& thyraX) const + // const EpetraOperatorWrapper & eow) const { - public: - /** */ - EpetraOperatorWrapper(const RCP > & thyraOp); - EpetraOperatorWrapper(const RCP > & thyraOp, - const RCP & mapStrategy); - EpetraOperatorWrapper(const RCP & mapStrategy); + forwardStrategy_->copyEpetraIntoThyra(epetraX, thyraX); + } + + virtual void copyThyraIntoEpetra(const RCP >& thyraX, + Epetra_MultiVector& epetraX) const + // const EpetraOperatorWrapper & eow) const + { + forwardStrategy_->copyThyraIntoEpetra(thyraX, epetraX); + } + + /** \brief Domain map for this strategy */ + virtual const RCP domainMap() const { return forwardStrategy_->rangeMap(); } + + /** \brief Range map for this strategy */ + virtual const RCP rangeMap() const { return forwardStrategy_->domainMap(); } + + /** \brief Identifier string */ + virtual std::string toString() const { + return std::string("InverseMapping(") + forwardStrategy_->toString() + std::string(")"); + } + + protected: + /** \brief Forward mapping strategy object */ + const RCP forwardStrategy_; + + private: + InverseMappingStrategy(); + InverseMappingStrategy(const InverseMappingStrategy&); +}; + +/// default mapping strategy for the basic EpetraOperatorWrapper +class DefaultMappingStrategy : public MappingStrategy { + public: + /** */ + DefaultMappingStrategy(const RCP >& thyraOp, + const Epetra_Comm& comm); + + virtual ~DefaultMappingStrategy() {} + + /** \brief Copy an Epetra_MultiVector into a Thyra::MultiVectorBase + * + * Copy an Epetra_MultiVector into a Thyra::MultiVectorBase. The exact + * method for copying is specified by the concrete implementations. + * + * \param[in] epetraX Vector to be copied into the Thyra object + * \param[in,out] thyraX Destination Thyra object + */ + virtual void copyEpetraIntoThyra( + const Epetra_MultiVector& epetraX, + const Teuchos::Ptr >& thyraX) const; + // const EpetraOperatorWrapper & eow) const; + + /** \brief Copy an Thyra::MultiVectorBase into a Epetra_MultiVector + * + * Copy an Thyra::MultiVectorBase into an Epetra_MultiVector. The exact + * method for copying is specified by the concrete implementations. + * + * \param[in] thyraX Source Thyra object + * \param[in,out] epetraX Destination Epetra object + */ + virtual void copyThyraIntoEpetra(const RCP >& thyraX, + Epetra_MultiVector& epetraX) const; + // const EpetraOperatorWrapper & eow) const; + + /** \brief Domain map for this strategy */ + virtual const RCP domainMap() const { return domainMap_; } + + /** \brief Range map for this strategy */ + virtual const RCP rangeMap() const { return rangeMap_; } + + /** \brief Identifier string */ + virtual std::string toString() const { return std::string("DefaultMappingStrategy"); } + + protected: + RCP > domainSpace_; ///< Domain space object + RCP > rangeSpace_; ///< Range space object + + RCP domainMap_; ///< Pointer to the constructed domain map + RCP rangeMap_; ///< Pointer to the constructed range map +}; + +/** \brief + * Implements the Epetra_Operator interface with a Thyra LinearOperator. This + * enables the use of absrtact Thyra operators in AztecOO as preconditioners and + * operators, without being rendered into concrete Epetra matrices. This is my own + * modified version that was originally in Thyra. + */ +class EpetraOperatorWrapper : public Epetra_Operator { + public: + /** */ + EpetraOperatorWrapper(const RCP >& thyraOp); + EpetraOperatorWrapper(const RCP >& thyraOp, + const RCP& mapStrategy); + EpetraOperatorWrapper(const RCP& mapStrategy); - /** */ - virtual ~EpetraOperatorWrapper() {;} + /** */ + virtual ~EpetraOperatorWrapper() { ; } - /** */ - int SetUseTranspose(bool useTranspose) { - useTranspose_ = useTranspose; - return 0; - } + /** */ + int SetUseTranspose(bool useTranspose) { + useTranspose_ = useTranspose; + return 0; + } - /** */ - int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const ; + /** */ + int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; - /** */ - int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const ; + /** */ + int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; - /** */ - double NormInf() const ; + /** */ + double NormInf() const; - /** */ - const char* Label() const {return label_.c_str();} + /** */ + const char* Label() const { return label_.c_str(); } - /** */ - bool UseTranspose() const {return useTranspose_;} + /** */ + bool UseTranspose() const { return useTranspose_; } - /** */ - bool HasNormInf() const {return false;} + /** */ + bool HasNormInf() const { return false; } - /** */ - const Epetra_Comm & Comm() const {return *comm_;} + /** */ + const Epetra_Comm& Comm() const { return *comm_; } - /** */ - const Epetra_Map& OperatorDomainMap() const {return *mapStrategy_->domainMap();} + /** */ + const Epetra_Map& OperatorDomainMap() const { return *mapStrategy_->domainMap(); } - /** */ - const Epetra_Map& OperatorRangeMap() const {return *mapStrategy_->rangeMap();} + /** */ + const Epetra_Map& OperatorRangeMap() const { return *mapStrategy_->rangeMap(); } - //! Return the thyra operator associated with this wrapper - const RCP > getThyraOp() const - { return thyraOp_; } + //! Return the thyra operator associated with this wrapper + const RCP > getThyraOp() const { return thyraOp_; } - //! Get the mapping strategy for this wrapper (translate between Thyra and Epetra) - const RCP getMapStrategy() const - { return mapStrategy_; } + //! Get the mapping strategy for this wrapper (translate between Thyra and Epetra) + const RCP getMapStrategy() const { return mapStrategy_; } - //! Get the number of block rows in this operator - virtual int GetBlockRowCount(); + //! Get the number of block rows in this operator + virtual int GetBlockRowCount(); - //! Get the number of block columns in this operator - virtual int GetBlockColCount(); + //! Get the number of block columns in this operator + virtual int GetBlockColCount(); - //! Grab the i,j block - Teuchos::RCP GetBlock(int i,int j) const; + //! Grab the i,j block + Teuchos::RCP GetBlock(int i, int j) const; - protected: - /** */ - EpetraOperatorWrapper(); + protected: + /** */ + EpetraOperatorWrapper(); - /** */ - RCP getEpetraComm(const Thyra::LinearOpBase & inOp) const; + /** */ + RCP getEpetraComm(const Thyra::LinearOpBase& inOp) const; - /** */ - void SetOperator(const RCP > & thyraOp,bool buildMap=true); + /** */ + void SetOperator(const RCP >& thyraOp, bool buildMap = true); - /** */ - void SetMapStrategy(const RCP & mapStrategy) - { mapStrategy_ = mapStrategy; } + /** */ + void SetMapStrategy(const RCP& mapStrategy) { mapStrategy_ = mapStrategy; } - /** */ - RCP mapStrategy_; + /** */ + RCP mapStrategy_; - /** */ - RCP > thyraOp_; + /** */ + RCP > thyraOp_; - /** */ - bool useTranspose_; + /** */ + bool useTranspose_; - /** */ - RCP comm_; + /** */ + RCP comm_; - /** */ - std::string label_; - }; -} // end namespace Epetra -} // end namespace Teko + /** */ + std::string label_; +}; +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_EpetraThyraConverter.cpp b/packages/teko/src/Epetra/Teko_EpetraThyraConverter.cpp index 86a6ab28792e..23fa9c4f7264 100644 --- a/packages/teko/src/Epetra/Teko_EpetraThyraConverter.cpp +++ b/packages/teko/src/Epetra/Teko_EpetraThyraConverter.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -60,238 +60,245 @@ #include #include -using Teuchos::RCP; +using Teuchos::null; using Teuchos::Ptr; +using Teuchos::ptr_dynamic_cast; +using Teuchos::RCP; using Teuchos::rcp; -using Teuchos::rcpFromRef; using Teuchos::rcp_dynamic_cast; -using Teuchos::ptr_dynamic_cast; -using Teuchos::null; +using Teuchos::rcpFromRef; namespace Teko { namespace Epetra { -// const Teuchos::RCP > -// blockEpetraToThyra(int numVectors,const double * epetraData,int leadingDim,const Teuchos::RCP > & vs,int & localDim) +// const Teuchos::RCP > +// blockEpetraToThyra(int numVectors,const double * epetraData,int leadingDim,const +// Teuchos::RCP > & vs,int & localDim) -void blockEpetraToThyra(int numVectors,const double * epetraData,int leadingDim,const Teuchos::Ptr > & mv,int & localDim) -{ - localDim = 0; +void blockEpetraToThyra(int numVectors, const double* epetraData, int leadingDim, + const Teuchos::Ptr >& mv, int& localDim) { + localDim = 0; - // check the base case - const Ptr > prodMV - = ptr_dynamic_cast > (mv); - if(prodMV==Teuchos::null) { - // VS object must be a SpmdMultiVector object - const Ptr > spmdX = ptr_dynamic_cast >(mv,true); - const RCP > spmdVS = spmdX->spmdSpace(); + // check the base case + const Ptr > prodMV = + ptr_dynamic_cast >(mv); + if (prodMV == Teuchos::null) { + // VS object must be a SpmdMultiVector object + const Ptr > spmdX = + ptr_dynamic_cast >(mv, true); + const RCP > spmdVS = spmdX->spmdSpace(); - int localSubDim = spmdVS->localSubDim(); + int localSubDim = spmdVS->localSubDim(); - Thyra::Ordinal thyraLeadingDim=0; - // double * thyraData=0; - // spmdX->getLocalData(&thyraData,&thyraLeadingDim); + Thyra::Ordinal thyraLeadingDim = 0; + // double * thyraData=0; + // spmdX->getLocalData(&thyraData,&thyraLeadingDim); - Teuchos::ArrayRCP thyraData_arcp; - Teuchos::ArrayView thyraData; - spmdX->getNonconstLocalData(Teuchos::outArg(thyraData_arcp),Teuchos::outArg(thyraLeadingDim)); - thyraData = thyraData_arcp(); // build array view + Teuchos::ArrayRCP thyraData_arcp; + Teuchos::ArrayView thyraData; + spmdX->getNonconstLocalData(Teuchos::outArg(thyraData_arcp), Teuchos::outArg(thyraLeadingDim)); + thyraData = thyraData_arcp(); // build array view - for(int i=0;icommitLocalData(&thyraData[0]); + // spmdX->commitLocalData(&thyraData[0]); - // set the local dimension - localDim = localSubDim; + // set the local dimension + localDim = localSubDim; - return; - } + return; + } - // this keeps track of current location in the epetraData vector - const double * localData = epetraData; + // this keeps track of current location in the epetraData vector + const double* localData = epetraData; - // loop over all the blocks in the vector space - for(int blkIndex=0;blkIndexproductSpace()->numBlocks();blkIndex++) { - int subDim = 0; - const RCP > blockVec = prodMV->getNonconstMultiVectorBlock(blkIndex); + // loop over all the blocks in the vector space + for (int blkIndex = 0; blkIndex < prodMV->productSpace()->numBlocks(); blkIndex++) { + int subDim = 0; + const RCP > blockVec = + prodMV->getNonconstMultiVectorBlock(blkIndex); - // perorm the recusive copy - blockEpetraToThyra(numVectors, localData,leadingDim,blockVec.ptr(),subDim); + // perorm the recusive copy + blockEpetraToThyra(numVectors, localData, leadingDim, blockVec.ptr(), subDim); - // shift to the next block - localData += subDim; + // shift to the next block + localData += subDim; - // account for the size of this subblock - localDim += subDim; - } + // account for the size of this subblock + localDim += subDim; + } } // Convert a Epetra_MultiVector with assumed block structure dictated by the // vector space into a Thyra::MultiVectorBase object. -// const Teuchos::RCP > blockEpetraToThyra(const Epetra_MultiVector & e,const Teuchos::RCP > & vs) -void blockEpetraToThyra(const Epetra_MultiVector & epetraX,const Teuchos::Ptr > & thyraX) -{ - TEUCHOS_ASSERT(thyraX->range()->dim()==epetraX.GlobalLength()); +// const Teuchos::RCP > blockEpetraToThyra(const +// Epetra_MultiVector & e,const Teuchos::RCP > & vs) +void blockEpetraToThyra(const Epetra_MultiVector& epetraX, + const Teuchos::Ptr >& thyraX) { + TEUCHOS_ASSERT(thyraX->range()->dim() == epetraX.GlobalLength()); - // extract local information from the Epetra_MultiVector - int leadingDim=0,numVectors=0,localDim=0; - double * epetraData=0; - epetraX.ExtractView(&epetraData,&leadingDim); + // extract local information from the Epetra_MultiVector + int leadingDim = 0, numVectors = 0, localDim = 0; + double* epetraData = 0; + epetraX.ExtractView(&epetraData, &leadingDim); - numVectors = epetraX.NumVectors(); + numVectors = epetraX.NumVectors(); - blockEpetraToThyra(numVectors,epetraData,leadingDim,thyraX.ptr(),localDim); + blockEpetraToThyra(numVectors, epetraData, leadingDim, thyraX.ptr(), localDim); - TEUCHOS_ASSERT(localDim==epetraX.MyLength()); + TEUCHOS_ASSERT(localDim == epetraX.MyLength()); } -void blockThyraToEpetra(int numVectors,double * epetraData,int leadingDim,const Teuchos::RCP > & tX,int & localDim) -{ - localDim = 0; +void blockThyraToEpetra(int numVectors, double* epetraData, int leadingDim, + const Teuchos::RCP >& tX, + int& localDim) { + localDim = 0; + + // check the base case + const RCP > prodX = + rcp_dynamic_cast >(tX); + if (prodX == Teuchos::null) { + // the base case - // check the base case - const RCP > prodX - = rcp_dynamic_cast > (tX); - if(prodX==Teuchos::null) { - // the base case + // VS object must be a SpmdMultiVector object + RCP > spmdX = + rcp_dynamic_cast >(tX, true); + RCP > spmdVS = spmdX->spmdSpace(); - // VS object must be a SpmdMultiVector object - RCP > spmdX = rcp_dynamic_cast >(tX,true); - RCP > spmdVS = spmdX->spmdSpace(); + int localSubDim = spmdVS->localSubDim(); - int localSubDim = spmdVS->localSubDim(); + Thyra::Ordinal thyraLeadingDim = 0; + // const double * thyraData=0; + // spmdX->getLocalData(&thyraData,&thyraLeadingDim); - Thyra::Ordinal thyraLeadingDim=0; - // const double * thyraData=0; - // spmdX->getLocalData(&thyraData,&thyraLeadingDim); - - Teuchos::ArrayView thyraData; - Teuchos::ArrayRCP thyraData_arcp; - spmdX->getLocalData(Teuchos::outArg(thyraData_arcp),Teuchos::outArg(thyraLeadingDim)); - thyraData = thyraData_arcp(); // grab the array view + Teuchos::ArrayView thyraData; + Teuchos::ArrayRCP thyraData_arcp; + spmdX->getLocalData(Teuchos::outArg(thyraData_arcp), Teuchos::outArg(thyraLeadingDim)); + thyraData = thyraData_arcp(); // grab the array view - for(int i=0;i > prodVS = prodX->productSpace(); + const RCP > prodVS = prodX->productSpace(); - // this keeps track of current location in the epetraData vector - double * localData = epetraData; + // this keeps track of current location in the epetraData vector + double* localData = epetraData; - // loop over all the blocks in the vector space - for(int blkIndex=0;blkIndexnumBlocks();blkIndex++) { - int subDim = 0; + // loop over all the blocks in the vector space + for (int blkIndex = 0; blkIndex < prodVS->numBlocks(); blkIndex++) { + int subDim = 0; - // construct the block vector - blockThyraToEpetra(numVectors, localData,leadingDim,prodX->getMultiVectorBlock(blkIndex),subDim); + // construct the block vector + blockThyraToEpetra(numVectors, localData, leadingDim, prodX->getMultiVectorBlock(blkIndex), + subDim); - // shift to the next block - localData += subDim; + // shift to the next block + localData += subDim; - // account for the size of this subblock - localDim += subDim; - } + // account for the size of this subblock + localDim += subDim; + } - return; + return; } // Convert a Thyra::MultiVectorBase object to a Epetra_MultiVector object with // the map defined by the Epetra_Map. -// const Teuchos::RCP -// blockThyraToEpetra(const Teuchos::RCP > & tX,const RCP & map) -void blockThyraToEpetra(const Teuchos::RCP > & thyraX,Epetra_MultiVector & epetraX) -{ - // build an Epetra_MultiVector object - int numVectors = thyraX->domain()->dim(); - - // make sure the number of vectors are the same - TEUCHOS_ASSERT(numVectors==epetraX.NumVectors()); - TEUCHOS_ASSERT(thyraX->range()->dim()==epetraX.GlobalLength()); - - // extract local information from the Epetra_MultiVector - int leadingDim=0,localDim=0; - double * epetraData=0; - epetraX.ExtractView(&epetraData,&leadingDim); - - // perform recursive copy - blockThyraToEpetra(numVectors,epetraData,leadingDim,thyraX,localDim); - - // sanity check - TEUCHOS_ASSERT(localDim==epetraX.Map().NumMyElements()); +// const Teuchos::RCP +// blockThyraToEpetra(const Teuchos::RCP > & tX,const RCP & map) +void blockThyraToEpetra(const Teuchos::RCP >& thyraX, + Epetra_MultiVector& epetraX) { + // build an Epetra_MultiVector object + int numVectors = thyraX->domain()->dim(); + + // make sure the number of vectors are the same + TEUCHOS_ASSERT(numVectors == epetraX.NumVectors()); + TEUCHOS_ASSERT(thyraX->range()->dim() == epetraX.GlobalLength()); + + // extract local information from the Epetra_MultiVector + int leadingDim = 0, localDim = 0; + double* epetraData = 0; + epetraX.ExtractView(&epetraData, &leadingDim); + + // perform recursive copy + blockThyraToEpetra(numVectors, epetraData, leadingDim, thyraX, localDim); + + // sanity check + TEUCHOS_ASSERT(localDim == epetraX.Map().NumMyElements()); } -void thyraVSToEpetraMap(std::vector & myIndicies, int blockOffset, const Thyra::VectorSpaceBase & vs, int & localDim) -{ - // zero out set local dimension - localDim = 0; +void thyraVSToEpetraMap(std::vector& myIndicies, int blockOffset, + const Thyra::VectorSpaceBase& vs, int& localDim) { + // zero out set local dimension + localDim = 0; - const RCP > prodVS - = rcp_dynamic_cast >(rcpFromRef(vs)); + const RCP > prodVS = + rcp_dynamic_cast >(rcpFromRef(vs)); - // is more recursion needed? - if(prodVS==Teuchos::null) { - // base case + // is more recursion needed? + if (prodVS == Teuchos::null) { + // base case - // try to cast to an SPMD capable vector space - const RCP > spmdVS - = rcp_dynamic_cast >(rcpFromRef(vs)); - TEUCHOS_TEST_FOR_EXCEPTION(spmdVS==Teuchos::null,std::runtime_error, - "thyraVSToEpetraMap requires all subblocks to be SPMD"); + // try to cast to an SPMD capable vector space + const RCP > spmdVS = + rcp_dynamic_cast >(rcpFromRef(vs)); + TEUCHOS_TEST_FOR_EXCEPTION(spmdVS == Teuchos::null, std::runtime_error, + "thyraVSToEpetraMap requires all subblocks to be SPMD"); - // get local data storage information - int localOffset = spmdVS->localOffset(); - int localSubDim = spmdVS->localSubDim(); + // get local data storage information + int localOffset = spmdVS->localOffset(); + int localSubDim = spmdVS->localSubDim(); - // add indicies to matrix - for(int i=0;inumBlocks();blkIndex++) { - int subDim = 0; + // loop over all the blocks in the vector space + for (int blkIndex = 0; blkIndex < prodVS->numBlocks(); blkIndex++) { + int subDim = 0; - // construct the block vector - thyraVSToEpetraMap(myIndicies, blockOffset,*prodVS->getBlock(blkIndex),subDim); + // construct the block vector + thyraVSToEpetraMap(myIndicies, blockOffset, *prodVS->getBlock(blkIndex), subDim); - blockOffset += prodVS->getBlock(blkIndex)->dim(); + blockOffset += prodVS->getBlock(blkIndex)->dim(); - // account for the size of this subblock - localDim += subDim; - } + // account for the size of this subblock + localDim += subDim; + } } // From a Thyra vector space create a compatable Epetra_Map -const RCP thyraVSToEpetraMap(const Thyra::VectorSpaceBase & vs,const RCP & comm) -{ - int localDim = 0; - std::vector myGIDs; - - // call recursive routine that constructs the mapping - thyraVSToEpetraMap(myGIDs,0,vs,localDim); - - TEUCHOS_ASSERT(myGIDs.size()==(unsigned int) localDim); - - // create the map - return rcp(new Epetra_Map(vs.dim(), myGIDs.size(), &(myGIDs[0]), 0, *comm)); +const RCP thyraVSToEpetraMap(const Thyra::VectorSpaceBase& vs, + const RCP& comm) { + int localDim = 0; + std::vector myGIDs; + + // call recursive routine that constructs the mapping + thyraVSToEpetraMap(myGIDs, 0, vs, localDim); + + TEUCHOS_ASSERT(myGIDs.size() == (unsigned int)localDim); + + // create the map + return rcp(new Epetra_Map(vs.dim(), myGIDs.size(), &(myGIDs[0]), 0, *comm)); } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_EpetraThyraConverter.hpp b/packages/teko/src/Epetra/Teko_EpetraThyraConverter.hpp index 64291ab9135e..4a937f0a1f78 100644 --- a/packages/teko/src/Epetra/Teko_EpetraThyraConverter.hpp +++ b/packages/teko/src/Epetra/Teko_EpetraThyraConverter.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -66,78 +66,96 @@ namespace Epetra { * * Converts a Epetra_MultiVector to a Thyra::MultiVectorBase object. The structure of * the Epetra_MultiVector is assumed to be described by a map produced from the vector space - * containing the destination vector. For instance if there is a vector \f$v = [ [v_0, v_1] , v_2]^T\f$ + * containing the destination vector. For instance if there is a vector \f$v = [ [v_0, v_1] , + v_2]^T\f$ * where \f$v_0\f$, \f$v_1\f$ and \f$v_2\f$ are all subvectors then the Epetra_Map * corresponding to \f$v\f$ would have indicies - + \f$v_0^0, v_0^1,\ldots,v_0^{n_0}, v_1^0, v_1^1,\ldots,v_1^{n_1} v_2^0, v_2^1,\ldots,v_2^{n_2} \f$. - + * That is the each of the subvectors are stacked on top of each other. The possibly recursive * block structure is then dictated by the vector space. The resulting Thyra::MultiVectorBase * object will be in the vectors space, with the contents of the Epetra_MultiVector copied to it. * - * \param[in] epetraX Source Epetra_MultiVector object to be converted. See assumptions in Preconditions section. - * \param[in,out] thyraX Destination Thyra::MultiVectorBase. See assumptions in Preconditions section + * \param[in] epetraX Source Epetra_MultiVector object to be converted. See assumptions in + Preconditions section. + * \param[in,out] thyraX Destination Thyra::MultiVectorBase. See assumptions in Preconditions + section * * Preconditions
    - *
  • [mv.Map()==thyraVSToEpetraMap(thyraX->space())] This method assumes that the map used to create - * epetraX was created using the thyraVSToEpetraMap function using the vector space defining - thyraX + *
  • [mv.Map()==thyraVSToEpetraMap(thyraX->space())] This method assumes that the map used to + create + * epetraX was created using the thyraVSToEpetraMap function using the vector + space defining thyraX *
  • All subvectors are of type Thyra::SpmdMultiVectorBase or Thyra::ProductMultiVectorBase *
* * Postconditions
    - *
  • [thryaX==epetraX] Contents of epetraX are copied into thyraX + *
  • [thryaX==epetraX] Contents of epetraX are copied into + thyraX *
* * \note Due to a Thyra issue with a somewhat incomplete inheritance hierarchy surrounding - * the SpmdMultiVectorBase and SpmdVectorBase interfaces thyraX must be of - * type SpmdMultiVectorBase, ProductMultiVectorBase, or ProductVectorBase. - * Notice that this does not include the SpmdVectorBase class. A fix of this might involve a more + * the SpmdMultiVectorBase and SpmdVectorBase interfaces + thyraX must be of + * type SpmdMultiVectorBase, ProductMultiVectorBase, or + ProductVectorBase. + * Notice that this does not include the SpmdVectorBase class. A fix of this + might involve a more * general implementation and use of DetachedSpmdMultiVectorView. */ -void blockEpetraToThyra(const Epetra_MultiVector & epetraX,const Teuchos::Ptr > & thyraX); +void blockEpetraToThyra(const Epetra_MultiVector& epetraX, + const Teuchos::Ptr >& thyraX); /** \brief Convert a Thyra::MultiVectorBase object to a Epetra_MultiVector object with * the map defined by the Epetra_Map. * * Converts a Thyra::MultiVectorBase object to a Epetra_MultiVector object. The Epetra_MultiVector - * should have been created to be compatiable with the Thyra multi-vector, i.e. using the corresponding + * should have been created to be compatiable with the Thyra multi-vector, i.e. using the + corresponding * map create by a call to thyraVSToEpetraMap. For example, for a Thyra::MultiVectorBase object * \f$v = [ [v_0, v_1] , v_2]^T\f$ where \f$v_0\f$, \f$v_1\f$ and \f$v_2\f$ are all subvectors, * the Epetra_MultiVector object will have global indicies - + \f$v_0^0, v_0^1,\ldots,v_0^{n_0}, v_1^0, v_1^1,\ldots,v_1^{n_1} v_2^0, v_2^1,\ldots,v_2^{n_2} \f$. - + * That is the each of the subvectors are stacked on top of each other. The possibly recursive - * block structure is then dictated by the Thyra::MultiVectorBase object. The resulting Epetra_MultiVector + * block structure is then dictated by the Thyra::MultiVectorBase object. The resulting + Epetra_MultiVector * object will be a copy of the Thyra::MultiVectorBase object. * - * \param[in] thyraX Source Thyra::MultiVectorBase object to be converted. See assumptions in Preconditions section. + * \param[in] thyraX Source Thyra::MultiVectorBase object to be converted. See assumptions in + Preconditions section. * \param[in,out] epetraX Destination Epetra_MultiVector. See assumptions in Preconditions section * * Preconditions
    - *
  • [epetraX.Map()==thyraVSToEpetraMap(thyraX->space())] This method assumes that the map used to create - * epetraX was created using the thyraVSToEpetraMap function using the vector space defining - thyraX + *
  • [epetraX.Map()==thyraVSToEpetraMap(thyraX->space())] This method assumes that + the map used to create + * epetraX was created using the thyraVSToEpetraMap function using the vector + space defining thyraX *
  • All subvectors are of type Thyra::SpmdMultiVectorBase or Thyra::ProductMultiVectorBase *
* * Postconditions
    - *
  • [thryaX==epetraX] Contents of epetraX are copied into thyraX + *
  • [thryaX==epetraX] Contents of epetraX are copied into + thyraX *
* * \note Due to a Thyra issue with a somewhat incomplete inheritance hierarchy surrounding - * the SpmdMultiVectorBase and SpmdVectorBase interfaces thyraX must be of - * type SpmdMultiVectorBase, ProductMultiVectorBase, or ProductVectorBase. - * Notice that this does not include the SpmdVectorBase class. A fix of this might involve a more + * the SpmdMultiVectorBase and SpmdVectorBase interfaces + thyraX must be of + * type SpmdMultiVectorBase, ProductMultiVectorBase, or + ProductVectorBase. + * Notice that this does not include the SpmdVectorBase class. A fix of this + might involve a more * general implementation and use of ConstDetachedSpmdMultiVectorView. */ -void blockThyraToEpetra(const Teuchos::RCP > & thyraX,Epetra_MultiVector & epetraX); +void blockThyraToEpetra(const Teuchos::RCP >& thyraX, + Epetra_MultiVector& epetraX); /** \brief From a Thyra vector space create a compatable Epetra_Map * @@ -149,12 +167,12 @@ void blockThyraToEpetra(const Teuchos::RCP * As an example consider the vector space that describes vectors of the form * \f$v = [ [v_0, v_1] , v_2]^T\f$ where \f$v_0\f$, \f$v_1\f$ and \f$v_2\f$ are all subvectors. * The Epetra_Map created from this vector space will have global indicies - + \f$v_0^0, v_0^1,\ldots,v_0^{n_0}, v_1^0, v_1^1,\ldots,v_1^{n_1} v_2^0, v_2^1,\ldots,v_2^{n_2} \f$. - - * That is the each of the subvectors are stacked on top of each other. + + * That is the each of the subvectors are stacked on top of each other. * * \param[in] vs A vector space object from which the Epetra_Map is to be created * \param[in] comm The Epetra_Comm object used to create the Epetra_Map @@ -167,10 +185,10 @@ void blockThyraToEpetra(const Teuchos::RCP * Thyra::SpmdMultiVectorBase objects. * */ -const Teuchos::RCP -thyraVSToEpetraMap(const Thyra::VectorSpaceBase & vs,const Teuchos::RCP & comm); +const Teuchos::RCP thyraVSToEpetraMap(const Thyra::VectorSpaceBase& vs, + const Teuchos::RCP& comm); -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_InterlacedEpetra.cpp b/packages/teko/src/Epetra/Teko_InterlacedEpetra.cpp index 530333bd6411..fc88c61b96c4 100644 --- a/packages/teko/src/Epetra/Teko_InterlacedEpetra.cpp +++ b/packages/teko/src/Epetra/Teko_InterlacedEpetra.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -58,386 +58,392 @@ namespace Strided { // this assumes that there are numGlobals with numVars each interlaced // i.e. for numVars = 2 (u,v) then the vector is // [u_0,v_0,u_1,v_1,u_2,v_2, ..., u_(numGlobals-1),v_(numGlobals-1)] -void buildSubMaps(int numGlobals,int numVars,const Epetra_Comm & comm,std::vector > > & subMaps) -{ - std::vector vars; - - // build vector describing the sub maps - for(int i=0;i > >& subMaps) { + std::vector vars; + + // build vector describing the sub maps + for (int i = 0; i < numVars; i++) vars.push_back(1); + + // build all the submaps + buildSubMaps(numGlobals, vars, comm, subMaps); } // build maps to make other conversions -void buildSubMaps(const Epetra_Map & globalMap,const std::vector & vars,const Epetra_Comm & comm, - std::vector > > & subMaps) -{ - buildSubMaps(globalMap.NumGlobalElements(),globalMap.NumMyElements(),globalMap.MinMyGID(), - vars,comm,subMaps); +void buildSubMaps(const Epetra_Map& globalMap, const std::vector& vars, + const Epetra_Comm& comm, + std::vector > >& subMaps) { + buildSubMaps(globalMap.NumGlobalElements(), globalMap.NumMyElements(), globalMap.MinMyGID(), vars, + comm, subMaps); } // build maps to make other conversions -void buildSubMaps(int numGlobals,const std::vector & vars,const Epetra_Comm & comm,std::vector > > & subMaps) -{ - std::vector::const_iterator varItr; +void buildSubMaps(int numGlobals, const std::vector& vars, const Epetra_Comm& comm, + std::vector > >& subMaps) { + std::vector::const_iterator varItr; - // compute total number of variables - int numGlobalVars = 0; - for(varItr=vars.begin();varItr!=vars.end();++varItr) - numGlobalVars += *varItr; + // compute total number of variables + int numGlobalVars = 0; + for (varItr = vars.begin(); varItr != vars.end(); ++varItr) numGlobalVars += *varItr; - // must be an even number of globals - TEUCHOS_ASSERT((numGlobals%numGlobalVars)==0); + // must be an even number of globals + TEUCHOS_ASSERT((numGlobals % numGlobalVars) == 0); - Epetra_Map sampleMap(numGlobals/numGlobalVars,0,comm); + Epetra_Map sampleMap(numGlobals / numGlobalVars, 0, comm); - buildSubMaps(numGlobals,numGlobalVars*sampleMap.NumMyElements(),numGlobalVars*sampleMap.MinMyGID(),vars,comm,subMaps); + buildSubMaps(numGlobals, numGlobalVars * sampleMap.NumMyElements(), + numGlobalVars * sampleMap.MinMyGID(), vars, comm, subMaps); } // build maps to make other conversions -void buildSubMaps(int numGlobals,int numMyElements,int minMyGID,const std::vector & vars,const Epetra_Comm & comm, - std::vector > > & subMaps) -{ - std::vector::const_iterator varItr; - - // compute total number of variables - int numGlobalVars = 0; - for(varItr=vars.begin();varItr!=vars.end();++varItr) - numGlobalVars += *varItr; - - // must be an even number of globals - TEUCHOS_ASSERT((numGlobals%numGlobalVars)==0); - TEUCHOS_ASSERT((numMyElements%numGlobalVars)==0); - TEUCHOS_ASSERT((minMyGID%numGlobalVars)==0); - - int numBlocks = numMyElements/numGlobalVars; - int minBlockID = minMyGID/numGlobalVars; - - subMaps.clear(); - - // index into local block in strided map - int blockOffset = 0; - for(varItr=vars.begin();varItr!=vars.end();++varItr) { - int numLocalVars = *varItr; - int numAllElmts = numLocalVars*numGlobals/numGlobalVars; - int numMyElmts = numLocalVars * numBlocks; - - // create global arrays describing the as of yet uncreated maps - std::vector subGlobals; - std::vector contigGlobals; // the contiguous globals - - // loop over each block of variables - int count = 0; - for(int blockNum=0;blockNum& vars, + const Epetra_Comm& comm, + std::vector > >& subMaps) { + std::vector::const_iterator varItr; + + // compute total number of variables + int numGlobalVars = 0; + for (varItr = vars.begin(); varItr != vars.end(); ++varItr) numGlobalVars += *varItr; + + // must be an even number of globals + TEUCHOS_ASSERT((numGlobals % numGlobalVars) == 0); + TEUCHOS_ASSERT((numMyElements % numGlobalVars) == 0); + TEUCHOS_ASSERT((minMyGID % numGlobalVars) == 0); + + int numBlocks = numMyElements / numGlobalVars; + int minBlockID = minMyGID / numGlobalVars; + + subMaps.clear(); + + // index into local block in strided map + int blockOffset = 0; + for (varItr = vars.begin(); varItr != vars.end(); ++varItr) { + int numLocalVars = *varItr; + int numAllElmts = numLocalVars * numGlobals / numGlobalVars; + int numMyElmts = numLocalVars * numBlocks; + + // create global arrays describing the as of yet uncreated maps + std::vector subGlobals; + std::vector contigGlobals; // the contiguous globals + + // loop over each block of variables + int count = 0; + for (int blockNum = 0; blockNum < numBlocks; blockNum++) { + // loop over each local variable in the block + for (int local = 0; local < numLocalVars; ++local) { + // global block number = minGID+blockNum + // block begin global id = numGlobalVars*(minGID+blockNum) + // global id block offset = blockOffset+local + subGlobals.push_back((minBlockID + blockNum) * numGlobalVars + blockOffset + local); + + // also build the contiguous IDs + contigGlobals.push_back(numLocalVars * minBlockID + count); + count++; } + } - // sanity check - assert((unsigned int) numMyElmts==subGlobals.size()); + // sanity check + assert((unsigned int)numMyElmts == subGlobals.size()); - // create the map with contiguous elements and the map with global elements - RCP subMap = rcp(new Epetra_Map(numAllElmts,numMyElmts,&subGlobals[0],0,comm)); - RCP contigMap = rcp(new Epetra_Map(numAllElmts,numMyElmts,&contigGlobals[0],0,comm)); + // create the map with contiguous elements and the map with global elements + RCP subMap = rcp(new Epetra_Map(numAllElmts, numMyElmts, &subGlobals[0], 0, comm)); + RCP contigMap = + rcp(new Epetra_Map(numAllElmts, numMyElmts, &contigGlobals[0], 0, comm)); - Teuchos::set_extra_data(contigMap,"contigMap",Teuchos::inOutArg(subMap)); - subMaps.push_back(std::make_pair(numLocalVars,subMap)); + Teuchos::set_extra_data(contigMap, "contigMap", Teuchos::inOutArg(subMap)); + subMaps.push_back(std::make_pair(numLocalVars, subMap)); - // update the block offset - blockOffset += numLocalVars; - } + // update the block offset + blockOffset += numLocalVars; + } } -void buildExportImport(const Epetra_Map & baseMap, const std::vector > > & subMaps, - std::vector > & subExport, - std::vector > & subImport) -{ - std::vector > >::const_iterator mapItr; - - // build importers and exporters - for(mapItr=subMaps.begin();mapItr!=subMaps.end();++mapItr) { - // exctract basic map - const Epetra_Map & map = *(mapItr->second); - - // add new elements to vectors - subImport.push_back(rcp(new Epetra_Import(map,baseMap))); - subExport.push_back(rcp(new Epetra_Export(map,baseMap))); - } +void buildExportImport(const Epetra_Map& baseMap, + const std::vector > >& subMaps, + std::vector >& subExport, + std::vector >& subImport) { + std::vector > >::const_iterator mapItr; + + // build importers and exporters + for (mapItr = subMaps.begin(); mapItr != subMaps.end(); ++mapItr) { + // exctract basic map + const Epetra_Map& map = *(mapItr->second); + + // add new elements to vectors + subImport.push_back(rcp(new Epetra_Import(map, baseMap))); + subExport.push_back(rcp(new Epetra_Export(map, baseMap))); + } } -void buildSubVectors(const std::vector > > & subMaps,std::vector > & subVectors,int count) -{ - std::vector > >::const_iterator mapItr; - - // build vectors - for(mapItr=subMaps.begin();mapItr!=subMaps.end();++mapItr) { - // exctract basic map - const Epetra_Map & map = *(Teuchos::get_extra_data >(mapItr->second,"contigMap")); - - // add new elements to vectors - RCP mv = rcp(new Epetra_MultiVector(map,count)); - Teuchos::set_extra_data(mapItr->second,"globalMap",Teuchos::inOutArg(mv)); - subVectors.push_back(mv); - } +void buildSubVectors(const std::vector > >& subMaps, + std::vector >& subVectors, int count) { + std::vector > >::const_iterator mapItr; + + // build vectors + for (mapItr = subMaps.begin(); mapItr != subMaps.end(); ++mapItr) { + // exctract basic map + const Epetra_Map& map = + *(Teuchos::get_extra_data >(mapItr->second, "contigMap")); + + // add new elements to vectors + RCP mv = rcp(new Epetra_MultiVector(map, count)); + Teuchos::set_extra_data(mapItr->second, "globalMap", Teuchos::inOutArg(mv)); + subVectors.push_back(mv); + } } -void associateSubVectors(const std::vector > > & subMaps,std::vector > & subVectors) -{ - std::vector > >::const_iterator mapItr; - std::vector >::iterator vecItr; +void associateSubVectors(const std::vector > >& subMaps, + std::vector >& subVectors) { + std::vector > >::const_iterator mapItr; + std::vector >::iterator vecItr; - TEUCHOS_ASSERT(subMaps.size()==subVectors.size()); + TEUCHOS_ASSERT(subMaps.size() == subVectors.size()); - // associate the sub vectors with the subMaps - for(mapItr=subMaps.begin(),vecItr=subVectors.begin();mapItr!=subMaps.end();++mapItr,++vecItr) - Teuchos::set_extra_data(mapItr->second,"globalMap",Teuchos::inOutArg(*vecItr)); + // associate the sub vectors with the subMaps + for (mapItr = subMaps.begin(), vecItr = subVectors.begin(); mapItr != subMaps.end(); + ++mapItr, ++vecItr) + Teuchos::set_extra_data(mapItr->second, "globalMap", Teuchos::inOutArg(*vecItr)); } // build a single subblock Epetra_CrsMatrix -RCP buildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector > > & subMaps) -{ - // get the number of variables families - int numVarFamily = subMaps.size(); - - TEUCHOS_ASSERT(i>=0 && i=0 && j >(subMaps[i].second,"contigMap"); - const Epetra_Map & colMap = *Teuchos::get_extra_data >(subMaps[j].second,"contigMap"); - int colFamilyCnt = subMaps[j].first; - - // compute the number of global variables - // and the row and column block offset - int numGlobalVars = 0; - int rowBlockOffset = 0; - int colBlockOffset = 0; - for(int k=0;k mat = rcp(new Epetra_CrsMatrix(Copy,rowMap,0)); - - // get entry information - int numMyRows = rowMap.NumMyElements(); - int maxNumEntries = A.GlobalMaxNumEntries(); - - // for extraction - std::vector indices(maxNumEntries); - std::vector values(maxNumEntries); - - // for insertion - std::vector colIndices(maxNumEntries); - std::vector colValues(maxNumEntries); - - // insert each row into subblock - // let FillComplete handle column distribution - for(int localRow=0;localRow=0); - TEUCHOS_ASSERT(contigRow>=0); - - // extract a global row copy - int err = localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]); - TEUCHOS_ASSERT(err==0); - - int numOwnedCols = 0; - for(int localCol=0;localCol globalCol); - - // is this column in the variable family - if(inFamily) { - int familyOffset = globalCol-(block*numGlobalVars+colBlockOffset); - - colIndices[numOwnedCols] = block*colFamilyCnt + familyOffset; - colValues[numOwnedCols] = values[localCol]; - - numOwnedCols++; - } +RCP buildSubBlock(int i, int j, const Epetra_CrsMatrix& A, + const std::vector > >& subMaps) { + // get the number of variables families + int numVarFamily = subMaps.size(); + + TEUCHOS_ASSERT(i >= 0 && i < numVarFamily); + TEUCHOS_ASSERT(j >= 0 && j < numVarFamily); + + const Epetra_Map& gRowMap = *subMaps[i].second; + const Epetra_Map& rowMap = + *Teuchos::get_extra_data >(subMaps[i].second, "contigMap"); + const Epetra_Map& colMap = + *Teuchos::get_extra_data >(subMaps[j].second, "contigMap"); + int colFamilyCnt = subMaps[j].first; + + // compute the number of global variables + // and the row and column block offset + int numGlobalVars = 0; + int rowBlockOffset = 0; + int colBlockOffset = 0; + for (int k = 0; k < numVarFamily; k++) { + numGlobalVars += subMaps[k].first; + + // compute block offsets + if (k < i) rowBlockOffset += subMaps[k].first; + if (k < j) colBlockOffset += subMaps[k].first; + } + + // copy all global rows to here + Epetra_Import import(gRowMap, A.RowMap()); + Epetra_CrsMatrix localA(Copy, gRowMap, 0); + localA.Import(A, import, Insert); + + RCP mat = rcp(new Epetra_CrsMatrix(Copy, rowMap, 0)); + + // get entry information + int numMyRows = rowMap.NumMyElements(); + int maxNumEntries = A.GlobalMaxNumEntries(); + + // for extraction + std::vector indices(maxNumEntries); + std::vector values(maxNumEntries); + + // for insertion + std::vector colIndices(maxNumEntries); + std::vector colValues(maxNumEntries); + + // insert each row into subblock + // let FillComplete handle column distribution + for (int localRow = 0; localRow < numMyRows; localRow++) { + int numEntries = -1; + int globalRow = gRowMap.GID(localRow); + int contigRow = rowMap.GID(localRow); + + TEUCHOS_ASSERT(globalRow >= 0); + TEUCHOS_ASSERT(contigRow >= 0); + + // extract a global row copy + int err = + localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]); + TEUCHOS_ASSERT(err == 0); + + int numOwnedCols = 0; + for (int localCol = 0; localCol < numEntries; localCol++) { + int globalCol = indices[localCol]; + + // determinate which block this column ID is in + int block = globalCol / numGlobalVars; + + bool inFamily = true; + + // test the beginning of the block + inFamily &= (block * numGlobalVars + colBlockOffset <= globalCol); + inFamily &= ((block * numGlobalVars + colBlockOffset + colFamilyCnt) > globalCol); + + // is this column in the variable family + if (inFamily) { + int familyOffset = globalCol - (block * numGlobalVars + colBlockOffset); + + colIndices[numOwnedCols] = block * colFamilyCnt + familyOffset; + colValues[numOwnedCols] = values[localCol]; + + numOwnedCols++; } + } - // insert it into the new matrix - mat->InsertGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]); - } + // insert it into the new matrix + mat->InsertGlobalValues(contigRow, numOwnedCols, &colValues[0], &colIndices[0]); + } - // fill it and automagically optimize the storage - mat->FillComplete(colMap,rowMap); + // fill it and automagically optimize the storage + mat->FillComplete(colMap, rowMap); - return mat; + return mat; } // rebuild a single subblock Epetra_CrsMatrix -void rebuildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector > > & subMaps,Epetra_CrsMatrix & mat) -{ - // get the number of variables families - int numVarFamily = subMaps.size(); - - TEUCHOS_ASSERT(i>=0 && i=0 && j >(subMaps[i].second,"contigMap"); - int colFamilyCnt = subMaps[j].first; - - // compute the number of global variables - // and the row and column block offset - int numGlobalVars = 0; - int rowBlockOffset = 0; - int colBlockOffset = 0; - for(int k=0;k indices(maxNumEntries); - std::vector values(maxNumEntries); - - // for insertion - std::vector colIndices(maxNumEntries); - std::vector colValues(maxNumEntries); - - // insert each row into subblock - // let FillComplete handle column distribution - for(int localRow=0;localRow=0); - TEUCHOS_ASSERT(contigRow>=0); - - // extract a global row copy - int err = localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]); - TEUCHOS_ASSERT(err==0); - - int numOwnedCols = 0; - for(int localCol=0;localCol globalCol); - - // is this column in the variable family - if(inFamily) { - int familyOffset = globalCol-(block*numGlobalVars+colBlockOffset); - - colIndices[numOwnedCols] = block*colFamilyCnt + familyOffset; - colValues[numOwnedCols] = values[localCol]; - - numOwnedCols++; - } +void rebuildSubBlock(int i, int j, const Epetra_CrsMatrix& A, + const std::vector > >& subMaps, + Epetra_CrsMatrix& mat) { + // get the number of variables families + int numVarFamily = subMaps.size(); + + TEUCHOS_ASSERT(i >= 0 && i < numVarFamily); + TEUCHOS_ASSERT(j >= 0 && j < numVarFamily); + TEUCHOS_ASSERT(mat.Filled()); + + const Epetra_Map& gRowMap = *subMaps[i].second; + const Epetra_Map& rowMap = + *Teuchos::get_extra_data >(subMaps[i].second, "contigMap"); + int colFamilyCnt = subMaps[j].first; + + // compute the number of global variables + // and the row and column block offset + int numGlobalVars = 0; + int rowBlockOffset = 0; + int colBlockOffset = 0; + for (int k = 0; k < numVarFamily; k++) { + numGlobalVars += subMaps[k].first; + + // compute block offsets + if (k < i) rowBlockOffset += subMaps[k].first; + if (k < j) colBlockOffset += subMaps[k].first; + } + + // copy all global rows to here + Epetra_Import import(gRowMap, A.RowMap()); + Epetra_CrsMatrix localA(Copy, gRowMap, 0); + localA.Import(A, import, Insert); + + // clear out the old matrix + mat.PutScalar(0.0); + + // get entry information + int numMyRows = rowMap.NumMyElements(); + int maxNumEntries = A.GlobalMaxNumEntries(); + + // for extraction + std::vector indices(maxNumEntries); + std::vector values(maxNumEntries); + + // for insertion + std::vector colIndices(maxNumEntries); + std::vector colValues(maxNumEntries); + + // insert each row into subblock + // let FillComplete handle column distribution + for (int localRow = 0; localRow < numMyRows; localRow++) { + int numEntries = -1; + int globalRow = gRowMap.GID(localRow); + int contigRow = rowMap.GID(localRow); + + TEUCHOS_ASSERT(globalRow >= 0); + TEUCHOS_ASSERT(contigRow >= 0); + + // extract a global row copy + int err = + localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]); + TEUCHOS_ASSERT(err == 0); + + int numOwnedCols = 0; + for (int localCol = 0; localCol < numEntries; localCol++) { + int globalCol = indices[localCol]; + + // determinate which block this column ID is in + int block = globalCol / numGlobalVars; + + bool inFamily = true; + + // test the beginning of the block + inFamily &= (block * numGlobalVars + colBlockOffset <= globalCol); + inFamily &= ((block * numGlobalVars + colBlockOffset + colFamilyCnt) > globalCol); + + // is this column in the variable family + if (inFamily) { + int familyOffset = globalCol - (block * numGlobalVars + colBlockOffset); + + colIndices[numOwnedCols] = block * colFamilyCnt + familyOffset; + colValues[numOwnedCols] = values[localCol]; + + numOwnedCols++; } + } - // insert it into the new matrix - mat.SumIntoGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]); - } + // insert it into the new matrix + mat.SumIntoGlobalValues(contigRow, numOwnedCols, &colValues[0], &colIndices[0]); + } } - // collect subvectors into a single global vector -void many2one(Epetra_MultiVector & one, const std::vector > & many, - const std::vector > & subExport) -{ - // std::vector >::const_iterator vecItr; - std::vector >::const_iterator vecItr; - std::vector >::const_iterator expItr; - - // using Exporters fill the empty vector from the sub-vectors - for(vecItr=many.begin(),expItr=subExport.begin(); - vecItr!=many.end();++vecItr,++expItr) { - - // for ease of access to the source - RCP srcVec = *vecItr; - - // extract the map with global indicies from the current vector - const Epetra_Map & globalMap = *(Teuchos::get_extra_data >(srcVec,"globalMap")); - - // build the export vector as a view of the destination - Epetra_MultiVector exportVector(View,globalMap,srcVec->Values(),srcVec->Stride(),srcVec->NumVectors()); - one.Export(exportVector,**expItr,Insert); - } +void many2one(Epetra_MultiVector& one, const std::vector >& many, + const std::vector >& subExport) { + // std::vector >::const_iterator vecItr; + std::vector >::const_iterator vecItr; + std::vector >::const_iterator expItr; + + // using Exporters fill the empty vector from the sub-vectors + for (vecItr = many.begin(), expItr = subExport.begin(); vecItr != many.end(); + ++vecItr, ++expItr) { + // for ease of access to the source + RCP srcVec = *vecItr; + + // extract the map with global indicies from the current vector + const Epetra_Map& globalMap = *(Teuchos::get_extra_data >(srcVec, "globalMap")); + + // build the export vector as a view of the destination + Epetra_MultiVector exportVector(View, globalMap, srcVec->Values(), srcVec->Stride(), + srcVec->NumVectors()); + one.Export(exportVector, **expItr, Insert); + } } // distribute one global vector into a many subvectors -void one2many(std::vector > & many,const Epetra_MultiVector & single, - const std::vector > & subImport) -{ - // std::vector >::const_iterator vecItr; - std::vector >::const_iterator vecItr; - std::vector >::const_iterator impItr; - - // using Importers fill the sub vectors from the mama vector - for(vecItr=many.begin(),impItr=subImport.begin(); - vecItr!=many.end();++vecItr,++impItr) { - // for ease of access to the destination - RCP destVec = *vecItr; - - // extract the map with global indicies from the current vector - const Epetra_Map & globalMap = *(Teuchos::get_extra_data >(destVec,"globalMap")); - - // build the import vector as a view on the destination - Epetra_MultiVector importVector(View,globalMap,destVec->Values(),destVec->Stride(),destVec->NumVectors()); - - // perform the import - importVector.Import(single,**impItr,Insert); - } +void one2many(std::vector >& many, const Epetra_MultiVector& single, + const std::vector >& subImport) { + // std::vector >::const_iterator vecItr; + std::vector >::const_iterator vecItr; + std::vector >::const_iterator impItr; + + // using Importers fill the sub vectors from the mama vector + for (vecItr = many.begin(), impItr = subImport.begin(); vecItr != many.end(); + ++vecItr, ++impItr) { + // for ease of access to the destination + RCP destVec = *vecItr; + + // extract the map with global indicies from the current vector + const Epetra_Map& globalMap = + *(Teuchos::get_extra_data >(destVec, "globalMap")); + + // build the import vector as a view on the destination + Epetra_MultiVector importVector(View, globalMap, destVec->Values(), destVec->Stride(), + destVec->NumVectors()); + + // perform the import + importVector.Import(single, **impItr, Insert); + } } -} -} // end namespace Epetra -} // end namespace Teko +} // namespace Strided +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_InterlacedEpetra.hpp b/packages/teko/src/Epetra/Teko_InterlacedEpetra.hpp index fe5d5358d68a..c5639a73476a 100644 --- a/packages/teko/src/Epetra/Teko_InterlacedEpetra.hpp +++ b/packages/teko/src/Epetra/Teko_InterlacedEpetra.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,9 +52,9 @@ // include basic Epetra information #ifdef HAVE_MPI - #include "Epetra_MpiComm.h" +#include "Epetra_MpiComm.h" #else - #include "Epetra_SerialComm.h" +#include "Epetra_SerialComm.h" #endif #include "Epetra_Map.h" #include "Epetra_CrsMatrix.h" @@ -70,130 +70,136 @@ namespace Epetra { namespace Strided { /** Build maps to make other conversions. This functions build maps assuming - * that there are number of variables and you want to break them all up - * into single blocks. - * - * \param[in] numGlobals The number of global unknowns in the original map - * \param[in] numVars The number of sub maps to build - * \param[in] comm Communicator to use in construction of the maps - * \param[in,out] subMaps The maps for each block of unknowns. This vector - * will be of length numVars. The integer - * in the pair is the number of local variables being - * represented. For this function it will always be 1. - * The map itself will contain the global indices from - * the original problem. This is useful for Export/Import - * operations. The RCP for the map contains another map - * associated with the string "contigMap" based on a - * contiguous unknown numbering. - * - * \note numGlobals % numVars == 0 - */ -void buildSubMaps(int numGlobals,int numVars,const Epetra_Comm & comm, - std::vector > > & subMaps); + * that there are number of variables and you want to break them all up + * into single blocks. + * + * \param[in] numGlobals The number of global unknowns in the original map + * \param[in] numVars The number of sub maps to build + * \param[in] comm Communicator to use in construction of the maps + * \param[in,out] subMaps The maps for each block of unknowns. This vector + * will be of length numVars. The integer + * in the pair is the number of local variables being + * represented. For this function it will always be 1. + * The map itself will contain the global indices from + * the original problem. This is useful for Export/Import + * operations. The RCP for the map contains another map + * associated with the string "contigMap" based on a + * contiguous unknown numbering. + * + * \note numGlobals % numVars == 0 + */ +void buildSubMaps(int numGlobals, int numVars, const Epetra_Comm& comm, + std::vector > >& subMaps); /** Build maps to make other conversions. This functions build maps assuming - * that there are number of variables and you want to break them all up - * into blocks with sizes (in the number of varaibles) specified in vars - * - * \param[in] numGlobals The number of global unknowns in the original map - * \param[in] vars Breakdown of each varaible to build. - * \param[in] comm Communicator to use in construction of the maps - * \param[in,out] subMaps The maps for each block of unknowns. This vector - * will be of length vars.size(). The integer - * in the pair is the number of local variables being - * represented (this will be from vars). - * The map itself will contain the global indices from - * the original problem. This is useful for Export/Import - * operations. The RCP for the map contains another map - * associated with the string "contigMap" based on a - * contiguous unknown numbering. - * - * \note numGlobals % sum(vars) == 0 - */ -void buildSubMaps(int numGlobals,const std::vector & vars,const Epetra_Comm & comm, - std::vector > > & subMaps); + * that there are number of variables and you want to break them all up + * into blocks with sizes (in the number of varaibles) specified in vars + * + * \param[in] numGlobals The number of global unknowns in the original map + * \param[in] vars Breakdown of each varaible to build. + * \param[in] comm Communicator to use in construction of the maps + * \param[in,out] subMaps The maps for each block of unknowns. This vector + * will be of length vars.size(). The integer + * in the pair is the number of local variables being + * represented (this will be from vars). + * The map itself will contain the global indices from + * the original problem. This is useful for Export/Import + * operations. The RCP for the map contains another map + * associated with the string "contigMap" based on a + * contiguous unknown numbering. + * + * \note numGlobals % sum(vars) == 0 + */ +void buildSubMaps(int numGlobals, const std::vector& vars, const Epetra_Comm& comm, + std::vector > >& subMaps); /** Build maps to make other conversions. This functions build maps assuming - * that there are number of variables and you want to break them all up - * into blocks with sizes (in the number of varaibles) specified in vars - * - * \param[in] numGlobals The number of global unknowns in the original map - * \param[in] numMyElements Number of nodes in this processor. - * \param[in] minMyGID Minimum global ID on this processor. - * \param[in] vars Breakdown of each varaible to build. - * \param[in] comm Communicator to use in construction of the maps - * \param[in,out] subMaps The maps for each block of unknowns. This vector - * will be of length vars.size(). The integer - * in the pair is the number of local variables being - * represented (this will be from vars). - * The map itself will contain the global indices from - * the original problem. This is useful for Export/Import - * operations. The RCP for the map contains another map - * associated with the string "contigMap" based on a - * contiguous unknown numbering. - * - * \note numGlobals % sum(vars) == 0 - */ -void buildSubMaps(int numGlobals,int numMyElements,int minMyGID,const std::vector & vars,const Epetra_Comm & comm, - std::vector > > & subMaps); + * that there are number of variables and you want to break them all up + * into blocks with sizes (in the number of varaibles) specified in vars + * + * \param[in] numGlobals The number of global unknowns in the original map + * \param[in] numMyElements Number of nodes in this processor. + * \param[in] minMyGID Minimum global ID on this processor. + * \param[in] vars Breakdown of each varaible to build. + * \param[in] comm Communicator to use in construction of the maps + * \param[in,out] subMaps The maps for each block of unknowns. This vector + * will be of length vars.size(). The integer + * in the pair is the number of local variables being + * represented (this will be from vars). + * The map itself will contain the global indices from + * the original problem. This is useful for Export/Import + * operations. The RCP for the map contains another map + * associated with the string "contigMap" based on a + * contiguous unknown numbering. + * + * \note numGlobals % sum(vars) == 0 + */ +void buildSubMaps(int numGlobals, int numMyElements, int minMyGID, const std::vector& vars, + const Epetra_Comm& comm, + std::vector > >& subMaps); /** Build maps to make other conversions. This functions build maps assuming - * that there are number of variables and you want to break them all up - * into blocks with sizes (in the number of varaibles) specified in vars - * - * \param[in] globalMap Parent map that describes the parallel layout of the new - * sub maps. - * \param[in] vars Breakdown of each varaible to build. - * \param[in] comm Communicator to use in construction of the maps - * \param[in,out] subMaps The maps for each block of unknowns. This vector - * will be of length vars.size(). The integer - * in the pair is the number of local variables being - * represented (this will be from vars). - * The map itself will contain the global indices from - * the original problem. This is useful for Export/Import - * operations. The RCP for the map contains another map - * associated with the string "contigMap" based on a - * contiguous unknown numbering. - * - * \note numGlobals % sum(vars) == 0 - */ -void buildSubMaps(const Epetra_Map & globalMap,const std::vector & vars,const Epetra_Comm & comm, - std::vector > > & subMaps); + * that there are number of variables and you want to break them all up + * into blocks with sizes (in the number of varaibles) specified in vars + * + * \param[in] globalMap Parent map that describes the parallel layout of the new + * sub maps. + * \param[in] vars Breakdown of each varaible to build. + * \param[in] comm Communicator to use in construction of the maps + * \param[in,out] subMaps The maps for each block of unknowns. This vector + * will be of length vars.size(). The integer + * in the pair is the number of local variables being + * represented (this will be from vars). + * The map itself will contain the global indices from + * the original problem. This is useful for Export/Import + * operations. The RCP for the map contains another map + * associated with the string "contigMap" based on a + * contiguous unknown numbering. + * + * \note numGlobals % sum(vars) == 0 + */ +void buildSubMaps(const Epetra_Map& globalMap, const std::vector& vars, + const Epetra_Comm& comm, + std::vector > >& subMaps); // build conversion import and export operators -void buildExportImport(const Epetra_Map & baseMap, - const std::vector > > & subMaps, - std::vector > & subExport, - std::vector > & subImport); +void buildExportImport(const Epetra_Map& baseMap, + const std::vector > >& subMaps, + std::vector >& subExport, + std::vector >& subImport); // build a vector of subVectors -void buildSubVectors(const std::vector > > & subMaps, - std::vector > & subVectors,int count); +void buildSubVectors(const std::vector > >& subMaps, + std::vector >& subVectors, int count); /** Associate a set of multi-vectors with a set of sub maps (this modifies the "extra data" - * of the subVectors to contain info about the maps. - */ -void associateSubVectors(const std::vector > > & subMaps, - std::vector > & subVectors); + * of the subVectors to contain info about the maps. + */ +void associateSubVectors(const std::vector > >& subMaps, + std::vector >& subVectors); // build a single subblock Epetra_CrsMatrix -Teuchos::RCP buildSubBlock(int i,int j,const Epetra_CrsMatrix & A, - const std::vector > > & subMaps); +Teuchos::RCP buildSubBlock( + int i, int j, const Epetra_CrsMatrix& A, + const std::vector > >& subMaps); // Rebuild a single subblock of a matrix -void rebuildSubBlock(int i,int j,const Epetra_CrsMatrix & A, - const std::vector > > & subMaps,Epetra_CrsMatrix & mat); +void rebuildSubBlock(int i, int j, const Epetra_CrsMatrix& A, + const std::vector > >& subMaps, + Epetra_CrsMatrix& mat); // copy contents of many subvectors to a single vector -void many2one(Epetra_MultiVector & one, const std::vector > & many, - const std::vector > & subExport); +void many2one(Epetra_MultiVector& one, + const std::vector >& many, + const std::vector >& subExport); // copy contents of a single vector to many subvectors -void one2many(std::vector > & many,const Epetra_MultiVector & single, - const std::vector > & subImport); +void one2many(std::vector >& many, + const Epetra_MultiVector& single, + const std::vector >& subImport); -} -} // end namespace Epetra -} // end namespace Teko +} // namespace Strided +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_InverseFactoryOperator.cpp b/packages/teko/src/Epetra/Teko_InverseFactoryOperator.cpp index 962a85f56518..255a2db566a3 100644 --- a/packages/teko/src/Epetra/Teko_InverseFactoryOperator.cpp +++ b/packages/teko/src/Epetra/Teko_InverseFactoryOperator.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -54,173 +54,163 @@ using Teuchos::RCP; using Teuchos::rcp; -using Teuchos::rcpFromRef; using Teuchos::rcp_dynamic_cast; +using Teuchos::rcpFromRef; namespace Teko { namespace Epetra { /** \brief Constructor that takes the InverseFactory that will - * build the operator. - * - * Constructor that takes the InverseFactory that will - * build the operator. - */ -InverseFactoryOperator::InverseFactoryOperator(const Teuchos::RCP & ifp) - : inverseFactory_(ifp), firstBuildComplete_(false), setConstFwdOp_(true) -{ -} + * build the operator. + * + * Constructor that takes the InverseFactory that will + * build the operator. + */ +InverseFactoryOperator::InverseFactoryOperator(const Teuchos::RCP& ifp) + : inverseFactory_(ifp), firstBuildComplete_(false), setConstFwdOp_(true) {} /** \brief Build the underlying data structure for the inverse operator. - * - * Build the underlying data structure for the inverse operator. This - * permits the manipulation of the state object for an inverse operator. - * - * \param[in] clearOld If true any previously constructed - * operator will be wiped out and - * a new one created. If false, anoperator - * will be created only if the current one is - * empty (i.e. initPreconditioner - * had not been called). - */ -void InverseFactoryOperator::initInverse(bool clearOld) -{ - if(not clearOld) - return; - invOperator_ = Teuchos::null; + * + * Build the underlying data structure for the inverse operator. This + * permits the manipulation of the state object for an inverse operator. + * + * \param[in] clearOld If true any previously constructed + * operator will be wiped out and + * a new one created. If false, anoperator + * will be created only if the current one is + * empty (i.e. initPreconditioner + * had not been called). + */ +void InverseFactoryOperator::initInverse(bool clearOld) { + if (not clearOld) return; + invOperator_ = Teuchos::null; } -/** \brief Build this inverse operator from an Epetra_Operator - * passed in to this object. - * - * Build this inverse opeerator from an Epetra_Operator - * passed in to this object. If this Epetra_Operator - * is an EpetraOperatorWrapper object then the block Thyra components - * are extracted. - * - * \param[in] A The Epetra source operator. - * \param[in] clear If true, than any previous state saved by the operator - * is discarded. - */ -void InverseFactoryOperator::buildInverseOperator(const Teuchos::RCP & A,bool clear) -{ - Teko_DEBUG_SCOPE("InverseFactoryOperator::buildInverseOperator",10); +/** \brief Build this inverse operator from an Epetra_Operator + * passed in to this object. + * + * Build this inverse opeerator from an Epetra_Operator + * passed in to this object. If this Epetra_Operator + * is an EpetraOperatorWrapper object then the block Thyra components + * are extracted. + * + * \param[in] A The Epetra source operator. + * \param[in] clear If true, than any previous state saved by the operator + * is discarded. + */ +void InverseFactoryOperator::buildInverseOperator(const Teuchos::RCP& A, + bool clear) { + Teko_DEBUG_SCOPE("InverseFactoryOperator::buildInverseOperator", 10); - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - RCP > thyraA = extractLinearOp(A); + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + RCP > thyraA = extractLinearOp(A); - // set the mapping strategy - SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A)))); + // set the mapping strategy + SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A)))); - initInverse(clear); + initInverse(clear); - // actually build the inverse operator - invOperator_ = Teko::buildInverse(*inverseFactory_,thyraA); + // actually build the inverse operator + invOperator_ = Teko::buildInverse(*inverseFactory_, thyraA); - SetOperator(invOperator_,false); + SetOperator(invOperator_, false); - firstBuildComplete_ = true; + firstBuildComplete_ = true; - if(setConstFwdOp_) - fwdOp_ = A; + if (setConstFwdOp_) fwdOp_ = A; - setConstFwdOp_ = true; + setConstFwdOp_ = true; - TEUCHOS_ASSERT(invOperator_!=Teuchos::null); - TEUCHOS_ASSERT(getForwardOp()!=Teuchos::null); - TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null); - TEUCHOS_ASSERT(getMapStrategy()!=Teuchos::null); - TEUCHOS_ASSERT(firstBuildComplete_==true); + TEUCHOS_ASSERT(invOperator_ != Teuchos::null); + TEUCHOS_ASSERT(getForwardOp() != Teuchos::null); + TEUCHOS_ASSERT(getThyraOp() != Teuchos::null); + TEUCHOS_ASSERT(getMapStrategy() != Teuchos::null); + TEUCHOS_ASSERT(firstBuildComplete_ == true); } -void InverseFactoryOperator::buildInverseOperator(const Teuchos::RCP & A,bool /* clear */) -{ - setConstFwdOp_ = false; +void InverseFactoryOperator::buildInverseOperator(const Teuchos::RCP& A, + bool /* clear */) { + setConstFwdOp_ = false; - fwdOp_.initialize(A); + fwdOp_.initialize(A); - buildInverseOperator(A.getConst()); + buildInverseOperator(A.getConst()); - TEUCHOS_ASSERT(setConstFwdOp_==true); + TEUCHOS_ASSERT(setConstFwdOp_ == true); } /** \brief Rebuild this inverse from an Epetra_Operator passed - * in this to object. - * - * Rebuild this inverse from an Epetra_Operator passed - * in this to object. If buildInverseOperator has not been called - * the inverse operator will be built instead. Otherwise efforts are taken - * to only rebuild what is neccessary. Also, that this Epetra_Operator - * may be an EpetraOperatorWrapper object, so the block Thyra components - * can be extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - */ -void InverseFactoryOperator::rebuildInverseOperator(const Teuchos::RCP & A) -{ - Teko_DEBUG_SCOPE("InverseFactoryOperator::rebuildPreconditioner",10); - - // if the inverse hasn't been built yet, rebuild from scratch - if(not firstBuildComplete_) { - buildInverseOperator(A,false); - return; - } - - RCP > thyraA = extractLinearOp(A); - Teko::rebuildInverse(*inverseFactory_,thyraA,invOperator_); - - if(setConstFwdOp_) - fwdOp_.initialize(A); - - SetOperator(invOperator_,false); - - setConstFwdOp_ = true; - - TEUCHOS_ASSERT(getForwardOp()!=Teuchos::null); - TEUCHOS_ASSERT(invOperator_!=Teuchos::null); - TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null); - TEUCHOS_ASSERT(firstBuildComplete_==true); + * in this to object. + * + * Rebuild this inverse from an Epetra_Operator passed + * in this to object. If buildInverseOperator has not been called + * the inverse operator will be built instead. Otherwise efforts are taken + * to only rebuild what is neccessary. Also, that this Epetra_Operator + * may be an EpetraOperatorWrapper object, so the block Thyra components + * can be extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + */ +void InverseFactoryOperator::rebuildInverseOperator(const Teuchos::RCP& A) { + Teko_DEBUG_SCOPE("InverseFactoryOperator::rebuildPreconditioner", 10); + + // if the inverse hasn't been built yet, rebuild from scratch + if (not firstBuildComplete_) { + buildInverseOperator(A, false); + return; + } + + RCP > thyraA = extractLinearOp(A); + Teko::rebuildInverse(*inverseFactory_, thyraA, invOperator_); + + if (setConstFwdOp_) fwdOp_.initialize(A); + + SetOperator(invOperator_, false); + + setConstFwdOp_ = true; + + TEUCHOS_ASSERT(getForwardOp() != Teuchos::null); + TEUCHOS_ASSERT(invOperator_ != Teuchos::null); + TEUCHOS_ASSERT(getThyraOp() != Teuchos::null); + TEUCHOS_ASSERT(firstBuildComplete_ == true); } -void InverseFactoryOperator::rebuildInverseOperator(const Teuchos::RCP & A) -{ - setConstFwdOp_ = false; +void InverseFactoryOperator::rebuildInverseOperator(const Teuchos::RCP& A) { + setConstFwdOp_ = false; + + fwdOp_.initialize(A); - fwdOp_.initialize(A); - - // build from constant epetra operator - rebuildInverseOperator(A.getConst()); + // build from constant epetra operator + rebuildInverseOperator(A.getConst()); - TEUCHOS_ASSERT(setConstFwdOp_==true); + TEUCHOS_ASSERT(setConstFwdOp_ == true); } -Teuchos::RCP > InverseFactoryOperator::extractLinearOp(const Teuchos::RCP & A) const -{ - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - const RCP & eow = rcp_dynamic_cast(A); - - // if it is an EpetraOperatorWrapper, then get the Thyra operator - if(eow!=Teuchos::null) - return eow->getThyraOp(); - - // otherwise wrap it up as a thyra operator - return Thyra::epetraLinearOp(A); +Teuchos::RCP > InverseFactoryOperator::extractLinearOp( + const Teuchos::RCP& A) const { + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + const RCP& eow = rcp_dynamic_cast(A); + + // if it is an EpetraOperatorWrapper, then get the Thyra operator + if (eow != Teuchos::null) return eow->getThyraOp(); + + // otherwise wrap it up as a thyra operator + return Thyra::epetraLinearOp(A); } -Teuchos::RCP InverseFactoryOperator::extractMappingStrategy(const Teuchos::RCP & A) const -{ - // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator - const RCP & eow = rcp_dynamic_cast(A); - - // if it is an EpetraOperatorWrapper, then get the Thyra operator - if(eow!=Teuchos::null) - return eow->getMapStrategy(); - - // otherwise wrap it up as a thyra operator - RCP range = rcpFromRef(A->OperatorRangeMap()); - RCP domain = rcpFromRef(A->OperatorDomainMap()); - return rcp(new BasicMappingStrategy(range,domain,A->Comm())); +Teuchos::RCP InverseFactoryOperator::extractMappingStrategy( + const Teuchos::RCP& A) const { + // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator + const RCP& eow = rcp_dynamic_cast(A); + + // if it is an EpetraOperatorWrapper, then get the Thyra operator + if (eow != Teuchos::null) return eow->getMapStrategy(); + + // otherwise wrap it up as a thyra operator + RCP range = rcpFromRef(A->OperatorRangeMap()); + RCP domain = rcpFromRef(A->OperatorDomainMap()); + return rcp(new BasicMappingStrategy(range, domain, A->Comm())); } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_InverseFactoryOperator.hpp b/packages/teko/src/Epetra/Teko_InverseFactoryOperator.hpp index 4a2091de661f..7d73c4dc961f 100644 --- a/packages/teko/src/Epetra/Teko_InverseFactoryOperator.hpp +++ b/packages/teko/src/Epetra/Teko_InverseFactoryOperator.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -56,121 +56,124 @@ namespace Teko { namespace Epetra { /** \brief A single Epetra wrapper for all operators constructed - * from an inverse operator. - * - * This class uses the Teko inverse factories to - * build an Epetra_Operator that behaves like the inverse operatotr. - * This is done by using the InverseFactory, and letting - * it build whatever operator is neccessary. Thus the Epetra - * "layer" is just a single class that handles any generic - * InverseFactory. - */ + * from an inverse operator. + * + * This class uses the Teko inverse factories to + * build an Epetra_Operator that behaves like the inverse operatotr. + * This is done by using the InverseFactory, and letting + * it build whatever operator is neccessary. Thus the Epetra + * "layer" is just a single class that handles any generic + * InverseFactory. + */ class InverseFactoryOperator : public EpetraInverseOpWrapper { -public: - /** \brief Constructor that takes the InverseFactory that will - * build the operator. - * - * Constructor that takes the InverseFactory that will - * build the operator. - */ - InverseFactoryOperator(const Teuchos::RCP & bfp); - - /** \brief Build the underlying data structure for the inverse operator. - * - * Build the underlying data structure for the inverse operator. This - * permits the manipulation of the state object for an inverse operator. - * - * \param[in] clearOld If true any previously constructed - * operator will be wiped out and - * a new one created. If false, anoperator - * will be created only if the current one is - * empty (i.e. initPreconditioner - * had not been called). - */ - virtual void initInverse(bool clearOld=false); - - /** \brief Build this inverse operator from an Epetra_Operator - * passed in to this object. - * - * Build this inverse opeerator from an Epetra_Operator - * passed in to this object. If this Epetra_Operator - * is an EpetraOperatorWrapper object then the block Thyra components - * are extracted. - * - * \param[in] A The Epetra source operator. - * \param[in] clear If true, than any previous state saved by the operator - * is discarded. - */ - virtual void buildInverseOperator(const Teuchos::RCP & A,bool clear=true); - - /** \brief Build this inverse operator from an Epetra_Operator - * passed in to this object. - * - * Build this inverse opeerator from an Epetra_Operator - * passed in to this object. If this Epetra_Operator - * is an EpetraOperatorWrapper object then the block Thyra components - * are extracted. - * - * \param[in] A The Epetra source operator. - * \param[in] clear If true, than any previous state saved by the operator - * is discarded. - */ - virtual void buildInverseOperator(const Teuchos::RCP & A,bool clear=true); - - /** \brief Rebuild this inverse from an Epetra_Operator passed - * in this to object. - * - * Rebuild this inverse from an Epetra_Operator passed - * in this to object. If buildInverseOperator has not been called - * the inverse operator will be built instead. Otherwise efforts are taken - * to only rebuild what is neccessary. Also, that this Epetra_Operator - * may be an EpetraOperatorWrapper object, so the block Thyra components - * can be extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - */ - virtual void rebuildInverseOperator(const Teuchos::RCP & A); - - /** \brief Rebuild this inverse from an Epetra_Operator passed - * in this to object. - * - * Rebuild this inverse from an Epetra_Operator passed - * in this to object. If buildInverseOperator has not been called - * the inverse operator will be built instead. Otherwise efforts are taken - * to only rebuild what is neccessary. Also, that this Epetra_Operator - * may be an EpetraOperatorWrapper object, so the block Thyra components - * can be extracted. - * - * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) - */ - virtual void rebuildInverseOperator(const Teuchos::RCP & A); - - /** Extract the forward op used by buildInverseOperator - * or rebuildInverseOperator. - */ - Teuchos::RCP getForwardOp() const { return fwdOp_.getConstObj(); } - - /** Extract the forward op used by buildInverseOperator - * or rebuildInverseOperator. - */ - Teuchos::RCP getNonconstForwardOp() const { return fwdOp_.getNonconstObj(); } - -protected: - Teuchos::RCP > extractLinearOp(const Teuchos::RCP & A) const; - Teuchos::RCP extractMappingStrategy(const Teuchos::RCP & A) const; - - InverseFactoryOperator(); - InverseFactoryOperator(const InverseFactoryOperator &); - - Teuchos::RCP inverseFactory_; - Teko::ModifiableLinearOp invOperator_; - bool firstBuildComplete_; - - Teuchos::ConstNonconstObjectContainer fwdOp_; - bool setConstFwdOp_; + public: + /** \brief Constructor that takes the InverseFactory that will + * build the operator. + * + * Constructor that takes the InverseFactory that will + * build the operator. + */ + InverseFactoryOperator(const Teuchos::RCP &bfp); + + /** \brief Build the underlying data structure for the inverse operator. + * + * Build the underlying data structure for the inverse operator. This + * permits the manipulation of the state object for an inverse operator. + * + * \param[in] clearOld If true any previously constructed + * operator will be wiped out and + * a new one created. If false, anoperator + * will be created only if the current one is + * empty (i.e. initPreconditioner + * had not been called). + */ + virtual void initInverse(bool clearOld = false); + + /** \brief Build this inverse operator from an Epetra_Operator + * passed in to this object. + * + * Build this inverse opeerator from an Epetra_Operator + * passed in to this object. If this Epetra_Operator + * is an EpetraOperatorWrapper object then the block Thyra components + * are extracted. + * + * \param[in] A The Epetra source operator. + * \param[in] clear If true, than any previous state saved by the operator + * is discarded. + */ + virtual void buildInverseOperator(const Teuchos::RCP &A, + bool clear = true); + + /** \brief Build this inverse operator from an Epetra_Operator + * passed in to this object. + * + * Build this inverse opeerator from an Epetra_Operator + * passed in to this object. If this Epetra_Operator + * is an EpetraOperatorWrapper object then the block Thyra components + * are extracted. + * + * \param[in] A The Epetra source operator. + * \param[in] clear If true, than any previous state saved by the operator + * is discarded. + */ + virtual void buildInverseOperator(const Teuchos::RCP &A, bool clear = true); + + /** \brief Rebuild this inverse from an Epetra_Operator passed + * in this to object. + * + * Rebuild this inverse from an Epetra_Operator passed + * in this to object. If buildInverseOperator has not been called + * the inverse operator will be built instead. Otherwise efforts are taken + * to only rebuild what is neccessary. Also, that this Epetra_Operator + * may be an EpetraOperatorWrapper object, so the block Thyra components + * can be extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + */ + virtual void rebuildInverseOperator(const Teuchos::RCP &A); + + /** \brief Rebuild this inverse from an Epetra_Operator passed + * in this to object. + * + * Rebuild this inverse from an Epetra_Operator passed + * in this to object. If buildInverseOperator has not been called + * the inverse operator will be built instead. Otherwise efforts are taken + * to only rebuild what is neccessary. Also, that this Epetra_Operator + * may be an EpetraOperatorWrapper object, so the block Thyra components + * can be extracted. + * + * \param[in] A The Epetra source operator. (Should be a EpetraOperatorWrapper!) + */ + virtual void rebuildInverseOperator(const Teuchos::RCP &A); + + /** Extract the forward op used by buildInverseOperator + * or rebuildInverseOperator. + */ + Teuchos::RCP getForwardOp() const { return fwdOp_.getConstObj(); } + + /** Extract the forward op used by buildInverseOperator + * or rebuildInverseOperator. + */ + Teuchos::RCP getNonconstForwardOp() const { return fwdOp_.getNonconstObj(); } + + protected: + Teuchos::RCP > extractLinearOp( + const Teuchos::RCP &A) const; + Teuchos::RCP extractMappingStrategy( + const Teuchos::RCP &A) const; + + InverseFactoryOperator(); + InverseFactoryOperator(const InverseFactoryOperator &); + + Teuchos::RCP inverseFactory_; + Teko::ModifiableLinearOp invOperator_; + bool firstBuildComplete_; + + Teuchos::ConstNonconstObjectContainer fwdOp_; + bool setConstFwdOp_; }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_ReorderedMappingStrategy.cpp b/packages/teko/src/Epetra/Teko_ReorderedMappingStrategy.cpp index 0652ccee25de..f2a43b0acb7a 100644 --- a/packages/teko/src/Epetra/Teko_ReorderedMappingStrategy.cpp +++ b/packages/teko/src/Epetra/Teko_ReorderedMappingStrategy.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -56,37 +56,38 @@ using Teuchos::rcpFromRef; namespace Teko { namespace Epetra { -ReorderedMappingStrategy::ReorderedMappingStrategy(const BlockReorderManager & brm,const Teuchos::RCP & map) - : reorderManager_(brm), mapStrategy_(map) -{ - rangeMap_ = mapStrategy_->rangeMap(); - domainMap_ = mapStrategy_->domainMap(); +ReorderedMappingStrategy::ReorderedMappingStrategy(const BlockReorderManager& brm, + const Teuchos::RCP& map) + : reorderManager_(brm), mapStrategy_(map) { + rangeMap_ = mapStrategy_->rangeMap(); + domainMap_ = mapStrategy_->domainMap(); } -void ReorderedMappingStrategy::copyEpetraIntoThyra(const Epetra_MultiVector& X, - const Teuchos::Ptr > & thyra_X) const -{ - using Teuchos::ptr_const_cast; - using Teuchos::rcp_const_cast; +void ReorderedMappingStrategy::copyEpetraIntoThyra( + const Epetra_MultiVector& X, + const Teuchos::Ptr >& thyra_X) const { + using Teuchos::ptr_const_cast; + using Teuchos::rcp_const_cast; - // first flatten the vector: notice this just works on the block structure - RCP > prod_X = rcp_dynamic_cast >(rcpFromRef(*thyra_X)); - RCP > flat_X = buildFlatMultiVector(reorderManager_,prod_X); + // first flatten the vector: notice this just works on the block structure + RCP > prod_X = + rcp_dynamic_cast >(rcpFromRef(*thyra_X)); + RCP > flat_X = buildFlatMultiVector(reorderManager_, prod_X); - // now use the underlying mapping strategy to copy the flat vector - mapStrategy_->copyEpetraIntoThyra(X,flat_X.ptr()); + // now use the underlying mapping strategy to copy the flat vector + mapStrategy_->copyEpetraIntoThyra(X, flat_X.ptr()); } -void ReorderedMappingStrategy::copyThyraIntoEpetra(const RCP > & thyra_Y, - Epetra_MultiVector& Y) const -{ - // first flatten the vector: notice this just works on the block structure - RCP > prod_Y = rcp_dynamic_cast >(rcpFromRef(*thyra_Y)); - RCP > flat_Y = buildFlatMultiVector(reorderManager_,prod_Y); +void ReorderedMappingStrategy::copyThyraIntoEpetra( + const RCP >& thyra_Y, Epetra_MultiVector& Y) const { + // first flatten the vector: notice this just works on the block structure + RCP > prod_Y = + rcp_dynamic_cast >(rcpFromRef(*thyra_Y)); + RCP > flat_Y = buildFlatMultiVector(reorderManager_, prod_Y); - // now use the underlying mapping strategy to copy the flat vector - mapStrategy_->copyThyraIntoEpetra(flat_Y,Y); + // now use the underlying mapping strategy to copy the flat vector + mapStrategy_->copyThyraIntoEpetra(flat_Y, Y); } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_ReorderedMappingStrategy.hpp b/packages/teko/src/Epetra/Teko_ReorderedMappingStrategy.hpp index db56c8852546..b3578a28d9c8 100644 --- a/packages/teko/src/Epetra/Teko_ReorderedMappingStrategy.hpp +++ b/packages/teko/src/Epetra/Teko_ReorderedMappingStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -73,93 +73,92 @@ namespace Teko { namespace Epetra { class ReorderedMappingStrategy : public MappingStrategy { -public: - //! \name Constructors - //@{ - - /** Creates a reordered mapping strategy. This class is useful - * for using a reordering manager to build a new mapping strategy. - * This is new strategy is based on some prior mapping. - * - * \param[in] brm How the vectors are to be reordered - * \param[in] map Original mapping strategy to base the reordering on - */ - ReorderedMappingStrategy(const BlockReorderManager & brm,const Teuchos::RCP & map); - //@} - - //!\name Member functions inherited from Teko::Epetra::MappingStrategy - //@{ - - /** Virtual function defined in MappingStrategy. This copies - * an Epetra_MultiVector into a Thyra::MultiVectorBase with - * blocking handled by the strides defined in the constructor. - * - * \param[in] epetra_X source Epetra_MultiVector - * \param[in,out] thyra_X destination Thyra::MultiVectorBase - */ - virtual void copyEpetraIntoThyra(const Epetra_MultiVector& epetra_X, - const Teuchos::Ptr > & thyra_X) const; - - /** Virtual function defined in MappingStrategy. This copies - * an Epetra_MultiVector into a Thyra::MultiVectorBase with - * blocking handled by the strides defined in the constructor. - * - * \param[in] thyra_Y source Thyra::MultiVectorBase - * \param[in,out] epetra_Y destination Epetra_MultiVector - */ - virtual void copyThyraIntoEpetra(const Teuchos::RCP > & thyra_Y, - Epetra_MultiVector& epetra_Y) const; - - /** Returns the domain and range maps used by this class. - * This faciliates building an Epetra_Operator around this - * class with its core functionality being a Thyra::LinearOpBase - * operator - * - * \returns Range map corresponding to this class - */ - virtual const Teuchos::RCP domainMap() const - { return domainMap_; } - - /** Returns the domain and range maps used by this class. - * This faciliates building an Epetra_Operator around this - * class with its core functionality being a Thyra::LinearOpBase - * operator - * - * \returns Range map corresponding to this class - */ - virtual const Teuchos::RCP rangeMap() const - { return rangeMap_; } - - /** A function for my sanity - * - * \returns String with description of this class - */ - virtual std::string toString() const - { return std::string("ReorderedMappingStrategy"); } - - //@} - - //! Get the underlying maping strategy used by this object - virtual RCP GetPrimaryMapStrategy() const - { return mapStrategy_; } - -protected: - // member variables - - //! \name storage for sanity - //@{ - Teuchos::RCP domainMap_; - Teuchos::RCP rangeMap_; - //@} - - //! \name Reordering information - //@{ - const BlockReorderManager reorderManager_; - RCP mapStrategy_; - //@} + public: + //! \name Constructors + //@{ + + /** Creates a reordered mapping strategy. This class is useful + * for using a reordering manager to build a new mapping strategy. + * This is new strategy is based on some prior mapping. + * + * \param[in] brm How the vectors are to be reordered + * \param[in] map Original mapping strategy to base the reordering on + */ + ReorderedMappingStrategy(const BlockReorderManager& brm, + const Teuchos::RCP& map); + //@} + + //!\name Member functions inherited from Teko::Epetra::MappingStrategy + //@{ + + /** Virtual function defined in MappingStrategy. This copies + * an Epetra_MultiVector into a Thyra::MultiVectorBase with + * blocking handled by the strides defined in the constructor. + * + * \param[in] epetra_X source Epetra_MultiVector + * \param[in,out] thyra_X destination Thyra::MultiVectorBase + */ + virtual void copyEpetraIntoThyra( + const Epetra_MultiVector& epetra_X, + const Teuchos::Ptr >& thyra_X) const; + + /** Virtual function defined in MappingStrategy. This copies + * an Epetra_MultiVector into a Thyra::MultiVectorBase with + * blocking handled by the strides defined in the constructor. + * + * \param[in] thyra_Y source Thyra::MultiVectorBase + * \param[in,out] epetra_Y destination Epetra_MultiVector + */ + virtual void copyThyraIntoEpetra( + const Teuchos::RCP >& thyra_Y, + Epetra_MultiVector& epetra_Y) const; + + /** Returns the domain and range maps used by this class. + * This faciliates building an Epetra_Operator around this + * class with its core functionality being a Thyra::LinearOpBase + * operator + * + * \returns Range map corresponding to this class + */ + virtual const Teuchos::RCP domainMap() const { return domainMap_; } + + /** Returns the domain and range maps used by this class. + * This faciliates building an Epetra_Operator around this + * class with its core functionality being a Thyra::LinearOpBase + * operator + * + * \returns Range map corresponding to this class + */ + virtual const Teuchos::RCP rangeMap() const { return rangeMap_; } + + /** A function for my sanity + * + * \returns String with description of this class + */ + virtual std::string toString() const { return std::string("ReorderedMappingStrategy"); } + + //@} + + //! Get the underlying maping strategy used by this object + virtual RCP GetPrimaryMapStrategy() const { return mapStrategy_; } + + protected: + // member variables + + //! \name storage for sanity + //@{ + Teuchos::RCP domainMap_; + Teuchos::RCP rangeMap_; + //@} + + //! \name Reordering information + //@{ + const BlockReorderManager reorderManager_; + RCP mapStrategy_; + //@} }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_StridedEpetraOperator.cpp b/packages/teko/src/Epetra/Teko_StridedEpetraOperator.cpp index 07dd7874acdd..96b55f46bc2d 100644 --- a/packages/teko/src/Epetra/Teko_StridedEpetraOperator.cpp +++ b/packages/teko/src/Epetra/Teko_StridedEpetraOperator.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -71,195 +71,183 @@ using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcp_dynamic_cast; -StridedEpetraOperator::StridedEpetraOperator(int numVars,const Teuchos::RCP & content, - const std::string & label) - : Teko::Epetra::EpetraOperatorWrapper(), label_(label) -{ - std::vector vars; - - // build vector describing the sub maps - for(int i=0;i& content, + const std::string& label) + : Teko::Epetra::EpetraOperatorWrapper(), label_(label) { + std::vector vars; - SetContent(vars,content); + // build vector describing the sub maps + for (int i = 0; i < numVars; i++) vars.push_back(1); + + SetContent(vars, content); } -StridedEpetraOperator::StridedEpetraOperator(const std::vector & vars,const Teuchos::RCP & content, - const std::string & label) - : Teko::Epetra::EpetraOperatorWrapper(), label_(label) -{ - SetContent(vars,content); +StridedEpetraOperator::StridedEpetraOperator(const std::vector& vars, + const Teuchos::RCP& content, + const std::string& label) + : Teko::Epetra::EpetraOperatorWrapper(), label_(label) { + SetContent(vars, content); } -void StridedEpetraOperator::SetContent(const std::vector & vars,const Teuchos::RCP & content) -{ - fullContent_ = content; - stridedMapping_ = rcp(new StridedMappingStrategy(vars,Teuchos::rcpFromRef(fullContent_->OperatorDomainMap()), - fullContent_->Comm())); - SetMapStrategy(stridedMapping_); +void StridedEpetraOperator::SetContent(const std::vector& vars, + const Teuchos::RCP& content) { + fullContent_ = content; + stridedMapping_ = rcp(new StridedMappingStrategy( + vars, Teuchos::rcpFromRef(fullContent_->OperatorDomainMap()), fullContent_->Comm())); + SetMapStrategy(stridedMapping_); - // build thyra operator - BuildBlockedOperator(); + // build thyra operator + BuildBlockedOperator(); } -void StridedEpetraOperator::BuildBlockedOperator() -{ - TEUCHOS_ASSERT(stridedMapping_!=Teuchos::null); +void StridedEpetraOperator::BuildBlockedOperator() { + TEUCHOS_ASSERT(stridedMapping_ != Teuchos::null); - // get a CRS matrix - const RCP crsContent = rcp_dynamic_cast(fullContent_); + // get a CRS matrix + const RCP crsContent = + rcp_dynamic_cast(fullContent_); - // ask the strategy to build the Thyra operator for you - if(stridedOperator_==Teuchos::null) { - stridedOperator_ = stridedMapping_->buildBlockedThyraOp(crsContent,label_); - } - else { - const RCP > blkOp = rcp_dynamic_cast >(stridedOperator_,true); - stridedMapping_->rebuildBlockedThyraOp(crsContent,blkOp); - } + // ask the strategy to build the Thyra operator for you + if (stridedOperator_ == Teuchos::null) { + stridedOperator_ = stridedMapping_->buildBlockedThyraOp(crsContent, label_); + } else { + const RCP > blkOp = + rcp_dynamic_cast >(stridedOperator_, true); + stridedMapping_->rebuildBlockedThyraOp(crsContent, blkOp); + } - // set whatever is returned - SetOperator(stridedOperator_,false); + // set whatever is returned + SetOperator(stridedOperator_, false); - // reorder if neccessary - if(reorderManager_!=Teuchos::null) - Reorder(*reorderManager_); + // reorder if neccessary + if (reorderManager_ != Teuchos::null) Reorder(*reorderManager_); } -const Teuchos::RCP StridedEpetraOperator::GetBlock(int i,int j) const -{ - const RCP > blkOp - = Teuchos::rcp_dynamic_cast >(getThyraOp()); +const Teuchos::RCP StridedEpetraOperator::GetBlock(int i, int j) const { + const RCP > blkOp = + Teuchos::rcp_dynamic_cast >(getThyraOp()); - return Thyra::get_Epetra_Operator(*blkOp->getBlock(i,j)); + return Thyra::get_Epetra_Operator(*blkOp->getBlock(i, j)); } /** Use a reorder manager to block this operator as desired. - * Multiple calls to the function reorder only the underlying object. - */ -void StridedEpetraOperator::Reorder(const BlockReorderManager & brm) -{ - reorderManager_ = rcp(new BlockReorderManager(brm)); - - // build reordered objects - RCP reorderMapping = rcp(new ReorderedMappingStrategy(*reorderManager_,stridedMapping_)); - RCP > blockOp - = rcp_dynamic_cast >(stridedOperator_); - - RCP > A = buildReorderedLinearOp(*reorderManager_,blockOp); - - // set them as working values - SetMapStrategy(reorderMapping); - SetOperator(A,false); + * Multiple calls to the function reorder only the underlying object. + */ +void StridedEpetraOperator::Reorder(const BlockReorderManager& brm) { + reorderManager_ = rcp(new BlockReorderManager(brm)); + + // build reordered objects + RCP reorderMapping = + rcp(new ReorderedMappingStrategy(*reorderManager_, stridedMapping_)); + RCP > blockOp = + rcp_dynamic_cast >(stridedOperator_); + + RCP > A = buildReorderedLinearOp(*reorderManager_, blockOp); + + // set them as working values + SetMapStrategy(reorderMapping); + SetOperator(A, false); } //! Remove any reordering on this object -void StridedEpetraOperator::RemoveReording() -{ - SetMapStrategy(stridedMapping_); - SetOperator(stridedOperator_,false); - reorderManager_ = Teuchos::null; +void StridedEpetraOperator::RemoveReording() { + SetMapStrategy(stridedMapping_); + SetOperator(stridedOperator_, false); + reorderManager_ = Teuchos::null; } /** Write out this operator to matrix market files - */ -void StridedEpetraOperator::WriteBlocks(const std::string & prefix) const -{ - RCP > blockOp - = rcp_dynamic_cast >(stridedOperator_); - - // get size of strided block operator - int rows = Teko::blockRowCount(blockOp); - - for(int i=0;i mat - = Teuchos::rcp_dynamic_cast(Thyra::get_Epetra_Operator(*blockOp->getBlock(i,j))); - - // write to file - EpetraExt::RowMatrixToMatrixMarketFile(formatBlockName(prefix,i,j,rows).c_str(),*mat); - } - } + */ +void StridedEpetraOperator::WriteBlocks(const std::string& prefix) const { + RCP > blockOp = + rcp_dynamic_cast >(stridedOperator_); + + // get size of strided block operator + int rows = Teko::blockRowCount(blockOp); + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < rows; j++) { + // get the row matrix object (Note: can't use "GetBlock" method b/c matrix might be reordered) + RCP mat = Teuchos::rcp_dynamic_cast( + Thyra::get_Epetra_Operator(*blockOp->getBlock(i, j))); + + // write to file + EpetraExt::RowMatrixToMatrixMarketFile(formatBlockName(prefix, i, j, rows).c_str(), *mat); + } + } } /** Print the Norm of the sub matrces. The type of norm - * is specified by the argument. - * - * \param[in] nrmType Type of norm to use - * \param[in] newline Character to use when a new line - * is needed. - */ -std::string StridedEpetraOperator::PrintNorm(const eNormType & nrmType,const char newline) -{ - BlockedLinearOp blockOp = toBlockedLinearOp(stridedOperator_); - - // get size of strided block operator - int rowCount = Teko::blockRowCount(blockOp); - int colCount = Teko::blockRowCount(blockOp); - - std::stringstream ss; - ss.precision(4); - ss << std::scientific; - for(int row=0;row mat = Teuchos::rcp_dynamic_cast( - Thyra::get_Epetra_Operator(*blockOp->getBlock(row,col))); - - // compute the norm - double norm = 0.0; - switch(nrmType) { - case Inf: - norm = mat->NormInf(); - break; - case One: - norm = mat->NormOne(); - break; - case Frobenius: - norm = mat->NormFrobenius(); - break; - default: - TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error, - "StridedEpetraOperator::eNormType incorrectly specified"); - } - - ss << norm << " "; + * is specified by the argument. + * + * \param[in] nrmType Type of norm to use + * \param[in] newline Character to use when a new line + * is needed. + */ +std::string StridedEpetraOperator::PrintNorm(const eNormType& nrmType, const char newline) { + BlockedLinearOp blockOp = toBlockedLinearOp(stridedOperator_); + + // get size of strided block operator + int rowCount = Teko::blockRowCount(blockOp); + int colCount = Teko::blockRowCount(blockOp); + + std::stringstream ss; + ss.precision(4); + ss << std::scientific; + for (int row = 0; row < rowCount; row++) { + for (int col = 0; col < colCount; col++) { + // get the row matrix object (Note: can't use "GetBlock" method b/c matrix might be reordered) + RCP mat = Teuchos::rcp_dynamic_cast( + Thyra::get_Epetra_Operator(*blockOp->getBlock(row, col))); + + // compute the norm + double norm = 0.0; + switch (nrmType) { + case Inf: norm = mat->NormInf(); break; + case One: norm = mat->NormOne(); break; + case Frobenius: norm = mat->NormFrobenius(); break; + default: + TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, + "StridedEpetraOperator::eNormType incorrectly specified"); } - ss << newline; - } - return ss.str(); + ss << norm << " "; + } + ss << newline; + } + + return ss.str(); } -bool StridedEpetraOperator::testAgainstFullOperator(int count,double tol) const -{ - Epetra_Vector xf(OperatorRangeMap()); - Epetra_Vector xs(OperatorRangeMap()); - Epetra_Vector y(OperatorDomainMap()); - - // test operator many times - bool result = true; - double diffNorm=0.0,trueNorm=0.0; - for(int i=0;iApply(y,xf); // xf = A*y - - // compute norms - xs.Update(-1.0,xf,1.0); - xs.Norm2(&diffNorm); - xf.Norm2(&trueNorm); - - // check result - result &= (diffNorm/trueNorm < tol); - } - - return result; +bool StridedEpetraOperator::testAgainstFullOperator(int count, double tol) const { + Epetra_Vector xf(OperatorRangeMap()); + Epetra_Vector xs(OperatorRangeMap()); + Epetra_Vector y(OperatorDomainMap()); + + // test operator many times + bool result = true; + double diffNorm = 0.0, trueNorm = 0.0; + for (int i = 0; i < count; i++) { + xf.PutScalar(0.0); + xs.PutScalar(0.0); + y.Random(); + + // apply operator + Apply(y, xs); // xs = A*y + fullContent_->Apply(y, xf); // xf = A*y + + // compute norms + xs.Update(-1.0, xf, 1.0); + xs.Norm2(&diffNorm); + xf.Norm2(&trueNorm); + + // check result + result &= (diffNorm / trueNorm < tol); + } + + return result; } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_StridedEpetraOperator.hpp b/packages/teko/src/Epetra/Teko_StridedEpetraOperator.hpp index 84da1a6b56cd..74335438e20f 100644 --- a/packages/teko/src/Epetra/Teko_StridedEpetraOperator.hpp +++ b/packages/teko/src/Epetra/Teko_StridedEpetraOperator.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -64,88 +64,90 @@ namespace Teko { namespace Epetra { class StridedEpetraOperator : public EpetraOperatorWrapper { -public: - enum eNormType { Inf, One, Frobenius}; + public: + enum eNormType { Inf, One, Frobenius }; - StridedEpetraOperator(int numVars,const Teuchos::RCP & content, - const std::string & label=""); - StridedEpetraOperator(const std::vector & vars,const Teuchos::RCP & content, - const std::string & label=""); + StridedEpetraOperator(int numVars, const Teuchos::RCP &content, + const std::string &label = ""); + StridedEpetraOperator(const std::vector &vars, + const Teuchos::RCP &content, + const std::string &label = ""); - virtual void SetContent(const std::vector & vars,const Teuchos::RCP & content); + virtual void SetContent(const std::vector &vars, + const Teuchos::RCP &content); - virtual void RebuildOps() - { BuildBlockedOperator(); } + virtual void RebuildOps() { BuildBlockedOperator(); } - virtual const Teuchos::RCP GetContent() const - { return fullContent_; } + virtual const Teuchos::RCP GetContent() const { return fullContent_; } - // virtual const Teuchos::RCP GetContent() - // { return fullContent_; } + // virtual const Teuchos::RCP GetContent() + // { return fullContent_; } - const Teuchos::RCP GetBlock(int i,int j) const; + const Teuchos::RCP GetBlock(int i, int j) const; - /** Use a reorder manager to block this operator as desired. - * Multiple calls to the function reorder only the underlying object. - */ - void Reorder(const BlockReorderManager & brm); + /** Use a reorder manager to block this operator as desired. + * Multiple calls to the function reorder only the underlying object. + */ + void Reorder(const BlockReorderManager &brm); - //! Remove any reordering on this object - void RemoveReording(); + //! Remove any reordering on this object + void RemoveReording(); - /** Write out this operator to matrix market files - */ - virtual void WriteBlocks(const std::string & prefix) const; + /** Write out this operator to matrix market files + */ + virtual void WriteBlocks(const std::string &prefix) const; - /** Print the Norm of the sub matrces. The type of norm - * is specified by the argument. - * - * \param[in] nrmType Type of norm to use - * \param[in] newline Character to use when a new line - * is needed. - */ - virtual std::string PrintNorm(const eNormType & nrmType=Frobenius,const char newline='\n'); + /** Print the Norm of the sub matrces. The type of norm + * is specified by the argument. + * + * \param[in] nrmType Type of norm to use + * \param[in] newline Character to use when a new line + * is needed. + */ + virtual std::string PrintNorm(const eNormType &nrmType = Frobenius, const char newline = '\n'); - // functions overloading Epetra_Operator - //////////////////////////////////////////////// + // functions overloading Epetra_Operator + //////////////////////////////////////////////// - // destructor - virtual ~StridedEpetraOperator() {} + // destructor + virtual ~StridedEpetraOperator() {} - // attribute set methods - - // don't use transpose...ever! - virtual int SetUseTranspose(bool /* useTranspose */) - { return -1; } + // attribute set methods - virtual int ApplyInverse(const Epetra_MultiVector &/* X */, Epetra_MultiVector &/* Y */) const - { TEUCHOS_ASSERT(false); return -1; } + // don't use transpose...ever! + virtual int SetUseTranspose(bool /* useTranspose */) { return -1; } - virtual double NormInf() const - { TEUCHOS_ASSERT(false); return 0.0; } + virtual int ApplyInverse(const Epetra_MultiVector & /* X */, Epetra_MultiVector & /* Y */) const { + TEUCHOS_ASSERT(false); + return -1; + } - // attribute access functions - virtual bool UseTranspose() const { return false; } - virtual bool HasNormInf() const { return false; } - virtual const Epetra_Comm & Comm() const { return fullContent_->Comm(); } + virtual double NormInf() const { + TEUCHOS_ASSERT(false); + return 0.0; + } - - //! Helps perform sanity checks - bool testAgainstFullOperator(int count,double tol) const; + // attribute access functions + virtual bool UseTranspose() const { return false; } + virtual bool HasNormInf() const { return false; } + virtual const Epetra_Comm &Comm() const { return fullContent_->Comm(); } -protected: - // gooey center of this shell - Teuchos::RCP fullContent_; - Teuchos::RCP stridedMapping_; - Teuchos::RCP > stridedOperator_; - Teuchos::RCP reorderManager_; + //! Helps perform sanity checks + bool testAgainstFullOperator(int count, double tol) const; - std::string label_; + protected: + // gooey center of this shell + Teuchos::RCP fullContent_; + Teuchos::RCP stridedMapping_; + Teuchos::RCP > stridedOperator_; + Teuchos::RCP reorderManager_; - void BuildBlockedOperator(); + std::string label_; + + void BuildBlockedOperator(); }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/Epetra/Teko_StridedMappingStrategy.cpp b/packages/teko/src/Epetra/Teko_StridedMappingStrategy.cpp index 6bc72f6f2328..57e3ea20e01c 100644 --- a/packages/teko/src/Epetra/Teko_StridedMappingStrategy.cpp +++ b/packages/teko/src/Epetra/Teko_StridedMappingStrategy.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -68,17 +68,17 @@ namespace Epetra { // in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current // implimentation only supports a fixed number of variables // -// arguments: -// vars - Number of different variables +// arguments: +// vars - Number of different variables // map - original Epetra_Map to be broken up // comm - Epetra_Comm object related to the map // -StridedMappingStrategy::StridedMappingStrategy(const std::vector & vars,const RCP & map, - const Epetra_Comm & comm) -{ - rangeMap_ = map; - domainMap_ = map; - buildBlockTransferData(vars, rangeMap_,comm); +StridedMappingStrategy::StridedMappingStrategy(const std::vector& vars, + const RCP& map, + const Epetra_Comm& comm) { + rangeMap_ = map; + domainMap_ = map; + buildBlockTransferData(vars, rangeMap_, comm); } // Virtual function defined in MappingStrategy. This copies @@ -89,28 +89,29 @@ StridedMappingStrategy::StridedMappingStrategy(const std::vector & vars,con // X - source Epetra_MultiVector // thyra_X - destination Thyra::MultiVectorBase // -void StridedMappingStrategy::copyEpetraIntoThyra(const Epetra_MultiVector& X, - const Teuchos::Ptr > & thyra_X) const -{ - int count = X.NumVectors(); - - std::vector > subX; - - // allocate vectors to copy into - Strided::buildSubVectors(blockMaps_,subX,count); - - // copy source vector to X vector - Strided::one2many(subX,X,blockImport_); - - // convert subX to an array of multi vectors - Teuchos::Array > > thyra_subX; - Teuchos::Ptr > prod_X - = Teuchos::ptr_dynamic_cast >(thyra_X); - for(unsigned int i=0;i > vec - = rcp_dynamic_cast >(prod_X->getNonconstMultiVectorBlock(i)); - fillDefaultSpmdMultiVector(vec,subX[i]); - } +void StridedMappingStrategy::copyEpetraIntoThyra( + const Epetra_MultiVector& X, + const Teuchos::Ptr >& thyra_X) const { + int count = X.NumVectors(); + + std::vector > subX; + + // allocate vectors to copy into + Strided::buildSubVectors(blockMaps_, subX, count); + + // copy source vector to X vector + Strided::one2many(subX, X, blockImport_); + + // convert subX to an array of multi vectors + Teuchos::Array > > thyra_subX; + Teuchos::Ptr > prod_X = + Teuchos::ptr_dynamic_cast >(thyra_X); + for (unsigned int i = 0; i < blockMaps_.size(); i++) { + RCP > vec = + rcp_dynamic_cast >( + prod_X->getNonconstMultiVectorBlock(i)); + fillDefaultSpmdMultiVector(vec, subX[i]); + } } // Virtual function defined in MappingStrategy. This copies @@ -121,22 +122,22 @@ void StridedMappingStrategy::copyEpetraIntoThyra(const Epetra_MultiVector& X, // thyra_Y - source Thyra::MultiVectorBase // Y - destination Epetra_MultiVector // -void StridedMappingStrategy::copyThyraIntoEpetra(const RCP > & thyra_Y, - Epetra_MultiVector& Y) const -{ - std::vector > subY; - RCP > prod_Y - = rcp_dynamic_cast >(thyra_Y); - - // convert thyra product vector to subY - for(unsigned int i=0;igetMultiVectorBlock(i))); - - // endow the subVectors with required information about the maps - Strided::associateSubVectors(blockMaps_,subY); - - // copy solution vectors to Y vector - Strided::many2one(Y,subY,blockExport_); +void StridedMappingStrategy::copyThyraIntoEpetra( + const RCP >& thyra_Y, Epetra_MultiVector& Y) const { + std::vector > subY; + RCP > prod_Y = + rcp_dynamic_cast >(thyra_Y); + + // convert thyra product vector to subY + for (unsigned int i = 0; i < blockMaps_.size(); i++) + subY.push_back( + Thyra::get_Epetra_MultiVector(*blockMaps_[i].second, prod_Y->getMultiVectorBlock(i))); + + // endow the subVectors with required information about the maps + Strided::associateSubVectors(blockMaps_, subY); + + // copy solution vectors to Y vector + Strided::many2one(Y, subY, blockExport_); } // this is the core routine that builds the maps @@ -151,11 +152,12 @@ void StridedMappingStrategy::copyThyraIntoEpetra(const RCP & vars,const Teuchos::RCP & baseMap, const Epetra_Comm & comm) -{ - // build maps and exporters/importers - Strided::buildSubMaps(*baseMap,vars,comm,blockMaps_); - Strided::buildExportImport(*baseMap, blockMaps_, blockExport_,blockImport_); +void StridedMappingStrategy::buildBlockTransferData(const std::vector& vars, + const Teuchos::RCP& baseMap, + const Epetra_Comm& comm) { + // build maps and exporters/importers + Strided::buildSubMaps(*baseMap, vars, comm, blockMaps_); + Strided::buildExportImport(*baseMap, blockMaps_, blockExport_, blockImport_); } // Builds a blocked Thyra operator that uses the strided @@ -168,27 +170,28 @@ void StridedMappingStrategy::buildBlockTransferData(const std::vector & var // returns: Blocked Thyra linear operator with sub blocks // defined by this mapping strategy // -const Teuchos::RCP > -StridedMappingStrategy::buildBlockedThyraOp(const RCP & crsContent,const std::string & label) const -{ - int dim = blockMaps_.size(); - - RCP > A = Thyra::defaultBlockedLinearOp(); - - A->beginBlockFill(dim,dim); - for(int i=0;isetNonconstBlock(i,j,Thyra::nonconstEpetraLinearOp(Strided::buildSubBlock(i,j,*crsContent,blockMaps_),ss.str())); - } - } // end for i - A->endBlockFill(); - - return A; +const Teuchos::RCP > StridedMappingStrategy::buildBlockedThyraOp( + const RCP& crsContent, const std::string& label) const { + int dim = blockMaps_.size(); + + RCP > A = Thyra::defaultBlockedLinearOp(); + + A->beginBlockFill(dim, dim); + for (int i = 0; i < dim; i++) { + for (int j = 0; j < dim; j++) { + // label block correctly + std::stringstream ss; + ss << label << "_" << i << "," << j; + + // build the blocks and place it the right location + A->setNonconstBlock(i, j, + Thyra::nonconstEpetraLinearOp( + Strided::buildSubBlock(i, j, *crsContent, blockMaps_), ss.str())); + } + } // end for i + A->endBlockFill(); + + return A; } // Rebuilds a blocked Thyra operator that uses the strided @@ -201,22 +204,23 @@ StridedMappingStrategy::buildBlockedThyraOp(const RCP & // A - Destination block linear op composed of blocks of // Epetra_CrsMatrix at all relevant locations // -void StridedMappingStrategy::rebuildBlockedThyraOp(const RCP & crsContent, - const RCP > & A) const -{ - int dim = blockMaps_.size(); - - for(int i=0;i > Aij = A->getNonconstBlock(i,j); - RCP eAij = rcp_dynamic_cast(Thyra::get_Epetra_Operator(*Aij),true); - - // rebuild the blocks and place it the right location - Strided::rebuildSubBlock(i,j,*crsContent,blockMaps_,*eAij); - } - } // end for i +void StridedMappingStrategy::rebuildBlockedThyraOp( + const RCP& crsContent, + const RCP >& A) const { + int dim = blockMaps_.size(); + + for (int i = 0; i < dim; i++) { + for (int j = 0; j < dim; j++) { + // get Epetra version of desired block + RCP > Aij = A->getNonconstBlock(i, j); + RCP eAij = + rcp_dynamic_cast(Thyra::get_Epetra_Operator(*Aij), true); + + // rebuild the blocks and place it the right location + Strided::rebuildSubBlock(i, j, *crsContent, blockMaps_, *eAij); + } + } // end for i } -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko diff --git a/packages/teko/src/Epetra/Teko_StridedMappingStrategy.hpp b/packages/teko/src/Epetra/Teko_StridedMappingStrategy.hpp index f755d4d5f8de..6ac37c6fce31 100644 --- a/packages/teko/src/Epetra/Teko_StridedMappingStrategy.hpp +++ b/packages/teko/src/Epetra/Teko_StridedMappingStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -73,154 +73,156 @@ namespace Teko { namespace Epetra { class StridedMappingStrategy : public MappingStrategy { -public: - //! \name Constructors - //@{ - - /** Creates a strided mapping strategy. This class is useful - * for breaking up nodally ordered matrices (i.e. the unknowns - * in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current - * implimentation only supports a fixed number of variables - * - * \param[in] vars Vector describing the blocking of variables - * \param[in] map original Epetra_Map to be broken up - * \param[in] comm Epetra_Comm object related to the map - */ - StridedMappingStrategy(const std::vector & vars,const Teuchos::RCP & map, const Epetra_Comm & comm); - //@} - - //!\name Member functions inherited from Teko::Epetra::MappingStrategy - //@{ - - /** Virtual function defined in MappingStrategy. This copies - * an Epetra_MultiVector into a Thyra::MultiVectorBase with - * blocking handled by the strides defined in the constructor. - * - * \param[in] epetra_X source Epetra_MultiVector - * \param[in,out] thyra_X destination Thyra::MultiVectorBase - */ - virtual void copyEpetraIntoThyra(const Epetra_MultiVector& epetra_X, - const Teuchos::Ptr > & thyra_X) const; - - /** Virtual function defined in MappingStrategy. This copies - * an Epetra_MultiVector into a Thyra::MultiVectorBase with - * blocking handled by the strides defined in the constructor. - * - * \param[in] thyra_Y source Thyra::MultiVectorBase - * \param[in,out] epetra_Y destination Epetra_MultiVector - */ - virtual void copyThyraIntoEpetra(const Teuchos::RCP > & thyra_Y, - Epetra_MultiVector& epetra_Y) const; - - /** Returns the domain and range maps used by this class. - * This faciliates building an Epetra_Operator around this - * class with its core functionality being a Thyra::LinearOpBase - * operator - * - * \returns Range map corresponding to this class - */ - virtual const Teuchos::RCP domainMap() const - { return domainMap_; } - - /** Returns the domain and range maps used by this class. - * This faciliates building an Epetra_Operator around this - * class with its core functionality being a Thyra::LinearOpBase - * operator - * - * \returns Range map corresponding to this class - */ - virtual const Teuchos::RCP rangeMap() const - { return rangeMap_; } - - /** A function for my sanity - * - * \returns String with description of this class - */ - virtual std::string toString() const - { return std::string("StridedMappingStrategy"); } - - //@} - - //! \name Locally useful functions - //@{ - - /** \brief This is the core routine that builds the maps - * and importers/exporters. - * - * This is the core routine that builds the maps - * and importers/exporters neccessary for all the - * transfers. Currently it simply calls out to the - * interlaced epetra functions. (Comment: this - * routine should probably be private or protected - * ... it is basically the meat of the constructor) - * - * \param[in] vars Vector describing the blocking of variables - * \param[in] baseMap basic map to use in the transfers - * \param[in] comm Epetra_Comm object - */ - void buildBlockTransferData(const std::vector & vars,const Teuchos::RCP & baseMap, - const Epetra_Comm & comm); - - /** \brief Get the individual block maps underlying that - * make up a strided vector/operator. - * - * Get the individual block maps underlying that - * make up a strided vector/operator. These are - * useful if you want to tear something ... i.e. - * a matrix ... apart. - * - * \returns Return a vector of block maps - * created for this strided operator - */ - const std::vector > > & getMaps() const - { return blockMaps_; } - - /** Builds a blocked Thyra operator that uses the strided - * mapping strategy to define sub blocks. - * - * \param[in] mat Epetra_CrsMatrix with FillComplete called, this - * matrix is assumed to be square, with the same - * range and domain maps - * \param[in] label String to be used to prefix the sub block's labels - * - * \returns Blocked Thyra linear operator with sub blocks - * defined by this mapping strategy - */ - const Teuchos::RCP > - buildBlockedThyraOp(const Teuchos::RCP & mat,const std::string & label="") const; - - /** Rebuilds a block Thyra operator using the strided mapping - * strategy to define sub blocks. - * - * \param[in] mat Epetra_CrsMatrix with FillComplete called, this - * matrix is assumed to be square, with the same - * range and domain maps - * \param[in] A Destination block linear op composed of blocks of - * Epetra_CrsMatrix at all relevant locations - */ - void rebuildBlockedThyraOp(const RCP & mat, - const RCP > & A) const; - - //@} - -protected: - // member variables - - //! \name storage for sanity - //@{ - Teuchos::RCP domainMap_; - Teuchos::RCP rangeMap_; - //@} - - //! \name block transfer data - //@{ - std::vector > > blockMaps_; - std::vector > blockExport_; - std::vector > blockImport_; - //@} + public: + //! \name Constructors + //@{ + + /** Creates a strided mapping strategy. This class is useful + * for breaking up nodally ordered matrices (i.e. the unknowns + * in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current + * implimentation only supports a fixed number of variables + * + * \param[in] vars Vector describing the blocking of variables + * \param[in] map original Epetra_Map to be broken up + * \param[in] comm Epetra_Comm object related to the map + */ + StridedMappingStrategy(const std::vector& vars, const Teuchos::RCP& map, + const Epetra_Comm& comm); + //@} + + //!\name Member functions inherited from Teko::Epetra::MappingStrategy + //@{ + + /** Virtual function defined in MappingStrategy. This copies + * an Epetra_MultiVector into a Thyra::MultiVectorBase with + * blocking handled by the strides defined in the constructor. + * + * \param[in] epetra_X source Epetra_MultiVector + * \param[in,out] thyra_X destination Thyra::MultiVectorBase + */ + virtual void copyEpetraIntoThyra( + const Epetra_MultiVector& epetra_X, + const Teuchos::Ptr >& thyra_X) const; + + /** Virtual function defined in MappingStrategy. This copies + * an Epetra_MultiVector into a Thyra::MultiVectorBase with + * blocking handled by the strides defined in the constructor. + * + * \param[in] thyra_Y source Thyra::MultiVectorBase + * \param[in,out] epetra_Y destination Epetra_MultiVector + */ + virtual void copyThyraIntoEpetra( + const Teuchos::RCP >& thyra_Y, + Epetra_MultiVector& epetra_Y) const; + + /** Returns the domain and range maps used by this class. + * This faciliates building an Epetra_Operator around this + * class with its core functionality being a Thyra::LinearOpBase + * operator + * + * \returns Range map corresponding to this class + */ + virtual const Teuchos::RCP domainMap() const { return domainMap_; } + + /** Returns the domain and range maps used by this class. + * This faciliates building an Epetra_Operator around this + * class with its core functionality being a Thyra::LinearOpBase + * operator + * + * \returns Range map corresponding to this class + */ + virtual const Teuchos::RCP rangeMap() const { return rangeMap_; } + + /** A function for my sanity + * + * \returns String with description of this class + */ + virtual std::string toString() const { return std::string("StridedMappingStrategy"); } + + //@} + + //! \name Locally useful functions + //@{ + + /** \brief This is the core routine that builds the maps + * and importers/exporters. + * + * This is the core routine that builds the maps + * and importers/exporters neccessary for all the + * transfers. Currently it simply calls out to the + * interlaced epetra functions. (Comment: this + * routine should probably be private or protected + * ... it is basically the meat of the constructor) + * + * \param[in] vars Vector describing the blocking of variables + * \param[in] baseMap basic map to use in the transfers + * \param[in] comm Epetra_Comm object + */ + void buildBlockTransferData(const std::vector& vars, + const Teuchos::RCP& baseMap, + const Epetra_Comm& comm); + + /** \brief Get the individual block maps underlying that + * make up a strided vector/operator. + * + * Get the individual block maps underlying that + * make up a strided vector/operator. These are + * useful if you want to tear something ... i.e. + * a matrix ... apart. + * + * \returns Return a vector of block maps + * created for this strided operator + */ + const std::vector > >& getMaps() const { + return blockMaps_; + } + + /** Builds a blocked Thyra operator that uses the strided + * mapping strategy to define sub blocks. + * + * \param[in] mat Epetra_CrsMatrix with FillComplete called, this + * matrix is assumed to be square, with the same + * range and domain maps + * \param[in] label String to be used to prefix the sub block's labels + * + * \returns Blocked Thyra linear operator with sub blocks + * defined by this mapping strategy + */ + const Teuchos::RCP > buildBlockedThyraOp( + const Teuchos::RCP& mat, const std::string& label = "") const; + + /** Rebuilds a block Thyra operator using the strided mapping + * strategy to define sub blocks. + * + * \param[in] mat Epetra_CrsMatrix with FillComplete called, this + * matrix is assumed to be square, with the same + * range and domain maps + * \param[in] A Destination block linear op composed of blocks of + * Epetra_CrsMatrix at all relevant locations + */ + void rebuildBlockedThyraOp(const RCP& mat, + const RCP >& A) const; + + //@} + + protected: + // member variables + + //! \name storage for sanity + //@{ + Teuchos::RCP domainMap_; + Teuchos::RCP rangeMap_; + //@} + + //! \name block transfer data + //@{ + std::vector > > blockMaps_; + std::vector > blockExport_; + std::vector > blockImport_; + //@} }; -} // end namespace Epetra -} // end namespace Teko +} // end namespace Epetra +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_ALOperator.cpp b/packages/teko/src/NS/Teko_ALOperator.cpp index 56e5de484331..7f643dc4be97 100644 --- a/packages/teko/src/NS/Teko_ALOperator.cpp +++ b/packages/teko/src/NS/Teko_ALOperator.cpp @@ -25,210 +25,173 @@ #include "Teko_ALOperator.hpp" -namespace Teko -{ - -namespace NS -{ - -ALOperator::ALOperator(const std::vector > & vars, - const Teuchos::RCP & content, - LinearOp pressureMassMatrix, double gamma, - const std::string & label) : - Teko::Epetra::BlockedEpetraOperator(vars, content, label), - pressureMassMatrix_(pressureMassMatrix), gamma_(gamma) -{ - checkDim(vars); - SetContent(vars, content); - BuildALOperator(); +namespace Teko { + +namespace NS { + +ALOperator::ALOperator(const std::vector >& vars, + const Teuchos::RCP& content, LinearOp pressureMassMatrix, + double gamma, const std::string& label) + : Teko::Epetra::BlockedEpetraOperator(vars, content, label), + pressureMassMatrix_(pressureMassMatrix), + gamma_(gamma) { + checkDim(vars); + SetContent(vars, content); + BuildALOperator(); } -ALOperator::ALOperator(const std::vector > & vars, - const Teuchos::RCP & content, - double gamma, const std::string & label) : - Teko::Epetra::BlockedEpetraOperator(vars, content, label), - pressureMassMatrix_(Teuchos::null), gamma_(gamma) -{ - checkDim(vars); - SetContent(vars, content); - BuildALOperator(); +ALOperator::ALOperator(const std::vector >& vars, + const Teuchos::RCP& content, double gamma, + const std::string& label) + : Teko::Epetra::BlockedEpetraOperator(vars, content, label), + pressureMassMatrix_(Teuchos::null), + gamma_(gamma) { + checkDim(vars); + SetContent(vars, content); + BuildALOperator(); } -void -ALOperator::setPressureMassMatrix(LinearOp pressureMassMatrix) -{ - if(pressureMassMatrix != Teuchos::null) - { - pressureMassMatrix_ = pressureMassMatrix; - } +void ALOperator::setPressureMassMatrix(LinearOp pressureMassMatrix) { + if (pressureMassMatrix != Teuchos::null) { + pressureMassMatrix_ = pressureMassMatrix; + } } -void -ALOperator::setGamma(double gamma) -{ - TEUCHOS_ASSERT(gamma > 0.0); - gamma_ = gamma; +void ALOperator::setGamma(double gamma) { + TEUCHOS_ASSERT(gamma > 0.0); + gamma_ = gamma; } -const Teuchos::RCP -ALOperator::GetBlock(int i, int j) const -{ - const Teuchos::RCP > blkOp - = Teuchos::rcp_dynamic_cast< Thyra::BlockedLinearOpBase > - (blockedOperator_, true); +const Teuchos::RCP ALOperator::GetBlock(int i, int j) const { + const Teuchos::RCP > blkOp = + Teuchos::rcp_dynamic_cast >(blockedOperator_, true); - return Thyra::get_Epetra_Operator(*blkOp->getBlock(i, j)); + return Thyra::get_Epetra_Operator(*blkOp->getBlock(i, j)); } -void -ALOperator::checkDim(const std::vector > & vars) -{ - dim_ = vars.size() - 1; - TEUCHOS_ASSERT(dim_ == 2 || dim_ == 3); +void ALOperator::checkDim(const std::vector >& vars) { + dim_ = vars.size() - 1; + TEUCHOS_ASSERT(dim_ == 2 || dim_ == 3); } -void -ALOperator::BuildALOperator() -{ - TEUCHOS_ASSERT(blockedMapping_ != Teuchos::null); - - // Get an Epetra_CrsMatrix. - const Teuchos::RCP crsContent - = Teuchos::rcp_dynamic_cast(fullContent_); - - // Ask the strategy to build the Thyra operator for you. - if(blockedOperator_ == Teuchos::null) - { - blockedOperator_ - = blockedMapping_->buildBlockedThyraOp(crsContent, label_); - } - else - { - const Teuchos::RCP > blkOp - = Teuchos::rcp_dynamic_cast > - (blockedOperator_, true); - blockedMapping_->rebuildBlockedThyraOp(crsContent, blkOp); - } - - // Extract blocks. - const Teuchos::RCP > blkOp - = Teuchos::rcp_dynamic_cast > - (blockedOperator_, true); - numBlockRows_ = blkOp->productRange()->numBlocks(); - Teuchos::RCP > blockedOpBlocks[4][4]; - for(int i = 0; i <= dim_; i++) - { - for(int j = 0; j <= dim_; j++) - { - blockedOpBlocks[i][j] = blkOp->getBlock(i, j); - } - } - - // Pressure mass matrix. - if(pressureMassMatrix_ != Teuchos::null) - { - invPressureMassMatrix_ = getInvDiagonalOp(pressureMassMatrix_); - } - // We need the size of the sub-block to build the identity matrix. - else - { - std::cout << "Pressure mass matrix is null. Use identity." << std::endl; - pressureMassMatrix_ - = Thyra::identity(blockedOpBlocks[dim_][0]->range()); - invPressureMassMatrix_ - = Thyra::identity(blockedOpBlocks[dim_][0]->range()); - } - - // Build the AL operator. - Teuchos::RCP > alOperator - = Thyra::defaultBlockedLinearOp(); - alOperator->beginBlockFill(dim_ + 1, dim_ + 1); - - // Set blocks for the velocity parts and gradient. - for(int i = 0; i < dim_; i++) - { - for(int j = 0; j < dim_; j++) - { - // build the blocks and place it the right location - alOperator->setBlock(i, j, - Thyra::add(blockedOpBlocks[i][j], - Thyra::scale(gamma_, - Thyra::multiply(blockedOpBlocks[i][dim_], - invPressureMassMatrix_, blockedOpBlocks[dim_][j])))); - } // end for j - } // end for i - - // Last row. Divergence and (possible) stabilization matrix. - for(int j = 0; j <= dim_; j++) - { - alOperator->setBlock(dim_, j, blockedOpBlocks[dim_][j]); - } - - // Last column. Gradient. - for(int i = 0; i < dim_; i++) - { - alOperator->setBlock(i, dim_, - Thyra::add(blockedOpBlocks[i][dim_], - Thyra::scale(gamma_, - Thyra::multiply(blockedOpBlocks[i][dim_], - invPressureMassMatrix_,blockedOpBlocks[dim_][dim_])))); - } - - alOperator->endBlockFill(); - - // Set whatever is returned. - SetOperator(alOperator, false); - - // Set operator for augmenting the right-hand side. - Teuchos::RCP > alOpRhs_ - = Thyra::defaultBlockedLinearOp(); - alOpRhs_->beginBlockFill(dim_ + 1, dim_ + 1); - - // Identity matrices on the main diagonal. - for(int i = 0; i < dim_; i++) - { +void ALOperator::BuildALOperator() { + TEUCHOS_ASSERT(blockedMapping_ != Teuchos::null); + + // Get an Epetra_CrsMatrix. + const Teuchos::RCP crsContent = + Teuchos::rcp_dynamic_cast(fullContent_); + + // Ask the strategy to build the Thyra operator for you. + if (blockedOperator_ == Teuchos::null) { + blockedOperator_ = blockedMapping_->buildBlockedThyraOp(crsContent, label_); + } else { + const Teuchos::RCP > blkOp = + Teuchos::rcp_dynamic_cast >(blockedOperator_, true); + blockedMapping_->rebuildBlockedThyraOp(crsContent, blkOp); + } + + // Extract blocks. + const Teuchos::RCP > blkOp = + Teuchos::rcp_dynamic_cast >(blockedOperator_, true); + numBlockRows_ = blkOp->productRange()->numBlocks(); + Teuchos::RCP > blockedOpBlocks[4][4]; + for (int i = 0; i <= dim_; i++) { + for (int j = 0; j <= dim_; j++) { + blockedOpBlocks[i][j] = blkOp->getBlock(i, j); + } + } + + // Pressure mass matrix. + if (pressureMassMatrix_ != Teuchos::null) { + invPressureMassMatrix_ = getInvDiagonalOp(pressureMassMatrix_); + } + // We need the size of the sub-block to build the identity matrix. + else { + std::cout << "Pressure mass matrix is null. Use identity." << std::endl; + pressureMassMatrix_ = Thyra::identity(blockedOpBlocks[dim_][0]->range()); + invPressureMassMatrix_ = Thyra::identity(blockedOpBlocks[dim_][0]->range()); + } + + // Build the AL operator. + Teuchos::RCP > alOperator = + Thyra::defaultBlockedLinearOp(); + alOperator->beginBlockFill(dim_ + 1, dim_ + 1); + + // Set blocks for the velocity parts and gradient. + for (int i = 0; i < dim_; i++) { + for (int j = 0; j < dim_; j++) { // build the blocks and place it the right location - alOpRhs_->setBlock(i, i, - Thyra::identity(blockedOpBlocks[0][0]->range())); - } // end for i - alOpRhs_->setBlock(dim_, dim_, - Thyra::identity(blockedOpBlocks[dim_][dim_]->range())); - - // Last column. - for(int i = 0; i < dim_; i++) - { - alOpRhs_->setBlock(i, dim_, - Thyra::scale(gamma_, - Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_))); - } - - alOpRhs_->endBlockFill(); - - alOperatorRhs_ = alOpRhs_; - - // reorder if necessary - if(reorderManager_ != Teuchos::null) - Reorder(*reorderManager_); + alOperator->setBlock( + i, j, + Thyra::add( + blockedOpBlocks[i][j], + Thyra::scale(gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_, + blockedOpBlocks[dim_][j])))); + } // end for j + } // end for i + + // Last row. Divergence and (possible) stabilization matrix. + for (int j = 0; j <= dim_; j++) { + alOperator->setBlock(dim_, j, blockedOpBlocks[dim_][j]); + } + + // Last column. Gradient. + for (int i = 0; i < dim_; i++) { + alOperator->setBlock( + i, dim_, + Thyra::add( + blockedOpBlocks[i][dim_], + Thyra::scale(gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_, + blockedOpBlocks[dim_][dim_])))); + } + + alOperator->endBlockFill(); + + // Set whatever is returned. + SetOperator(alOperator, false); + + // Set operator for augmenting the right-hand side. + Teuchos::RCP > alOpRhs_ = + Thyra::defaultBlockedLinearOp(); + alOpRhs_->beginBlockFill(dim_ + 1, dim_ + 1); + + // Identity matrices on the main diagonal. + for (int i = 0; i < dim_; i++) { + // build the blocks and place it the right location + alOpRhs_->setBlock(i, i, Thyra::identity(blockedOpBlocks[0][0]->range())); + } // end for i + alOpRhs_->setBlock(dim_, dim_, Thyra::identity(blockedOpBlocks[dim_][dim_]->range())); + + // Last column. + for (int i = 0; i < dim_; i++) { + alOpRhs_->setBlock( + i, dim_, + Thyra::scale(gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_))); + } + + alOpRhs_->endBlockFill(); + + alOperatorRhs_ = alOpRhs_; + + // reorder if necessary + if (reorderManager_ != Teuchos::null) Reorder(*reorderManager_); } -void -ALOperator::augmentRHS(const Epetra_MultiVector & b, Epetra_MultiVector & bAugmented) -{ - Teuchos::RCP mapping - = this->getMapStrategy(); - Teuchos::RCP > bThyra - = Thyra::createMembers(thyraOp_->range(), b.NumVectors()); - Teuchos::RCP > bThyraAugmented - = Thyra::createMembers(thyraOp_->range(), b.NumVectors()); - //std::cout << Teuchos::describe(*bThyra, Teuchos::VERB_EXTREME) << std::endl; - // Copy Epetra vector to Thyra vector. - mapping->copyEpetraIntoThyra(b, bThyra.ptr()); - // Apply operator. - alOperatorRhs_->apply(Thyra::NOTRANS, *bThyra, bThyraAugmented.ptr(), 1.0, 0.0); - // Copy Thyra vector to Epetra vector. - mapping->copyThyraIntoEpetra(bThyraAugmented, bAugmented); +void ALOperator::augmentRHS(const Epetra_MultiVector& b, Epetra_MultiVector& bAugmented) { + Teuchos::RCP mapping = this->getMapStrategy(); + Teuchos::RCP > bThyra = + Thyra::createMembers(thyraOp_->range(), b.NumVectors()); + Teuchos::RCP > bThyraAugmented = + Thyra::createMembers(thyraOp_->range(), b.NumVectors()); + // std::cout << Teuchos::describe(*bThyra, Teuchos::VERB_EXTREME) << std::endl; + // Copy Epetra vector to Thyra vector. + mapping->copyEpetraIntoThyra(b, bThyra.ptr()); + // Apply operator. + alOperatorRhs_->apply(Thyra::NOTRANS, *bThyra, bThyraAugmented.ptr(), 1.0, 0.0); + // Copy Thyra vector to Epetra vector. + mapping->copyThyraIntoEpetra(bThyraAugmented, bAugmented); } -} // end namespace NS +} // end namespace NS -} // end namespace Teko +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_ALOperator.hpp b/packages/teko/src/NS/Teko_ALOperator.hpp index cc1eb3fe5f46..27075b642518 100644 --- a/packages/teko/src/NS/Teko_ALOperator.hpp +++ b/packages/teko/src/NS/Teko_ALOperator.hpp @@ -10,11 +10,9 @@ #include "Teko_BlockedEpetraOperator.hpp" #include "Teko_Utilities.hpp" -namespace Teko -{ +namespace Teko { -namespace NS -{ +namespace NS { /** \brief Sparse matrix vector multiplication * for augmented Lagrangian-based preconditioners. @@ -40,7 +38,7 @@ namespace NS * \end{array} \right] * \left[ \begin{array}{c} * u \\ - * p + * p * \end{array} \right] * = * \left[ \begin{array}{c} @@ -80,179 +78,150 @@ namespace NS * \f$ \widehat{\mathcal{A}} \f$. */ -class ALOperator : public Teko::Epetra::BlockedEpetraOperator -{ -public: - - /** Build an augmented Lagrangian operator based on a vector of vector - * of global IDs. - * - * \param[in] vars - * Vector of vectors of global ids specifying - * how the operator is to be blocked. - * \param[in] content - * Operator to be blocked - * \param[in] pressureMassMatrix - * Pressure mass matrix - * \param[in] gamma - * Augmentation parameter - * \param[in] label - * Label for name the operator - */ - ALOperator(const std::vector > & vars, - const Teuchos::RCP & content, - LinearOp pressureMassMatrix, - double gamma = 0.05, const std::string & label = ""); - - /** Build a modified augmented Lagrangian operator based on a vector of vector - * of global IDs. - * - * \param[in] vars - * Vector of vectors of global ids specifying - * how the operator is to be blocked. - * \param[in] content - * Operator to be blocked - * \param[in] gamma - * Augmentation parameter - * \param[in] label - * Name of the operator - */ - ALOperator(const std::vector > & vars, - const Teuchos::RCP & content, - double gamma = 0.05, const std::string & label = ""); - - // Destructor - virtual - ~ALOperator() - { - } - - /** Set the pressure mass matrix. - * - * \param[in] pressureMassMatrix - * Pressure mass matrix. - * - */ - void - setPressureMassMatrix(LinearOp pressureMassMatrix); - - /** - * \returns Pressure mass matrix that can be used to construct preconditioner. - */ - const LinearOp & - getPressureMassMatrix() const - { - return pressureMassMatrix_; - } - - /** Set gamma. - * - * \param[in] gamma - * Augmentation parameter. - */ - void - setGamma(double gamma); - - /** - * \returns Gamma - * Augmentation parameter. - */ - const double & - getGamma() const - { - return gamma_; - } - - /** - * \param[in] b - * Right-hand side. - * \param[out] bAugmented - * Augmented right-hand side. - */ - void - augmentRHS(const Epetra_MultiVector & b, Epetra_MultiVector & bAugmented); - - /** - * \returns Number of rows. - */ - int - getNumberOfBlockRows() const - { - return numBlockRows_; - } - - /** - * Force a rebuild of the blocked operator from the stored - * content operator. - */ - virtual void - RebuildOps() - { - BuildALOperator(); - } - - /** Get the (i,j) block of the original (non-augmented) operator. - * - * \param[in] i - * Row index. - * \param[in] j - * Column index. - */ - const Teuchos::RCP - GetBlock(int i, int j) const; - -protected: - - /** - * AL operator. - */ - Teuchos::RCP > alOperator_; - - /** - * Operator for augmenting the right-hand side. - */ - Teuchos::RCP > alOperatorRhs_; - - /** - * Pressure mass matrix and its inverse. - */ - LinearOp pressureMassMatrix_; - - /** - * Inverse of the pressure mass matrix. - */ - LinearOp invPressureMassMatrix_; - - /** - * Augmentation parameter. - */ - double gamma_; - - /** - * Dimension of the problem. - */ - int dim_; - - /** - * Number of block rows. - */ - int numBlockRows_; - - /** - * Check dimension. Only implemente for 2D and 3D problems. - */ - void - checkDim(const std::vector > & vars); - - /** - * Build AL operator. - */ - void - BuildALOperator(); +class ALOperator : public Teko::Epetra::BlockedEpetraOperator { + public: + /** Build an augmented Lagrangian operator based on a vector of vector + * of global IDs. + * + * \param[in] vars + * Vector of vectors of global ids specifying + * how the operator is to be blocked. + * \param[in] content + * Operator to be blocked + * \param[in] pressureMassMatrix + * Pressure mass matrix + * \param[in] gamma + * Augmentation parameter + * \param[in] label + * Label for name the operator + */ + ALOperator(const std::vector >& vars, + const Teuchos::RCP& content, LinearOp pressureMassMatrix, + double gamma = 0.05, const std::string& label = ""); + + /** Build a modified augmented Lagrangian operator based on a vector of vector + * of global IDs. + * + * \param[in] vars + * Vector of vectors of global ids specifying + * how the operator is to be blocked. + * \param[in] content + * Operator to be blocked + * \param[in] gamma + * Augmentation parameter + * \param[in] label + * Name of the operator + */ + ALOperator(const std::vector >& vars, + const Teuchos::RCP& content, double gamma = 0.05, + const std::string& label = ""); + + // Destructor + virtual ~ALOperator() {} + + /** Set the pressure mass matrix. + * + * \param[in] pressureMassMatrix + * Pressure mass matrix. + * + */ + void setPressureMassMatrix(LinearOp pressureMassMatrix); + + /** + * \returns Pressure mass matrix that can be used to construct preconditioner. + */ + const LinearOp& getPressureMassMatrix() const { return pressureMassMatrix_; } + + /** Set gamma. + * + * \param[in] gamma + * Augmentation parameter. + */ + void setGamma(double gamma); + + /** + * \returns Gamma + * Augmentation parameter. + */ + const double& getGamma() const { return gamma_; } + + /** + * \param[in] b + * Right-hand side. + * \param[out] bAugmented + * Augmented right-hand side. + */ + void augmentRHS(const Epetra_MultiVector& b, Epetra_MultiVector& bAugmented); + + /** + * \returns Number of rows. + */ + int getNumberOfBlockRows() const { return numBlockRows_; } + + /** + * Force a rebuild of the blocked operator from the stored + * content operator. + */ + virtual void RebuildOps() { BuildALOperator(); } + + /** Get the (i,j) block of the original (non-augmented) operator. + * + * \param[in] i + * Row index. + * \param[in] j + * Column index. + */ + const Teuchos::RCP GetBlock(int i, int j) const; + + protected: + /** + * AL operator. + */ + Teuchos::RCP > alOperator_; + + /** + * Operator for augmenting the right-hand side. + */ + Teuchos::RCP > alOperatorRhs_; + + /** + * Pressure mass matrix and its inverse. + */ + LinearOp pressureMassMatrix_; + + /** + * Inverse of the pressure mass matrix. + */ + LinearOp invPressureMassMatrix_; + + /** + * Augmentation parameter. + */ + double gamma_; + + /** + * Dimension of the problem. + */ + int dim_; + + /** + * Number of block rows. + */ + int numBlockRows_; + + /** + * Check dimension. Only implemente for 2D and 3D problems. + */ + void checkDim(const std::vector >& vars); + + /** + * Build AL operator. + */ + void BuildALOperator(); }; -} // end namespace NS +} // end namespace NS -} // end namespace Teko +} // end namespace Teko #endif /* __Teko_ALOperator_hpp__ */ diff --git a/packages/teko/src/NS/Teko_InvLSCStrategy.cpp b/packages/teko/src/NS/Teko_InvLSCStrategy.cpp index b77780524d7f..de9d4e97f518 100644 --- a/packages/teko/src/NS/Teko_InvLSCStrategy.cpp +++ b/packages/teko/src/NS/Teko_InvLSCStrategy.cpp @@ -76,8 +76,8 @@ #include "Thyra_TpetraLinearOp.hpp" using Teuchos::RCP; -using Teuchos::rcp_dynamic_cast; using Teuchos::rcp_const_cast; +using Teuchos::rcp_dynamic_cast; namespace Teko { namespace NS { @@ -89,486 +89,514 @@ namespace NS { // constructors ///////////////////////////////////////////////////////////////////////////// InvLSCStrategy::InvLSCStrategy() - : massMatrix_(Teuchos::null), invFactoryF_(Teuchos::null), invFactoryS_(Teuchos::null), eigSolveParam_(5) - , rowZeroingNeeded_(false), useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal) - , isSymmetric_(true), assumeStable_(false) -{ } - -InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP & factory,bool rzn) - : massMatrix_(Teuchos::null), invFactoryF_(factory), invFactoryS_(factory), eigSolveParam_(5), rowZeroingNeeded_(rzn) - , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal) - , isSymmetric_(true), assumeStable_(false) -{ } - -InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP & invFactF, - const Teuchos::RCP & invFactS, + : massMatrix_(Teuchos::null), + invFactoryF_(Teuchos::null), + invFactoryS_(Teuchos::null), + eigSolveParam_(5), + rowZeroingNeeded_(false), + useFullLDU_(false), + useMass_(false), + useLumping_(false), + useWScaling_(false), + scaleType_(Diagonal), + isSymmetric_(true), + assumeStable_(false) {} + +InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP& factory, bool rzn) + : massMatrix_(Teuchos::null), + invFactoryF_(factory), + invFactoryS_(factory), + eigSolveParam_(5), + rowZeroingNeeded_(rzn), + useFullLDU_(false), + useMass_(false), + useLumping_(false), + useWScaling_(false), + scaleType_(Diagonal), + isSymmetric_(true), + assumeStable_(false) {} + +InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP& invFactF, + const Teuchos::RCP& invFactS, bool rzn) + : massMatrix_(Teuchos::null), + invFactoryF_(invFactF), + invFactoryS_(invFactS), + eigSolveParam_(5), + rowZeroingNeeded_(rzn), + useFullLDU_(false), + useMass_(false), + useLumping_(false), + useWScaling_(false), + scaleType_(Diagonal), + isSymmetric_(true), + assumeStable_(false) {} + +InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP& factory, LinearOp& mass, + bool rzn) + : massMatrix_(mass), + invFactoryF_(factory), + invFactoryS_(factory), + eigSolveParam_(5), + rowZeroingNeeded_(rzn), + useFullLDU_(false), + useMass_(false), + useLumping_(false), + useWScaling_(false), + scaleType_(Diagonal), + isSymmetric_(true), + assumeStable_(false) {} + +InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP& invFactF, + const Teuchos::RCP& invFactS, LinearOp& mass, bool rzn) - : massMatrix_(Teuchos::null), invFactoryF_(invFactF), invFactoryS_(invFactS), eigSolveParam_(5), rowZeroingNeeded_(rzn) - , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal) - , isSymmetric_(true), assumeStable_(false) -{ } - -InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP & factory,LinearOp & mass,bool rzn) - : massMatrix_(mass), invFactoryF_(factory), invFactoryS_(factory), eigSolveParam_(5), rowZeroingNeeded_(rzn) - , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal) - , isSymmetric_(true), assumeStable_(false) -{ } - -InvLSCStrategy::InvLSCStrategy(const Teuchos::RCP & invFactF, - const Teuchos::RCP & invFactS, - LinearOp & mass,bool rzn) - : massMatrix_(mass), invFactoryF_(invFactF), invFactoryS_(invFactS), eigSolveParam_(5), rowZeroingNeeded_(rzn) - , useFullLDU_(false), useMass_(false), useLumping_(false), useWScaling_(false), scaleType_(Diagonal) - , isSymmetric_(true), assumeStable_(false) -{ } + : massMatrix_(mass), + invFactoryF_(invFactF), + invFactoryS_(invFactS), + eigSolveParam_(5), + rowZeroingNeeded_(rzn), + useFullLDU_(false), + useMass_(false), + useLumping_(false), + useWScaling_(false), + scaleType_(Diagonal), + isSymmetric_(true), + assumeStable_(false) {} ///////////////////////////////////////////////////////////////////////////// -void InvLSCStrategy::buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - Teko_DEBUG_SCOPE("InvLSCStrategy::buildState",10); +void InvLSCStrategy::buildState(BlockedLinearOp& A, BlockPreconditionerState& state) const { + Teko_DEBUG_SCOPE("InvLSCStrategy::buildState", 10); - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); - // if neccessary save state information - if(not lscState->isInitialized()) { - Teko_DEBUG_EXPR(Teuchos::Time timer("")); + // if neccessary save state information + if (not lscState->isInitialized()) { + Teko_DEBUG_EXPR(Teuchos::Time timer("")); - // construct operators - { - Teko_DEBUG_SCOPE("LSC::buildState constructing operators",1); - Teko_DEBUG_EXPR(timer.start(true)); + // construct operators + { + Teko_DEBUG_SCOPE("LSC::buildState constructing operators", 1); + Teko_DEBUG_EXPR(timer.start(true)); - initializeState(A,lscState); + initializeState(A, lscState); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("LSC::buildState BuildOpsTime = " << timer.totalElapsedTime(),1); - } + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("LSC::buildState BuildOpsTime = " << timer.totalElapsedTime(), 1); + } - // Build the inverses - { - Teko_DEBUG_SCOPE("LSC::buildState calculating inverses",1); - Teko_DEBUG_EXPR(timer.start(true)); + // Build the inverses + { + Teko_DEBUG_SCOPE("LSC::buildState calculating inverses", 1); + Teko_DEBUG_EXPR(timer.start(true)); - computeInverses(A,lscState); + computeInverses(A, lscState); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("LSC::buildState BuildInvTime = " << timer.totalElapsedTime(),1); - } - } + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("LSC::buildState BuildInvTime = " << timer.totalElapsedTime(), 1); + } + } } // functions inherited from LSCStrategy -LinearOp InvLSCStrategy::getInvBQBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getInverse("invBQBtmC"); +LinearOp InvLSCStrategy::getInvBQBt(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getInverse("invBQBtmC"); } -LinearOp InvLSCStrategy::getInvBHBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getInverse("invBHBtmC"); +LinearOp InvLSCStrategy::getInvBHBt(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getInverse("invBHBtmC"); } -LinearOp InvLSCStrategy::getInvF(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getInverse("invF"); +LinearOp InvLSCStrategy::getInvF(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getInverse("invF"); } -LinearOp InvLSCStrategy::getOuterStabilization(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); - TEUCHOS_ASSERT(lscState->isInitialized()) +LinearOp InvLSCStrategy::getOuterStabilization(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); + TEUCHOS_ASSERT(lscState->isInitialized()) - return lscState->aiD_; + return lscState->aiD_; } -LinearOp InvLSCStrategy::getInvMass(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); - TEUCHOS_ASSERT(lscState->isInitialized()) +LinearOp InvLSCStrategy::getInvMass(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); + TEUCHOS_ASSERT(lscState->isInitialized()) - return lscState->invMass_; + return lscState->invMass_; } -LinearOp InvLSCStrategy::getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - if(hScaling_!=Teuchos::null) return hScaling_; - return getInvMass(A,state); +LinearOp InvLSCStrategy::getHScaling(const BlockedLinearOp& A, + BlockPreconditionerState& state) const { + if (hScaling_ != Teuchos::null) return hScaling_; + return getInvMass(A, state); } //! Initialize the state object using this blocked linear operator -void InvLSCStrategy::initializeState(const BlockedLinearOp & A,LSCPrecondState * state) const -{ - Teko_DEBUG_SCOPE("InvLSCStrategy::initializeState",10); - - const LinearOp F = getBlock(0,0,A); - const LinearOp Bt = getBlock(0,1,A); - const LinearOp B = getBlock(1,0,A); - const LinearOp C = getBlock(1,1,A); - - LinearOp D = B; - LinearOp G = isSymmetric_ ? Bt : adjoint(D); - - bool isStabilized = assumeStable_ ? false : (not isZeroOp(C)); - - // The logic follows like this - // if there is no mass matrix available --> build from F - // if there is a mass matrix and the inverse hasn't yet been built - // --> build from the mass matrix - // otherwise, there is already an invMass_ matrix that is appropriate - // --> use that one - if(massMatrix_==Teuchos::null) { - Teko_DEBUG_MSG("LSC::initializeState Build Scaling type \"" - << getDiagonalName(scaleType_) << "\"" ,1); - state->invMass_ = getInvDiagonalOp(F,scaleType_); - } - else if(state->invMass_==Teuchos::null) { - Teko_DEBUG_MSG("LSC::initializeState Build Scaling type \"" - << getDiagonalName(scaleType_) << "\"" ,1); - state->invMass_ = getInvDiagonalOp(massMatrix_,scaleType_); - } - // else "invMass_" should be set and there is no reason to rebuild it - - // compute BQBt - state->BQBt_ = explicitMultiply(B,state->invMass_,Bt,state->BQBt_); - Teko_DEBUG_MSG("Computed BQBt",10); - - // if there is no H-Scaling - if(wScaling_!=Teuchos::null && hScaling_==Teuchos::null) { - // from W vector build H operator scaling - RCP > w = wScaling_->col(0); - RCP > iQu - = rcp_dynamic_cast >(state->invMass_)->getDiag(); - RCP > h = Thyra::createMember(iQu->space()); - - Thyra::put_scalar(0.0,h.ptr()); - Thyra::ele_wise_prod(1.0,*w,*iQu,h.ptr()); - hScaling_ = Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp(h)); - } - - LinearOp H = hScaling_; - if(H==Teuchos::null && not isSymmetric_) - H = state->invMass_; - - // setup the scaling operator - if(H==Teuchos::null) - state->BHBt_ = state->BQBt_; - else { - RCP time = Teuchos::TimeMonitor::getNewTimer("InvLSCStrategy::initializeState Build BHBt"); - Teuchos::TimeMonitor timer(*time); - - // compute BHBt - state->BHBt_ = explicitMultiply(D,H,G,state->BHBt_); - } - - // if this is a stable discretization...we are done! - if(not isStabilized) { - state->addInverse("BQBtmC",state->BQBt_); - state->addInverse("BHBtmC",state->BHBt_); - state->gamma_ = 0.0; - state->alpha_ = 0.0; - state->aiD_ = Teuchos::null; +void InvLSCStrategy::initializeState(const BlockedLinearOp& A, LSCPrecondState* state) const { + Teko_DEBUG_SCOPE("InvLSCStrategy::initializeState", 10); + + const LinearOp F = getBlock(0, 0, A); + const LinearOp Bt = getBlock(0, 1, A); + const LinearOp B = getBlock(1, 0, A); + const LinearOp C = getBlock(1, 1, A); + + LinearOp D = B; + LinearOp G = isSymmetric_ ? Bt : adjoint(D); + + bool isStabilized = assumeStable_ ? false : (not isZeroOp(C)); + + // The logic follows like this + // if there is no mass matrix available --> build from F + // if there is a mass matrix and the inverse hasn't yet been built + // --> build from the mass matrix + // otherwise, there is already an invMass_ matrix that is appropriate + // --> use that one + if (massMatrix_ == Teuchos::null) { + Teko_DEBUG_MSG( + "LSC::initializeState Build Scaling type \"" << getDiagonalName(scaleType_) << "\"", 1); + state->invMass_ = getInvDiagonalOp(F, scaleType_); + } else if (state->invMass_ == Teuchos::null) { + Teko_DEBUG_MSG( + "LSC::initializeState Build Scaling type \"" << getDiagonalName(scaleType_) << "\"", + 1); + state->invMass_ = getInvDiagonalOp(massMatrix_, scaleType_); + } + // else "invMass_" should be set and there is no reason to rebuild it + + // compute BQBt + state->BQBt_ = explicitMultiply(B, state->invMass_, Bt, state->BQBt_); + Teko_DEBUG_MSG("Computed BQBt", 10); + + // if there is no H-Scaling + if (wScaling_ != Teuchos::null && hScaling_ == Teuchos::null) { + // from W vector build H operator scaling + RCP > w = wScaling_->col(0); + RCP > iQu = + rcp_dynamic_cast >(state->invMass_)->getDiag(); + RCP > h = Thyra::createMember(iQu->space()); + + Thyra::put_scalar(0.0, h.ptr()); + Thyra::ele_wise_prod(1.0, *w, *iQu, h.ptr()); + hScaling_ = Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp(h)); + } + + LinearOp H = hScaling_; + if (H == Teuchos::null && not isSymmetric_) H = state->invMass_; + + // setup the scaling operator + if (H == Teuchos::null) + state->BHBt_ = state->BQBt_; + else { + RCP time = + Teuchos::TimeMonitor::getNewTimer("InvLSCStrategy::initializeState Build BHBt"); + Teuchos::TimeMonitor timer(*time); + + // compute BHBt + state->BHBt_ = explicitMultiply(D, H, G, state->BHBt_); + } + + // if this is a stable discretization...we are done! + if (not isStabilized) { + state->addInverse("BQBtmC", state->BQBt_); + state->addInverse("BHBtmC", state->BHBt_); + state->gamma_ = 0.0; + state->alpha_ = 0.0; + state->aiD_ = Teuchos::null; + + state->setInitialized(true); + + return; + } + + // for Epetra_CrsMatrix...zero out certain rows: this ensures spectral radius is correct + LinearOp modF = F; + if (!Teko::TpetraHelpers::isTpetraLinearOp(F)) { // Epetra +#ifdef TEKO_HAVE_EPETRA + const RCP epF = Thyra::get_Epetra_Operator(*F); + if (epF != Teuchos::null && rowZeroingNeeded_) { + // try to get a CRS matrix + const RCP crsF = rcp_dynamic_cast(epF); - state->setInitialized(true); + // if it is a CRS matrix get rows that need to be zeroed + if (crsF != Teuchos::null) { + std::vector zeroIndices; - return; - } + // get rows in need of zeroing + Teko::Epetra::identityRowIndices(crsF->RowMap(), *crsF, zeroIndices); - // for Epetra_CrsMatrix...zero out certain rows: this ensures spectral radius is correct - LinearOp modF = F; - if(!Teko::TpetraHelpers::isTpetraLinearOp(F)){ // Epetra -#ifdef TEKO_HAVE_EPETRA - const RCP epF = Thyra::get_Epetra_Operator(*F); - if(epF!=Teuchos::null && rowZeroingNeeded_) { - // try to get a CRS matrix - const RCP crsF = rcp_dynamic_cast(epF); - - // if it is a CRS matrix get rows that need to be zeroed - if(crsF!=Teuchos::null) { - std::vector zeroIndices; - - // get rows in need of zeroing - Teko::Epetra::identityRowIndices(crsF->RowMap(), *crsF,zeroIndices); - - // build an operator that zeros those rows - modF = Thyra::epetraLinearOp(rcp(new Teko::Epetra::ZeroedOperator(zeroIndices,crsF))); - } - } + // build an operator that zeros those rows + modF = Thyra::epetraLinearOp(rcp(new Teko::Epetra::ZeroedOperator(zeroIndices, crsF))); + } + } #else - throw std::logic_error("InvLSCStrategy::initializeState is trying to use " - "Epetra code, but TEKO is not built with Epetra!"); + throw std::logic_error( + "InvLSCStrategy::initializeState is trying to use " + "Epetra code, but TEKO is not built with Epetra!"); #endif - } else { //Tpetra - ST scalar = 0.0; - bool transp = false; - RCP > crsF = Teko::TpetraHelpers::getTpetraCrsMatrix(F, &scalar, &transp); - - std::vector zeroIndices; - - // get rows in need of zeroing - Teko::TpetraHelpers::identityRowIndices(*crsF->getRowMap(), *crsF,zeroIndices); - - // build an operator that zeros those rows - modF = Thyra::tpetraLinearOp(Thyra::tpetraVectorSpace(crsF->getDomainMap()),Thyra::tpetraVectorSpace(crsF->getRangeMap()),rcp(new Teko::TpetraHelpers::ZeroedOperator(zeroIndices,crsF))); - } - - // compute gamma - Teko_DEBUG_MSG("Calculating gamma",10); - LinearOp iQuF = multiply(state->invMass_,modF); - - // do 6 power iterations to compute spectral radius: EHSST2007 Eq. 4.28 - Teko::LinearOp stabMatrix; // this is the pressure stabilization matrix to use - state->gamma_ = std::fabs(Teko::computeSpectralRad(iQuF,5e-2,false,eigSolveParam_))/3.0; - Teko_DEBUG_MSG("Calculated gamma",10); - if(userPresStabMat_!=Teuchos::null) { - Teko::LinearOp invDGl = Teko::getInvDiagonalOp(userPresStabMat_); - Teko::LinearOp gammaOp = multiply(invDGl,C); - state->gamma_ *= std::fabs(Teko::computeSpectralRad(gammaOp,5e-2,false,eigSolveParam_)); - stabMatrix = userPresStabMat_; - } else - stabMatrix = C; - - // compute alpha scaled inv(D): EHSST2007 Eq. 4.29 - // construct B_idF_Bt and save it for refilling later: This could reuse BQBt graph - LinearOp invDiagF = getInvDiagonalOp(F); - Teko::ModifiableLinearOp modB_idF_Bt = state->getInverse("BidFBt"); - modB_idF_Bt = explicitMultiply(B,invDiagF,Bt,modB_idF_Bt); - state->addInverse("BidFBt",modB_idF_Bt); - const LinearOp B_idF_Bt = modB_idF_Bt; - - MultiVector vec_D = getDiagonal(B_idF_Bt); // this memory could be reused - update(-1.0,getDiagonal(C),1.0,vec_D); // vec_D = diag(B*inv(diag(F))*Bt)-diag(C) - const LinearOp invD = buildInvDiagonal(vec_D,"inv(D)"); - - Teko_DEBUG_MSG("Calculating alpha",10); - const LinearOp BidFBtidD = multiply(B_idF_Bt,invD); - double num = std::fabs(Teko::computeSpectralRad(BidFBtidD,5e-2,false,eigSolveParam_)); - Teko_DEBUG_MSG("Calculated alpha",10); - state->alpha_ = 1.0/num; - state->aiD_ = Thyra::scale(state->alpha_,invD); - - // now build B*Q*Bt-gamma*C - Teko::ModifiableLinearOp BQBtmC = state->getInverse("BQBtmC"); - BQBtmC = explicitAdd(state->BQBt_,scale(-state->gamma_,stabMatrix),BQBtmC); - state->addInverse("BQBtmC",BQBtmC); - - // now build B*H*Bt-gamma*C - Teko::ModifiableLinearOp BHBtmC = state->getInverse("BHBtmC"); - if(H==Teuchos::null) - BHBtmC = BQBtmC; - else { - BHBtmC = explicitAdd(state->BHBt_,scale(-state->gamma_,stabMatrix),BHBtmC); - } - state->addInverse("BHBtmC",BHBtmC); - - Teko_DEBUG_MSG_BEGIN(5) - DEBUG_STREAM << "LSC Gamma Parameter = " << state->gamma_ << std::endl; - DEBUG_STREAM << "LSC Alpha Parameter = " << state->alpha_ << std::endl; - Teko_DEBUG_MSG_END() - - state->setInitialized(true); + } else { // Tpetra + ST scalar = 0.0; + bool transp = false; + RCP > crsF = + Teko::TpetraHelpers::getTpetraCrsMatrix(F, &scalar, &transp); + + std::vector zeroIndices; + + // get rows in need of zeroing + Teko::TpetraHelpers::identityRowIndices(*crsF->getRowMap(), *crsF, zeroIndices); + + // build an operator that zeros those rows + modF = Thyra::tpetraLinearOp( + Thyra::tpetraVectorSpace(crsF->getDomainMap()), + Thyra::tpetraVectorSpace(crsF->getRangeMap()), + rcp(new Teko::TpetraHelpers::ZeroedOperator(zeroIndices, crsF))); + } + + // compute gamma + Teko_DEBUG_MSG("Calculating gamma", 10); + LinearOp iQuF = multiply(state->invMass_, modF); + + // do 6 power iterations to compute spectral radius: EHSST2007 Eq. 4.28 + Teko::LinearOp stabMatrix; // this is the pressure stabilization matrix to use + state->gamma_ = std::fabs(Teko::computeSpectralRad(iQuF, 5e-2, false, eigSolveParam_)) / 3.0; + Teko_DEBUG_MSG("Calculated gamma", 10); + if (userPresStabMat_ != Teuchos::null) { + Teko::LinearOp invDGl = Teko::getInvDiagonalOp(userPresStabMat_); + Teko::LinearOp gammaOp = multiply(invDGl, C); + state->gamma_ *= std::fabs(Teko::computeSpectralRad(gammaOp, 5e-2, false, eigSolveParam_)); + stabMatrix = userPresStabMat_; + } else + stabMatrix = C; + + // compute alpha scaled inv(D): EHSST2007 Eq. 4.29 + // construct B_idF_Bt and save it for refilling later: This could reuse BQBt graph + LinearOp invDiagF = getInvDiagonalOp(F); + Teko::ModifiableLinearOp modB_idF_Bt = state->getInverse("BidFBt"); + modB_idF_Bt = explicitMultiply(B, invDiagF, Bt, modB_idF_Bt); + state->addInverse("BidFBt", modB_idF_Bt); + const LinearOp B_idF_Bt = modB_idF_Bt; + + MultiVector vec_D = getDiagonal(B_idF_Bt); // this memory could be reused + update(-1.0, getDiagonal(C), 1.0, vec_D); // vec_D = diag(B*inv(diag(F))*Bt)-diag(C) + const LinearOp invD = buildInvDiagonal(vec_D, "inv(D)"); + + Teko_DEBUG_MSG("Calculating alpha", 10); + const LinearOp BidFBtidD = multiply(B_idF_Bt, invD); + double num = std::fabs(Teko::computeSpectralRad(BidFBtidD, 5e-2, false, eigSolveParam_)); + Teko_DEBUG_MSG("Calculated alpha", 10); + state->alpha_ = 1.0 / num; + state->aiD_ = Thyra::scale(state->alpha_, invD); + + // now build B*Q*Bt-gamma*C + Teko::ModifiableLinearOp BQBtmC = state->getInverse("BQBtmC"); + BQBtmC = explicitAdd(state->BQBt_, scale(-state->gamma_, stabMatrix), BQBtmC); + state->addInverse("BQBtmC", BQBtmC); + + // now build B*H*Bt-gamma*C + Teko::ModifiableLinearOp BHBtmC = state->getInverse("BHBtmC"); + if (H == Teuchos::null) + BHBtmC = BQBtmC; + else { + BHBtmC = explicitAdd(state->BHBt_, scale(-state->gamma_, stabMatrix), BHBtmC); + } + state->addInverse("BHBtmC", BHBtmC); + + Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "LSC Gamma Parameter = " << state->gamma_ << std::endl; + DEBUG_STREAM << "LSC Alpha Parameter = " << state->alpha_ << std::endl; + Teko_DEBUG_MSG_END() + + state->setInitialized(true); } /** Compute the inverses required for the LSC Schur complement - * - * \note This method assumes that the BQBt and BHBt operators have - * been constructed. - */ -void InvLSCStrategy::computeInverses(const BlockedLinearOp & A,LSCPrecondState * state) const -{ - Teko_DEBUG_SCOPE("InvLSCStrategy::computeInverses",10); - Teko_DEBUG_EXPR(Teuchos::Time invTimer("")); - - const LinearOp F = getBlock(0,0,A); - - ///////////////////////////////////////////////////////// - - // (re)build the inverse of F - Teko_DEBUG_MSG("LSC::computeInverses Building inv(F)",1); - Teko_DEBUG_EXPR(invTimer.start(true)); - InverseLinearOp invF = state->getInverse("invF"); - if(invF==Teuchos::null) { - invF = buildInverse(*invFactoryF_,F); - state->addInverse("invF",invF); - } else { - rebuildInverse(*invFactoryF_,F,invF); - } - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("LSC::computeInverses GetInvF = " << invTimer.totalElapsedTime(),1); - - ///////////////////////////////////////////////////////// - - // (re)build the inverse of BQBt - Teko_DEBUG_MSG("LSC::computeInverses Building inv(BQBtmC)",1); - Teko_DEBUG_EXPR(invTimer.start(true)); - const LinearOp BQBt = state->getInverse("BQBtmC"); - InverseLinearOp invBQBt = state->getInverse("invBQBtmC"); - if(invBQBt==Teuchos::null) { - invBQBt = buildInverse(*invFactoryS_,BQBt); - state->addInverse("invBQBtmC",invBQBt); - } else { - rebuildInverse(*invFactoryS_,BQBt,invBQBt); - } - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("LSC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(),1); - - ///////////////////////////////////////////////////////// - - // Compute the inverse of BHBt or just use BQBt - ModifiableLinearOp invBHBt = state->getInverse("invBHBtmC"); - if(hScaling_!=Teuchos::null || not isSymmetric_) { - // (re)build the inverse of BHBt - Teko_DEBUG_MSG("LSC::computeInverses Building inv(BHBtmC)",1); - Teko_DEBUG_EXPR(invTimer.start(true)); - const LinearOp BHBt = state->getInverse("BHBtmC"); - if(invBHBt==Teuchos::null) { - invBHBt = buildInverse(*invFactoryS_,BHBt); - state->addInverse("invBHBtmC",invBHBt); - } else { - rebuildInverse(*invFactoryS_,BHBt,invBHBt); - } - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("LSC::computeInverses GetInvBHBt = " << invTimer.totalElapsedTime(),1); - } - else if(invBHBt==Teuchos::null) { - // just use the Q version - state->addInverse("invBHBtmC",invBQBt); - } + * + * \note This method assumes that the BQBt and BHBt operators have + * been constructed. + */ +void InvLSCStrategy::computeInverses(const BlockedLinearOp& A, LSCPrecondState* state) const { + Teko_DEBUG_SCOPE("InvLSCStrategy::computeInverses", 10); + Teko_DEBUG_EXPR(Teuchos::Time invTimer("")); + + const LinearOp F = getBlock(0, 0, A); + + ///////////////////////////////////////////////////////// + + // (re)build the inverse of F + Teko_DEBUG_MSG("LSC::computeInverses Building inv(F)", 1); + Teko_DEBUG_EXPR(invTimer.start(true)); + InverseLinearOp invF = state->getInverse("invF"); + if (invF == Teuchos::null) { + invF = buildInverse(*invFactoryF_, F); + state->addInverse("invF", invF); + } else { + rebuildInverse(*invFactoryF_, F, invF); + } + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("LSC::computeInverses GetInvF = " << invTimer.totalElapsedTime(), 1); + + ///////////////////////////////////////////////////////// + + // (re)build the inverse of BQBt + Teko_DEBUG_MSG("LSC::computeInverses Building inv(BQBtmC)", 1); + Teko_DEBUG_EXPR(invTimer.start(true)); + const LinearOp BQBt = state->getInverse("BQBtmC"); + InverseLinearOp invBQBt = state->getInverse("invBQBtmC"); + if (invBQBt == Teuchos::null) { + invBQBt = buildInverse(*invFactoryS_, BQBt); + state->addInverse("invBQBtmC", invBQBt); + } else { + rebuildInverse(*invFactoryS_, BQBt, invBQBt); + } + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("LSC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(), 1); + + ///////////////////////////////////////////////////////// + + // Compute the inverse of BHBt or just use BQBt + ModifiableLinearOp invBHBt = state->getInverse("invBHBtmC"); + if (hScaling_ != Teuchos::null || not isSymmetric_) { + // (re)build the inverse of BHBt + Teko_DEBUG_MSG("LSC::computeInverses Building inv(BHBtmC)", 1); + Teko_DEBUG_EXPR(invTimer.start(true)); + const LinearOp BHBt = state->getInverse("BHBtmC"); + if (invBHBt == Teuchos::null) { + invBHBt = buildInverse(*invFactoryS_, BHBt); + state->addInverse("invBHBtmC", invBHBt); + } else { + rebuildInverse(*invFactoryS_, BHBt, invBHBt); + } + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("LSC::computeInverses GetInvBHBt = " << invTimer.totalElapsedTime(), 1); + } else if (invBHBt == Teuchos::null) { + // just use the Q version + state->addInverse("invBHBtmC", invBQBt); + } } //! Initialize from a parameter list -void InvLSCStrategy::initializeFromParameterList(const Teuchos::ParameterList & pl,const InverseLibrary & invLib) -{ - // get string specifying inverse - std::string invStr="", invVStr="", invPStr=""; - bool rowZeroing = true; - bool useLDU = false; - scaleType_ = Diagonal; - - // "parse" the parameter list - if(pl.isParameter("Inverse Type")) - invStr = pl.get("Inverse Type"); - if(pl.isParameter("Inverse Velocity Type")) - invVStr = pl.get("Inverse Velocity Type"); - if(pl.isParameter("Inverse Pressure Type")) - invPStr = pl.get("Inverse Pressure Type"); - if(pl.isParameter("Ignore Boundary Rows")) - rowZeroing = pl.get("Ignore Boundary Rows"); - if(pl.isParameter("Use LDU")) - useLDU = pl.get("Use LDU"); - if(pl.isParameter("Use Mass Scaling")) - useMass_ = pl.get("Use Mass Scaling"); - // if(pl.isParameter("Use Lumping")) - // useLumping_ = pl.get("Use Lumping"); - if(pl.isParameter("Use W-Scaling")) - useWScaling_ = pl.get("Use W-Scaling"); - if(pl.isParameter("Eigen Solver Iterations")) - eigSolveParam_ = pl.get("Eigen Solver Iterations"); - if(pl.isParameter("Scaling Type")) { - scaleType_ = getDiagonalType(pl.get("Scaling Type")); - TEUCHOS_TEST_FOR_EXCEPT(scaleType_==NotDiag); - } - if(pl.isParameter("Assume Stable Discretization")) - assumeStable_ = pl.get("Assume Stable Discretization"); - - Teko_DEBUG_MSG_BEGIN(5) - DEBUG_STREAM << "LSC Inverse Strategy Parameters: " << std::endl; - DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; - DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; - DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; - DEBUG_STREAM << " bndry rows = " << rowZeroing << std::endl; - DEBUG_STREAM << " use ldu = " << useLDU << std::endl; - DEBUG_STREAM << " use mass = " << useMass_ << std::endl; - DEBUG_STREAM << " use w-scaling = " << useWScaling_ << std::endl; - DEBUG_STREAM << " assume stable = " << assumeStable_ << std::endl; - DEBUG_STREAM << " scale type = " << getDiagonalName(scaleType_) << std::endl; - DEBUG_STREAM << "LSC Inverse Strategy Parameter list: " << std::endl; - pl.print(DEBUG_STREAM); - Teko_DEBUG_MSG_END() - - // set defaults as needed - if(invStr=="") invStr = "Amesos"; - if(invVStr=="") invVStr = invStr; - if(invPStr=="") invPStr = invStr; - - // build velocity inverse factory - invFactoryF_ = invLib.getInverseFactory(invVStr); - invFactoryS_ = invFactoryF_; // by default these are the same - if(invVStr!=invPStr) // if different, build pressure inverse factory - invFactoryS_ = invLib.getInverseFactory(invPStr); - - // set other parameters - setUseFullLDU(useLDU); - setRowZeroing(rowZeroing); - - if(useMass_) { - Teuchos::RCP rh = getRequestHandler(); - rh->preRequest(Teko::RequestMesg("Velocity Mass Matrix")); - Teko::LinearOp mass - = rh->request(Teko::RequestMesg("Velocity Mass Matrix")); - setMassMatrix(mass); - } - +void InvLSCStrategy::initializeFromParameterList(const Teuchos::ParameterList& pl, + const InverseLibrary& invLib) { + // get string specifying inverse + std::string invStr = "", invVStr = "", invPStr = ""; + bool rowZeroing = true; + bool useLDU = false; + scaleType_ = Diagonal; + + // "parse" the parameter list + if (pl.isParameter("Inverse Type")) invStr = pl.get("Inverse Type"); + if (pl.isParameter("Inverse Velocity Type")) + invVStr = pl.get("Inverse Velocity Type"); + if (pl.isParameter("Inverse Pressure Type")) + invPStr = pl.get("Inverse Pressure Type"); + if (pl.isParameter("Ignore Boundary Rows")) rowZeroing = pl.get("Ignore Boundary Rows"); + if (pl.isParameter("Use LDU")) useLDU = pl.get("Use LDU"); + if (pl.isParameter("Use Mass Scaling")) useMass_ = pl.get("Use Mass Scaling"); + // if(pl.isParameter("Use Lumping")) + // useLumping_ = pl.get("Use Lumping"); + if (pl.isParameter("Use W-Scaling")) useWScaling_ = pl.get("Use W-Scaling"); + if (pl.isParameter("Eigen Solver Iterations")) + eigSolveParam_ = pl.get("Eigen Solver Iterations"); + if (pl.isParameter("Scaling Type")) { + scaleType_ = getDiagonalType(pl.get("Scaling Type")); + TEUCHOS_TEST_FOR_EXCEPT(scaleType_ == NotDiag); + } + if (pl.isParameter("Assume Stable Discretization")) + assumeStable_ = pl.get("Assume Stable Discretization"); + + Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "LSC Inverse Strategy Parameters: " << std::endl; + DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; + DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; + DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; + DEBUG_STREAM << " bndry rows = " << rowZeroing << std::endl; + DEBUG_STREAM << " use ldu = " << useLDU << std::endl; + DEBUG_STREAM << " use mass = " << useMass_ << std::endl; + DEBUG_STREAM << " use w-scaling = " << useWScaling_ << std::endl; + DEBUG_STREAM << " assume stable = " << assumeStable_ << std::endl; + DEBUG_STREAM << " scale type = " << getDiagonalName(scaleType_) << std::endl; + DEBUG_STREAM << "LSC Inverse Strategy Parameter list: " << std::endl; + pl.print(DEBUG_STREAM); + Teko_DEBUG_MSG_END() + + // set defaults as needed + if (invStr == "") invStr = "Amesos"; + if (invVStr == "") invVStr = invStr; + if (invPStr == "") invPStr = invStr; + + // build velocity inverse factory + invFactoryF_ = invLib.getInverseFactory(invVStr); + invFactoryS_ = invFactoryF_; // by default these are the same + if (invVStr != invPStr) // if different, build pressure inverse factory + invFactoryS_ = invLib.getInverseFactory(invPStr); + + // set other parameters + setUseFullLDU(useLDU); + setRowZeroing(rowZeroing); + + if (useMass_) { + Teuchos::RCP rh = getRequestHandler(); + rh->preRequest(Teko::RequestMesg("Velocity Mass Matrix")); + Teko::LinearOp mass = rh->request(Teko::RequestMesg("Velocity Mass Matrix")); + setMassMatrix(mass); + } } //! For assiting in construction of the preconditioner -Teuchos::RCP InvLSCStrategy::getRequestedParameters() const -{ - Teuchos::RCP result; - Teuchos::RCP pl = rcp(new Teuchos::ParameterList()); - - // grab parameters from F solver - RCP fList = invFactoryF_->getRequestedParameters(); - if(fList!=Teuchos::null) { - Teuchos::ParameterList::ConstIterator itr; - for(itr=fList->begin();itr!=fList->end();++itr) - pl->setEntry(itr->first,itr->second); - result = pl; - } - - // grab parameters from S solver - RCP sList = invFactoryS_->getRequestedParameters(); - if(sList!=Teuchos::null) { - Teuchos::ParameterList::ConstIterator itr; - for(itr=sList->begin();itr!=sList->end();++itr) - pl->setEntry(itr->first,itr->second); - result = pl; - } - - // use the mass matrix - if(useWScaling_) { - pl->set("W-Scaling Vector", Teuchos::null,"W-Scaling Vector"); - result = pl; - } - - return result; +Teuchos::RCP InvLSCStrategy::getRequestedParameters() const { + Teuchos::RCP result; + Teuchos::RCP pl = rcp(new Teuchos::ParameterList()); + + // grab parameters from F solver + RCP fList = invFactoryF_->getRequestedParameters(); + if (fList != Teuchos::null) { + Teuchos::ParameterList::ConstIterator itr; + for (itr = fList->begin(); itr != fList->end(); ++itr) pl->setEntry(itr->first, itr->second); + result = pl; + } + + // grab parameters from S solver + RCP sList = invFactoryS_->getRequestedParameters(); + if (sList != Teuchos::null) { + Teuchos::ParameterList::ConstIterator itr; + for (itr = sList->begin(); itr != sList->end(); ++itr) pl->setEntry(itr->first, itr->second); + result = pl; + } + + // use the mass matrix + if (useWScaling_) { + pl->set("W-Scaling Vector", Teuchos::null, "W-Scaling Vector"); + result = pl; + } + + return result; } //! For assiting in construction of the preconditioner -bool InvLSCStrategy::updateRequestedParameters(const Teuchos::ParameterList & pl) -{ - Teko_DEBUG_SCOPE("InvLSCStrategy::updateRequestedParameters",10); - bool result = true; - - // update requested parameters in solvers - result &= invFactoryF_->updateRequestedParameters(pl); - result &= invFactoryS_->updateRequestedParameters(pl); - - // use W scaling matrix - if(useWScaling_) { - Teko::MultiVector wScale = pl.get("W-Scaling Vector"); - - if(wScale==Teuchos::null) - result &= false; - else - setWScaling(wScale); - } - - return result; +bool InvLSCStrategy::updateRequestedParameters(const Teuchos::ParameterList& pl) { + Teko_DEBUG_SCOPE("InvLSCStrategy::updateRequestedParameters", 10); + bool result = true; + + // update requested parameters in solvers + result &= invFactoryF_->updateRequestedParameters(pl); + result &= invFactoryS_->updateRequestedParameters(pl); + + // use W scaling matrix + if (useWScaling_) { + Teko::MultiVector wScale = pl.get("W-Scaling Vector"); + + if (wScale == Teuchos::null) + result &= false; + else + setWScaling(wScale); + } + + return result; } -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_InvLSCStrategy.hpp b/packages/teko/src/NS/Teko_InvLSCStrategy.hpp index fc0984e09643..fbc457ac8b51 100644 --- a/packages/teko/src/NS/Teko_InvLSCStrategy.hpp +++ b/packages/teko/src/NS/Teko_InvLSCStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,218 +52,216 @@ namespace Teko { namespace NS { -class LSCPrecondState; // forward declration +class LSCPrecondState; // forward declration /** \brief A strategy that takes a single inverse factory and - * uses that for all inverses. If no mass matrix is - * passed in the diagonal of the 1,1 block is used. - * - * A strategy that takes a single inverse factory and uses that - * for all inverses. Optionally the mass matrix can be passed - * in, if it is the diagonal is extracted and that is used to - * form the inverse approximation. - */ + * uses that for all inverses. If no mass matrix is + * passed in the diagonal of the 1,1 block is used. + * + * A strategy that takes a single inverse factory and uses that + * for all inverses. Optionally the mass matrix can be passed + * in, if it is the diagonal is extracted and that is used to + * form the inverse approximation. + */ class InvLSCStrategy : public LSCStrategy { -public: - //! \name Constructors - //@{ - InvLSCStrategy(); - InvLSCStrategy(const Teuchos::RCP & factory, - bool rzn=false); - InvLSCStrategy(const Teuchos::RCP & factory, - LinearOp & mass,bool rzn=false); - InvLSCStrategy(const Teuchos::RCP & invFactF, - const Teuchos::RCP & invFactS, - bool rzn=false); - InvLSCStrategy(const Teuchos::RCP & invFactF, - const Teuchos::RCP & invFactS, - LinearOp & mass,bool rzn=false); - //@} - - virtual ~InvLSCStrategy() {} - - //! Functions inherited from LSCStrategy - //@{ - - /** This informs the strategy object to build the state associated - * with this operator. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - */ - virtual void buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of \f$B Q_u^{-1} B^T\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T\f$. - */ - virtual LinearOp getInvBQBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of \f$B H B^T - \gamma C\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. - */ - virtual LinearOp getInvBHBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of the \f$F\f$ block. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$F\f$. - */ - virtual LinearOp getInvF(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse for stabilizing the whole schur complement approximation. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The operator to stabilize the whole Schur complement. - */ - // virtual LinearOp getInvAlphaD(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - virtual LinearOp getOuterStabilization(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - virtual LinearOp getInnerStabilization(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return Teuchos::null; } - - /** Get the inverse mass matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The inverse of the mass matrix \f$Q_u\f$. - */ - virtual LinearOp getInvMass(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the \f$H\f$ scaling matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The \f$H\f$ scaling matrix. - */ - virtual LinearOp getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Should the approximation of the inverse use a full LDU decomposition, or - * is a upper triangular approximation sufficient. - * - * \returns True if the full LDU decomposition should be used, otherwise - * only an upper triangular version is used. - */ - virtual bool useFullLDU() const { return useFullLDU_; } - - /** Tell strategy that this operator is supposed to be symmetric. - * Behavior of LSC is slightly different for non-symmetric case. - * - * \param[in] isSymmetric Is this operator symmetric? - */ - virtual void setSymmetric(bool isSymmetric) - { isSymmetric_ = isSymmetric; } - - //! Initialize from a parameter list - virtual void initializeFromParameterList(const Teuchos::ParameterList & pl, - const InverseLibrary & invLib); - - //! For assiting in construction of the preconditioner - virtual Teuchos::RCP getRequestedParameters() const; - - //! For assiting in construction of the preconditioner - virtual bool updateRequestedParameters(const Teuchos::ParameterList & pl); - //@} - - //! When computing the Schur complement, use the passed in matrix instead - //! of \f$C\f$ to stabilize the gradient operator. - virtual void setPressureStabMatrix(const Teko::LinearOp & psm) - { userPresStabMat_ = psm; } - - //! Initialize the state object using this blocked linear operator - virtual void initializeState(const BlockedLinearOp & A,LSCPrecondState * state) const; - - /** Compute the inverses required for the LSC Schur complement - * - * \note This method assumes that the BQBt and BHBt operators have - * been constructed. - */ - void computeInverses(const BlockedLinearOp & A,LSCPrecondState * state) const; - - // //! Initialize the state object using this blocked linear operator - // virtual void reinitializeState(const BlockedLinearOp & A,LSCPrecondState * state) const; - - //! Set the number of power series iterations to use when finding the spectral radius - virtual void setEigSolveParam(int sz) { eigSolveParam_ = sz; } - - //! Return the number of power series iterations to use when finding the spectral radius - virtual int getEigSolveParam() { return eigSolveParam_; } - - //! Set to true to use the Full LDU decomposition, false otherwise - virtual void setUseFullLDU(bool val) { useFullLDU_ = val; } - - //! Set to true to zero the rows of F when computing the spectral radius - virtual void setRowZeroing(bool val) { rowZeroingNeeded_ = val; } - - //! set the mass matrix to use in computing the scaling - virtual void setMassMatrix(const LinearOp & mass) { massMatrix_ = mass; } - - /** Set the \f$H\f$-Scaling operator used in \f$B H B^T\f$. It is expected - * that this will be a diagonal matrix. - */ - virtual void setHScaling(const LinearOp & hScaling) { hScaling_ = hScaling; } - - /** Set the \f$H\f$-Scaling operator used in \f$B H B^T\f$. This method - * takes a vector and constructs the diagonal matrix. - */ - virtual void setHScaling(const MultiVector & hScaling) - { hScaling_ = buildDiagonal(hScaling,"H"); } - - /** Set the \f$W\f$-Scaling vector used in \f$B H B^T\f$. This method - * takes a vector. - */ - virtual void setWScaling(const MultiVector & wScaling) - { wScaling_ = wScaling; } - -protected: - LinearOp massMatrix_; - - // how to invert the matrices - Teuchos::RCP invFactoryF_; - Teuchos::RCP invFactoryS_; - - // number of power iterations when computing spectral radius - int eigSolveParam_; - - // flags for handling various options - bool rowZeroingNeeded_; - bool useFullLDU_; - bool useMass_; - bool useLumping_; - bool useWScaling_; - DiagonalType scaleType_; - bool isSymmetric_; - bool assumeStable_; - - // operators requested, to be filled by user - LinearOp userPresStabMat_; - mutable LinearOp hScaling_; - MultiVector wScaling_; - -private: - InvLSCStrategy(const InvLSCStrategy &); + public: + //! \name Constructors + //@{ + InvLSCStrategy(); + InvLSCStrategy(const Teuchos::RCP &factory, bool rzn = false); + InvLSCStrategy(const Teuchos::RCP &factory, LinearOp &mass, bool rzn = false); + InvLSCStrategy(const Teuchos::RCP &invFactF, + const Teuchos::RCP &invFactS, bool rzn = false); + InvLSCStrategy(const Teuchos::RCP &invFactF, + const Teuchos::RCP &invFactS, LinearOp &mass, bool rzn = false); + //@} + + virtual ~InvLSCStrategy() {} + + //! Functions inherited from LSCStrategy + //@{ + + /** This informs the strategy object to build the state associated + * with this operator. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + */ + virtual void buildState(BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of \f$B Q_u^{-1} B^T\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T\f$. + */ + virtual LinearOp getInvBQBt(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of \f$B H B^T - \gamma C\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. + */ + virtual LinearOp getInvBHBt(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of the \f$F\f$ block. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$F\f$. + */ + virtual LinearOp getInvF(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse for stabilizing the whole schur complement approximation. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The operator to stabilize the whole Schur complement. + */ + // virtual LinearOp getInvAlphaD(const BlockedLinearOp & A,BlockPreconditionerState & state) + // const; + virtual LinearOp getOuterStabilization(const BlockedLinearOp &A, + BlockPreconditionerState &state) const; + virtual LinearOp getInnerStabilization(const BlockedLinearOp & /* A */, + BlockPreconditionerState & /* state */) const { + return Teuchos::null; + } + + /** Get the inverse mass matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The inverse of the mass matrix \f$Q_u\f$. + */ + virtual LinearOp getInvMass(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the \f$H\f$ scaling matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The \f$H\f$ scaling matrix. + */ + virtual LinearOp getHScaling(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Should the approximation of the inverse use a full LDU decomposition, or + * is a upper triangular approximation sufficient. + * + * \returns True if the full LDU decomposition should be used, otherwise + * only an upper triangular version is used. + */ + virtual bool useFullLDU() const { return useFullLDU_; } + + /** Tell strategy that this operator is supposed to be symmetric. + * Behavior of LSC is slightly different for non-symmetric case. + * + * \param[in] isSymmetric Is this operator symmetric? + */ + virtual void setSymmetric(bool isSymmetric) { isSymmetric_ = isSymmetric; } + + //! Initialize from a parameter list + virtual void initializeFromParameterList(const Teuchos::ParameterList &pl, + const InverseLibrary &invLib); + + //! For assiting in construction of the preconditioner + virtual Teuchos::RCP getRequestedParameters() const; + + //! For assiting in construction of the preconditioner + virtual bool updateRequestedParameters(const Teuchos::ParameterList &pl); + //@} + + //! When computing the Schur complement, use the passed in matrix instead + //! of \f$C\f$ to stabilize the gradient operator. + virtual void setPressureStabMatrix(const Teko::LinearOp &psm) { userPresStabMat_ = psm; } + + //! Initialize the state object using this blocked linear operator + virtual void initializeState(const BlockedLinearOp &A, LSCPrecondState *state) const; + + /** Compute the inverses required for the LSC Schur complement + * + * \note This method assumes that the BQBt and BHBt operators have + * been constructed. + */ + void computeInverses(const BlockedLinearOp &A, LSCPrecondState *state) const; + + // //! Initialize the state object using this blocked linear operator + // virtual void reinitializeState(const BlockedLinearOp & A,LSCPrecondState * state) const; + + //! Set the number of power series iterations to use when finding the spectral radius + virtual void setEigSolveParam(int sz) { eigSolveParam_ = sz; } + + //! Return the number of power series iterations to use when finding the spectral radius + virtual int getEigSolveParam() { return eigSolveParam_; } + + //! Set to true to use the Full LDU decomposition, false otherwise + virtual void setUseFullLDU(bool val) { useFullLDU_ = val; } + + //! Set to true to zero the rows of F when computing the spectral radius + virtual void setRowZeroing(bool val) { rowZeroingNeeded_ = val; } + + //! set the mass matrix to use in computing the scaling + virtual void setMassMatrix(const LinearOp &mass) { massMatrix_ = mass; } + + /** Set the \f$H\f$-Scaling operator used in \f$B H B^T\f$. It is expected + * that this will be a diagonal matrix. + */ + virtual void setHScaling(const LinearOp &hScaling) { hScaling_ = hScaling; } + + /** Set the \f$H\f$-Scaling operator used in \f$B H B^T\f$. This method + * takes a vector and constructs the diagonal matrix. + */ + virtual void setHScaling(const MultiVector &hScaling) { + hScaling_ = buildDiagonal(hScaling, "H"); + } + + /** Set the \f$W\f$-Scaling vector used in \f$B H B^T\f$. This method + * takes a vector. + */ + virtual void setWScaling(const MultiVector &wScaling) { wScaling_ = wScaling; } + + protected: + LinearOp massMatrix_; + + // how to invert the matrices + Teuchos::RCP invFactoryF_; + Teuchos::RCP invFactoryS_; + + // number of power iterations when computing spectral radius + int eigSolveParam_; + + // flags for handling various options + bool rowZeroingNeeded_; + bool useFullLDU_; + bool useMass_; + bool useLumping_; + bool useWScaling_; + DiagonalType scaleType_; + bool isSymmetric_; + bool assumeStable_; + + // operators requested, to be filled by user + LinearOp userPresStabMat_; + mutable LinearOp hScaling_; + MultiVector wScaling_; + + private: + InvLSCStrategy(const InvLSCStrategy &); }; -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_InvModALStrategy.cpp b/packages/teko/src/NS/Teko_InvModALStrategy.cpp index e7c2be317da9..ab8924c36f92 100644 --- a/packages/teko/src/NS/Teko_InvModALStrategy.cpp +++ b/packages/teko/src/NS/Teko_InvModALStrategy.cpp @@ -16,336 +16,311 @@ #include "Teko_ModALPreconditionerFactory.hpp" using Teuchos::RCP; -using Teuchos::rcp_dynamic_cast; using Teuchos::rcp_const_cast; +using Teuchos::rcp_dynamic_cast; -namespace Teko -{ +namespace Teko { -namespace NS -{ +namespace NS { // Empty constructor. -InvModALStrategy::InvModALStrategy() : - invFactoryA_(Teuchos::null), invFactoryS_(Teuchos::null), - pressureMassMatrix_(Teuchos::null), gamma_(0.05), - scaleType_(Diagonal), isSymmetric_(true) -{ -} +InvModALStrategy::InvModALStrategy() + : invFactoryA_(Teuchos::null), + invFactoryS_(Teuchos::null), + pressureMassMatrix_(Teuchos::null), + gamma_(0.05), + scaleType_(Diagonal), + isSymmetric_(true) {} // If there is only one InverseFactory, use it for all solves. -InvModALStrategy::InvModALStrategy(const Teuchos::RCP & factory) : - invFactoryA_(factory), invFactoryS_(factory), - pressureMassMatrix_(Teuchos::null), gamma_(0.05), - scaleType_(Diagonal), isSymmetric_(true) -{ -} +InvModALStrategy::InvModALStrategy(const Teuchos::RCP &factory) + : invFactoryA_(factory), + invFactoryS_(factory), + pressureMassMatrix_(Teuchos::null), + gamma_(0.05), + scaleType_(Diagonal), + isSymmetric_(true) {} // If there are two InverseFactory's... -InvModALStrategy::InvModALStrategy(const Teuchos::RCP & invFactoryA, - const Teuchos::RCP & invFactoryS) : - invFactoryA_(invFactoryA), invFactoryS_(invFactoryS), - pressureMassMatrix_(Teuchos::null), gamma_(0.05), - scaleType_(Diagonal), isSymmetric_(true) -{ -} +InvModALStrategy::InvModALStrategy(const Teuchos::RCP &invFactoryA, + const Teuchos::RCP &invFactoryS) + : invFactoryA_(invFactoryA), + invFactoryS_(invFactoryS), + pressureMassMatrix_(Teuchos::null), + gamma_(0.05), + scaleType_(Diagonal), + isSymmetric_(true) {} // If there are two InverseFactory's... -InvModALStrategy::InvModALStrategy(const Teuchos::RCP & invFactory, - LinearOp & pressureMassMatrix) : - invFactoryA_(invFactory), invFactoryS_(invFactory), - pressureMassMatrix_(pressureMassMatrix), gamma_(0.05), - scaleType_(Diagonal), isSymmetric_(true) -{ -} +InvModALStrategy::InvModALStrategy(const Teuchos::RCP &invFactory, + LinearOp &pressureMassMatrix) + : invFactoryA_(invFactory), + invFactoryS_(invFactory), + pressureMassMatrix_(pressureMassMatrix), + gamma_(0.05), + scaleType_(Diagonal), + isSymmetric_(true) {} // If there are two InverseFactory's... -InvModALStrategy::InvModALStrategy(const Teuchos::RCP & invFactoryA, - const Teuchos::RCP & invFactoryS, LinearOp & pressureMassMatrix) : - invFactoryA_(invFactoryA), invFactoryS_(invFactoryS), - pressureMassMatrix_(pressureMassMatrix), gamma_(0.05), - scaleType_(Diagonal), isSymmetric_(true) -{ -} +InvModALStrategy::InvModALStrategy(const Teuchos::RCP &invFactoryA, + const Teuchos::RCP &invFactoryS, + LinearOp &pressureMassMatrix) + : invFactoryA_(invFactoryA), + invFactoryS_(invFactoryS), + pressureMassMatrix_(pressureMassMatrix), + gamma_(0.05), + scaleType_(Diagonal), + isSymmetric_(true) {} // Return "inverses". -LinearOp InvModALStrategy::getInvA11p(BlockPreconditionerState & state) const -{ - return state.getInverse("invA11p"); +LinearOp InvModALStrategy::getInvA11p(BlockPreconditionerState &state) const { + return state.getInverse("invA11p"); } -LinearOp InvModALStrategy::getInvA22p(BlockPreconditionerState & state) const -{ - return state.getInverse("invA22p"); +LinearOp InvModALStrategy::getInvA22p(BlockPreconditionerState &state) const { + return state.getInverse("invA22p"); } -LinearOp InvModALStrategy::getInvA33p(BlockPreconditionerState & state) const -{ - return state.getInverse("invA33p"); +LinearOp InvModALStrategy::getInvA33p(BlockPreconditionerState &state) const { + return state.getInverse("invA33p"); } -LinearOp InvModALStrategy::getInvS(BlockPreconditionerState & state) const -{ - return state.getInverse("invS"); +LinearOp InvModALStrategy::getInvS(BlockPreconditionerState &state) const { + return state.getInverse("invS"); } // Set pressure mass matrix. -void InvModALStrategy::setPressureMassMatrix(const LinearOp & pressureMassMatrix) -{ - pressureMassMatrix_ = pressureMassMatrix; +void InvModALStrategy::setPressureMassMatrix(const LinearOp &pressureMassMatrix) { + pressureMassMatrix_ = pressureMassMatrix; } // Set gamma. -void InvModALStrategy::setGamma(double gamma) -{ - TEUCHOS_ASSERT(gamma > 0.0); - gamma_ = gamma; +void InvModALStrategy::setGamma(double gamma) { + TEUCHOS_ASSERT(gamma > 0.0); + gamma_ = gamma; } -void InvModALStrategy::buildState(const BlockedLinearOp & alOp, - BlockPreconditionerState & state) const -{ - Teko_DEBUG_SCOPE("InvModALStrategy::buildState", 10); +void InvModALStrategy::buildState(const BlockedLinearOp &alOp, + BlockPreconditionerState &state) const { + Teko_DEBUG_SCOPE("InvModALStrategy::buildState", 10); - ModALPrecondState * modALState = dynamic_cast(&state); - TEUCHOS_ASSERT(modALState != NULL); + ModALPrecondState *modALState = dynamic_cast(&state); + TEUCHOS_ASSERT(modALState != NULL); - // if necessary save state information - if(not modALState->isInitialized()) - { - Teko_DEBUG_EXPR(Teuchos::Time timer("")); + // if necessary save state information + if (not modALState->isInitialized()) { + Teko_DEBUG_EXPR(Teuchos::Time timer("")); - { - // construct operators - Teko_DEBUG_SCOPE("ModAL::buildState: Initializing state object", 1); - Teko_DEBUG_EXPR(timer.start(true)); + { + // construct operators + Teko_DEBUG_SCOPE("ModAL::buildState: Initializing state object", 1); + Teko_DEBUG_EXPR(timer.start(true)); - initializeState(alOp, modALState); + initializeState(alOp, modALState); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("ModAL::buildState: BuildOpsTime = " << timer.totalElapsedTime(), 1); - } + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("ModAL::buildState: BuildOpsTime = " << timer.totalElapsedTime(), 1); + } - { - // Build the inverses - Teko_DEBUG_SCOPE("ModAL::buildState: Computing inverses", 1); - Teko_DEBUG_EXPR(timer.start(true)); + { + // Build the inverses + Teko_DEBUG_SCOPE("ModAL::buildState: Computing inverses", 1); + Teko_DEBUG_EXPR(timer.start(true)); - computeInverses(alOp, modALState); + computeInverses(alOp, modALState); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("ModAL::buildState: BuildInvTime = " << timer.totalElapsedTime(), 1); - } - } + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("ModAL::buildState: BuildInvTime = " << timer.totalElapsedTime(), 1); + } + } } // Initialize the state object using the ALOperator. -void InvModALStrategy::initializeState(const BlockedLinearOp & alOp, - ModALPrecondState *state) const -{ - Teko_DEBUG_SCOPE("InvModALStrategy::initializeState", 10); - - // Extract sub-matrices from blocked linear operator. - int dim = blockRowCount(alOp) - 1; - TEUCHOS_ASSERT(dim == 2 || dim == 3); - - LinearOp lpA11 = getBlock(0, 0, alOp); - LinearOp lpA22 = getBlock(1, 1, alOp); - LinearOp lpA33, lpB1, lpB2, lpB3, lpB1t, lpB2t, lpB3t, lpC; - - // 2D problem. - if(dim == 2) - { - lpB1 = getBlock(2, 0, alOp); - lpB2 = getBlock(2, 1, alOp); - lpB1t = getBlock(0, 2, alOp); - lpB2t = getBlock(1, 2, alOp); - lpC = getBlock(2, 2, alOp); - } - // 3D problem. - else if(dim == 3) - { - lpA33 = getBlock(2, 2, alOp); - lpB1 = getBlock(3, 0, alOp); - lpB2 = getBlock(3, 1, alOp); - lpB3 = getBlock(3, 2, alOp); - lpB1t = getBlock(0, 3, alOp); - lpB2t = getBlock(1, 3, alOp); - lpB3t = getBlock(2, 3, alOp); - lpC = getBlock(3, 3, alOp); - } - - // For problems using stabilized finite elements, - // lpB1t, lpB2t and lpB3t are added linear operators. Extract original operators. - LinearOp B1t = (rcp_dynamic_cast >(lpB1t))->getOp(0); - LinearOp B2t = (rcp_dynamic_cast >(lpB2t))->getOp(0); - LinearOp B3t; - if(dim == 3) - { - B3t = (rcp_dynamic_cast >(lpB3t))->getOp(0); - } - - //std::cout << Teuchos::describe(*lpC, Teuchos::VERB_EXTREME) << std::endl; - // Check whether the finite elements are stable or not. - state->isStabilized_ =(not isZeroOp(lpC)); - //state->isStabilized_ = false; - //std::cout << state->isStabilized_ << std::endl; - - state->pressureMassMatrix_ = pressureMassMatrix_; - // If pressure mass matrix is not set, use identity. - if(state->pressureMassMatrix_ == Teuchos::null) - { - Teko_DEBUG_MSG("InvModALStrategy::initializeState(): Build identity type \"" - << getDiagonalName(scaleType_) << "\"", 1); - state->invPressureMassMatrix_ = Thyra::identity(lpB1->range()); - } - // If the inverse of the pressure mass matrix is not set, - // build it from the pressure mass matrix. - else if(state->invPressureMassMatrix_ == Teuchos::null) - { - Teko_DEBUG_MSG("ModAL::initializeState(): Build Scaling type \"" - << getDiagonalName(scaleType_) << "\"", 1); - state->invPressureMassMatrix_ = getInvDiagonalOp(pressureMassMatrix_, scaleType_); - } - // Else "invPressureMassMatrix_" should be set and there is no reason to rebuild it - state->gamma_ = gamma_; - //S_ = scale(1.0/gamma_, pressureMassMatrix_); - std::cout << Teuchos::describe(*(state->invPressureMassMatrix_), Teuchos::VERB_EXTREME) << std::endl; - - // Build state variables: B_1^T*W^{-1}*B_1, A11p, etc. - // B_1^T*W^{-1}*B_1 may not change so save it in the state. - if(state->B1tMpB1_ == Teuchos::null) - state->B1tMpB1_ = explicitMultiply(B1t, state->invPressureMassMatrix_, lpB1, state->B1tMpB1_); - // Get the(1,1) block of the non-augmented matrix. - // Recall alOp is augmented. So lpA11 = A11 + gamma B_1^T W^{-1} B_1. - // Cast lpA11 as an added linear operator and get the first item. - LinearOp A11 = (rcp_dynamic_cast >(lpA11))->getOp(0); - state->A11p_ = explicitAdd(A11, scale(state->gamma_, state->B1tMpB1_), state->A11p_); - //std::cout << Teuchos::describe(*(state->B1tMpB1_), Teuchos::VERB_EXTREME) << std::endl; - Teko_DEBUG_MSG("Computed A11p", 10); - - if(state->B2tMpB2_ == Teuchos::null) - state->B2tMpB2_ = explicitMultiply(B2t, state->invPressureMassMatrix_, lpB2, state->B2tMpB2_); - LinearOp A22 = (rcp_dynamic_cast >(lpA22))->getOp(0); - state->A22p_ = explicitAdd(A22, scale(state->gamma_, state->B2tMpB2_), state->A22p_); - Teko_DEBUG_MSG("Computed A22p", 10); - - if(dim == 3) - { - if(state->B3tMpB3_ == Teuchos::null) - state->B3tMpB3_ = explicitMultiply(B3t, state->invPressureMassMatrix_, lpB3, state->B3tMpB3_); - LinearOp A33 = (rcp_dynamic_cast >(lpA33))->getOp(0); - state->A33p_ = explicitAdd(A33, scale(state->gamma_, state->B3tMpB3_), state->A33p_); - Teko_DEBUG_MSG("Computed A33p", 10); - } - - // Inverse the Schur complement. - if(state->isStabilized_) - { - if(state->S_ == Teuchos::null) - { - state->S_ = explicitAdd(scale(-1.0, lpC), scale(1.0/state->gamma_, pressureMassMatrix_), state->S_); - } - Teko_DEBUG_MSG("Computed S", 10); - } - - state->setInitialized(true); +void InvModALStrategy::initializeState(const BlockedLinearOp &alOp, + ModALPrecondState *state) const { + Teko_DEBUG_SCOPE("InvModALStrategy::initializeState", 10); + + // Extract sub-matrices from blocked linear operator. + int dim = blockRowCount(alOp) - 1; + TEUCHOS_ASSERT(dim == 2 || dim == 3); + + LinearOp lpA11 = getBlock(0, 0, alOp); + LinearOp lpA22 = getBlock(1, 1, alOp); + LinearOp lpA33, lpB1, lpB2, lpB3, lpB1t, lpB2t, lpB3t, lpC; + + // 2D problem. + if (dim == 2) { + lpB1 = getBlock(2, 0, alOp); + lpB2 = getBlock(2, 1, alOp); + lpB1t = getBlock(0, 2, alOp); + lpB2t = getBlock(1, 2, alOp); + lpC = getBlock(2, 2, alOp); + } + // 3D problem. + else if (dim == 3) { + lpA33 = getBlock(2, 2, alOp); + lpB1 = getBlock(3, 0, alOp); + lpB2 = getBlock(3, 1, alOp); + lpB3 = getBlock(3, 2, alOp); + lpB1t = getBlock(0, 3, alOp); + lpB2t = getBlock(1, 3, alOp); + lpB3t = getBlock(2, 3, alOp); + lpC = getBlock(3, 3, alOp); + } + + // For problems using stabilized finite elements, + // lpB1t, lpB2t and lpB3t are added linear operators. Extract original operators. + LinearOp B1t = (rcp_dynamic_cast >(lpB1t))->getOp(0); + LinearOp B2t = (rcp_dynamic_cast >(lpB2t))->getOp(0); + LinearOp B3t; + if (dim == 3) { + B3t = (rcp_dynamic_cast >(lpB3t))->getOp(0); + } + + // std::cout << Teuchos::describe(*lpC, Teuchos::VERB_EXTREME) << std::endl; + // Check whether the finite elements are stable or not. + state->isStabilized_ = (not isZeroOp(lpC)); + // state->isStabilized_ = false; + // std::cout << state->isStabilized_ << std::endl; + + state->pressureMassMatrix_ = pressureMassMatrix_; + // If pressure mass matrix is not set, use identity. + if (state->pressureMassMatrix_ == Teuchos::null) { + Teko_DEBUG_MSG("InvModALStrategy::initializeState(): Build identity type \"" + << getDiagonalName(scaleType_) << "\"", + 1); + state->invPressureMassMatrix_ = Thyra::identity(lpB1->range()); + } + // If the inverse of the pressure mass matrix is not set, + // build it from the pressure mass matrix. + else if (state->invPressureMassMatrix_ == Teuchos::null) { + Teko_DEBUG_MSG("ModAL::initializeState(): Build Scaling type \"" + << getDiagonalName(scaleType_) << "\"", + 1); + state->invPressureMassMatrix_ = getInvDiagonalOp(pressureMassMatrix_, scaleType_); + } + // Else "invPressureMassMatrix_" should be set and there is no reason to rebuild it + state->gamma_ = gamma_; + // S_ = scale(1.0/gamma_, pressureMassMatrix_); + std::cout << Teuchos::describe(*(state->invPressureMassMatrix_), Teuchos::VERB_EXTREME) + << std::endl; + + // Build state variables: B_1^T*W^{-1}*B_1, A11p, etc. + // B_1^T*W^{-1}*B_1 may not change so save it in the state. + if (state->B1tMpB1_ == Teuchos::null) + state->B1tMpB1_ = explicitMultiply(B1t, state->invPressureMassMatrix_, lpB1, state->B1tMpB1_); + // Get the(1,1) block of the non-augmented matrix. + // Recall alOp is augmented. So lpA11 = A11 + gamma B_1^T W^{-1} B_1. + // Cast lpA11 as an added linear operator and get the first item. + LinearOp A11 = (rcp_dynamic_cast >(lpA11))->getOp(0); + state->A11p_ = explicitAdd(A11, scale(state->gamma_, state->B1tMpB1_), state->A11p_); + // std::cout << Teuchos::describe(*(state->B1tMpB1_), Teuchos::VERB_EXTREME) << std::endl; + Teko_DEBUG_MSG("Computed A11p", 10); + + if (state->B2tMpB2_ == Teuchos::null) + state->B2tMpB2_ = explicitMultiply(B2t, state->invPressureMassMatrix_, lpB2, state->B2tMpB2_); + LinearOp A22 = (rcp_dynamic_cast >(lpA22))->getOp(0); + state->A22p_ = explicitAdd(A22, scale(state->gamma_, state->B2tMpB2_), state->A22p_); + Teko_DEBUG_MSG("Computed A22p", 10); + + if (dim == 3) { + if (state->B3tMpB3_ == Teuchos::null) + state->B3tMpB3_ = explicitMultiply(B3t, state->invPressureMassMatrix_, lpB3, state->B3tMpB3_); + LinearOp A33 = (rcp_dynamic_cast >(lpA33))->getOp(0); + state->A33p_ = explicitAdd(A33, scale(state->gamma_, state->B3tMpB3_), state->A33p_); + Teko_DEBUG_MSG("Computed A33p", 10); + } + + // Inverse the Schur complement. + if (state->isStabilized_) { + if (state->S_ == Teuchos::null) { + state->S_ = + explicitAdd(scale(-1.0, lpC), scale(1.0 / state->gamma_, pressureMassMatrix_), state->S_); + } + Teko_DEBUG_MSG("Computed S", 10); + } + + state->setInitialized(true); } // Compute inverses. -void InvModALStrategy::computeInverses(const BlockedLinearOp & alOp, - ModALPrecondState *state) const -{ - int dim = blockRowCount(alOp) - 1; - TEUCHOS_ASSERT(dim == 2 || dim == 3); - - Teko_DEBUG_SCOPE("InvModALStrategy::computeInverses", 10); - Teko_DEBUG_EXPR(Teuchos::Time invTimer("")); - - //(re)build the inverse of A11 - Teko_DEBUG_MSG("ModAL::computeInverses(): Building inv(A11)", 1); - Teko_DEBUG_EXPR(invTimer.start(true)); - - InverseLinearOp invA11p = state->getInverse("invA11p"); - if(invA11p == Teuchos::null) - { - invA11p = buildInverse(*invFactoryA_, state->A11p_); - state->addInverse("invA11p", invA11p); - } - else - { - rebuildInverse(*invFactoryA_, state->A11p_, invA11p); - } - - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("ModAL::computeInverses GetInvA11 = " << invTimer.totalElapsedTime(), 1); - - //(re)build the inverse of A22 - Teko_DEBUG_MSG("ModAL::computeInverses(): Building inv(A22)", 2); - Teko_DEBUG_EXPR(invTimer.start(true)); - - InverseLinearOp invA22p = state->getInverse("invA22p"); - if(invA22p == Teuchos::null) - { - invA22p = buildInverse(*invFactoryA_, state->A22p_); - state->addInverse("invA22p", invA22p); - } - else - { - rebuildInverse(*invFactoryA_, state->A22p_, invA22p); - } - - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("ModAL::computeInverses(): GetInvA22 = " << invTimer.totalElapsedTime(), 2); - - //(re)build the inverse of A33 - if(dim == 3) - { - Teko_DEBUG_MSG("ModAL::computeInverses Building inv(A33)", 3); - Teko_DEBUG_EXPR(invTimer.start(true)); - - InverseLinearOp invA33p = state->getInverse("invA33p"); - if(invA33p == Teuchos::null) - { - invA33p = buildInverse(*invFactoryA_, state->A33p_); - state->addInverse("invA33p", invA33p); - } - else - { - rebuildInverse(*invFactoryA_, state->A33p_, invA33p); - } - - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("ModAL::computeInverses GetInvA33 = " << invTimer.totalElapsedTime(), 3); - } - - //(re)build the inverse of S - Teko_DEBUG_MSG("ModAL::computeInverses Building inv(S)", 4); - Teko_DEBUG_EXPR(invTimer.start(true)); - - // There are two ways to "invert" S. - // The following method construct invS by InverseFactory invFactoryS_. - // The other way is to use diagonal approximation, - // which is done in ModALPreconditionerFactory.cpp. - if(state->isStabilized_) - { - InverseLinearOp invS = state->getInverse("invS"); - if(invS == Teuchos::null) - { - invS = buildInverse(*invFactoryS_, state->S_); - state->addInverse("invS", invS); - } - else - { - rebuildInverse(*invFactoryS_, state->S_, invS); - } - } - - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("ModAL::computeInverses GetInvS = " << invTimer.totalElapsedTime(), 4); - +void InvModALStrategy::computeInverses(const BlockedLinearOp &alOp, + ModALPrecondState *state) const { + int dim = blockRowCount(alOp) - 1; + TEUCHOS_ASSERT(dim == 2 || dim == 3); + + Teko_DEBUG_SCOPE("InvModALStrategy::computeInverses", 10); + Teko_DEBUG_EXPR(Teuchos::Time invTimer("")); + + //(re)build the inverse of A11 + Teko_DEBUG_MSG("ModAL::computeInverses(): Building inv(A11)", 1); + Teko_DEBUG_EXPR(invTimer.start(true)); + + InverseLinearOp invA11p = state->getInverse("invA11p"); + if (invA11p == Teuchos::null) { + invA11p = buildInverse(*invFactoryA_, state->A11p_); + state->addInverse("invA11p", invA11p); + } else { + rebuildInverse(*invFactoryA_, state->A11p_, invA11p); + } + + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("ModAL::computeInverses GetInvA11 = " << invTimer.totalElapsedTime(), 1); + + //(re)build the inverse of A22 + Teko_DEBUG_MSG("ModAL::computeInverses(): Building inv(A22)", 2); + Teko_DEBUG_EXPR(invTimer.start(true)); + + InverseLinearOp invA22p = state->getInverse("invA22p"); + if (invA22p == Teuchos::null) { + invA22p = buildInverse(*invFactoryA_, state->A22p_); + state->addInverse("invA22p", invA22p); + } else { + rebuildInverse(*invFactoryA_, state->A22p_, invA22p); + } + + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("ModAL::computeInverses(): GetInvA22 = " << invTimer.totalElapsedTime(), 2); + + //(re)build the inverse of A33 + if (dim == 3) { + Teko_DEBUG_MSG("ModAL::computeInverses Building inv(A33)", 3); + Teko_DEBUG_EXPR(invTimer.start(true)); + + InverseLinearOp invA33p = state->getInverse("invA33p"); + if (invA33p == Teuchos::null) { + invA33p = buildInverse(*invFactoryA_, state->A33p_); + state->addInverse("invA33p", invA33p); + } else { + rebuildInverse(*invFactoryA_, state->A33p_, invA33p); + } + + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("ModAL::computeInverses GetInvA33 = " << invTimer.totalElapsedTime(), 3); + } + + //(re)build the inverse of S + Teko_DEBUG_MSG("ModAL::computeInverses Building inv(S)", 4); + Teko_DEBUG_EXPR(invTimer.start(true)); + + // There are two ways to "invert" S. + // The following method construct invS by InverseFactory invFactoryS_. + // The other way is to use diagonal approximation, + // which is done in ModALPreconditionerFactory.cpp. + if (state->isStabilized_) { + InverseLinearOp invS = state->getInverse("invS"); + if (invS == Teuchos::null) { + invS = buildInverse(*invFactoryS_, state->S_); + state->addInverse("invS", invS); + } else { + rebuildInverse(*invFactoryS_, state->S_, invS); + } + } + + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("ModAL::computeInverses GetInvS = " << invTimer.totalElapsedTime(), 4); } -} // end namespace NS +} // end namespace NS -} // end namespace Teko +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_InvModALStrategy.hpp b/packages/teko/src/NS/Teko_InvModALStrategy.hpp index 4de67c77db01..43484bc0bb99 100644 --- a/packages/teko/src/NS/Teko_InvModALStrategy.hpp +++ b/packages/teko/src/NS/Teko_InvModALStrategy.hpp @@ -15,147 +15,124 @@ #include "Teko_InverseFactory.hpp" #include "Teko_BlockPreconditionerFactory.hpp" -namespace Teko -{ +namespace Teko { -namespace NS -{ +namespace NS { class ModALPrecondState; -class InvModALStrategy -{ -public: - - //! Empty constructor. - InvModALStrategy(); - - InvModALStrategy(const Teuchos::RCP & factory); - - InvModALStrategy(const Teuchos::RCP & factory, - LinearOp & pressureMassMatrix); - - InvModALStrategy(const Teuchos::RCP & invFactA, - const Teuchos::RCP & invFactS); - - InvModALStrategy(const Teuchos::RCP & invFactA, - const Teuchos::RCP & invFactS, - LinearOp & pressureMassMatrix); - - //! Destructor. - virtual - ~InvModALStrategy() - { - } - - /** Get the inverse of the \f$A_{11}p = A_{11} + \gamma B^T_1 W^{-1} B_1 \f$ block. - * - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$A_{11}p\f$. - */ - virtual LinearOp - getInvA11p(BlockPreconditionerState & state) const; - - /** Get the inverse of the \f$A_{22}p = A_{22} + \gamma B^T_2 W^{-1} B_2 \f$ block. - * - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$A_{22}p\f$. - */ - virtual LinearOp - getInvA22p(BlockPreconditionerState & state) const; - - /** Get the inverse of the \f$A_{33}p = A_{33} + \gamma B^T_3 W^{-1} B_3 \f$ block. - * - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$A_{33}p\f$. - */ - virtual LinearOp - getInvA33p(BlockPreconditionerState & state) const; - - /** Get the inverse of the pressure Schur complement \f$ S \f$. - * - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$S\f$. - */ - virtual LinearOp - getInvS(BlockPreconditionerState & state) const; - - /** This informs the strategy object to build the state associated - * with this operator. - * - * \param[in] A The linear operator to be preconditioned by modified AL. - * \param[in] state State object for storying reusable information about - * the operator A. - */ - virtual void - buildState(const BlockedLinearOp & A, BlockPreconditionerState & state) const; - - /** - * Initialize the state object using this blocked linear operator. - */ - virtual void - initializeState(const BlockedLinearOp & A, ModALPrecondState * state) const; - - /** Compute the inverses. - * - * \param[in] A ALOperator. - * - * \note This method assumes that the operators required have been constructed. - */ - virtual void - computeInverses(const BlockedLinearOp & A, ModALPrecondState * state) const; - - /** Set pressure mass matrix. - * - * \param[in] pressureMassMatrix - * Pressure mass matrix. - */ - void - setPressureMassMatrix(const LinearOp & pressureMassMatrix); - - /** Set the augmentation parameter gamma. - * - * \param[in] gamma - * Augmentation paramter. - */ - void - setGamma(double gamma); - - /** Tell strategy that this operator is supposed to be symmetric. - * - * \param[in] isSymmetric Is this operator symmetric? - */ - virtual void - setSymmetric(bool isSymmetric) - { - isSymmetric_ = isSymmetric; - } - -protected: - - // In the modified AL preconditioner, we need to two methods, - // one for solving \f$ A_{ii}, i = 1, 2(, 3) \f$, - // the other for solving \f$ S \f$. - Teuchos::RCP invFactoryA_; - Teuchos::RCP invFactoryS_; - LinearOp pressureMassMatrix_; - double gamma_; - - DiagonalType scaleType_; - bool isSymmetric_; - int dim_; +class InvModALStrategy { + public: + //! Empty constructor. + InvModALStrategy(); + + InvModALStrategy(const Teuchos::RCP& factory); + + InvModALStrategy(const Teuchos::RCP& factory, LinearOp& pressureMassMatrix); + + InvModALStrategy(const Teuchos::RCP& invFactA, + const Teuchos::RCP& invFactS); + + InvModALStrategy(const Teuchos::RCP& invFactA, + const Teuchos::RCP& invFactS, LinearOp& pressureMassMatrix); + + //! Destructor. + virtual ~InvModALStrategy() {} + + /** Get the inverse of the \f$A_{11}p = A_{11} + \gamma B^T_1 W^{-1} B_1 \f$ block. + * + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$A_{11}p\f$. + */ + virtual LinearOp getInvA11p(BlockPreconditionerState& state) const; + + /** Get the inverse of the \f$A_{22}p = A_{22} + \gamma B^T_2 W^{-1} B_2 \f$ block. + * + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$A_{22}p\f$. + */ + virtual LinearOp getInvA22p(BlockPreconditionerState& state) const; + + /** Get the inverse of the \f$A_{33}p = A_{33} + \gamma B^T_3 W^{-1} B_3 \f$ block. + * + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$A_{33}p\f$. + */ + virtual LinearOp getInvA33p(BlockPreconditionerState& state) const; + + /** Get the inverse of the pressure Schur complement \f$ S \f$. + * + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$S\f$. + */ + virtual LinearOp getInvS(BlockPreconditionerState& state) const; + + /** This informs the strategy object to build the state associated + * with this operator. + * + * \param[in] A The linear operator to be preconditioned by modified AL. + * \param[in] state State object for storying reusable information about + * the operator A. + */ + virtual void buildState(const BlockedLinearOp& A, BlockPreconditionerState& state) const; + + /** + * Initialize the state object using this blocked linear operator. + */ + virtual void initializeState(const BlockedLinearOp& A, ModALPrecondState* state) const; + + /** Compute the inverses. + * + * \param[in] A ALOperator. + * + * \note This method assumes that the operators required have been constructed. + */ + virtual void computeInverses(const BlockedLinearOp& A, ModALPrecondState* state) const; + + /** Set pressure mass matrix. + * + * \param[in] pressureMassMatrix + * Pressure mass matrix. + */ + void setPressureMassMatrix(const LinearOp& pressureMassMatrix); + + /** Set the augmentation parameter gamma. + * + * \param[in] gamma + * Augmentation paramter. + */ + void setGamma(double gamma); + + /** Tell strategy that this operator is supposed to be symmetric. + * + * \param[in] isSymmetric Is this operator symmetric? + */ + virtual void setSymmetric(bool isSymmetric) { isSymmetric_ = isSymmetric; } + + protected: + // In the modified AL preconditioner, we need to two methods, + // one for solving \f$ A_{ii}, i = 1, 2(, 3) \f$, + // the other for solving \f$ S \f$. + Teuchos::RCP invFactoryA_; + Teuchos::RCP invFactoryS_; + LinearOp pressureMassMatrix_; + double gamma_; + + DiagonalType scaleType_; + bool isSymmetric_; + int dim_; }; -} // end namespace NS +} // end namespace NS -} // end namespace Teko +} // end namespace Teko #endif /* __Teko_ModALStrategy_hpp__ */ diff --git a/packages/teko/src/NS/Teko_LSCPreconditionerFactory.cpp b/packages/teko/src/NS/Teko_LSCPreconditionerFactory.cpp index 9680e0cf7b25..dd9172f9a851 100644 --- a/packages/teko/src/NS/Teko_LSCPreconditionerFactory.cpp +++ b/packages/teko/src/NS/Teko_LSCPreconditionerFactory.cpp @@ -65,167 +65,157 @@ namespace Teko { namespace NS { using Teuchos::rcp; -using Teuchos::rcp_dynamic_cast; using Teuchos::RCP; +using Teuchos::rcp_dynamic_cast; -using Thyra::multiply; using Thyra::add; using Thyra::identity; +using Thyra::multiply; // Stabilized constructor -LSCPreconditionerFactory::LSCPreconditionerFactory(const LinearOp & invF,const LinearOp & invBQBtmC, - const LinearOp & invD,const LinearOp & invMass) - : invOpsStrategy_(rcp(new StaticLSCStrategy(invF,invBQBtmC,invD,invMass))), isSymmetric_(true) -{ } +LSCPreconditionerFactory::LSCPreconditionerFactory(const LinearOp& invF, const LinearOp& invBQBtmC, + const LinearOp& invD, const LinearOp& invMass) + : invOpsStrategy_(rcp(new StaticLSCStrategy(invF, invBQBtmC, invD, invMass))), + isSymmetric_(true) {} // Stable constructor -LSCPreconditionerFactory::LSCPreconditionerFactory(const LinearOp & invF, const LinearOp & invBQBtmC, - const LinearOp & invMass) - : invOpsStrategy_(rcp(new StaticLSCStrategy(invF,invBQBtmC,invMass))), isSymmetric_(true) -{ } +LSCPreconditionerFactory::LSCPreconditionerFactory(const LinearOp& invF, const LinearOp& invBQBtmC, + const LinearOp& invMass) + : invOpsStrategy_(rcp(new StaticLSCStrategy(invF, invBQBtmC, invMass))), isSymmetric_(true) {} // fully generic constructor -LSCPreconditionerFactory::LSCPreconditionerFactory(const RCP & strategy) - : invOpsStrategy_(strategy), isSymmetric_(true) -{ } +LSCPreconditionerFactory::LSCPreconditionerFactory(const RCP& strategy) + : invOpsStrategy_(strategy), isSymmetric_(true) {} -LSCPreconditionerFactory::LSCPreconditionerFactory() : isSymmetric_(true) -{ } +LSCPreconditionerFactory::LSCPreconditionerFactory() : isSymmetric_(true) {} // for PreconditionerFactoryBase /////////////////////////////////////////////////////////////////////// // initialize a newly created preconditioner object -LinearOp LSCPreconditionerFactory::buildPreconditionerOperator(BlockedLinearOp & blockOp,BlockPreconditionerState & state) const -{ - Teko_DEBUG_SCOPE("LSCPreconditionerFactory::buildPreconditionerOperator",10); - Teko_DEBUG_EXPR(Teuchos::Time timer("")); - Teko_DEBUG_EXPR(Teuchos::Time totalTimer("")); - Teko_DEBUG_EXPR(totalTimer.start()); - - // extract sub-matrices from source operator - LinearOp F = blockOp->getBlock(0,0); - LinearOp B = blockOp->getBlock(1,0); - LinearOp Bt = blockOp->getBlock(0,1); - - if(not isSymmetric_) - Bt = scale(-1.0,adjoint(B)); - - // build what is neccessary for the state object - Teko_DEBUG_EXPR(timer.start(true)); - invOpsStrategy_->buildState(blockOp,state); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("LSCPrecFact::buildPO BuildStateTime = " << timer.totalElapsedTime(),2); - - // extract operators from strategy - Teko_DEBUG_EXPR(timer.start(true)); - LinearOp invF = invOpsStrategy_->getInvF(blockOp,state); - LinearOp invBQBtmC = invOpsStrategy_->getInvBQBt(blockOp,state); - LinearOp invBHBtmC = invOpsStrategy_->getInvBHBt(blockOp,state); - LinearOp outerStab = invOpsStrategy_->getOuterStabilization(blockOp,state); - LinearOp innerStab = invOpsStrategy_->getInnerStabilization(blockOp,state); - - // if necessary build an identity mass matrix - LinearOp invMass = invOpsStrategy_->getInvMass(blockOp,state); - LinearOp HScaling = invOpsStrategy_->getHScaling(blockOp,state); - if(invMass==Teuchos::null) invMass = identity(F->range()); - if(HScaling==Teuchos::null) HScaling = identity(F->range()); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("LSCPrecFact::buildPO GetInvTime = " << timer.totalElapsedTime(),2); - - // need to build Schur complement, inv(P) = inv(B*Bt)*(B*F*Bt)*inv(B*Bt) - - // first construct middle operator: M = B * inv(Mass) * F * inv(Mass) * Bt - LinearOp M = +LinearOp LSCPreconditionerFactory::buildPreconditionerOperator( + BlockedLinearOp& blockOp, BlockPreconditionerState& state) const { + Teko_DEBUG_SCOPE("LSCPreconditionerFactory::buildPreconditionerOperator", 10); + Teko_DEBUG_EXPR(Teuchos::Time timer("")); + Teko_DEBUG_EXPR(Teuchos::Time totalTimer("")); + Teko_DEBUG_EXPR(totalTimer.start()); + + // extract sub-matrices from source operator + LinearOp F = blockOp->getBlock(0, 0); + LinearOp B = blockOp->getBlock(1, 0); + LinearOp Bt = blockOp->getBlock(0, 1); + + if (not isSymmetric_) Bt = scale(-1.0, adjoint(B)); + + // build what is neccessary for the state object + Teko_DEBUG_EXPR(timer.start(true)); + invOpsStrategy_->buildState(blockOp, state); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("LSCPrecFact::buildPO BuildStateTime = " << timer.totalElapsedTime(), 2); + + // extract operators from strategy + Teko_DEBUG_EXPR(timer.start(true)); + LinearOp invF = invOpsStrategy_->getInvF(blockOp, state); + LinearOp invBQBtmC = invOpsStrategy_->getInvBQBt(blockOp, state); + LinearOp invBHBtmC = invOpsStrategy_->getInvBHBt(blockOp, state); + LinearOp outerStab = invOpsStrategy_->getOuterStabilization(blockOp, state); + LinearOp innerStab = invOpsStrategy_->getInnerStabilization(blockOp, state); + + // if necessary build an identity mass matrix + LinearOp invMass = invOpsStrategy_->getInvMass(blockOp, state); + LinearOp HScaling = invOpsStrategy_->getHScaling(blockOp, state); + if (invMass == Teuchos::null) invMass = identity(F->range()); + if (HScaling == Teuchos::null) HScaling = identity(F->range()); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("LSCPrecFact::buildPO GetInvTime = " << timer.totalElapsedTime(), 2); + + // need to build Schur complement, inv(P) = inv(B*Bt)*(B*F*Bt)*inv(B*Bt) + + // first construct middle operator: M = B * inv(Mass) * F * inv(Mass) * Bt + LinearOp M = // (B * inv(Mass) ) * F * (inv(Mass) * Bt) - multiply( multiply(B,invMass), F , multiply(HScaling,Bt)); - if(innerStab!=Teuchos::null) // deal with inner stabilization - M = add(M, innerStab); - - // now construct a linear operator schur complement - LinearOp invPschur; - if(outerStab!=Teuchos::null) - invPschur = add(multiply(invBQBtmC, M , invBHBtmC), outerStab); - else - invPschur = multiply(invBQBtmC, M , invBHBtmC); - - // build the preconditioner operator: Use LDU or upper triangular approximation - if(invOpsStrategy_->useFullLDU()) { - Teko_DEBUG_EXPR(totalTimer.stop()); - Teko_DEBUG_MSG("LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(),2); - - // solve using a full LDU decomposition - return createLU2x2InverseOp(blockOp,invF,invPschur,"LSC-LDU"); - } else { - // build diagonal operations - std::vector invDiag(2); - invDiag[0] = invF; - invDiag[1] = Thyra::scale(-1.0,invPschur); - - // get upper triangular matrix - BlockedLinearOp U = getUpperTriBlocks(blockOp); - - Teko_DEBUG_EXPR(totalTimer.stop()); - Teko_DEBUG_MSG("LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(),2); - - // solve using only one inversion of F - return createBlockUpperTriInverseOp(U,invDiag,"LSC-Upper"); - } + multiply(multiply(B, invMass), F, multiply(HScaling, Bt)); + if (innerStab != Teuchos::null) // deal with inner stabilization + M = add(M, innerStab); + + // now construct a linear operator schur complement + LinearOp invPschur; + if (outerStab != Teuchos::null) + invPschur = add(multiply(invBQBtmC, M, invBHBtmC), outerStab); + else + invPschur = multiply(invBQBtmC, M, invBHBtmC); + + // build the preconditioner operator: Use LDU or upper triangular approximation + if (invOpsStrategy_->useFullLDU()) { + Teko_DEBUG_EXPR(totalTimer.stop()); + Teko_DEBUG_MSG("LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(), 2); + + // solve using a full LDU decomposition + return createLU2x2InverseOp(blockOp, invF, invPschur, "LSC-LDU"); + } else { + // build diagonal operations + std::vector invDiag(2); + invDiag[0] = invF; + invDiag[1] = Thyra::scale(-1.0, invPschur); + + // get upper triangular matrix + BlockedLinearOp U = getUpperTriBlocks(blockOp); + + Teko_DEBUG_EXPR(totalTimer.stop()); + Teko_DEBUG_MSG("LSCPrecFact::buildPO TotalTime = " << totalTimer.totalElapsedTime(), 2); + + // solve using only one inversion of F + return createBlockUpperTriInverseOp(U, invDiag, "LSC-Upper"); + } } //! Initialize from a parameter list -void LSCPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList & pl) -{ - Teko_DEBUG_SCOPE("LSCPreconditionerFactory::initializeFromParameterList",10); - - RCP invLib = getInverseLibrary(); - - if(pl.isParameter("Is Symmetric")) - isSymmetric_ = pl.get("Is Symmetric"); - - std::string name = "Basic Inverse"; - if(pl.isParameter("Strategy Name")) - name = pl.get("Strategy Name"); - const Teuchos::ParameterEntry * pe = pl.getEntryPtr("Strategy Settings"); - - // check for a mistake in input file - if(name!="Basic Inverse" && pe==0) { - RCP out = getOutputStream(); - *out << "LSC Construction failed: "; - *out << "Strategy \"" << name << "\" requires a \"Strategy Settings\" sublist" << std::endl; - throw std::runtime_error("LSC Construction failed: Strategy Settings not set"); - } - - // get the parameter list to construct the strategy - Teuchos::RCP stratPL = Teuchos::rcpFromRef(pl); - if(pe!=0) - stratPL = Teuchos::rcpFromRef(pl.sublist("Strategy Settings")); - - // build the strategy object - RCP strategy = buildStrategy(name,*stratPL,invLib,getRequestHandler()); - - // strategy could not be built - if(strategy==Teuchos::null) { - RCP out = getOutputStream(); - *out << "LSC Construction failed: "; - *out << "Strategy \"" << name << "\" could not be constructed" << std::endl; - throw std::runtime_error("LSC Construction failed: Strategy could not be constructed"); - } - - strategy->setSymmetric(isSymmetric_); - invOpsStrategy_ = strategy; +void LSCPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList& pl) { + Teko_DEBUG_SCOPE("LSCPreconditionerFactory::initializeFromParameterList", 10); + + RCP invLib = getInverseLibrary(); + + if (pl.isParameter("Is Symmetric")) isSymmetric_ = pl.get("Is Symmetric"); + + std::string name = "Basic Inverse"; + if (pl.isParameter("Strategy Name")) name = pl.get("Strategy Name"); + const Teuchos::ParameterEntry* pe = pl.getEntryPtr("Strategy Settings"); + + // check for a mistake in input file + if (name != "Basic Inverse" && pe == 0) { + RCP out = getOutputStream(); + *out << "LSC Construction failed: "; + *out << "Strategy \"" << name << "\" requires a \"Strategy Settings\" sublist" << std::endl; + throw std::runtime_error("LSC Construction failed: Strategy Settings not set"); + } + + // get the parameter list to construct the strategy + Teuchos::RCP stratPL = Teuchos::rcpFromRef(pl); + if (pe != 0) stratPL = Teuchos::rcpFromRef(pl.sublist("Strategy Settings")); + + // build the strategy object + RCP strategy = buildStrategy(name, *stratPL, invLib, getRequestHandler()); + + // strategy could not be built + if (strategy == Teuchos::null) { + RCP out = getOutputStream(); + *out << "LSC Construction failed: "; + *out << "Strategy \"" << name << "\" could not be constructed" << std::endl; + throw std::runtime_error("LSC Construction failed: Strategy could not be constructed"); + } + + strategy->setSymmetric(isSymmetric_); + invOpsStrategy_ = strategy; } //! For assiting in construction of the preconditioner -Teuchos::RCP LSCPreconditionerFactory::getRequestedParameters() const -{ - return invOpsStrategy_->getRequestedParameters(); +Teuchos::RCP LSCPreconditionerFactory::getRequestedParameters() const { + return invOpsStrategy_->getRequestedParameters(); } //! For assiting in construction of the preconditioner -bool LSCPreconditionerFactory::updateRequestedParameters(const Teuchos::ParameterList & pl) -{ - return invOpsStrategy_->updateRequestedParameters(pl); +bool LSCPreconditionerFactory::updateRequestedParameters(const Teuchos::ParameterList& pl) { + return invOpsStrategy_->updateRequestedParameters(pl); } ///////////////////////////////////////////////////// @@ -236,80 +226,77 @@ bool LSCPreconditionerFactory::updateRequestedParameters(const Teuchos::Paramete CloneFactory LSCPreconditionerFactory::strategyBuilder_; /** \brief Builder function for creating strategies. - * - * Builder function for creating strategies. - * - * \param[in] name String name of strategy to build - * \param[in] settings Parameter list describing the parameters for the - * strategy to build - * \param[in] invLib Inverse library for the strategy to use. - * - * \returns If the name is associated with a strategy - * a pointer is returned, otherwise Teuchos::null is returned. - */ -RCP LSCPreconditionerFactory::buildStrategy(const std::string & name, - const Teuchos::ParameterList & settings, - const RCP & invLib, - const RCP & rh) -{ - Teko_DEBUG_SCOPE("LSCPreconditionerFactory::buildStrategy",10); - - // initialize the defaults if necessary - if(strategyBuilder_.cloneCount()==0) initializeStrategyBuilder(); - - // request the preconditioner factory from the CloneFactory - Teko_DEBUG_MSG("Building LSC strategy \"" << name << "\"",1); - RCP strategy = strategyBuilder_.build(name); - - if(strategy==Teuchos::null) return Teuchos::null; - - // now that inverse library has been set, - // pass in the parameter list - strategy->setRequestHandler(rh); - strategy->initializeFromParameterList(settings,*invLib); - - return strategy; + * + * Builder function for creating strategies. + * + * \param[in] name String name of strategy to build + * \param[in] settings Parameter list describing the parameters for the + * strategy to build + * \param[in] invLib Inverse library for the strategy to use. + * + * \returns If the name is associated with a strategy + * a pointer is returned, otherwise Teuchos::null is returned. + */ +RCP LSCPreconditionerFactory::buildStrategy(const std::string& name, + const Teuchos::ParameterList& settings, + const RCP& invLib, + const RCP& rh) { + Teko_DEBUG_SCOPE("LSCPreconditionerFactory::buildStrategy", 10); + + // initialize the defaults if necessary + if (strategyBuilder_.cloneCount() == 0) initializeStrategyBuilder(); + + // request the preconditioner factory from the CloneFactory + Teko_DEBUG_MSG("Building LSC strategy \"" << name << "\"", 1); + RCP strategy = strategyBuilder_.build(name); + + if (strategy == Teuchos::null) return Teuchos::null; + + // now that inverse library has been set, + // pass in the parameter list + strategy->setRequestHandler(rh); + strategy->initializeFromParameterList(settings, *invLib); + + return strategy; } /** \brief Add a strategy to the builder. This is done using the - * clone pattern. - * - * Add a strategy to the builder. This is done using the - * clone pattern. If your class does not support the Cloneable interface then - * you can use the AutoClone class to construct your object. - * - * \note If this method is called twice with the same string, the latter clone pointer - * will be used. - * - * \param[in] name String to associate with this object - * \param[in] clone Pointer to Cloneable object - */ -void LSCPreconditionerFactory::addStrategy(const std::string & name,const RCP & clone) -{ - // initialize the defaults if necessary - if(strategyBuilder_.cloneCount()==0) initializeStrategyBuilder(); - - // add clone to builder - strategyBuilder_.addClone(name,clone); + * clone pattern. + * + * Add a strategy to the builder. This is done using the + * clone pattern. If your class does not support the Cloneable interface then + * you can use the AutoClone class to construct your object. + * + * \note If this method is called twice with the same string, the latter clone pointer + * will be used. + * + * \param[in] name String to associate with this object + * \param[in] clone Pointer to Cloneable object + */ +void LSCPreconditionerFactory::addStrategy(const std::string& name, const RCP& clone) { + // initialize the defaults if necessary + if (strategyBuilder_.cloneCount() == 0) initializeStrategyBuilder(); + + // add clone to builder + strategyBuilder_.addClone(name, clone); } //! This is where the default objects are put into the strategyBuilder_ -void LSCPreconditionerFactory::initializeStrategyBuilder() -{ - RCP clone; +void LSCPreconditionerFactory::initializeStrategyBuilder() { + RCP clone; - // add various strategies to the factory - clone = rcp(new AutoClone()); - strategyBuilder_.addClone("Basic Inverse",clone); + // add various strategies to the factory + clone = rcp(new AutoClone()); + strategyBuilder_.addClone("Basic Inverse", clone); - // add various strategies to the factory - clone = rcp(new AutoClone()); - strategyBuilder_.addClone("Pressure Laplace",clone); + // add various strategies to the factory + clone = rcp(new AutoClone()); + strategyBuilder_.addClone("Pressure Laplace", clone); - // add various strategies to the factory - clone = rcp(new AutoClone()); - strategyBuilder_.addClone("SIMPLEC",clone); + // add various strategies to the factory + clone = rcp(new AutoClone()); + strategyBuilder_.addClone("SIMPLEC", clone); } -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_LSCPreconditionerFactory.hpp b/packages/teko/src/NS/Teko_LSCPreconditionerFactory.hpp index c3488f873f6a..6305bd18cc08 100644 --- a/packages/teko/src/NS/Teko_LSCPreconditionerFactory.hpp +++ b/packages/teko/src/NS/Teko_LSCPreconditionerFactory.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -51,141 +51,140 @@ #include "Teko_LSCStrategy.hpp" namespace Teko { -namespace NS { // Navier-Stokes specialization - -/** \brief Preconditioner state for the LSC factory. - * - * Preconditioner state for the LSC factory. This is based - * on the notation and concepts found in - * - * Elman, Howle, Shadid, Silvester, and Tuminaro, "Least Squares Preconditioners - * for Stabilized Discretizations of the Navier-Stokes Euqations," SISC-2007. - */ +namespace NS { // Navier-Stokes specialization + +/** \brief Preconditioner state for the LSC factory. + * + * Preconditioner state for the LSC factory. This is based + * on the notation and concepts found in + * + * Elman, Howle, Shadid, Silvester, and Tuminaro, "Least Squares Preconditioners + * for Stabilized Discretizations of the Navier-Stokes Euqations," SISC-2007. + */ class LSCPrecondState : public BlockPreconditionerState { -public: - LSCPrecondState() {} + public: + LSCPrecondState() {} - //! Inverse mass operator (\f$Q_u^{-1}\f$) - LinearOp invMass_; + //! Inverse mass operator (\f$Q_u^{-1}\f$) + LinearOp invMass_; - /** \f$B Q_u^{-1} B^T\f$ - */ - ModifiableLinearOp BQBt_; + /** \f$B Q_u^{-1} B^T\f$ + */ + ModifiableLinearOp BQBt_; - /** \f$B H B^T\f$ - */ - ModifiableLinearOp BHBt_; + /** \f$B H B^T\f$ + */ + ModifiableLinearOp BHBt_; - /** \f$B Q_u^{-1} B^T-\gamma C\f$ - */ - LinearOp BQBtmC_; - InverseLinearOp invBQBtmC_; + /** \f$B Q_u^{-1} B^T-\gamma C\f$ + */ + LinearOp BQBtmC_; + InverseLinearOp invBQBtmC_; - /** \f$B H B^T-\gamma C\f$ - */ - LinearOp BHBtmC_; - InverseLinearOp invBHBtmC_; + /** \f$B H B^T-\gamma C\f$ + */ + LinearOp BHBtmC_; + InverseLinearOp invBHBtmC_; - //! \f$\alpha D^{-1}\f$ where - LinearOp aiD_; + //! \f$\alpha D^{-1}\f$ where + LinearOp aiD_; - //! \f$\gamma = \rho(Q_u^{-1} F / 3)\f$ - double gamma_; + //! \f$\gamma = \rho(Q_u^{-1} F / 3)\f$ + double gamma_; - /** \f$\alpha = 1/\rho(B \; diag(F)^{-1} B^T D^{-1})\f$ where - * \f$D = diag(B \; diag(F)^{-1} B^T + C)\f$. - */ - double alpha_; + /** \f$\alpha = 1/\rho(B \; diag(F)^{-1} B^T D^{-1})\f$ where + * \f$D = diag(B \; diag(F)^{-1} B^T + C)\f$. + */ + double alpha_; }; -class LSCPreconditionerFactory - : public BlockPreconditionerFactory { -public: - //! \name Constructors - //@{ - - //! Staiblized constructor - LSCPreconditionerFactory(const LinearOp & invF,const LinearOp & invBQBtmC, - const LinearOp & invD,const LinearOp & invMass); - - //! Stable constructor - LSCPreconditionerFactory(const LinearOp & invF, - const LinearOp & invBQBtmC, - const LinearOp & invMass); - - //! fully generic constructor - LSCPreconditionerFactory(const Teuchos::RCP & strategy); - - //! Default constructor - LSCPreconditionerFactory(); - //@} - - //! for PreconditionerFactoryBase - virtual LinearOp buildPreconditionerOperator(BlockedLinearOp & blo,BlockPreconditionerState & state) const; - - //! Build the LSCPrecondState object - virtual RCP buildPreconditionerState() const - { return rcp(new LSCPrecondState()); } - - //! For assiting in construction of the preconditioner - virtual Teuchos::RCP getRequestedParameters() const; - - //! For assiting in construction of the preconditioner - virtual bool updateRequestedParameters(const Teuchos::ParameterList & pl); - -protected: - using Teko::BlockPreconditionerFactory::buildPreconditionerOperator; - - // Gimmie object - Teuchos::RCP invOpsStrategy_; - bool isSymmetric_; - - //! Initialize from a parameter list - virtual void initializeFromParameterList(const Teuchos::ParameterList & pl); - -public: - /** \brief Builder function for creating strategies. - * - * Builder function for creating strategies. - * - * \param[in] name String name of strategy to build - * \param[in] settings Parameter list describing the parameters for the - * strategy to build - * \param[in] invLib Inverse library for the strategy to use. - * - * \returns If the name is associated with a strategy - * a pointer is returned, otherwise Teuchos::null is returned. - */ - static RCP - buildStrategy(const std::string & name, - const Teuchos::ParameterList & settings, - const RCP & invLib, - const RCP & rh); - - /** \brief Add a strategy to the builder. This is done using the - * clone pattern. - * - * Add a strategy to the builder. This is done using the - * clone pattern. If your class does not support the Cloneable interface then - * you can use the AutoClone class to construct your object. - * - * \note If this method is called twice with the same string, the latter clone pointer - * will be used. - * - * \param[in] name String to associate with this object - * \param[in] clone Pointer to Cloneable object - */ - static void addStrategy(const std::string & name,const RCP & clone); - -private: - //! for creating the strategy objects - static CloneFactory strategyBuilder_; - - //! This is where the default objects are put into the strategyBuilder_ - static void initializeStrategyBuilder(); +class LSCPreconditionerFactory : public BlockPreconditionerFactory { + public: + //! \name Constructors + //@{ + + //! Staiblized constructor + LSCPreconditionerFactory(const LinearOp& invF, const LinearOp& invBQBtmC, const LinearOp& invD, + const LinearOp& invMass); + + //! Stable constructor + LSCPreconditionerFactory(const LinearOp& invF, const LinearOp& invBQBtmC, + const LinearOp& invMass); + + //! fully generic constructor + LSCPreconditionerFactory(const Teuchos::RCP& strategy); + + //! Default constructor + LSCPreconditionerFactory(); + //@} + + //! for PreconditionerFactoryBase + virtual LinearOp buildPreconditionerOperator(BlockedLinearOp& blo, + BlockPreconditionerState& state) const; + + //! Build the LSCPrecondState object + virtual RCP buildPreconditionerState() const { + return rcp(new LSCPrecondState()); + } + + //! For assiting in construction of the preconditioner + virtual Teuchos::RCP getRequestedParameters() const; + + //! For assiting in construction of the preconditioner + virtual bool updateRequestedParameters(const Teuchos::ParameterList& pl); + + protected: + using Teko::BlockPreconditionerFactory::buildPreconditionerOperator; + + // Gimmie object + Teuchos::RCP invOpsStrategy_; + bool isSymmetric_; + + //! Initialize from a parameter list + virtual void initializeFromParameterList(const Teuchos::ParameterList& pl); + + public: + /** \brief Builder function for creating strategies. + * + * Builder function for creating strategies. + * + * \param[in] name String name of strategy to build + * \param[in] settings Parameter list describing the parameters for the + * strategy to build + * \param[in] invLib Inverse library for the strategy to use. + * + * \returns If the name is associated with a strategy + * a pointer is returned, otherwise Teuchos::null is returned. + */ + static RCP buildStrategy(const std::string& name, + const Teuchos::ParameterList& settings, + const RCP& invLib, + const RCP& rh); + + /** \brief Add a strategy to the builder. This is done using the + * clone pattern. + * + * Add a strategy to the builder. This is done using the + * clone pattern. If your class does not support the Cloneable interface then + * you can use the AutoClone class to construct your object. + * + * \note If this method is called twice with the same string, the latter clone pointer + * will be used. + * + * \param[in] name String to associate with this object + * \param[in] clone Pointer to Cloneable object + */ + static void addStrategy(const std::string& name, const RCP& clone); + + private: + //! for creating the strategy objects + static CloneFactory strategyBuilder_; + + //! This is where the default objects are put into the strategyBuilder_ + static void initializeStrategyBuilder(); }; -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_LSCSIMPLECStrategy.cpp b/packages/teko/src/NS/Teko_LSCSIMPLECStrategy.cpp index c63e4f40364e..0a06e35bb023 100644 --- a/packages/teko/src/NS/Teko_LSCSIMPLECStrategy.cpp +++ b/packages/teko/src/NS/Teko_LSCSIMPLECStrategy.cpp @@ -57,8 +57,8 @@ #include "Teko_LSCPreconditionerFactory.hpp" using Teuchos::RCP; -using Teuchos::rcp_dynamic_cast; using Teuchos::rcp_const_cast; +using Teuchos::rcp_dynamic_cast; namespace Teko { namespace NS { @@ -70,206 +70,200 @@ namespace NS { // constructors ///////////////////////////////////////////////////////////////////////////// LSCSIMPLECStrategy::LSCSIMPLECStrategy() - : invFactoryF_(Teuchos::null), invFactoryS_(Teuchos::null) - , useFullLDU_(false), scaleType_(Diagonal) -{ } + : invFactoryF_(Teuchos::null), + invFactoryS_(Teuchos::null), + useFullLDU_(false), + scaleType_(Diagonal) {} ///////////////////////////////////////////////////////////////////////////// -void LSCSIMPLECStrategy::buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::buildState",10); +void LSCSIMPLECStrategy::buildState(BlockedLinearOp& A, BlockPreconditionerState& state) const { + Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::buildState", 10); - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); - // if neccessary save state information - if(not lscState->isInitialized()) { - Teko_DEBUG_EXPR(Teuchos::Time timer("")); + // if neccessary save state information + if (not lscState->isInitialized()) { + Teko_DEBUG_EXPR(Teuchos::Time timer("")); - // construct operators - { - Teko_DEBUG_SCOPE("LSC-SIMPLEC::buildState constructing operators",1); - Teko_DEBUG_EXPR(timer.start(true)); + // construct operators + { + Teko_DEBUG_SCOPE("LSC-SIMPLEC::buildState constructing operators", 1); + Teko_DEBUG_EXPR(timer.start(true)); - initializeState(A,lscState); + initializeState(A, lscState); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("LSC-SIMPLEC::buildState BuildOpsTime = " << timer.totalElapsedTime(),1); - } + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("LSC-SIMPLEC::buildState BuildOpsTime = " << timer.totalElapsedTime(), 1); + } - // Build the inverses - { - Teko_DEBUG_SCOPE("LSC-SIMPLEC::buildState calculating inverses",1); - Teko_DEBUG_EXPR(timer.start(true)); + // Build the inverses + { + Teko_DEBUG_SCOPE("LSC-SIMPLEC::buildState calculating inverses", 1); + Teko_DEBUG_EXPR(timer.start(true)); - computeInverses(A,lscState); + computeInverses(A, lscState); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("LSC-SIMPLEC::buildState BuildInvTime = " << timer.totalElapsedTime(),1); - } - } + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("LSC-SIMPLEC::buildState BuildInvTime = " << timer.totalElapsedTime(), 1); + } + } } // functions inherited from LSCStrategy -LinearOp LSCSIMPLECStrategy::getInvBQBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getInverse("invBQBtmC"); +LinearOp LSCSIMPLECStrategy::getInvBQBt(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getInverse("invBQBtmC"); } -LinearOp LSCSIMPLECStrategy::getInvBHBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getInverse("invBQBtmC").getConst(); +LinearOp LSCSIMPLECStrategy::getInvBHBt(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getInverse("invBQBtmC").getConst(); } -LinearOp LSCSIMPLECStrategy::getInvF(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getInverse("invF"); +LinearOp LSCSIMPLECStrategy::getInvF(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getInverse("invF"); } -LinearOp LSCSIMPLECStrategy::getInnerStabilization(const BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); - TEUCHOS_ASSERT(lscState->isInitialized()) +LinearOp LSCSIMPLECStrategy::getInnerStabilization(const BlockedLinearOp& A, + BlockPreconditionerState& state) const { + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); + TEUCHOS_ASSERT(lscState->isInitialized()) - const LinearOp C = getBlock(1,1,A); - return scale(-1.0,C); + const LinearOp C = getBlock(1, 1, A); + return scale(-1.0, C); } +LinearOp LSCSIMPLECStrategy::getInvMass(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); + TEUCHOS_ASSERT(lscState->isInitialized()) -LinearOp LSCSIMPLECStrategy::getInvMass(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); - TEUCHOS_ASSERT(lscState->isInitialized()) - - return lscState->invMass_; + return lscState->invMass_; } -LinearOp LSCSIMPLECStrategy::getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - return getInvMass(A,state); +LinearOp LSCSIMPLECStrategy::getHScaling(const BlockedLinearOp& A, + BlockPreconditionerState& state) const { + return getInvMass(A, state); } //! Initialize the state object using this blocked linear operator -void LSCSIMPLECStrategy::initializeState(const BlockedLinearOp & A,LSCPrecondState * state) const -{ - Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::initializeState",10); - - const LinearOp F = getBlock(0,0,A); - const LinearOp Bt = getBlock(0,1,A); - const LinearOp B = getBlock(1,0,A); - const LinearOp C = getBlock(1,1,A); - - bool isStabilized = (not isZeroOp(C)); - - state->invMass_ = getInvDiagonalOp(F,scaleType_); - - // compute BQBt - state->BQBt_ = explicitMultiply(B,state->invMass_,Bt,state->BQBt_); - if(isStabilized) { - // now build B*Q*Bt-C - Teko::ModifiableLinearOp BQBtmC = state->getInverse("BQBtmC"); - BQBtmC = explicitAdd(state->BQBt_,scale(-1.0,C),BQBtmC); - state->addInverse("BQBtmC",BQBtmC); - } - Teko_DEBUG_MSG("Computed BQBt",10); - - state->setInitialized(true); +void LSCSIMPLECStrategy::initializeState(const BlockedLinearOp& A, LSCPrecondState* state) const { + Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::initializeState", 10); + + const LinearOp F = getBlock(0, 0, A); + const LinearOp Bt = getBlock(0, 1, A); + const LinearOp B = getBlock(1, 0, A); + const LinearOp C = getBlock(1, 1, A); + + bool isStabilized = (not isZeroOp(C)); + + state->invMass_ = getInvDiagonalOp(F, scaleType_); + + // compute BQBt + state->BQBt_ = explicitMultiply(B, state->invMass_, Bt, state->BQBt_); + if (isStabilized) { + // now build B*Q*Bt-C + Teko::ModifiableLinearOp BQBtmC = state->getInverse("BQBtmC"); + BQBtmC = explicitAdd(state->BQBt_, scale(-1.0, C), BQBtmC); + state->addInverse("BQBtmC", BQBtmC); + } + Teko_DEBUG_MSG("Computed BQBt", 10); + + state->setInitialized(true); } /** Compute the inverses required for the LSC Schur complement - * - * \note This method assumes that the BQBt and BHBt operators have - * been constructed. - */ -void LSCSIMPLECStrategy::computeInverses(const BlockedLinearOp & A,LSCPrecondState * state) const -{ - Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::computeInverses",10); - Teko_DEBUG_EXPR(Teuchos::Time invTimer("")); - - const LinearOp F = getBlock(0,0,A); - - ///////////////////////////////////////////////////////// - - // (re)build the inverse of F - Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses Building inv(F)",1); - Teko_DEBUG_EXPR(invTimer.start(true)); - InverseLinearOp invF = state->getInverse("invF"); - if(invF==Teuchos::null) { - invF = buildInverse(*invFactoryF_,F); - state->addInverse("invF",invF); - } else { - rebuildInverse(*invFactoryF_,F,invF); - } - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses GetInvF = " << invTimer.totalElapsedTime(),1); - - ///////////////////////////////////////////////////////// - - // (re)build the inverse of BQBt - Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses Building inv(BQBtmC)",1); - Teko_DEBUG_EXPR(invTimer.start(true)); - const LinearOp BQBt = state->getInverse("BQBtmC"); - InverseLinearOp invBQBt = state->getInverse("invBQBtmC"); - if(invBQBt==Teuchos::null) { - invBQBt = buildInverse(*invFactoryS_,BQBt); - state->addInverse("invBQBtmC",invBQBt); - } else { - rebuildInverse(*invFactoryS_,BQBt,invBQBt); - } - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(),1); + * + * \note This method assumes that the BQBt and BHBt operators have + * been constructed. + */ +void LSCSIMPLECStrategy::computeInverses(const BlockedLinearOp& A, LSCPrecondState* state) const { + Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::computeInverses", 10); + Teko_DEBUG_EXPR(Teuchos::Time invTimer("")); + + const LinearOp F = getBlock(0, 0, A); + + ///////////////////////////////////////////////////////// + + // (re)build the inverse of F + Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses Building inv(F)", 1); + Teko_DEBUG_EXPR(invTimer.start(true)); + InverseLinearOp invF = state->getInverse("invF"); + if (invF == Teuchos::null) { + invF = buildInverse(*invFactoryF_, F); + state->addInverse("invF", invF); + } else { + rebuildInverse(*invFactoryF_, F, invF); + } + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses GetInvF = " << invTimer.totalElapsedTime(), 1); + + ///////////////////////////////////////////////////////// + + // (re)build the inverse of BQBt + Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses Building inv(BQBtmC)", 1); + Teko_DEBUG_EXPR(invTimer.start(true)); + const LinearOp BQBt = state->getInverse("BQBtmC"); + InverseLinearOp invBQBt = state->getInverse("invBQBtmC"); + if (invBQBt == Teuchos::null) { + invBQBt = buildInverse(*invFactoryS_, BQBt); + state->addInverse("invBQBtmC", invBQBt); + } else { + rebuildInverse(*invFactoryS_, BQBt, invBQBt); + } + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(), 1); } //! Initialize from a parameter list -void LSCSIMPLECStrategy::initializeFromParameterList(const Teuchos::ParameterList & pl,const InverseLibrary & invLib) -{ - // get string specifying inverse - std::string invStr="", invVStr="", invPStr=""; - bool useLDU = false; - scaleType_ = Diagonal; - - // "parse" the parameter list - if(pl.isParameter("Inverse Type")) - invStr = pl.get("Inverse Type"); - if(pl.isParameter("Inverse Velocity Type")) - invVStr = pl.get("Inverse Velocity Type"); - if(pl.isParameter("Inverse Pressure Type")) - invPStr = pl.get("Inverse Pressure Type"); - if(pl.isParameter("Use LDU")) - useLDU = pl.get("Use LDU"); - if(pl.isParameter("Scaling Type")) { - scaleType_ = getDiagonalType(pl.get("Scaling Type")); - TEUCHOS_TEST_FOR_EXCEPT(scaleType_==NotDiag); - } - - Teko_DEBUG_MSG_BEGIN(0) - DEBUG_STREAM << "LSC Inverse Strategy Parameters: " << std::endl; - DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; - DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; - DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; - DEBUG_STREAM << " use ldu = " << useLDU << std::endl; - DEBUG_STREAM << " scale type = " << getDiagonalName(scaleType_) << std::endl; - DEBUG_STREAM << "LSC Inverse Strategy Parameter list: " << std::endl; - pl.print(DEBUG_STREAM); - Teko_DEBUG_MSG_END() - - // set defaults as needed - if(invStr=="") invStr = "Amesos"; - if(invVStr=="") invVStr = invStr; - if(invPStr=="") invPStr = invStr; - - // build velocity inverse factory - invFactoryF_ = invLib.getInverseFactory(invVStr); - invFactoryS_ = invFactoryF_; // by default these are the same - if(invVStr!=invPStr) // if different, build pressure inverse factory - invFactoryS_ = invLib.getInverseFactory(invPStr); - - // set other parameters - setUseFullLDU(useLDU); +void LSCSIMPLECStrategy::initializeFromParameterList(const Teuchos::ParameterList& pl, + const InverseLibrary& invLib) { + // get string specifying inverse + std::string invStr = "", invVStr = "", invPStr = ""; + bool useLDU = false; + scaleType_ = Diagonal; + + // "parse" the parameter list + if (pl.isParameter("Inverse Type")) invStr = pl.get("Inverse Type"); + if (pl.isParameter("Inverse Velocity Type")) + invVStr = pl.get("Inverse Velocity Type"); + if (pl.isParameter("Inverse Pressure Type")) + invPStr = pl.get("Inverse Pressure Type"); + if (pl.isParameter("Use LDU")) useLDU = pl.get("Use LDU"); + if (pl.isParameter("Scaling Type")) { + scaleType_ = getDiagonalType(pl.get("Scaling Type")); + TEUCHOS_TEST_FOR_EXCEPT(scaleType_ == NotDiag); + } + + Teko_DEBUG_MSG_BEGIN(0) DEBUG_STREAM << "LSC Inverse Strategy Parameters: " << std::endl; + DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; + DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; + DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; + DEBUG_STREAM << " use ldu = " << useLDU << std::endl; + DEBUG_STREAM << " scale type = " << getDiagonalName(scaleType_) << std::endl; + DEBUG_STREAM << "LSC Inverse Strategy Parameter list: " << std::endl; + pl.print(DEBUG_STREAM); + Teko_DEBUG_MSG_END() + + // set defaults as needed + if (invStr == "") invStr = "Amesos"; + if (invVStr == "") invVStr = invStr; + if (invPStr == "") invPStr = invStr; + + // build velocity inverse factory + invFactoryF_ = invLib.getInverseFactory(invVStr); + invFactoryS_ = invFactoryF_; // by default these are the same + if (invVStr != invPStr) // if different, build pressure inverse factory + invFactoryS_ = invLib.getInverseFactory(invPStr); + + // set other parameters + setUseFullLDU(useLDU); } -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_LSCSIMPLECStrategy.hpp b/packages/teko/src/NS/Teko_LSCSIMPLECStrategy.hpp index ca09e36df7a6..eadd43348de4 100644 --- a/packages/teko/src/NS/Teko_LSCSIMPLECStrategy.hpp +++ b/packages/teko/src/NS/Teko_LSCSIMPLECStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,143 +52,146 @@ namespace Teko { namespace NS { -class LSCPrecondState; // forward declration +class LSCPrecondState; // forward declration /** \brief A strategy that takes a single inverse factory and - * uses that for all inverses. If no mass matrix is - * passed in the diagonal of the 1,1 block is used. - * - * A strategy that takes a single inverse factory and uses that - * for all inverses. Optionally the mass matrix can be passed - * in, if it is the diagonal is extracted and that is used to - * form the inverse approximation. - */ + * uses that for all inverses. If no mass matrix is + * passed in the diagonal of the 1,1 block is used. + * + * A strategy that takes a single inverse factory and uses that + * for all inverses. Optionally the mass matrix can be passed + * in, if it is the diagonal is extracted and that is used to + * form the inverse approximation. + */ class LSCSIMPLECStrategy : public LSCStrategy { -public: - //! \name Constructors - //@{ - LSCSIMPLECStrategy(); - //@} - - virtual ~LSCSIMPLECStrategy() {} - - //! Functions inherited from LSCStrategy - //@{ - - /** This informs the strategy object to build the state associated - * with this operator. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - */ - virtual void buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of \f$B Q_u^{-1} B^T\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T\f$. - */ - virtual LinearOp getInvBQBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of \f$B H B^T - \gamma C\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. - */ - virtual LinearOp getInvBHBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of the \f$F\f$ block. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$F\f$. - */ - virtual LinearOp getInvF(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse for stabilizing the whole schur complement approximation. - * Returns \f$\alpha D^{-1}\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The operator to stabilize the whole Schur complement. - */ - virtual LinearOp getOuterStabilization(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return Teuchos::null; } - - virtual LinearOp getInnerStabilization(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse mass matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The inverse of the mass matrix \f$Q_u\f$. - */ - virtual LinearOp getInvMass(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the \f$H\f$ scaling matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The \f$H\f$ scaling matrix. - */ - virtual LinearOp getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Should the approximation of the inverse use a full LDU decomposition, or - * is a upper triangular approximation sufficient. - * - * \returns True if the full LDU decomposition should be used, otherwise - * only an upper triangular version is used. - */ - virtual bool useFullLDU() const { return useFullLDU_; } - - //! Initialize from a parameter list - virtual void initializeFromParameterList(const Teuchos::ParameterList & pl, - const InverseLibrary & invLib); - - //! Initialize the state object using this blocked linear operator - virtual void initializeState(const BlockedLinearOp & A,LSCPrecondState * state) const; - - /** Compute the inverses required for the LSC Schur complement - * - * \note This method assumes that the BQBt and BHBt operators have - * been constructed. - */ - void computeInverses(const BlockedLinearOp & A,LSCPrecondState * state) const; - - //! Set to true to use the Full LDU decomposition, false otherwise - virtual void setUseFullLDU(bool val) { useFullLDU_ = val; } - - virtual void setSymmetric(bool /* isSymmetric */) { } - -protected: - // how to invert the matrices - Teuchos::RCP invFactoryF_; - Teuchos::RCP invFactoryS_; - - // flags for handling various options - bool useFullLDU_; - DiagonalType scaleType_; - -private: - LSCSIMPLECStrategy(const LSCSIMPLECStrategy &); + public: + //! \name Constructors + //@{ + LSCSIMPLECStrategy(); + //@} + + virtual ~LSCSIMPLECStrategy() {} + + //! Functions inherited from LSCStrategy + //@{ + + /** This informs the strategy object to build the state associated + * with this operator. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + */ + virtual void buildState(BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of \f$B Q_u^{-1} B^T\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T\f$. + */ + virtual LinearOp getInvBQBt(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of \f$B H B^T - \gamma C\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. + */ + virtual LinearOp getInvBHBt(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of the \f$F\f$ block. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$F\f$. + */ + virtual LinearOp getInvF(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse for stabilizing the whole schur complement approximation. + * Returns \f$\alpha D^{-1}\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The operator to stabilize the whole Schur complement. + */ + virtual LinearOp getOuterStabilization(const BlockedLinearOp & /* A */, + BlockPreconditionerState & /* state */) const { + return Teuchos::null; + } + + virtual LinearOp getInnerStabilization(const BlockedLinearOp &A, + BlockPreconditionerState &state) const; + + /** Get the inverse mass matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The inverse of the mass matrix \f$Q_u\f$. + */ + virtual LinearOp getInvMass(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the \f$H\f$ scaling matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The \f$H\f$ scaling matrix. + */ + virtual LinearOp getHScaling(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Should the approximation of the inverse use a full LDU decomposition, or + * is a upper triangular approximation sufficient. + * + * \returns True if the full LDU decomposition should be used, otherwise + * only an upper triangular version is used. + */ + virtual bool useFullLDU() const { return useFullLDU_; } + + //! Initialize from a parameter list + virtual void initializeFromParameterList(const Teuchos::ParameterList &pl, + const InverseLibrary &invLib); + + //! Initialize the state object using this blocked linear operator + virtual void initializeState(const BlockedLinearOp &A, LSCPrecondState *state) const; + + /** Compute the inverses required for the LSC Schur complement + * + * \note This method assumes that the BQBt and BHBt operators have + * been constructed. + */ + void computeInverses(const BlockedLinearOp &A, LSCPrecondState *state) const; + + //! Set to true to use the Full LDU decomposition, false otherwise + virtual void setUseFullLDU(bool val) { useFullLDU_ = val; } + + virtual void setSymmetric(bool /* isSymmetric */) {} + + protected: + // how to invert the matrices + Teuchos::RCP invFactoryF_; + Teuchos::RCP invFactoryS_; + + // flags for handling various options + bool useFullLDU_; + DiagonalType scaleType_; + + private: + LSCSIMPLECStrategy(const LSCSIMPLECStrategy &); }; -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_LSCStrategy.hpp b/packages/teko/src/NS/Teko_LSCStrategy.hpp index 0827d554fe09..48f8dee1723d 100644 --- a/packages/teko/src/NS/Teko_LSCStrategy.hpp +++ b/packages/teko/src/NS/Teko_LSCStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -58,108 +58,108 @@ namespace Teko { namespace NS { -class LSCPrecondState; // forward declaration +class LSCPrecondState; // forward declaration /** \brief Strategy for driving LSCPreconditionerFactory. - * - * Strategy for driving the LSCPreconditionerFactory. This - * class provides all the pieces required by the LSC preconditioner. - * The intent is that the user can overide them and build - * there own implementation. Though a fairly substantial implementation - * is provided in InvLSCStrategy. - * - * The basics of this method can be found in - * - * [1] Elman, Howle, Shadid, Silvester, and Tuminaro, "Least Squares Preconditioners - * for Stabilized Discretizations of the Navier-Stokes Euqations," SISC-2007. - * - * [2] Elman, and Tuminaro, "Boundary Conditions in Approximate Commutator - * Preconditioners for the Navier-Stokes Equations," In press (8/2009)? - * - * The Least Squares Commuator preconditioner provides a (nearly) Algebraic approximation - * of the Schur complement of the (Navier-)Stokes system - * - * \f$ A = \left[\begin{array}{cc} - * F & B^T \\ - * B & C - * \end{array}\right] \f$ - * - * The approximation to the Schur complement is - * - * \f$ C - B F^{-1} B^T \approx (B \hat{Q}_u^{-1} B^T - \gamma C)^{-1} - * (B \hat{Q}_u^{-1} F H B^T+C_I) (B H B^T - \gamma C)^{-1} - * + C_O \f$. - * - * Where \f$\hat{Q}_u\f$ is typically a diagonal approximation of the mass matrix, - * and \f$H\f$ is an appropriate diagonal scaling matrix (see [2] for details). - * The scalars \f$\alpha\f$ and \f$\gamma\f$ are chosen to stabilize an unstable - * discretization (for the case of \f$C\neq 0\f$). If the system is stable then - * they can be set to \f$0\f$ (see [1] for more details). - * - * In order to approximate \f$A\f$ two decompositions can be chosen, a full LU - * decomposition and a purely upper triangular version. A full LU decomposition - * requires that the velocity convection-diffusion operator (\f$F\f$) is inverted - * twice, while an upper triangular approximation requires only a single inverse. - * - * The methods of this strategy provide the different pieces. For instance - * getInvF provides \f$F^{-1}\f$. Similarly there are calls to get - * the inverses of \f$B \hat{Q}_u^{-1} B^T - \gamma C\f$, - * \f$B \hat{Q}_u^{-1} B^T - \gamma C\f$, and \f$\hat{Q}_u^{-1}\f$ as well as - * the \f$H\f$ operator. All these methods are required by the - * LSCPreconditionerFactory. Additionally there is a - * buildState method that is called everytime a preconditiner is - * (re)constructed. This is to allow for any preprocessing neccessary to be - * handled. - * - * The final set of methods help construct a LSCStrategy object, they are - * primarily used by the parameter list construction inteface. They are - * more advanced and can be ignored by initial implementations of this - * class. - */ + * + * Strategy for driving the LSCPreconditionerFactory. This + * class provides all the pieces required by the LSC preconditioner. + * The intent is that the user can overide them and build + * there own implementation. Though a fairly substantial implementation + * is provided in InvLSCStrategy. + * + * The basics of this method can be found in + * + * [1] Elman, Howle, Shadid, Silvester, and Tuminaro, "Least Squares Preconditioners + * for Stabilized Discretizations of the Navier-Stokes Euqations," SISC-2007. + * + * [2] Elman, and Tuminaro, "Boundary Conditions in Approximate Commutator + * Preconditioners for the Navier-Stokes Equations," In press (8/2009)? + * + * The Least Squares Commuator preconditioner provides a (nearly) Algebraic approximation + * of the Schur complement of the (Navier-)Stokes system + * + * \f$ A = \left[\begin{array}{cc} + * F & B^T \\ + * B & C + * \end{array}\right] \f$ + * + * The approximation to the Schur complement is + * + * \f$ C - B F^{-1} B^T \approx (B \hat{Q}_u^{-1} B^T - \gamma C)^{-1} + * (B \hat{Q}_u^{-1} F H B^T+C_I) (B H B^T - \gamma C)^{-1} + * + C_O \f$. + * + * Where \f$\hat{Q}_u\f$ is typically a diagonal approximation of the mass matrix, + * and \f$H\f$ is an appropriate diagonal scaling matrix (see [2] for details). + * The scalars \f$\alpha\f$ and \f$\gamma\f$ are chosen to stabilize an unstable + * discretization (for the case of \f$C\neq 0\f$). If the system is stable then + * they can be set to \f$0\f$ (see [1] for more details). + * + * In order to approximate \f$A\f$ two decompositions can be chosen, a full LU + * decomposition and a purely upper triangular version. A full LU decomposition + * requires that the velocity convection-diffusion operator (\f$F\f$) is inverted + * twice, while an upper triangular approximation requires only a single inverse. + * + * The methods of this strategy provide the different pieces. For instance + * getInvF provides \f$F^{-1}\f$. Similarly there are calls to get + * the inverses of \f$B \hat{Q}_u^{-1} B^T - \gamma C\f$, + * \f$B \hat{Q}_u^{-1} B^T - \gamma C\f$, and \f$\hat{Q}_u^{-1}\f$ as well as + * the \f$H\f$ operator. All these methods are required by the + * LSCPreconditionerFactory. Additionally there is a + * buildState method that is called everytime a preconditiner is + * (re)constructed. This is to allow for any preprocessing neccessary to be + * handled. + * + * The final set of methods help construct a LSCStrategy object, they are + * primarily used by the parameter list construction inteface. They are + * more advanced and can be ignored by initial implementations of this + * class. + */ class LSCStrategy { -public: - virtual ~LSCStrategy() {} + public: + virtual ~LSCStrategy() {} - /** This informs the strategy object to build the state associated - * with this operator. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - */ - virtual void buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; + /** This informs the strategy object to build the state associated + * with this operator. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + */ + virtual void buildState(BlockedLinearOp& A, BlockPreconditionerState& state) const = 0; - /** Get the inverse of \f$B Q_u^{-1} B^T - \gamma C\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T - \gamma C\f$. - */ - virtual LinearOp getInvBQBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; + /** Get the inverse of \f$B Q_u^{-1} B^T - \gamma C\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T - \gamma C\f$. + */ + virtual LinearOp getInvBQBt(const BlockedLinearOp& A, BlockPreconditionerState& state) const = 0; - /** Get the inverse of \f$B H B^T - \gamma C\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. - */ - virtual LinearOp getInvBHBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; + /** Get the inverse of \f$B H B^T - \gamma C\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. + */ + virtual LinearOp getInvBHBt(const BlockedLinearOp& A, BlockPreconditionerState& state) const = 0; - /** Get the inverse of the \f$F\f$ block. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$F\f$. - */ - virtual LinearOp getInvF(const BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; + /** Get the inverse of the \f$F\f$ block. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$F\f$. + */ + virtual LinearOp getInvF(const BlockedLinearOp& A, BlockPreconditionerState& state) const = 0; - #if 0 +#if 0 /** Get the inverse for stabilizing the whole Schur complement approximation. * * \param[in] A The linear operator to be preconditioned by LSC. @@ -169,90 +169,93 @@ class LSCStrategy { * \returns The operator to stabilize the whole Schur complement (\f$\alpha D^{-1} \f$). */ virtual LinearOp getInvAlphaD(const BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; - #endif - - /** Get the inverse to stablized stabilizing the Schur complement approximation using - * a placement on the ``outside''. That is what is the value for \f$C_O\f$. This quantity - * may be null. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The operator to stabilize the whole Schur complement (originally \f$\alpha D^{-1} \f$). - */ - virtual LinearOp getOuterStabilization(const BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; +#endif - /** Get the inverse to stablized stabilizing the Schur complement approximation using - * a placement on the ``inside''. That is what is the value for \f$C_I\f$. This quantity - * may be null. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The operator to stabilize the whole Schur complement. - */ - virtual LinearOp getInnerStabilization(const BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; + /** Get the inverse to stablized stabilizing the Schur complement approximation using + * a placement on the ``outside''. That is what is the value for \f$C_O\f$. This quantity + * may be null. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The operator to stabilize the whole Schur complement (originally \f$\alpha D^{-1} + * \f$). + */ + virtual LinearOp getOuterStabilization(const BlockedLinearOp& A, + BlockPreconditionerState& state) const = 0; - /** Get the inverse mass matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The inverse of the mass matrix \f$Q_u\f$. - */ - virtual LinearOp getInvMass(const BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; + /** Get the inverse to stablized stabilizing the Schur complement approximation using + * a placement on the ``inside''. That is what is the value for \f$C_I\f$. This quantity + * may be null. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The operator to stabilize the whole Schur complement. + */ + virtual LinearOp getInnerStabilization(const BlockedLinearOp& A, + BlockPreconditionerState& state) const = 0; - /** Get the \f$H\f$ scaling matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The \f$H\f$ scaling matrix. - */ - virtual LinearOp getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const = 0; + /** Get the inverse mass matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The inverse of the mass matrix \f$Q_u\f$. + */ + virtual LinearOp getInvMass(const BlockedLinearOp& A, BlockPreconditionerState& state) const = 0; - /** Should the approximation of the inverse use a full LDU decomposition, or - * is a upper triangular approximation sufficient. - * - * \returns True if the full LDU decomposition should be used, otherwise - * only an upper triangular version is used. - */ - virtual bool useFullLDU() const = 0; + /** Get the \f$H\f$ scaling matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The \f$H\f$ scaling matrix. + */ + virtual LinearOp getHScaling(const BlockedLinearOp& A, BlockPreconditionerState& state) const = 0; - /** Tell strategy that this operator is supposed to be symmetric. - * Behavior of LSC is slightly different for non-symmetric case. - * - * \param[in] isSymmetric Is this operator symmetric? - */ - virtual void setSymmetric(bool isSymmetric) = 0; + /** Should the approximation of the inverse use a full LDU decomposition, or + * is a upper triangular approximation sufficient. + * + * \returns True if the full LDU decomposition should be used, otherwise + * only an upper triangular version is used. + */ + virtual bool useFullLDU() const = 0; - //! Initialize from a parameter list - virtual void initializeFromParameterList(const Teuchos::ParameterList & /* pl */,const InverseLibrary & /* invLib */) {} + /** Tell strategy that this operator is supposed to be symmetric. + * Behavior of LSC is slightly different for non-symmetric case. + * + * \param[in] isSymmetric Is this operator symmetric? + */ + virtual void setSymmetric(bool isSymmetric) = 0; - //! For assiting in construction of the preconditioner - virtual Teuchos::RCP getRequestedParameters() const { return Teuchos::null;} + //! Initialize from a parameter list + virtual void initializeFromParameterList(const Teuchos::ParameterList& /* pl */, + const InverseLibrary& /* invLib */) {} - //! For assiting in construction of the preconditioner - virtual bool updateRequestedParameters(const Teuchos::ParameterList & /* pl */) { return true; } + //! For assiting in construction of the preconditioner + virtual Teuchos::RCP getRequestedParameters() const { + return Teuchos::null; + } - //! This method sets the request handler for this object - void setRequestHandler(const Teuchos::RCP & rh) - { requestHandler_ = rh; } + //! For assiting in construction of the preconditioner + virtual bool updateRequestedParameters(const Teuchos::ParameterList& /* pl */) { return true; } - //! This method gets the request handler uses by this object - Teuchos::RCP getRequestHandler() const - { return requestHandler_; } + //! This method sets the request handler for this object + void setRequestHandler(const Teuchos::RCP& rh) { requestHandler_ = rh; } -private: - Teuchos::RCP requestHandler_; + //! This method gets the request handler uses by this object + Teuchos::RCP getRequestHandler() const { return requestHandler_; } + private: + Teuchos::RCP requestHandler_; }; -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_ModALPreconditionerFactory.cpp b/packages/teko/src/NS/Teko_ModALPreconditionerFactory.cpp index d8aa6853e89f..a7677e3efa6f 100644 --- a/packages/teko/src/NS/Teko_ModALPreconditionerFactory.cpp +++ b/packages/teko/src/NS/Teko_ModALPreconditionerFactory.cpp @@ -21,123 +21,106 @@ #include "Teuchos_Time.hpp" -namespace Teko -{ +namespace Teko { -namespace NS -{ +namespace NS { -ModALPrecondState::ModALPrecondState(): -pressureMassMatrix_(Teuchos::null), invPressureMassMatrix_(Teuchos::null) -{ -} +ModALPrecondState::ModALPrecondState() + : pressureMassMatrix_(Teuchos::null), invPressureMassMatrix_(Teuchos::null) {} -ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP & factory) : - invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(factory))), - isSymmetric_(true) -{ -} +ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP& factory) + : invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(factory))), isSymmetric_(true) {} -ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP & invFactoryA, - const Teuchos::RCP & invFactoryS) : - invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(invFactoryA, invFactoryS))), - isSymmetric_(true) -{ -} +ModALPreconditionerFactory::ModALPreconditionerFactory( + const Teuchos::RCP& invFactoryA, + const Teuchos::RCP& invFactoryS) + : invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(invFactoryA, invFactoryS))), + isSymmetric_(true) {} -ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP & factory, - LinearOp & pressureMassMatrix) : - invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(factory, pressureMassMatrix))), isSymmetric_(true) -{ -} +ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP& factory, + LinearOp& pressureMassMatrix) + : invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(factory, pressureMassMatrix))), + isSymmetric_(true) {} -ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP & invFactoryA, - const Teuchos::RCP & invFactoryS, - LinearOp & pressureMassMatrix) : - invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(invFactoryA, invFactoryS, pressureMassMatrix))), - isSymmetric_(true) -{ -} +ModALPreconditionerFactory::ModALPreconditionerFactory( + const Teuchos::RCP& invFactoryA, + const Teuchos::RCP& invFactoryS, LinearOp& pressureMassMatrix) + : invOpsStrategy_( + Teuchos::rcp(new InvModALStrategy(invFactoryA, invFactoryS, pressureMassMatrix))), + isSymmetric_(true) {} // Construct from a strategy. -ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP & strategy) : - invOpsStrategy_(strategy), isSymmetric_(true) -{ -} - -LinearOp ModALPreconditionerFactory::buildPreconditionerOperator(BlockedLinearOp & alOp, - BlockPreconditionerState & state) const -{ - Teko_DEBUG_SCOPE("ModALPreconditionerFactory::buildPreconditionerOperator()", 10); - Teko_DEBUG_EXPR(Teuchos::Time timer("")); - Teko_DEBUG_EXPR(Teuchos::Time totalTimer("")); - Teko_DEBUG_EXPR(totalTimer.start()); - - // Only for 2D or 3D problems. - int dim = blockRowCount(alOp) - 1; - TEUCHOS_ASSERT(dim == 2 || dim == 3); - - // Build what is necessary for the state object. - Teko_DEBUG_EXPR(timer.start(true)); - invOpsStrategy_->buildState(alOp, state); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("ModALPreconditionerFactory::buildPreconditionerOperator():BuildStateTime = " - << timer.totalElapsedTime(), 2); - - // Extract inverse operators from strategy - Teko_DEBUG_EXPR(timer.start(true)); - LinearOp invA11p = invOpsStrategy_->getInvA11p(state); - LinearOp invA22p = invOpsStrategy_->getInvA22p(state); - LinearOp invA33p; - if(dim == 3) - { - invA33p = invOpsStrategy_->getInvA33p(state); - } - - // The inverse of S can be built from strategy, - // or just a diagonal matrix. - ModALPrecondState * modALState = dynamic_cast(&state); - TEUCHOS_ASSERT(modALState != NULL); - LinearOp invS; - if(modALState->isStabilized_) - { - invS = invOpsStrategy_->getInvS(state); - } - else - { - invS = scale(modALState->gamma_, modALState->invPressureMassMatrix_); - } - - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("ModALPrecFact::buildPreconditionerOperator(): GetInvTime = " - << timer.totalElapsedTime(), 2); - - // Build diagonal operations. - std::vector invDiag; - invDiag.resize(dim + 1); - invDiag[0] = invA11p; - invDiag[1] = invA22p; - if(dim == 2) - { - invDiag[2] = scale(-1.0, invS); - } - else if(dim == 3) - { - invDiag[2] = invA33p; - invDiag[3] = scale(-1.0, invS); - } - - // Get the upper triangular matrix. - BlockedLinearOp U = getUpperTriBlocks(alOp); - - Teko_DEBUG_EXPR(totalTimer.stop()); - Teko_DEBUG_MSG("ModALPrecFact::buildPreconditionerOperator TotalTime = " - << totalTimer.totalElapsedTime(), 2); - - // Create the preconditioner - return createBlockUpperTriInverseOp(U, invDiag, "Modified AL preconditioner-Upper"); +ModALPreconditionerFactory::ModALPreconditionerFactory( + const Teuchos::RCP& strategy) + : invOpsStrategy_(strategy), isSymmetric_(true) {} + +LinearOp ModALPreconditionerFactory::buildPreconditionerOperator( + BlockedLinearOp& alOp, BlockPreconditionerState& state) const { + Teko_DEBUG_SCOPE("ModALPreconditionerFactory::buildPreconditionerOperator()", 10); + Teko_DEBUG_EXPR(Teuchos::Time timer("")); + Teko_DEBUG_EXPR(Teuchos::Time totalTimer("")); + Teko_DEBUG_EXPR(totalTimer.start()); + + // Only for 2D or 3D problems. + int dim = blockRowCount(alOp) - 1; + TEUCHOS_ASSERT(dim == 2 || dim == 3); + + // Build what is necessary for the state object. + Teko_DEBUG_EXPR(timer.start(true)); + invOpsStrategy_->buildState(alOp, state); + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("ModALPreconditionerFactory::buildPreconditionerOperator():BuildStateTime = " + << timer.totalElapsedTime(), + 2); + + // Extract inverse operators from strategy + Teko_DEBUG_EXPR(timer.start(true)); + LinearOp invA11p = invOpsStrategy_->getInvA11p(state); + LinearOp invA22p = invOpsStrategy_->getInvA22p(state); + LinearOp invA33p; + if (dim == 3) { + invA33p = invOpsStrategy_->getInvA33p(state); + } + + // The inverse of S can be built from strategy, + // or just a diagonal matrix. + ModALPrecondState* modALState = dynamic_cast(&state); + TEUCHOS_ASSERT(modALState != NULL); + LinearOp invS; + if (modALState->isStabilized_) { + invS = invOpsStrategy_->getInvS(state); + } else { + invS = scale(modALState->gamma_, modALState->invPressureMassMatrix_); + } + + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG( + "ModALPrecFact::buildPreconditionerOperator(): GetInvTime = " << timer.totalElapsedTime(), 2); + + // Build diagonal operations. + std::vector invDiag; + invDiag.resize(dim + 1); + invDiag[0] = invA11p; + invDiag[1] = invA22p; + if (dim == 2) { + invDiag[2] = scale(-1.0, invS); + } else if (dim == 3) { + invDiag[2] = invA33p; + invDiag[3] = scale(-1.0, invS); + } + + // Get the upper triangular matrix. + BlockedLinearOp U = getUpperTriBlocks(alOp); + + Teko_DEBUG_EXPR(totalTimer.stop()); + Teko_DEBUG_MSG( + "ModALPrecFact::buildPreconditionerOperator TotalTime = " << totalTimer.totalElapsedTime(), + 2); + + // Create the preconditioner + return createBlockUpperTriInverseOp(U, invDiag, "Modified AL preconditioner-Upper"); } -} // end namespace NS +} // end namespace NS -} // end namespace Teko +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_ModALPreconditionerFactory.hpp b/packages/teko/src/NS/Teko_ModALPreconditionerFactory.hpp index 0066ae0d0b82..42335e1e6a7e 100644 --- a/packages/teko/src/NS/Teko_ModALPreconditionerFactory.hpp +++ b/packages/teko/src/NS/Teko_ModALPreconditionerFactory.hpp @@ -10,29 +10,26 @@ #include "Teko_BlockPreconditionerFactory.hpp" #include "Teko_InvModALStrategy.hpp" -namespace Teko -{ +namespace Teko { -namespace NS -{ +namespace NS { /** \brief Class for saving state variables for * ModALPreconditionerFactory. */ -class ModALPrecondState : public BlockPreconditionerState -{ -public: - ModALPrecondState(); - - LinearOp pressureMassMatrix_; - LinearOp invPressureMassMatrix_; - ModifiableLinearOp B1tMpB1_, B2tMpB2_, B3tMpB3_; - ModifiableLinearOp A11p_, A22p_, A33p_; - ModifiableLinearOp invA11p_, invA22p_, invA33p_, invS_; - ModifiableLinearOp S_; - - double gamma_; - bool isStabilized_; +class ModALPrecondState : public BlockPreconditionerState { + public: + ModALPrecondState(); + + LinearOp pressureMassMatrix_; + LinearOp invPressureMassMatrix_; + ModifiableLinearOp B1tMpB1_, B2tMpB2_, B3tMpB3_; + ModifiableLinearOp A11p_, A22p_, A33p_; + ModifiableLinearOp invA11p_, invA22p_, invA33p_, invS_; + ModifiableLinearOp S_; + + double gamma_; + bool isStabilized_; }; /** \brief Modified augmented Lagrangian-based preconditioner @@ -78,7 +75,7 @@ class ModALPrecondState : public BlockPreconditionerState * \end{array} \right] * \left[ \begin{array}{c} * u \\ - * p + * p * \end{array} \right] * = * \left[ \begin{array}{c} @@ -100,7 +97,8 @@ class ModALPrecondState : public BlockPreconditionerState * * \f$ * \left[ \begin{array}{ccc} - * A_{11} + \gamma B_1^T W^{-1} B_1^T & A_{12} + \gamma B_1^T W^{-1} B_2^T & B_1^T - \gamma B_1^T W^{-1} C \\ + * A_{11} + \gamma B_1^T W^{-1} B_1^T & A_{12} + \gamma B_1^T W^{-1} B_2^T & B_1^T - \gamma B_1^T + * W^{-1} C \\ * 0 & A_{22} + \gamma B_2^T W^{-1} B_2^T & B_1^T - \gamma B_2^T W^{-1} C \\ * 0 & 0 & S * \end{array} \right]. @@ -109,79 +107,68 @@ class ModALPrecondState : public BlockPreconditionerState * More details (analysis, numerical results) can be found in [2]. */ -class ModALPreconditionerFactory : public BlockPreconditionerFactory -{ -public: - - ModALPreconditionerFactory(); - - ModALPreconditionerFactory(const Teuchos::RCP & factory); - - ModALPreconditionerFactory(const Teuchos::RCP & invFactoryA, - const Teuchos::RCP & invFactoryS); - - ModALPreconditionerFactory(const Teuchos::RCP & factory, - LinearOp & pressureMassMatrix); - - ModALPreconditionerFactory(const Teuchos::RCP & invFactoryA, - const Teuchos::RCP & invFactoryS, - LinearOp & pressureMassMatrix); - - ModALPreconditionerFactory(const Teuchos::RCP & strategy); - - /** Set pressure mass matrix. - * - * \param[in] pressureMassMatrix - * Pressure mass matrix. - */ - void - setPressureMassMatrix(const LinearOp & pressureMassMatrix) - { - invOpsStrategy_->setPressureMassMatrix(pressureMassMatrix); - } - - /** Set the augmentation parameter gamma. - * - * \param[in] gamma - * Augmentation paramter. - */ - void - setGamma(double gamma) - { - invOpsStrategy_->setGamma(gamma); - } - - /** - * Build modified AL preconditioner. - * - * \param[in] alOp - * The AL operator. - * \param[in] state - * State object for storying reusable information about the AL operator. - */ - virtual LinearOp - buildPreconditionerOperator(BlockedLinearOp & alOp, - BlockPreconditionerState & state) const; - - /** - * Build the ModALPrecondState object. - */ - virtual Teuchos::RCP - buildPreconditionerState() const - { - return Teuchos::rcp(new ModALPrecondState()); - } - -protected: - using BlockPreconditionerFactory::buildPreconditionerOperator; - - Teuchos::RCP invOpsStrategy_; - - bool isSymmetric_; +class ModALPreconditionerFactory : public BlockPreconditionerFactory { + public: + ModALPreconditionerFactory(); + + ModALPreconditionerFactory(const Teuchos::RCP& factory); + + ModALPreconditionerFactory(const Teuchos::RCP& invFactoryA, + const Teuchos::RCP& invFactoryS); + + ModALPreconditionerFactory(const Teuchos::RCP& factory, + LinearOp& pressureMassMatrix); + + ModALPreconditionerFactory(const Teuchos::RCP& invFactoryA, + const Teuchos::RCP& invFactoryS, + LinearOp& pressureMassMatrix); + + ModALPreconditionerFactory(const Teuchos::RCP& strategy); + + /** Set pressure mass matrix. + * + * \param[in] pressureMassMatrix + * Pressure mass matrix. + */ + void setPressureMassMatrix(const LinearOp& pressureMassMatrix) { + invOpsStrategy_->setPressureMassMatrix(pressureMassMatrix); + } + + /** Set the augmentation parameter gamma. + * + * \param[in] gamma + * Augmentation paramter. + */ + void setGamma(double gamma) { invOpsStrategy_->setGamma(gamma); } + + /** + * Build modified AL preconditioner. + * + * \param[in] alOp + * The AL operator. + * \param[in] state + * State object for storying reusable information about the AL operator. + */ + virtual LinearOp buildPreconditionerOperator(BlockedLinearOp& alOp, + BlockPreconditionerState& state) const; + + /** + * Build the ModALPrecondState object. + */ + virtual Teuchos::RCP buildPreconditionerState() const { + return Teuchos::rcp(new ModALPrecondState()); + } + + protected: + using BlockPreconditionerFactory::buildPreconditionerOperator; + + Teuchos::RCP invOpsStrategy_; + + bool isSymmetric_; }; -} // end namespace NS +} // end namespace NS -} // end namespace Teko +} // end namespace Teko #endif /* __Teko_ModALPreconditionerFactory_hpp__ */ diff --git a/packages/teko/src/NS/Teko_NavierStokesPreconditioners.hpp b/packages/teko/src/NS/Teko_NavierStokesPreconditioners.hpp index e3f2f2fb4a06..aa21210303fd 100644 --- a/packages/teko/src/NS/Teko_NavierStokesPreconditioners.hpp +++ b/packages/teko/src/NS/Teko_NavierStokesPreconditioners.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ diff --git a/packages/teko/src/NS/Teko_PCDStrategy.cpp b/packages/teko/src/NS/Teko_PCDStrategy.cpp index a34568481b0e..039161523c03 100644 --- a/packages/teko/src/NS/Teko_PCDStrategy.cpp +++ b/packages/teko/src/NS/Teko_PCDStrategy.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -59,274 +59,271 @@ Teuchos::RCP PCDStrategy::invSTimer_; Teuchos::RCP PCDStrategy::invFTimer_; Teuchos::RCP PCDStrategy::opsTimer_; -void PCDStrategy::buildTimers() -{ - if(initTimer_==Teuchos::null) - initTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec"); +void PCDStrategy::buildTimers() { + if (initTimer_ == Teuchos::null) + initTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec"); - if(invSTimer_==Teuchos::null) - invSTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec invS"); + if (invSTimer_ == Teuchos::null) + invSTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec invS"); - if(invFTimer_==Teuchos::null) - invFTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec invF"); + if (invFTimer_ == Teuchos::null) + invFTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec invF"); - if(opsTimer_==Teuchos::null) - opsTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec buildOps"); + if (opsTimer_ == Teuchos::null) + opsTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec buildOps"); } -PCDStrategy::PCDStrategy() : massInverseType_(Diagonal), schurCompOrdering_(false) -{ - pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList); - lapParams_ = Teuchos::rcp(new Teuchos::ParameterList); +PCDStrategy::PCDStrategy() : massInverseType_(Diagonal), schurCompOrdering_(false) { + pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList); + lapParams_ = Teuchos::rcp(new Teuchos::ParameterList); - lapParams_->set("Name",getPressureLaplaceString()); - pcdParams_->set("Name",getPCDString()); + lapParams_->set("Name", getPressureLaplaceString()); + pcdParams_->set("Name", getPCDString()); - buildTimers(); + buildTimers(); } //! Constructor to set the inverse factories. -PCDStrategy::PCDStrategy(const Teuchos::RCP & invFA, - const Teuchos::RCP & invS) - : invFactoryF_(invFA), invFactoryS_(invS), massInverseType_(Diagonal), schurCompOrdering_(false) -{ - pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList); - lapParams_ = Teuchos::rcp(new Teuchos::ParameterList); - - lapParams_->set("Name",getPressureLaplaceString()); - pcdParams_->set("Name",getPCDString()); - - buildTimers(); +PCDStrategy::PCDStrategy(const Teuchos::RCP& invFA, + const Teuchos::RCP& invS) + : invFactoryF_(invFA), + invFactoryS_(invS), + massInverseType_(Diagonal), + schurCompOrdering_(false) { + pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList); + lapParams_ = Teuchos::rcp(new Teuchos::ParameterList); + + lapParams_->set("Name", getPressureLaplaceString()); + pcdParams_->set("Name", getPCDString()); + + buildTimers(); } /** returns the first (approximate) inverse of \f$A_{00}\f$ */ -const Teko::LinearOp -PCDStrategy::getHatInvA00(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - initializeState(A,state); +const Teko::LinearOp PCDStrategy::getHatInvA00(const Teko::BlockedLinearOp& A, + BlockPreconditionerState& state) const { + initializeState(A, state); - return state.getModifiableOp("invF"); + return state.getModifiableOp("invF"); } /** returns the second (approximate) inverse of \f$A_{00}\f$ */ -const Teko::LinearOp -PCDStrategy::getTildeInvA00(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - initializeState(A,state); +const Teko::LinearOp PCDStrategy::getTildeInvA00(const Teko::BlockedLinearOp& A, + BlockPreconditionerState& state) const { + initializeState(A, state); - return state.getModifiableOp("invF"); + return state.getModifiableOp("invF"); } -/** returns an (approximate) inverse of \f$S = -A_{11} + A_{10} \mbox{diag}(A_{00})^{-1} A_{01}\f$ */ -const Teko::LinearOp -PCDStrategy::getInvS(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - initializeState(A,state); +/** returns an (approximate) inverse of \f$S = -A_{11} + A_{10} \mbox{diag}(A_{00})^{-1} A_{01}\f$ + */ +const Teko::LinearOp PCDStrategy::getInvS(const Teko::BlockedLinearOp& A, + BlockPreconditionerState& state) const { + initializeState(A, state); - return state.getLinearOp("invS"); + return state.getLinearOp("invS"); } -void PCDStrategy::initializeState(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - Teko_DEBUG_SCOPE("PCDStrategy::initializeState",10); - TEUCHOS_ASSERT(getRequestHandler()!=Teuchos::null); - - std::string pcdStr = getPCDString(); - std::string presLapStr = getPressureLaplaceString(); - std::string presMassStr = getPressureMassString(); - - // no work to be done - if(state.isInitialized()) - return; - - Teuchos::TimeMonitor timer(*initTimer_,true); - - // extract sub blocks - LinearOp F = Teko::getBlock(0,0,A); - LinearOp Bt = Teko::getBlock(0,1,A); - LinearOp B = Teko::getBlock(1,0,A); - LinearOp C = Teko::getBlock(1,1,A); - - LinearOp Qp = getRequestHandler()->request(presMassStr); - TEUCHOS_ASSERT(Qp!=Teuchos::null); - - // build the inverse Laplacian complement - ///////////////////////////////////////////// - LinearOp iQp; - if(massInverseType_==NotDiag) { - ModifiableLinearOp & invMass = state.getModifiableOp("invMass"); - Teko_DEBUG_SCOPE("Building inv(Mass)",10); - - if(invMass==Teuchos::null) - invMass = buildInverse(*invFactoryS_,Qp); - else - rebuildInverse(*invFactoryS_,Qp,invMass); - - iQp = invMass; - } - else { - Teko_DEBUG_MSG("Building inverse mass of type \"" << Teko::getDiagonalName(massInverseType_) << "\"",10); - iQp = getInvDiagonalOp(Qp,massInverseType_); - } - - // build the inverse Laplacian complement - ///////////////////////////////////////////// - ModifiableLinearOp & invLaplace = state.getModifiableOp("invLaplace"); - { - Teuchos::TimeMonitor timerInvS(*invSTimer_,true); - - // LinearOp laplace = getRequestHandler()->request(presLapStr); - LinearOp laplace = getRequestHandler()->request(RequestMesg(lapParams_)); - TEUCHOS_ASSERT(laplace!=Teuchos::null); - if(invLaplace==Teuchos::null) - invLaplace = buildInverse(*invFactoryS_,laplace); - else - rebuildInverse(*invFactoryS_,laplace,invLaplace); - } - - // build the inverse Schur complement - ///////////////////////////////////////////// - { - Teko_DEBUG_SCOPE("Building S",10); - Teuchos::TimeMonitor timerS(*opsTimer_,true); - - // build Schur-complement - // LinearOp pcd = getRequestHandler()->request(pcdStr); - LinearOp pcd = getRequestHandler()->request(RequestMesg(pcdParams_)); - TEUCHOS_ASSERT(pcd!=Teuchos::null); - LinearOp invL = invLaplace; - - LinearOp invS; - if(schurCompOrdering_==false) - invS = multiply(iQp,pcd,invL); - else - invS = multiply(invL,pcd,iQp); - - state.addLinearOp("invS",invS); - } - - // build inverse F - ///////////////////////////////////////////// - { - Teko_DEBUG_SCOPE("Building inv(F)",10); - Teuchos::TimeMonitor timerInvF(*invFTimer_,true); - - ModifiableLinearOp & invF = state.getModifiableOp("invF"); - if(invF==Teuchos::null) - invF = buildInverse(*invFactoryF_,F); - else - rebuildInverse(*invFactoryF_,F,invF); - } - - // mark state as initialized - state.setInitialized(true); +void PCDStrategy::initializeState(const Teko::BlockedLinearOp& A, + BlockPreconditionerState& state) const { + Teko_DEBUG_SCOPE("PCDStrategy::initializeState", 10); + TEUCHOS_ASSERT(getRequestHandler() != Teuchos::null); + + std::string pcdStr = getPCDString(); + std::string presLapStr = getPressureLaplaceString(); + std::string presMassStr = getPressureMassString(); + + // no work to be done + if (state.isInitialized()) return; + + Teuchos::TimeMonitor timer(*initTimer_, true); + + // extract sub blocks + LinearOp F = Teko::getBlock(0, 0, A); + LinearOp Bt = Teko::getBlock(0, 1, A); + LinearOp B = Teko::getBlock(1, 0, A); + LinearOp C = Teko::getBlock(1, 1, A); + + LinearOp Qp = getRequestHandler()->request(presMassStr); + TEUCHOS_ASSERT(Qp != Teuchos::null); + + // build the inverse Laplacian complement + ///////////////////////////////////////////// + LinearOp iQp; + if (massInverseType_ == NotDiag) { + ModifiableLinearOp& invMass = state.getModifiableOp("invMass"); + Teko_DEBUG_SCOPE("Building inv(Mass)", 10); + + if (invMass == Teuchos::null) + invMass = buildInverse(*invFactoryS_, Qp); + else + rebuildInverse(*invFactoryS_, Qp, invMass); + + iQp = invMass; + } else { + Teko_DEBUG_MSG( + "Building inverse mass of type \"" << Teko::getDiagonalName(massInverseType_) << "\"", 10); + iQp = getInvDiagonalOp(Qp, massInverseType_); + } + + // build the inverse Laplacian complement + ///////////////////////////////////////////// + ModifiableLinearOp& invLaplace = state.getModifiableOp("invLaplace"); + { + Teuchos::TimeMonitor timerInvS(*invSTimer_, true); + + // LinearOp laplace = getRequestHandler()->request(presLapStr); + LinearOp laplace = getRequestHandler()->request(RequestMesg(lapParams_)); + TEUCHOS_ASSERT(laplace != Teuchos::null); + if (invLaplace == Teuchos::null) + invLaplace = buildInverse(*invFactoryS_, laplace); + else + rebuildInverse(*invFactoryS_, laplace, invLaplace); + } + + // build the inverse Schur complement + ///////////////////////////////////////////// + { + Teko_DEBUG_SCOPE("Building S", 10); + Teuchos::TimeMonitor timerS(*opsTimer_, true); + + // build Schur-complement + // LinearOp pcd = getRequestHandler()->request(pcdStr); + LinearOp pcd = getRequestHandler()->request(RequestMesg(pcdParams_)); + TEUCHOS_ASSERT(pcd != Teuchos::null); + LinearOp invL = invLaplace; + + LinearOp invS; + if (schurCompOrdering_ == false) + invS = multiply(iQp, pcd, invL); + else + invS = multiply(invL, pcd, iQp); + + state.addLinearOp("invS", invS); + } + + // build inverse F + ///////////////////////////////////////////// + { + Teko_DEBUG_SCOPE("Building inv(F)", 10); + Teuchos::TimeMonitor timerInvF(*invFTimer_, true); + + ModifiableLinearOp& invF = state.getModifiableOp("invF"); + if (invF == Teuchos::null) + invF = buildInverse(*invFactoryF_, F); + else + rebuildInverse(*invFactoryF_, F, invF); + } + + // mark state as initialized + state.setInitialized(true); } /** \brief This function builds the internals of the state from a parameter list. - * - * This function builds the internals of the LU 2x2 state - * from a parameter list. Furthermore, it allows a - * developer to easily add a factory to the build system. - * - * \param[in] settings Parameter list to use as the internal settings - * \param[in] invLib Inverse library to use for building inverse factory objects - * - * \note The default implementation does nothing. - */ -void PCDStrategy::initializeFromParameterList(const Teuchos::ParameterList & pl, - const InverseLibrary & invLib) -{ - Teko_DEBUG_SCOPE("PCDStrategy::initializeFromParameterList",10); - - std::string invStr="Amesos", invFStr="", invSStr=""; - massInverseType_ = Diagonal; - - // "parse" the parameter list - if(pl.isParameter("Inverse Type")) - invStr = pl.get("Inverse Type"); - if(pl.isParameter("Inverse F Type")) - invFStr = pl.get("Inverse F Type"); - if(pl.isParameter("Inverse Laplace Type")) - invSStr = pl.get("Inverse Laplace Type"); - if(pl.isParameter("Inverse Mass Type")) { - std::string massInverseStr = pl.get("Inverse Mass Type"); - - // build inverse types - massInverseType_ = getDiagonalType(massInverseStr); - } - if(pl.isParameter("Flip Schur Complement Ordering")) - schurCompOrdering_ = pl.get("Flip Schur Complement Ordering"); - - // set defaults as needed - if(invFStr=="") invFStr = invStr; - if(invSStr=="") invSStr = invStr; - - // read pressure laplace parameters - if(pl.isSublist("Pressure Laplace Parameters")) - lapParams_ = Teuchos::rcp(new Teuchos::ParameterList(pl.sublist("Pressure Laplace Parameters"))); - else - lapParams_ = Teuchos::rcp(new Teuchos::ParameterList); - - // read pcd operator parameters - if(pl.isSublist("Pressure Convection Diffusion Parameters")) - pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList(pl.sublist("Pressure Convection Diffusion Parameters"))); - else - pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList); - - // The user should not have already added this parameters - TEUCHOS_TEST_FOR_EXCEPTION(lapParams_->isParameter("Name"),std::logic_error, - "Teko: Parameter \"Name\" is not allowed in the sublist \""+lapParams_->name()+"\""); - TEUCHOS_TEST_FOR_EXCEPTION(lapParams_->isParameter("Tag"),std::logic_error, - "Teko: Parameter \"Tag\" is not allowed in the sublist \""+lapParams_->name()+"\""); - TEUCHOS_TEST_FOR_EXCEPTION(pcdParams_->isParameter("Name"),std::logic_error, - "Teko: Parameter \"Name\" is not allowed in the sublist \""+pcdParams_->name()+"\""); - TEUCHOS_TEST_FOR_EXCEPTION(pcdParams_->isParameter("Tag"),std::logic_error, - "Teko: Parameter \"Tag\" is not allowed in the sublist \""+pcdParams_->name()+"\""); - - Teko_DEBUG_MSG_BEGIN(5) - DEBUG_STREAM << "PCD Strategy Parameters: " << std::endl; - DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; - DEBUG_STREAM << " inv F type = \"" << invFStr << "\"" << std::endl; - DEBUG_STREAM << " inv Laplace type = \"" << invSStr << "\"" << std::endl; - DEBUG_STREAM << " inv Mass type = \"" << Teko::getDiagonalName(massInverseType_) << "\"" << std::endl; - DEBUG_STREAM << "PCD Strategy Parameter list: " << std::endl; - pl.print(DEBUG_STREAM); - Teko_DEBUG_MSG_END() - - // build velocity inverse factory - invFactoryF_ = invLib.getInverseFactory(invFStr); - - if(invFStr==invSStr) - invFactoryS_ = invFactoryF_; - else - invFactoryS_ = invLib.getInverseFactory(invSStr); - - lapParams_->set("Name",getPressureLaplaceString()); - pcdParams_->set("Name",getPCDString()); - - // setup a request for required operators - getRequestHandler()->preRequest(getPressureMassString()); - // getRequestHandler()->preRequest(getPCDString()); - // getRequestHandler()->preRequest(getPressureLaplaceString()); - getRequestHandler()->preRequest(Teko::RequestMesg(lapParams_)); - getRequestHandler()->preRequest(Teko::RequestMesg(pcdParams_)); + * + * This function builds the internals of the LU 2x2 state + * from a parameter list. Furthermore, it allows a + * developer to easily add a factory to the build system. + * + * \param[in] settings Parameter list to use as the internal settings + * \param[in] invLib Inverse library to use for building inverse factory objects + * + * \note The default implementation does nothing. + */ +void PCDStrategy::initializeFromParameterList(const Teuchos::ParameterList& pl, + const InverseLibrary& invLib) { + Teko_DEBUG_SCOPE("PCDStrategy::initializeFromParameterList", 10); + + std::string invStr = "Amesos", invFStr = "", invSStr = ""; + massInverseType_ = Diagonal; + + // "parse" the parameter list + if (pl.isParameter("Inverse Type")) invStr = pl.get("Inverse Type"); + if (pl.isParameter("Inverse F Type")) invFStr = pl.get("Inverse F Type"); + if (pl.isParameter("Inverse Laplace Type")) invSStr = pl.get("Inverse Laplace Type"); + if (pl.isParameter("Inverse Mass Type")) { + std::string massInverseStr = pl.get("Inverse Mass Type"); + + // build inverse types + massInverseType_ = getDiagonalType(massInverseStr); + } + if (pl.isParameter("Flip Schur Complement Ordering")) + schurCompOrdering_ = pl.get("Flip Schur Complement Ordering"); + + // set defaults as needed + if (invFStr == "") invFStr = invStr; + if (invSStr == "") invSStr = invStr; + + // read pressure laplace parameters + if (pl.isSublist("Pressure Laplace Parameters")) + lapParams_ = + Teuchos::rcp(new Teuchos::ParameterList(pl.sublist("Pressure Laplace Parameters"))); + else + lapParams_ = Teuchos::rcp(new Teuchos::ParameterList); + + // read pcd operator parameters + if (pl.isSublist("Pressure Convection Diffusion Parameters")) + pcdParams_ = Teuchos::rcp( + new Teuchos::ParameterList(pl.sublist("Pressure Convection Diffusion Parameters"))); + else + pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList); + + // The user should not have already added this parameters + TEUCHOS_TEST_FOR_EXCEPTION( + lapParams_->isParameter("Name"), std::logic_error, + "Teko: Parameter \"Name\" is not allowed in the sublist \"" + lapParams_->name() + "\""); + TEUCHOS_TEST_FOR_EXCEPTION( + lapParams_->isParameter("Tag"), std::logic_error, + "Teko: Parameter \"Tag\" is not allowed in the sublist \"" + lapParams_->name() + "\""); + TEUCHOS_TEST_FOR_EXCEPTION( + pcdParams_->isParameter("Name"), std::logic_error, + "Teko: Parameter \"Name\" is not allowed in the sublist \"" + pcdParams_->name() + "\""); + TEUCHOS_TEST_FOR_EXCEPTION( + pcdParams_->isParameter("Tag"), std::logic_error, + "Teko: Parameter \"Tag\" is not allowed in the sublist \"" + pcdParams_->name() + "\""); + + Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "PCD Strategy Parameters: " << std::endl; + DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; + DEBUG_STREAM << " inv F type = \"" << invFStr << "\"" << std::endl; + DEBUG_STREAM << " inv Laplace type = \"" << invSStr << "\"" << std::endl; + DEBUG_STREAM << " inv Mass type = \"" << Teko::getDiagonalName(massInverseType_) << "\"" + << std::endl; + DEBUG_STREAM << "PCD Strategy Parameter list: " << std::endl; + pl.print(DEBUG_STREAM); + Teko_DEBUG_MSG_END() + + // build velocity inverse factory + invFactoryF_ = invLib.getInverseFactory(invFStr); + + if (invFStr == invSStr) + invFactoryS_ = invFactoryF_; + else + invFactoryS_ = invLib.getInverseFactory(invSStr); + + lapParams_->set("Name", getPressureLaplaceString()); + pcdParams_->set("Name", getPCDString()); + + // setup a request for required operators + getRequestHandler()->preRequest(getPressureMassString()); + // getRequestHandler()->preRequest(getPCDString()); + // getRequestHandler()->preRequest(getPressureLaplaceString()); + getRequestHandler()->preRequest(Teko::RequestMesg(lapParams_)); + getRequestHandler()->preRequest(Teko::RequestMesg(pcdParams_)); } //! For assiting in construction of the preconditioner -Teuchos::RCP PCDStrategy::getRequestedParameters() const -{ - TEUCHOS_ASSERT(false); +Teuchos::RCP PCDStrategy::getRequestedParameters() const { + TEUCHOS_ASSERT(false); - return Teuchos::null; + return Teuchos::null; } //! For assiting in construction of the preconditioner -bool PCDStrategy::updateRequestedParameters(const Teuchos::ParameterList & /* pl */) -{ - TEUCHOS_ASSERT(false); +bool PCDStrategy::updateRequestedParameters(const Teuchos::ParameterList& /* pl */) { + TEUCHOS_ASSERT(false); - return true; + return true; } -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_PCDStrategy.hpp b/packages/teko/src/NS/Teko_PCDStrategy.hpp index 69bb9f9220b9..6395b085d6d2 100644 --- a/packages/teko/src/NS/Teko_PCDStrategy.hpp +++ b/packages/teko/src/NS/Teko_PCDStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -55,138 +55,138 @@ namespace Teko { namespace NS { -/** @brief Strategy for computing implementation of the +/** @brief Strategy for computing implementation of the * Pressure convection diffusion preconditioner. * - * This requires the user to add a "PCD Operator", + * This requires the user to add a "PCD Operator", * "Pressure Laplace Operator" and "Press Mass Operators" * into the preconditioner state. The user is notified by * boolean fields returned from the requested paramters list. */ class PCDStrategy : public LU2x2Strategy { -public: - //! default Constructor - PCDStrategy(); - - //! Constructor to set the inverse factories. - PCDStrategy(const Teuchos::RCP & invFA, - const Teuchos::RCP & invS); - - //! Destructor (does nothing) - virtual ~PCDStrategy() {} - - /** returns the first (approximate) inverse of \f$A_{00}\f$ */ - virtual const Teko::LinearOp - getHatInvA00(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** returns the second (approximate) inverse of \f$A_{00}\f$ */ - virtual const Teko::LinearOp - getTildeInvA00(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** returns an (approximate) inverse of \f$S = -A_{11} + A_{10} \mbox{diag}(A_{00})^{-1} A_{01}\f$ */ - virtual const Teko::LinearOp - getInvS(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** \brief This function builds the internals of the state from a parameter list. - * - * \param[in] settings Parameter list to use as the internal settings - * \param[in] invLib Inverse library to use for building inverse factory objects - * - * \note The default implementation does nothing. - */ - virtual void initializeFromParameterList(const Teuchos::ParameterList & settings, - const InverseLibrary & invLib); - - /** \brief Request the additional parameters this preconditioner factory - * needs. - * - * Request the additonal parameters needed by this preconditioner factory. - * The parameter list will have a set of fields that can be filled with - * the requested values. These fields include all requirements, even those - * of the sub-solvers if there are any. Once correctly filled the object - * can be updated by calling the updateRequestedParameters with the filled - * parameter list. - * - * For the PCD strategy the following fields are required to be set to - * true, they are passed to the user as false. The user acknowledges that - * the operators are required by updating the parameters to true. - *
    - *
  • - *
  • - *
  • - *
- * - * \returns A parameter list with the requested parameters. - * - * \note The default implementation returns Teuchos::null. - */ - virtual Teuchos::RCP getRequestedParameters() const; - - /** \brief Update this object with the fields from a parameter list. - * - * Update the requested fields using a parameter list. This method is - * expected to pair with the getRequestedParameters method (i.e. the fields - * requested are going to be update using this method). - * - * For the PCD strategy the following fields are required to be set to - * true. Essentially, the user is acknowledging that the operators are - * required. - *
    - *
  • - *
  • - *
  • - *
- * - * \param[in] pl Parameter list containing the requested parameters. - * - * \returns If the method succeeded (found all its required parameters) this - * method returns true, otherwise it returns false. - * - * \note The default implementation returns true (it does nothing!). - */ - virtual bool updateRequestedParameters(const Teuchos::ParameterList & pl); - -protected: - /** Build timers for this type of object. - */ - static void buildTimers(); - - /** Initialize the operator's state. This builds the Schur complement and the inverse - * operators. If the state has already been initialized this method does nothing. - * - * \param[in] A Operator to intialize with. - * \param[in] state Storage object for this operator. - */ - void initializeState(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const; - - // how to invert the matrices - Teuchos::RCP invFactoryF_; // for \tilde{A_00}\f$ - Teuchos::RCP invFactoryS_; - - DiagonalType massInverseType_; - - //! Passed to application for construction of laplace operator - Teuchos::RCP lapParams_; - - //! Passed to application for construction of PCD operator - Teuchos::RCP pcdParams_; - - bool schurCompOrdering_; - - static Teuchos::RCP initTimer_; - static Teuchos::RCP invSTimer_; - static Teuchos::RCP invFTimer_; - static Teuchos::RCP opsTimer_; - -public: - // some static functions for determining strings - - static std::string getPCDString() { return "PCD Operator"; } - static std::string getPressureLaplaceString() { return "Pressure Laplace Operator"; } - static std::string getPressureMassString() { return "Pressure Mass Matrix"; } + public: + //! default Constructor + PCDStrategy(); + + //! Constructor to set the inverse factories. + PCDStrategy(const Teuchos::RCP& invFA, const Teuchos::RCP& invS); + + //! Destructor (does nothing) + virtual ~PCDStrategy() {} + + /** returns the first (approximate) inverse of \f$A_{00}\f$ */ + virtual const Teko::LinearOp getHatInvA00(const Teko::BlockedLinearOp& A, + BlockPreconditionerState& state) const; + + /** returns the second (approximate) inverse of \f$A_{00}\f$ */ + virtual const Teko::LinearOp getTildeInvA00(const Teko::BlockedLinearOp& A, + BlockPreconditionerState& state) const; + + /** returns an (approximate) inverse of \f$S = -A_{11} + A_{10} \mbox{diag}(A_{00})^{-1} A_{01}\f$ + */ + virtual const Teko::LinearOp getInvS(const Teko::BlockedLinearOp& A, + BlockPreconditionerState& state) const; + + /** \brief This function builds the internals of the state from a parameter list. + * + * \param[in] settings Parameter list to use as the internal settings + * \param[in] invLib Inverse library to use for building inverse factory objects + * + * \note The default implementation does nothing. + */ + virtual void initializeFromParameterList(const Teuchos::ParameterList& settings, + const InverseLibrary& invLib); + + /** \brief Request the additional parameters this preconditioner factory + * needs. + * + * Request the additonal parameters needed by this preconditioner factory. + * The parameter list will have a set of fields that can be filled with + * the requested values. These fields include all requirements, even those + * of the sub-solvers if there are any. Once correctly filled the object + * can be updated by calling the updateRequestedParameters with the filled + * parameter list. + * + * For the PCD strategy the following fields are required to be set to + * true, they are passed to the user as false. The user acknowledges that + * the operators are required by updating the parameters to true. + *
    + *
  • + *
  • + *
  • + *
+ * + * \returns A parameter list with the requested parameters. + * + * \note The default implementation returns Teuchos::null. + */ + virtual Teuchos::RCP getRequestedParameters() const; + + /** \brief Update this object with the fields from a parameter list. + * + * Update the requested fields using a parameter list. This method is + * expected to pair with the getRequestedParameters method (i.e. the fields + * requested are going to be update using this method). + * + * For the PCD strategy the following fields are required to be set to + * true. Essentially, the user is acknowledging that the operators are + * required. + *
    + *
  • + *
  • + *
  • + *
+ * + * \param[in] pl Parameter list containing the requested parameters. + * + * \returns If the method succeeded (found all its required parameters) this + * method returns true, otherwise it returns false. + * + * \note The default implementation returns true (it does nothing!). + */ + virtual bool updateRequestedParameters(const Teuchos::ParameterList& pl); + + protected: + /** Build timers for this type of object. + */ + static void buildTimers(); + + /** Initialize the operator's state. This builds the Schur complement and the inverse + * operators. If the state has already been initialized this method does nothing. + * + * \param[in] A Operator to intialize with. + * \param[in] state Storage object for this operator. + */ + void initializeState(const Teko::BlockedLinearOp& A, BlockPreconditionerState& state) const; + + // how to invert the matrices + Teuchos::RCP invFactoryF_; // for \tilde{A_00}\f$ + Teuchos::RCP invFactoryS_; + + DiagonalType massInverseType_; + + //! Passed to application for construction of laplace operator + Teuchos::RCP lapParams_; + + //! Passed to application for construction of PCD operator + Teuchos::RCP pcdParams_; + + bool schurCompOrdering_; + + static Teuchos::RCP initTimer_; + static Teuchos::RCP invSTimer_; + static Teuchos::RCP invFTimer_; + static Teuchos::RCP opsTimer_; + + public: + // some static functions for determining strings + + static std::string getPCDString() { return "PCD Operator"; } + static std::string getPressureLaplaceString() { return "Pressure Laplace Operator"; } + static std::string getPressureMassString() { return "Pressure Mass Matrix"; } }; -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_PresLaplaceLSCStrategy.cpp b/packages/teko/src/NS/Teko_PresLaplaceLSCStrategy.cpp index 005becc3b5ac..65166f6e2a10 100644 --- a/packages/teko/src/NS/Teko_PresLaplaceLSCStrategy.cpp +++ b/packages/teko/src/NS/Teko_PresLaplaceLSCStrategy.cpp @@ -56,8 +56,8 @@ #include "NS/Teko_LSCPreconditionerFactory.hpp" using Teuchos::RCP; -using Teuchos::rcp_dynamic_cast; using Teuchos::rcp_const_cast; +using Teuchos::rcp_dynamic_cast; namespace Teko { namespace NS { @@ -69,322 +69,327 @@ namespace NS { // constructors ///////////////////////////////////////////////////////////////////////////// PresLaplaceLSCStrategy::PresLaplaceLSCStrategy() - : invFactoryV_(Teuchos::null), invFactoryP_(Teuchos::null) - , eigSolveParam_(5), useFullLDU_(false), useMass_(false), scaleType_(AbsRowSum) -{ } - -PresLaplaceLSCStrategy::PresLaplaceLSCStrategy(const Teuchos::RCP & factory) - : invFactoryV_(factory), invFactoryP_(factory) - , eigSolveParam_(5), useFullLDU_(false), useMass_(false), scaleType_(AbsRowSum) -{ } - -PresLaplaceLSCStrategy::PresLaplaceLSCStrategy(const Teuchos::RCP & invFactF, - const Teuchos::RCP & invFactS) - : invFactoryV_(invFactF), invFactoryP_(invFactS) - , eigSolveParam_(5), useFullLDU_(false), useMass_(false), scaleType_(AbsRowSum) -{ } + : invFactoryV_(Teuchos::null), + invFactoryP_(Teuchos::null), + eigSolveParam_(5), + useFullLDU_(false), + useMass_(false), + scaleType_(AbsRowSum) {} + +PresLaplaceLSCStrategy::PresLaplaceLSCStrategy(const Teuchos::RCP& factory) + : invFactoryV_(factory), + invFactoryP_(factory), + eigSolveParam_(5), + useFullLDU_(false), + useMass_(false), + scaleType_(AbsRowSum) {} + +PresLaplaceLSCStrategy::PresLaplaceLSCStrategy(const Teuchos::RCP& invFactF, + const Teuchos::RCP& invFactS) + : invFactoryV_(invFactF), + invFactoryP_(invFactS), + eigSolveParam_(5), + useFullLDU_(false), + useMass_(false), + scaleType_(AbsRowSum) {} ///////////////////////////////////////////////////////////////////////////// -void PresLaplaceLSCStrategy::buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::buildState",10); +void PresLaplaceLSCStrategy::buildState(BlockedLinearOp& A, BlockPreconditionerState& state) const { + Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::buildState", 10); - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); - // if neccessary save state information - if(not lscState->isInitialized()) { - Teko_DEBUG_EXPR(Teuchos::Time timer("")); + // if neccessary save state information + if (not lscState->isInitialized()) { + Teko_DEBUG_EXPR(Teuchos::Time timer("")); - // construct operators - { - Teko_DEBUG_SCOPE("PL-LSC::buildState constructing operators",1); - Teko_DEBUG_EXPR(timer.start(true)); + // construct operators + { + Teko_DEBUG_SCOPE("PL-LSC::buildState constructing operators", 1); + Teko_DEBUG_EXPR(timer.start(true)); - initializeState(A,lscState); + initializeState(A, lscState); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("PL-LSC::buildState BuildOpsTime = " << timer.totalElapsedTime(),1); - } + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("PL-LSC::buildState BuildOpsTime = " << timer.totalElapsedTime(), 1); + } - // Build the inverses - { - Teko_DEBUG_SCOPE("PL-LSC::buildState calculating inverses",1); - Teko_DEBUG_EXPR(timer.start(true)); + // Build the inverses + { + Teko_DEBUG_SCOPE("PL-LSC::buildState calculating inverses", 1); + Teko_DEBUG_EXPR(timer.start(true)); - computeInverses(A,lscState); + computeInverses(A, lscState); - Teko_DEBUG_EXPR(timer.stop()); - Teko_DEBUG_MSG("PL-LSC::buildState BuildInvTime = " << timer.totalElapsedTime(),1); - } - } + Teko_DEBUG_EXPR(timer.stop()); + Teko_DEBUG_MSG("PL-LSC::buildState BuildInvTime = " << timer.totalElapsedTime(), 1); + } + } } // functions inherited from LSCStrategy -LinearOp PresLaplaceLSCStrategy::getInvBQBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getModifiableOp("invPresLap"); +LinearOp PresLaplaceLSCStrategy::getInvBQBt(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getModifiableOp("invPresLap"); } -LinearOp PresLaplaceLSCStrategy::getInvBHBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getModifiableOp("invPresLap"); +LinearOp PresLaplaceLSCStrategy::getInvBHBt(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getModifiableOp("invPresLap"); } -LinearOp PresLaplaceLSCStrategy::getInvF(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - return state.getModifiableOp("invF"); +LinearOp PresLaplaceLSCStrategy::getInvF(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + return state.getModifiableOp("invF"); } -// LinearOp PresLaplaceLSCStrategy::getInvAlphaD(const BlockedLinearOp & A,BlockPreconditionerState & state) const -LinearOp PresLaplaceLSCStrategy::getOuterStabilization(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); - TEUCHOS_ASSERT(lscState->isInitialized()) +// LinearOp PresLaplaceLSCStrategy::getInvAlphaD(const BlockedLinearOp & A,BlockPreconditionerState +// & state) const +LinearOp PresLaplaceLSCStrategy::getOuterStabilization(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); + TEUCHOS_ASSERT(lscState->isInitialized()) - return lscState->aiD_; + return lscState->aiD_; } -LinearOp PresLaplaceLSCStrategy::getInvMass(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const -{ - LSCPrecondState * lscState = dynamic_cast(&state); - TEUCHOS_ASSERT(lscState!=0); - TEUCHOS_ASSERT(lscState->isInitialized()) +LinearOp PresLaplaceLSCStrategy::getInvMass(const BlockedLinearOp& /* A */, + BlockPreconditionerState& state) const { + LSCPrecondState* lscState = dynamic_cast(&state); + TEUCHOS_ASSERT(lscState != 0); + TEUCHOS_ASSERT(lscState->isInitialized()) - return lscState->invMass_; + return lscState->invMass_; } -LinearOp PresLaplaceLSCStrategy::getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const -{ - return getInvMass(A,state); +LinearOp PresLaplaceLSCStrategy::getHScaling(const BlockedLinearOp& A, + BlockPreconditionerState& state) const { + return getInvMass(A, state); } //! Initialize the state object using this blocked linear operator -void PresLaplaceLSCStrategy::initializeState(const BlockedLinearOp & A,LSCPrecondState * state) const -{ - Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::initializeState",10); - - std::string velMassStr = getVelocityMassString(); - - const LinearOp F = getBlock(0,0,A); - const LinearOp Bt = getBlock(0,1,A); - const LinearOp B = getBlock(1,0,A); - const LinearOp C = getBlock(1,1,A); - - LinearOp D = B; - LinearOp G = Bt; - - bool isStabilized = (not isZeroOp(C)); - - // grab operators from state object - LinearOp massMatrix = state->getLinearOp(velMassStr); - - // The logic follows like this - // if there is no mass matrix available --> build from F - // if there is a mass matrix and the inverse hasn't yet been built - // --> build from the mass matrix - // otherwise, there is already an invMass_ matrix that is appropriate - // --> use that one - if(massMatrix==Teuchos::null) { - Teko_DEBUG_MSG("PL-LSC::initializeState Build Scaling type \"" - << getDiagonalName(scaleType_) << "\"" ,1); - state->invMass_ = getInvDiagonalOp(F,scaleType_); - } - else if(state->invMass_==Teuchos::null) { - Teko_DEBUG_MSG("PL-LSC::initializeState Build Scaling type \"" - << getDiagonalName(scaleType_) << "\"" ,1); - state->invMass_ = getInvDiagonalOp(massMatrix,scaleType_); - } - // else "invMass_" should be set and there is no reason to rebuild it - - // if this is a stable discretization...we are done! - if(not isStabilized) { - state->aiD_ = Teuchos::null; +void PresLaplaceLSCStrategy::initializeState(const BlockedLinearOp& A, + LSCPrecondState* state) const { + Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::initializeState", 10); + + std::string velMassStr = getVelocityMassString(); + + const LinearOp F = getBlock(0, 0, A); + const LinearOp Bt = getBlock(0, 1, A); + const LinearOp B = getBlock(1, 0, A); + const LinearOp C = getBlock(1, 1, A); + + LinearOp D = B; + LinearOp G = Bt; + + bool isStabilized = (not isZeroOp(C)); + + // grab operators from state object + LinearOp massMatrix = state->getLinearOp(velMassStr); + + // The logic follows like this + // if there is no mass matrix available --> build from F + // if there is a mass matrix and the inverse hasn't yet been built + // --> build from the mass matrix + // otherwise, there is already an invMass_ matrix that is appropriate + // --> use that one + if (massMatrix == Teuchos::null) { + Teko_DEBUG_MSG( + "PL-LSC::initializeState Build Scaling type \"" << getDiagonalName(scaleType_) << "\"", + 1); + state->invMass_ = getInvDiagonalOp(F, scaleType_); + } else if (state->invMass_ == Teuchos::null) { + Teko_DEBUG_MSG("PL-LSC::initializeState Build Scaling type \"" + << getDiagonalName(scaleType_) << "\"", + 1); + state->invMass_ = getInvDiagonalOp(massMatrix, scaleType_); + } + // else "invMass_" should be set and there is no reason to rebuild it + + // if this is a stable discretization...we are done! + if (not isStabilized) { + state->aiD_ = Teuchos::null; + + state->setInitialized(true); + + return; + } + + // compute alpha scaled inv(D): EHSST2007 Eq. 4.29 + // construct B_idF_Bt and save it for refilling later: This could reuse BQBt graph + LinearOp invDiagF = getInvDiagonalOp(F); + Teko::ModifiableLinearOp& modB_idF_Bt = state->getModifiableOp("BidFBt"); + modB_idF_Bt = explicitMultiply(B, invDiagF, Bt, modB_idF_Bt); + const LinearOp B_idF_Bt = modB_idF_Bt; + + MultiVector vec_D = getDiagonal(B_idF_Bt); // this memory could be reused + update(-1.0, getDiagonal(C), 1.0, vec_D); // vec_D = diag(B*inv(diag(F))*Bt)-diag(C) + const LinearOp invD = buildInvDiagonal(vec_D, "inv(D)"); + + Teko_DEBUG_MSG("Calculating alpha", 10); + const LinearOp BidFBtidD = multiply(B_idF_Bt, invD); + double num = std::fabs(Teko::computeSpectralRad(BidFBtidD, 5e-2, false, eigSolveParam_)); + Teko_DEBUG_MSG("Calculated alpha", 10); + state->alpha_ = 1.0 / num; + state->aiD_ = Thyra::scale(state->alpha_, invD); + + Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "PL-LSC Alpha Parameter = " << state->alpha_ << std::endl; + Teko_DEBUG_MSG_END() state->setInitialized(true); - - return; - } - - // compute alpha scaled inv(D): EHSST2007 Eq. 4.29 - // construct B_idF_Bt and save it for refilling later: This could reuse BQBt graph - LinearOp invDiagF = getInvDiagonalOp(F); - Teko::ModifiableLinearOp & modB_idF_Bt = state->getModifiableOp("BidFBt"); - modB_idF_Bt = explicitMultiply(B,invDiagF,Bt,modB_idF_Bt); - const LinearOp B_idF_Bt = modB_idF_Bt; - - MultiVector vec_D = getDiagonal(B_idF_Bt); // this memory could be reused - update(-1.0,getDiagonal(C),1.0,vec_D); // vec_D = diag(B*inv(diag(F))*Bt)-diag(C) - const LinearOp invD = buildInvDiagonal(vec_D,"inv(D)"); - - Teko_DEBUG_MSG("Calculating alpha",10); - const LinearOp BidFBtidD = multiply(B_idF_Bt,invD); - double num = std::fabs(Teko::computeSpectralRad(BidFBtidD,5e-2,false,eigSolveParam_)); - Teko_DEBUG_MSG("Calculated alpha",10); - state->alpha_ = 1.0/num; - state->aiD_ = Thyra::scale(state->alpha_,invD); - - Teko_DEBUG_MSG_BEGIN(5) - DEBUG_STREAM << "PL-LSC Alpha Parameter = " << state->alpha_ << std::endl; - Teko_DEBUG_MSG_END() - - state->setInitialized(true); } /** Compute the inverses required for the LSC Schur complement - * - * \note This method assumes that the BQBt and BHBt operators have - * been constructed. - */ -void PresLaplaceLSCStrategy::computeInverses(const BlockedLinearOp & A,LSCPrecondState * state) const -{ - Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::computeInverses",10); - Teko_DEBUG_EXPR(Teuchos::Time invTimer("")); - - std::string presLapStr = getPressureLaplaceString(); - - const LinearOp F = getBlock(0,0,A); - const LinearOp presLap = state->getLinearOp(presLapStr); - - ///////////////////////////////////////////////////////// - - // (re)build the inverse of F - Teko_DEBUG_MSG("PL-LSC::computeInverses Building inv(F)",1); - Teko_DEBUG_EXPR(invTimer.start(true)); - ModifiableLinearOp & invF = state->getModifiableOp("invF"); - if(invF==Teuchos::null) { - invF = buildInverse(*invFactoryV_,F); - } else { - rebuildInverse(*invFactoryV_,F,invF); - } - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("PL-LSC::computeInverses GetInvF = " << invTimer.totalElapsedTime(),1); - - ///////////////////////////////////////////////////////// - - // (re)build the inverse of P - Teko_DEBUG_MSG("PL-LSC::computeInverses Building inv(PresLap)",1); - Teko_DEBUG_EXPR(invTimer.start(true)); - ModifiableLinearOp & invPresLap = state->getModifiableOp("invPresLap"); - if(invPresLap==Teuchos::null) { - invPresLap = buildInverse(*invFactoryP_,presLap); - } else { - // not need because the pressure laplacian never changes - // rebuildInverse(*invFactoryP_,presLap,invPresLap); - } - Teko_DEBUG_EXPR(invTimer.stop()); - Teko_DEBUG_MSG("PL-LSC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(),1); + * + * \note This method assumes that the BQBt and BHBt operators have + * been constructed. + */ +void PresLaplaceLSCStrategy::computeInverses(const BlockedLinearOp& A, + LSCPrecondState* state) const { + Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::computeInverses", 10); + Teko_DEBUG_EXPR(Teuchos::Time invTimer("")); + + std::string presLapStr = getPressureLaplaceString(); + + const LinearOp F = getBlock(0, 0, A); + const LinearOp presLap = state->getLinearOp(presLapStr); + + ///////////////////////////////////////////////////////// + + // (re)build the inverse of F + Teko_DEBUG_MSG("PL-LSC::computeInverses Building inv(F)", 1); + Teko_DEBUG_EXPR(invTimer.start(true)); + ModifiableLinearOp& invF = state->getModifiableOp("invF"); + if (invF == Teuchos::null) { + invF = buildInverse(*invFactoryV_, F); + } else { + rebuildInverse(*invFactoryV_, F, invF); + } + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("PL-LSC::computeInverses GetInvF = " << invTimer.totalElapsedTime(), 1); + + ///////////////////////////////////////////////////////// + + // (re)build the inverse of P + Teko_DEBUG_MSG("PL-LSC::computeInverses Building inv(PresLap)", 1); + Teko_DEBUG_EXPR(invTimer.start(true)); + ModifiableLinearOp& invPresLap = state->getModifiableOp("invPresLap"); + if (invPresLap == Teuchos::null) { + invPresLap = buildInverse(*invFactoryP_, presLap); + } else { + // not need because the pressure laplacian never changes + // rebuildInverse(*invFactoryP_,presLap,invPresLap); + } + Teko_DEBUG_EXPR(invTimer.stop()); + Teko_DEBUG_MSG("PL-LSC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(), 1); } //! Initialize from a parameter list -void PresLaplaceLSCStrategy::initializeFromParameterList(const Teuchos::ParameterList & pl,const InverseLibrary & invLib) -{ - // get string specifying inverse - std::string invStr="Amesos", invVStr="", invPStr=""; - bool useLDU = false; - scaleType_ = AbsRowSum; - - // "parse" the parameter list - if(pl.isParameter("Inverse Type")) - invStr = pl.get("Inverse Type"); - if(pl.isParameter("Inverse Velocity Type")) - invVStr = pl.get("Inverse Velocity Type"); - if(pl.isParameter("Inverse Pressure Type")) - invPStr = pl.get("Inverse Pressure Type"); - if(pl.isParameter("Use LDU")) - useLDU = pl.get("Use LDU"); - if(pl.isParameter("Use Mass Scaling")) - useMass_ = pl.get("Use Mass Scaling"); - if(pl.isParameter("Eigen Solver Iterations")) - eigSolveParam_ = pl.get("Eigen Solver Iterations"); - if(pl.isParameter("Scaling Type")) { - scaleType_ = getDiagonalType(pl.get("Scaling Type")); - TEUCHOS_TEST_FOR_EXCEPT(scaleType_==NotDiag); - } - - // set defaults as needed - if(invVStr=="") invVStr = invStr; - if(invPStr=="") invPStr = invStr; - - Teko_DEBUG_MSG_BEGIN(5) - DEBUG_STREAM << "LSC Inverse Strategy Parameters: " << std::endl; - DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; - DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; - DEBUG_STREAM << " use ldu = " << useLDU << std::endl; - DEBUG_STREAM << " use mass = " << useMass_ << std::endl; - DEBUG_STREAM << " scale type = " << getDiagonalName(scaleType_) << std::endl; - DEBUG_STREAM << "LSC Pressure Laplace Strategy Parameter list: " << std::endl; - pl.print(DEBUG_STREAM); - Teko_DEBUG_MSG_END() - - // build velocity inverse factory - invFactoryV_ = invLib.getInverseFactory(invVStr); - invFactoryP_ = invFactoryV_; // by default these are the same - if(invVStr!=invPStr) // if different, build pressure inverse factory - invFactoryP_ = invLib.getInverseFactory(invPStr); - - // set other parameters - setUseFullLDU(useLDU); +void PresLaplaceLSCStrategy::initializeFromParameterList(const Teuchos::ParameterList& pl, + const InverseLibrary& invLib) { + // get string specifying inverse + std::string invStr = "Amesos", invVStr = "", invPStr = ""; + bool useLDU = false; + scaleType_ = AbsRowSum; + + // "parse" the parameter list + if (pl.isParameter("Inverse Type")) invStr = pl.get("Inverse Type"); + if (pl.isParameter("Inverse Velocity Type")) + invVStr = pl.get("Inverse Velocity Type"); + if (pl.isParameter("Inverse Pressure Type")) + invPStr = pl.get("Inverse Pressure Type"); + if (pl.isParameter("Use LDU")) useLDU = pl.get("Use LDU"); + if (pl.isParameter("Use Mass Scaling")) useMass_ = pl.get("Use Mass Scaling"); + if (pl.isParameter("Eigen Solver Iterations")) + eigSolveParam_ = pl.get("Eigen Solver Iterations"); + if (pl.isParameter("Scaling Type")) { + scaleType_ = getDiagonalType(pl.get("Scaling Type")); + TEUCHOS_TEST_FOR_EXCEPT(scaleType_ == NotDiag); + } + + // set defaults as needed + if (invVStr == "") invVStr = invStr; + if (invPStr == "") invPStr = invStr; + + Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "LSC Inverse Strategy Parameters: " << std::endl; + DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; + DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; + DEBUG_STREAM << " use ldu = " << useLDU << std::endl; + DEBUG_STREAM << " use mass = " << useMass_ << std::endl; + DEBUG_STREAM << " scale type = " << getDiagonalName(scaleType_) << std::endl; + DEBUG_STREAM << "LSC Pressure Laplace Strategy Parameter list: " << std::endl; + pl.print(DEBUG_STREAM); + Teko_DEBUG_MSG_END() + + // build velocity inverse factory + invFactoryV_ = invLib.getInverseFactory(invVStr); + invFactoryP_ = invFactoryV_; // by default these are the same + if (invVStr != invPStr) // if different, build pressure inverse factory + invFactoryP_ = invLib.getInverseFactory(invPStr); + + // set other parameters + setUseFullLDU(useLDU); } //! For assiting in construction of the preconditioner -Teuchos::RCP PresLaplaceLSCStrategy::getRequestedParameters() const -{ - Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::getRequestedParameters",10); - Teuchos::RCP pl = rcp(new Teuchos::ParameterList()); - - // grab parameters from F solver - RCP fList = invFactoryV_->getRequestedParameters(); - if(fList!=Teuchos::null) { - Teuchos::ParameterList::ConstIterator itr; - for(itr=fList->begin();itr!=fList->end();++itr) - pl->setEntry(itr->first,itr->second); - } - - // grab parameters from S solver - RCP sList = invFactoryP_->getRequestedParameters(); - if(sList!=Teuchos::null) { - Teuchos::ParameterList::ConstIterator itr; - for(itr=sList->begin();itr!=sList->end();++itr) - pl->setEntry(itr->first,itr->second); - } - - // use the mass matrix - if(useMass_) - pl->set(getVelocityMassString(), false,"Velocity mass matrix"); - pl->set(getPressureLaplaceString(), false,"Pressure Laplacian matrix"); - - return pl; +Teuchos::RCP PresLaplaceLSCStrategy::getRequestedParameters() const { + Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::getRequestedParameters", 10); + Teuchos::RCP pl = rcp(new Teuchos::ParameterList()); + + // grab parameters from F solver + RCP fList = invFactoryV_->getRequestedParameters(); + if (fList != Teuchos::null) { + Teuchos::ParameterList::ConstIterator itr; + for (itr = fList->begin(); itr != fList->end(); ++itr) pl->setEntry(itr->first, itr->second); + } + + // grab parameters from S solver + RCP sList = invFactoryP_->getRequestedParameters(); + if (sList != Teuchos::null) { + Teuchos::ParameterList::ConstIterator itr; + for (itr = sList->begin(); itr != sList->end(); ++itr) pl->setEntry(itr->first, itr->second); + } + + // use the mass matrix + if (useMass_) pl->set(getVelocityMassString(), false, "Velocity mass matrix"); + pl->set(getPressureLaplaceString(), false, "Pressure Laplacian matrix"); + + return pl; } //! For assiting in construction of the preconditioner -bool PresLaplaceLSCStrategy::updateRequestedParameters(const Teuchos::ParameterList & pl) -{ - Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::updateRequestedParameters",10); - bool result = true; +bool PresLaplaceLSCStrategy::updateRequestedParameters(const Teuchos::ParameterList& pl) { + Teko_DEBUG_SCOPE("PresLaplaceLSCStrategy::updateRequestedParameters", 10); + bool result = true; - // update requested parameters in solvers - result &= invFactoryV_->updateRequestedParameters(pl); - result &= invFactoryP_->updateRequestedParameters(pl); + // update requested parameters in solvers + result &= invFactoryV_->updateRequestedParameters(pl); + result &= invFactoryP_->updateRequestedParameters(pl); - Teuchos::ParameterList hackList(pl); + Teuchos::ParameterList hackList(pl); - // get required operator acknowledgment...user must set these to true - bool plo = hackList.get(getPressureLaplaceString(),false); + // get required operator acknowledgment...user must set these to true + bool plo = hackList.get(getPressureLaplaceString(), false); - bool vmo = true; - if(useMass_) - vmo = hackList.get(getVelocityMassString(),false); + bool vmo = true; + if (useMass_) vmo = hackList.get(getVelocityMassString(), false); - if(not plo) { Teko_DEBUG_MSG("User must acknowledge the use of the \"" << getPressureLaplaceString() << "\"!",0); } - if(not vmo) { Teko_DEBUG_MSG("User must acknowledge the use of the \"" << getVelocityMassString() << "\"!",0); } + if (not plo) { + Teko_DEBUG_MSG("User must acknowledge the use of the \"" << getPressureLaplaceString() << "\"!", + 0); + } + if (not vmo) { + Teko_DEBUG_MSG("User must acknowledge the use of the \"" << getVelocityMassString() << "\"!", + 0); + } - result &= (plo & vmo); + result &= (plo & vmo); - return result; + return result; } -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_PresLaplaceLSCStrategy.hpp b/packages/teko/src/NS/Teko_PresLaplaceLSCStrategy.hpp index 2db29c2285ee..246e78af2f4b 100644 --- a/packages/teko/src/NS/Teko_PresLaplaceLSCStrategy.hpp +++ b/packages/teko/src/NS/Teko_PresLaplaceLSCStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,176 +52,179 @@ namespace Teko { namespace NS { -class LSCPrecondState; // forward declration +class LSCPrecondState; // forward declration /** \brief A strategy that takes a single inverse factory and - * uses that for all inverses. If no mass matrix is - * passed in the diagonal of the 1,1 block is used. - * - * A strategy that takes a single inverse factory and uses that - * for all inverses. Optionally the mass matrix can be passed - * in, if it is the diagonal is extracted and that is used to - * form the inverse approximation. - */ + * uses that for all inverses. If no mass matrix is + * passed in the diagonal of the 1,1 block is used. + * + * A strategy that takes a single inverse factory and uses that + * for all inverses. Optionally the mass matrix can be passed + * in, if it is the diagonal is extracted and that is used to + * form the inverse approximation. + */ class PresLaplaceLSCStrategy : public LSCStrategy { -public: - //! \name Constructors - //@{ - PresLaplaceLSCStrategy(); - PresLaplaceLSCStrategy(const Teuchos::RCP & factory); - PresLaplaceLSCStrategy(const Teuchos::RCP & invFactF, - const Teuchos::RCP & invFactS); - //@} - - virtual ~PresLaplaceLSCStrategy() {} - - //! Functions inherited from LSCStrategy - //@{ - - /** This informs the strategy object to build the state associated - * with this operator. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - */ - virtual void buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of \f$B Q_u^{-1} B^T\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T\f$. - */ - virtual LinearOp getInvBQBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of \f$B H B^T - \gamma C\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. - */ - virtual LinearOp getInvBHBt(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse of the \f$F\f$ block. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$F\f$. - */ - virtual LinearOp getInvF(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the inverse for stabilizing the whole schur complement approximation. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The operator to stabilize the whole Schur complement. - */ - // virtual LinearOp getInvAlphaD(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - virtual LinearOp getOuterStabilization(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - virtual LinearOp getInnerStabilization(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return Teuchos::null; } - - /** Get the inverse mass matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The inverse of the mass matrix \f$Q_u\f$. - */ - virtual LinearOp getInvMass(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Get the \f$H\f$ scaling matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The \f$H\f$ scaling matrix. - */ - virtual LinearOp getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const; - - /** Should the approximation of the inverse use a full LDU decomposition, or - * is a upper triangular approximation sufficient. - * - * \returns True if the full LDU decomposition should be used, otherwise - * only an upper triangular version is used. - */ - virtual bool useFullLDU() const { return useFullLDU_; } - - /** Tell strategy that this operator is supposed to be symmetric. - * Behavior of LSC is slightly different for non-symmetric case. - * - * \param[in] isSymmetric Is this operator symmetric? - */ - virtual void setSymmetric(bool isSymmetric) - { isSymmetric_ = isSymmetric; } - - //! Initialize from a parameter list - virtual void initializeFromParameterList(const Teuchos::ParameterList & pl, - const InverseLibrary & invLib); - - //! For assiting in construction of the preconditioner - virtual Teuchos::RCP getRequestedParameters() const; - - //! For assiting in construction of the preconditioner - virtual bool updateRequestedParameters(const Teuchos::ParameterList & pl); - //@} - - //! Initialize the state object using this blocked linear operator - virtual void initializeState(const BlockedLinearOp & A,LSCPrecondState * state) const; - - /** Compute the inverses required for the LSC Schur complement - * - * \note This method assumes that the BQBt and BHBt operators have - * been constructed. - */ - void computeInverses(const BlockedLinearOp & A,LSCPrecondState * state) const; - - //! Set the number of power series iterations to use when finding the spectral radius - virtual void setEigSolveParam(int sz) { eigSolveParam_ = sz; } - - //! Return the number of power series iterations to use when finding the spectral radius - virtual int getEigSolveParam() { return eigSolveParam_; } - - //! Set to true to use the Full LDU decomposition, false otherwise - virtual void setUseFullLDU(bool val) { useFullLDU_ = val; } - -protected: - // how to invert the matrices - Teuchos::RCP invFactoryV_; - Teuchos::RCP invFactoryP_; - - // flags for handling various options - bool isSymmetric_; - int eigSolveParam_; - bool useFullLDU_; - - // scaling operator parameters - bool useMass_; - DiagonalType scaleType_; - -private: - PresLaplaceLSCStrategy(const PresLaplaceLSCStrategy &); - -public: - // some static functions for determining strings - - static std::string getPressureLaplaceString() { return "Pressure Laplace Operator"; } - static std::string getVelocityMassString() { return "Velocity Mass Operator"; } + public: + //! \name Constructors + //@{ + PresLaplaceLSCStrategy(); + PresLaplaceLSCStrategy(const Teuchos::RCP &factory); + PresLaplaceLSCStrategy(const Teuchos::RCP &invFactF, + const Teuchos::RCP &invFactS); + //@} + + virtual ~PresLaplaceLSCStrategy() {} + + //! Functions inherited from LSCStrategy + //@{ + + /** This informs the strategy object to build the state associated + * with this operator. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + */ + virtual void buildState(BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of \f$B Q_u^{-1} B^T\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T\f$. + */ + virtual LinearOp getInvBQBt(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of \f$B H B^T - \gamma C\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. + */ + virtual LinearOp getInvBHBt(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse of the \f$F\f$ block. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$F\f$. + */ + virtual LinearOp getInvF(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the inverse for stabilizing the whole schur complement approximation. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The operator to stabilize the whole Schur complement. + */ + // virtual LinearOp getInvAlphaD(const BlockedLinearOp & A,BlockPreconditionerState & state) + // const; + virtual LinearOp getOuterStabilization(const BlockedLinearOp &A, + BlockPreconditionerState &state) const; + + virtual LinearOp getInnerStabilization(const BlockedLinearOp & /* A */, + BlockPreconditionerState & /* state */) const { + return Teuchos::null; + } + + /** Get the inverse mass matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The inverse of the mass matrix \f$Q_u\f$. + */ + virtual LinearOp getInvMass(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Get the \f$H\f$ scaling matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The \f$H\f$ scaling matrix. + */ + virtual LinearOp getHScaling(const BlockedLinearOp &A, BlockPreconditionerState &state) const; + + /** Should the approximation of the inverse use a full LDU decomposition, or + * is a upper triangular approximation sufficient. + * + * \returns True if the full LDU decomposition should be used, otherwise + * only an upper triangular version is used. + */ + virtual bool useFullLDU() const { return useFullLDU_; } + + /** Tell strategy that this operator is supposed to be symmetric. + * Behavior of LSC is slightly different for non-symmetric case. + * + * \param[in] isSymmetric Is this operator symmetric? + */ + virtual void setSymmetric(bool isSymmetric) { isSymmetric_ = isSymmetric; } + + //! Initialize from a parameter list + virtual void initializeFromParameterList(const Teuchos::ParameterList &pl, + const InverseLibrary &invLib); + + //! For assiting in construction of the preconditioner + virtual Teuchos::RCP getRequestedParameters() const; + + //! For assiting in construction of the preconditioner + virtual bool updateRequestedParameters(const Teuchos::ParameterList &pl); + //@} + + //! Initialize the state object using this blocked linear operator + virtual void initializeState(const BlockedLinearOp &A, LSCPrecondState *state) const; + + /** Compute the inverses required for the LSC Schur complement + * + * \note This method assumes that the BQBt and BHBt operators have + * been constructed. + */ + void computeInverses(const BlockedLinearOp &A, LSCPrecondState *state) const; + + //! Set the number of power series iterations to use when finding the spectral radius + virtual void setEigSolveParam(int sz) { eigSolveParam_ = sz; } + + //! Return the number of power series iterations to use when finding the spectral radius + virtual int getEigSolveParam() { return eigSolveParam_; } + + //! Set to true to use the Full LDU decomposition, false otherwise + virtual void setUseFullLDU(bool val) { useFullLDU_ = val; } + + protected: + // how to invert the matrices + Teuchos::RCP invFactoryV_; + Teuchos::RCP invFactoryP_; + + // flags for handling various options + bool isSymmetric_; + int eigSolveParam_; + bool useFullLDU_; + + // scaling operator parameters + bool useMass_; + DiagonalType scaleType_; + + private: + PresLaplaceLSCStrategy(const PresLaplaceLSCStrategy &); + + public: + // some static functions for determining strings + + static std::string getPressureLaplaceString() { return "Pressure Laplace Operator"; } + static std::string getVelocityMassString() { return "Velocity Mass Operator"; } }; -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_SIMPLEPreconditionerFactory.cpp b/packages/teko/src/NS/Teko_SIMPLEPreconditionerFactory.cpp index 459ff5b3014e..406a8d1c36a3 100644 --- a/packages/teko/src/NS/Teko_SIMPLEPreconditionerFactory.cpp +++ b/packages/teko/src/NS/Teko_SIMPLEPreconditionerFactory.cpp @@ -63,296 +63,280 @@ namespace Teko { namespace NS { // Constructor definition -SIMPLEPreconditionerFactory - ::SIMPLEPreconditionerFactory(const RCP & inverse, - double alpha) - : invVelFactory_(inverse), invPrsFactory_(inverse), alpha_(alpha), fInverseType_(Diagonal), useMass_(false) -{ } - -SIMPLEPreconditionerFactory - ::SIMPLEPreconditionerFactory(const RCP & invVFact, - const RCP & invPFact, - double alpha) - : invVelFactory_(invVFact), invPrsFactory_(invPFact), alpha_(alpha), fInverseType_(Diagonal), useMass_(false) -{ } +SIMPLEPreconditionerFactory ::SIMPLEPreconditionerFactory(const RCP& inverse, + double alpha) + : invVelFactory_(inverse), + invPrsFactory_(inverse), + alpha_(alpha), + fInverseType_(Diagonal), + useMass_(false) {} + +SIMPLEPreconditionerFactory ::SIMPLEPreconditionerFactory(const RCP& invVFact, + const RCP& invPFact, + double alpha) + : invVelFactory_(invVFact), + invPrsFactory_(invPFact), + alpha_(alpha), + fInverseType_(Diagonal), + useMass_(false) {} SIMPLEPreconditionerFactory::SIMPLEPreconditionerFactory() - : alpha_(1.0), fInverseType_(Diagonal), useMass_(false) -{ } + : alpha_(1.0), fInverseType_(Diagonal), useMass_(false) {} // Use the factory to build the preconditioner (this is where the work goes) -LinearOp SIMPLEPreconditionerFactory - ::buildPreconditionerOperator(BlockedLinearOp & blockOp, - BlockPreconditionerState & state) const -{ - Teko_DEBUG_SCOPE("SIMPLEPreconditionerFactory::buildPreconditionerOperator",10); - Teko_DEBUG_EXPR(Teuchos::Time timer("")); - - int rows = blockRowCount(blockOp); - int cols = blockColCount(blockOp); - - TEUCHOS_ASSERT(rows==2); // sanity checks - TEUCHOS_ASSERT(cols==2); - - bool buildExplicitSchurComplement = true; - - // extract subblocks - const LinearOp F = getBlock(0,0,blockOp); - const LinearOp Bt = getBlock(0,1,blockOp); - const LinearOp B = getBlock(1,0,blockOp); - const LinearOp C = getBlock(1,1,blockOp); - - LinearOp matF = F; - if(useMass_) { - TEUCHOS_ASSERT(massMatrix_!=Teuchos::null); - matF = massMatrix_; - } - - // get approximation of inv(F) name H - std::string fApproxStr = ""; - LinearOp H; - if(fInverseType_==NotDiag) { - H = buildInverse(*customHFactory_,matF); - fApproxStr = customHFactory_->toString(); - - // since H is now implicit, we must build an implicit Schur complement - buildExplicitSchurComplement = false; - } - else if(fInverseType_==BlkDiag) { +LinearOp SIMPLEPreconditionerFactory ::buildPreconditionerOperator( + BlockedLinearOp& blockOp, BlockPreconditionerState& state) const { + Teko_DEBUG_SCOPE("SIMPLEPreconditionerFactory::buildPreconditionerOperator", 10); + Teko_DEBUG_EXPR(Teuchos::Time timer("")); + + int rows = blockRowCount(blockOp); + int cols = blockColCount(blockOp); + + TEUCHOS_ASSERT(rows == 2); // sanity checks + TEUCHOS_ASSERT(cols == 2); + + bool buildExplicitSchurComplement = true; + + // extract subblocks + const LinearOp F = getBlock(0, 0, blockOp); + const LinearOp Bt = getBlock(0, 1, blockOp); + const LinearOp B = getBlock(1, 0, blockOp); + const LinearOp C = getBlock(1, 1, blockOp); + + LinearOp matF = F; + if (useMass_) { + TEUCHOS_ASSERT(massMatrix_ != Teuchos::null); + matF = massMatrix_; + } + + // get approximation of inv(F) name H + std::string fApproxStr = ""; + LinearOp H; + if (fInverseType_ == NotDiag) { + H = buildInverse(*customHFactory_, matF); + fApproxStr = customHFactory_->toString(); + + // since H is now implicit, we must build an implicit Schur complement + buildExplicitSchurComplement = false; + } else if (fInverseType_ == BlkDiag) { #ifdef TEKO_HAVE_EPETRA - // Block diagonal approximation for H - DiagonalPreconditionerFactory Hfact; - DiagonalPrecondState Hstate; - Hfact.initializeFromParameterList(BlkDiagList_); - H = Hfact.buildPreconditionerOperator(matF,Hstate); - -/* - // Get a FECrsMarix out of the BDP - RCP Hcrs=rcp(Hstate.BDP_->CreateFECrsMatrix()); - H=Thyra::epetraLinearOp(Hcrs); -*/ - - buildExplicitSchurComplement = true; // NTS: Do I need this? + // Block diagonal approximation for H + DiagonalPreconditionerFactory Hfact; + DiagonalPrecondState Hstate; + Hfact.initializeFromParameterList(BlkDiagList_); + H = Hfact.buildPreconditionerOperator(matF, Hstate); + + /* + // Get a FECrsMarix out of the BDP + RCP Hcrs=rcp(Hstate.BDP_->CreateFECrsMatrix()); + H=Thyra::epetraLinearOp(Hcrs); + */ + + buildExplicitSchurComplement = true; // NTS: Do I need this? // Answer - no, but it is documenting whats going on here. #else - throw std::logic_error("SIMPLEPreconditionerFactory fInverseType_ == " - "BlkDiag but EPETRA is turned off!"); + throw std::logic_error( + "SIMPLEPreconditionerFactory fInverseType_ == " + "BlkDiag but EPETRA is turned off!"); #endif - } - else { - // get generic diagonal - H = getInvDiagonalOp(matF,fInverseType_); - fApproxStr = getDiagonalName(fInverseType_); - } - - // adjust H for time scaling if it is a mass matrix - if(useMass_) { - RCP pl = state.getParameterList(); - - if(pl->isParameter("stepsize")) { - // get the step size - double stepsize = pl->get("stepsize"); - - // scale by stepsize only if it is larger than 0 - if(stepsize>0.0) - H = scale(stepsize,H); - } - } - - // build approximate Schur complement: hatS = -C + B*H*Bt - LinearOp HBt, hatS; - - if(buildExplicitSchurComplement) { - ModifiableLinearOp & mHBt = state.getModifiableOp("HBt"); - ModifiableLinearOp & mhatS = state.getModifiableOp("hatS"); - ModifiableLinearOp & BHBt = state.getModifiableOp("BHBt"); - - // build H*Bt - mHBt = explicitMultiply(H,Bt,mHBt); - HBt = mHBt; - - // build B*H*Bt - BHBt = explicitMultiply(B,HBt,BHBt); - - // build C-B*H*Bt - mhatS = explicitAdd(C,scale(-1.0,BHBt),mhatS); - hatS = mhatS; - } - else { - // build an implicit Schur complement - HBt = multiply(H,Bt); - - hatS = add(C,scale(-1.0,multiply(B,HBt))); - } - - // build the inverse for F - ModifiableLinearOp & invF = state.getModifiableOp("invF"); - if(invF==Teuchos::null) - invF = buildInverse(*invVelFactory_,F); - else - rebuildInverse(*invVelFactory_,F,invF); - - // build the approximate Schur complement - ModifiableLinearOp & invS = state.getModifiableOp("invS"); - if(invS==Teuchos::null) - invS = buildInverse(*invPrsFactory_,hatS); - else - rebuildInverse(*invPrsFactory_,hatS,invS); - - std::vector invDiag(2); // vector storing inverses - - // build lower triangular inverse matrix - BlockedLinearOp L = zeroBlockedOp(blockOp); - setBlock(1,0,L,B); - endBlockFill(L); - - invDiag[0] = invF; - invDiag[1] = invS; - LinearOp invL = createBlockLowerTriInverseOp(L,invDiag); - - // build upper triangular matrix - BlockedLinearOp U = zeroBlockedOp(blockOp); - setBlock(0,1,U,scale(1.0/alpha_,HBt)); - endBlockFill(U); - - invDiag[0] = identity(rangeSpace(invF)); - invDiag[1] = scale(alpha_,identity(rangeSpace(invS))); - LinearOp invU = createBlockUpperTriInverseOp(U,invDiag); - - // return implicit product operator - return multiply(invU,invL,"SIMPLE_"+fApproxStr); + } else { + // get generic diagonal + H = getInvDiagonalOp(matF, fInverseType_); + fApproxStr = getDiagonalName(fInverseType_); + } + + // adjust H for time scaling if it is a mass matrix + if (useMass_) { + RCP pl = state.getParameterList(); + + if (pl->isParameter("stepsize")) { + // get the step size + double stepsize = pl->get("stepsize"); + + // scale by stepsize only if it is larger than 0 + if (stepsize > 0.0) H = scale(stepsize, H); + } + } + + // build approximate Schur complement: hatS = -C + B*H*Bt + LinearOp HBt, hatS; + + if (buildExplicitSchurComplement) { + ModifiableLinearOp& mHBt = state.getModifiableOp("HBt"); + ModifiableLinearOp& mhatS = state.getModifiableOp("hatS"); + ModifiableLinearOp& BHBt = state.getModifiableOp("BHBt"); + + // build H*Bt + mHBt = explicitMultiply(H, Bt, mHBt); + HBt = mHBt; + + // build B*H*Bt + BHBt = explicitMultiply(B, HBt, BHBt); + + // build C-B*H*Bt + mhatS = explicitAdd(C, scale(-1.0, BHBt), mhatS); + hatS = mhatS; + } else { + // build an implicit Schur complement + HBt = multiply(H, Bt); + + hatS = add(C, scale(-1.0, multiply(B, HBt))); + } + + // build the inverse for F + ModifiableLinearOp& invF = state.getModifiableOp("invF"); + if (invF == Teuchos::null) + invF = buildInverse(*invVelFactory_, F); + else + rebuildInverse(*invVelFactory_, F, invF); + + // build the approximate Schur complement + ModifiableLinearOp& invS = state.getModifiableOp("invS"); + if (invS == Teuchos::null) + invS = buildInverse(*invPrsFactory_, hatS); + else + rebuildInverse(*invPrsFactory_, hatS, invS); + + std::vector invDiag(2); // vector storing inverses + + // build lower triangular inverse matrix + BlockedLinearOp L = zeroBlockedOp(blockOp); + setBlock(1, 0, L, B); + endBlockFill(L); + + invDiag[0] = invF; + invDiag[1] = invS; + LinearOp invL = createBlockLowerTriInverseOp(L, invDiag); + + // build upper triangular matrix + BlockedLinearOp U = zeroBlockedOp(blockOp); + setBlock(0, 1, U, scale(1.0 / alpha_, HBt)); + endBlockFill(U); + + invDiag[0] = identity(rangeSpace(invF)); + invDiag[1] = scale(alpha_, identity(rangeSpace(invS))); + LinearOp invU = createBlockUpperTriInverseOp(U, invDiag); + + // return implicit product operator + return multiply(invU, invL, "SIMPLE_" + fApproxStr); } //! Initialize from a parameter list -void SIMPLEPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList & pl) -{ - RCP invLib = getInverseLibrary(); - - // default conditions - useMass_ = false; - customHFactory_ = Teuchos::null; - fInverseType_ = Diagonal; - - // get string specifying inverse - std::string invStr="", invVStr="", invPStr=""; - alpha_ = 1.0; - - // "parse" the parameter list - if(pl.isParameter("Inverse Type")) - invStr = pl.get("Inverse Type"); - if(pl.isParameter("Inverse Velocity Type")) - invVStr = pl.get("Inverse Velocity Type"); - if(pl.isParameter("Inverse Pressure Type")) - invPStr = pl.get("Inverse Pressure Type"); - if(pl.isParameter("Alpha")) - alpha_ = pl.get("Alpha"); - if(pl.isParameter("Explicit Velocity Inverse Type")) { - std::string fInverseStr = pl.get("Explicit Velocity Inverse Type"); - - // build inverse types - fInverseType_ = getDiagonalType(fInverseStr); - if(fInverseType_==NotDiag) - customHFactory_ = invLib->getInverseFactory(fInverseStr); - - // Grab the sublist if we're using the block diagonal - if(fInverseType_==BlkDiag) - BlkDiagList_=pl.sublist("H options"); - } - if(pl.isParameter("Use Mass Scaling")) - useMass_ = pl.get("Use Mass Scaling"); - - Teko_DEBUG_MSG_BEGIN(5) - DEBUG_STREAM << "SIMPLE Parameters: " << std::endl; - DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; - DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; - DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; - DEBUG_STREAM << " alpha = " << alpha_ << std::endl; - DEBUG_STREAM << " use mass = " << useMass_ << std::endl; - DEBUG_STREAM << " vel scaling = " << getDiagonalName(fInverseType_) << std::endl; - DEBUG_STREAM << "SIMPLE Parameter list: " << std::endl; - pl.print(DEBUG_STREAM); - Teko_DEBUG_MSG_END() - - // set defaults as needed - if(invStr=="") invStr = "Amesos"; - if(invVStr=="") invVStr = invStr; - if(invPStr=="") invPStr = invStr; - - // two inverse factory objects - RCP invVFact, invPFact; - - // build velocity inverse factory - invVFact = invLib->getInverseFactory(invVStr); - invPFact = invVFact; // by default these are the same - if(invVStr!=invPStr) // if different, build pressure inverse factory - invPFact = invLib->getInverseFactory(invPStr); - - // based on parameter type build a strategy - invVelFactory_ = invVFact; - invPrsFactory_ = invPFact; - - if(useMass_) { - Teuchos::RCP rh = getRequestHandler(); - rh->preRequest(Teko::RequestMesg("Velocity Mass Matrix")); - Teko::LinearOp mass - = rh->request(Teko::RequestMesg("Velocity Mass Matrix")); - setMassMatrix(mass); - } +void SIMPLEPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList& pl) { + RCP invLib = getInverseLibrary(); + + // default conditions + useMass_ = false; + customHFactory_ = Teuchos::null; + fInverseType_ = Diagonal; + + // get string specifying inverse + std::string invStr = "", invVStr = "", invPStr = ""; + alpha_ = 1.0; + + // "parse" the parameter list + if (pl.isParameter("Inverse Type")) invStr = pl.get("Inverse Type"); + if (pl.isParameter("Inverse Velocity Type")) + invVStr = pl.get("Inverse Velocity Type"); + if (pl.isParameter("Inverse Pressure Type")) + invPStr = pl.get("Inverse Pressure Type"); + if (pl.isParameter("Alpha")) alpha_ = pl.get("Alpha"); + if (pl.isParameter("Explicit Velocity Inverse Type")) { + std::string fInverseStr = pl.get("Explicit Velocity Inverse Type"); + + // build inverse types + fInverseType_ = getDiagonalType(fInverseStr); + if (fInverseType_ == NotDiag) customHFactory_ = invLib->getInverseFactory(fInverseStr); + + // Grab the sublist if we're using the block diagonal + if (fInverseType_ == BlkDiag) BlkDiagList_ = pl.sublist("H options"); + } + if (pl.isParameter("Use Mass Scaling")) useMass_ = pl.get("Use Mass Scaling"); + + Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "SIMPLE Parameters: " << std::endl; + DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; + DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; + DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; + DEBUG_STREAM << " alpha = " << alpha_ << std::endl; + DEBUG_STREAM << " use mass = " << useMass_ << std::endl; + DEBUG_STREAM << " vel scaling = " << getDiagonalName(fInverseType_) << std::endl; + DEBUG_STREAM << "SIMPLE Parameter list: " << std::endl; + pl.print(DEBUG_STREAM); + Teko_DEBUG_MSG_END() + + // set defaults as needed + if (invStr == "") invStr = "Amesos"; + if (invVStr == "") invVStr = invStr; + if (invPStr == "") invPStr = invStr; + + // two inverse factory objects + RCP invVFact, invPFact; + + // build velocity inverse factory + invVFact = invLib->getInverseFactory(invVStr); + invPFact = invVFact; // by default these are the same + if (invVStr != invPStr) // if different, build pressure inverse factory + invPFact = invLib->getInverseFactory(invPStr); + + // based on parameter type build a strategy + invVelFactory_ = invVFact; + invPrsFactory_ = invPFact; + + if (useMass_) { + Teuchos::RCP rh = getRequestHandler(); + rh->preRequest(Teko::RequestMesg("Velocity Mass Matrix")); + Teko::LinearOp mass = rh->request(Teko::RequestMesg("Velocity Mass Matrix")); + setMassMatrix(mass); + } } //! For assiting in construction of the preconditioner -Teuchos::RCP SIMPLEPreconditionerFactory::getRequestedParameters() const -{ - Teuchos::RCP result; - Teuchos::RCP pl = rcp(new Teuchos::ParameterList()); - - // grab parameters from F solver - RCP vList = invVelFactory_->getRequestedParameters(); - if(vList!=Teuchos::null) { +Teuchos::RCP SIMPLEPreconditionerFactory::getRequestedParameters() const { + Teuchos::RCP result; + Teuchos::RCP pl = rcp(new Teuchos::ParameterList()); + + // grab parameters from F solver + RCP vList = invVelFactory_->getRequestedParameters(); + if (vList != Teuchos::null) { + Teuchos::ParameterList::ConstIterator itr; + for (itr = vList->begin(); itr != vList->end(); ++itr) pl->setEntry(itr->first, itr->second); + result = pl; + } + + // grab parameters from S solver + RCP pList = invPrsFactory_->getRequestedParameters(); + if (pList != Teuchos::null) { + Teuchos::ParameterList::ConstIterator itr; + for (itr = pList->begin(); itr != pList->end(); ++itr) pl->setEntry(itr->first, itr->second); + result = pl; + } + + // grab parameters from S solver + if (customHFactory_ != Teuchos::null) { + RCP hList = customHFactory_->getRequestedParameters(); + if (hList != Teuchos::null) { Teuchos::ParameterList::ConstIterator itr; - for(itr=vList->begin();itr!=vList->end();++itr) - pl->setEntry(itr->first,itr->second); + for (itr = hList->begin(); itr != hList->end(); ++itr) pl->setEntry(itr->first, itr->second); result = pl; - } + } + } - // grab parameters from S solver - RCP pList = invPrsFactory_->getRequestedParameters(); - if(pList!=Teuchos::null) { - Teuchos::ParameterList::ConstIterator itr; - for(itr=pList->begin();itr!=pList->end();++itr) - pl->setEntry(itr->first,itr->second); - result = pl; - } - - // grab parameters from S solver - if(customHFactory_!=Teuchos::null) { - RCP hList = customHFactory_->getRequestedParameters(); - if(hList!=Teuchos::null) { - Teuchos::ParameterList::ConstIterator itr; - for(itr=hList->begin();itr!=hList->end();++itr) - pl->setEntry(itr->first,itr->second); - result = pl; - } - } - - return result; + return result; } //! For assiting in construction of the preconditioner -bool SIMPLEPreconditionerFactory::updateRequestedParameters(const Teuchos::ParameterList & pl) -{ - Teko_DEBUG_SCOPE("InvLSCStrategy::updateRequestedParameters",10); - bool result = true; - - // update requested parameters in solvers - result &= invVelFactory_->updateRequestedParameters(pl); - result &= invPrsFactory_->updateRequestedParameters(pl); - if(customHFactory_!=Teuchos::null) - result &= customHFactory_->updateRequestedParameters(pl); - - return result; +bool SIMPLEPreconditionerFactory::updateRequestedParameters(const Teuchos::ParameterList& pl) { + Teko_DEBUG_SCOPE("InvLSCStrategy::updateRequestedParameters", 10); + bool result = true; + + // update requested parameters in solvers + result &= invVelFactory_->updateRequestedParameters(pl); + result &= invPrsFactory_->updateRequestedParameters(pl); + if (customHFactory_ != Teuchos::null) result &= customHFactory_->updateRequestedParameters(pl); + + return result; } -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_SIMPLEPreconditionerFactory.hpp b/packages/teko/src/NS/Teko_SIMPLEPreconditionerFactory.hpp index 0f1cbcd93727..ce0f4c87cf5d 100644 --- a/packages/teko/src/NS/Teko_SIMPLEPreconditionerFactory.hpp +++ b/packages/teko/src/NS/Teko_SIMPLEPreconditionerFactory.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -55,7 +55,7 @@ namespace NS { // Declaration of the preconditioner factory /** The basic XML parameter list for SIMPLE looks like. - + \code @@ -71,55 +71,51 @@ namespace NS { \endcode */ class SIMPLEPreconditionerFactory : public BlockPreconditionerFactory { -public: - // Constructor - SIMPLEPreconditionerFactory(const Teuchos::RCP & inverse, - double alpha); - - // Constructor - SIMPLEPreconditionerFactory(const Teuchos::RCP & invVelFactory, - const Teuchos::RCP & invPrsFactory, - double alpha); - - //! Default constructor - SIMPLEPreconditionerFactory(); - - // Function inherited from BlockPreconditionerFactory - LinearOp buildPreconditionerOperator(BlockedLinearOp & blo, - BlockPreconditionerState & state) const; - - //! Set the mass matrix for this factory - virtual void setMassMatrix(Teko::LinearOp & mass) - { massMatrix_ = mass; } - - //! For assisting in construction of the preconditioner - virtual Teuchos::RCP getRequestedParameters() const; - - //! For assisting in construction of the preconditioner - virtual bool updateRequestedParameters(const Teuchos::ParameterList & pl); - - //! Initialize from a parameter list - virtual void initializeFromParameterList(const Teuchos::ParameterList & pl); - -protected: - using BlockPreconditionerFactory::buildPreconditionerOperator; - - // class members - Teuchos::RCP customHFactory_; - Teuchos::RCP invVelFactory_; - Teuchos::RCP invPrsFactory_; - double alpha_; - DiagonalType fInverseType_; - // enum FInverseType {Diagonal,Lumped,AbsRowSum,Custom} fInverseType_; - - bool useMass_; - Teko::LinearOp massMatrix_; - - // Info for the block-diagonal approximation to H if used. - mutable Teuchos::ParameterList BlkDiagList_; + public: + // Constructor + SIMPLEPreconditionerFactory(const Teuchos::RCP& inverse, double alpha); + + // Constructor + SIMPLEPreconditionerFactory(const Teuchos::RCP& invVelFactory, + const Teuchos::RCP& invPrsFactory, double alpha); + + //! Default constructor + SIMPLEPreconditionerFactory(); + + // Function inherited from BlockPreconditionerFactory + LinearOp buildPreconditionerOperator(BlockedLinearOp& blo, BlockPreconditionerState& state) const; + + //! Set the mass matrix for this factory + virtual void setMassMatrix(Teko::LinearOp& mass) { massMatrix_ = mass; } + + //! For assisting in construction of the preconditioner + virtual Teuchos::RCP getRequestedParameters() const; + + //! For assisting in construction of the preconditioner + virtual bool updateRequestedParameters(const Teuchos::ParameterList& pl); + + //! Initialize from a parameter list + virtual void initializeFromParameterList(const Teuchos::ParameterList& pl); + + protected: + using BlockPreconditionerFactory::buildPreconditionerOperator; + + // class members + Teuchos::RCP customHFactory_; + Teuchos::RCP invVelFactory_; + Teuchos::RCP invPrsFactory_; + double alpha_; + DiagonalType fInverseType_; + // enum FInverseType {Diagonal,Lumped,AbsRowSum,Custom} fInverseType_; + + bool useMass_; + Teko::LinearOp massMatrix_; + + // Info for the block-diagonal approximation to H if used. + mutable Teuchos::ParameterList BlkDiagList_; }; - -} // end namespace NS -} // end namespace Teko + +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_StaticLSCStrategy.cpp b/packages/teko/src/NS/Teko_StaticLSCStrategy.cpp index 2989a42d1289..097c8fb440cc 100644 --- a/packages/teko/src/NS/Teko_StaticLSCStrategy.cpp +++ b/packages/teko/src/NS/Teko_StaticLSCStrategy.cpp @@ -54,26 +54,21 @@ #include "Teko_Utilities.hpp" using Teuchos::RCP; -using Teuchos::rcp_dynamic_cast; using Teuchos::rcp_const_cast; +using Teuchos::rcp_dynamic_cast; namespace Teko { namespace NS { - // Staiblized constructor -StaticLSCStrategy::StaticLSCStrategy(const LinearOp & invF, - const LinearOp & invBQBtmC, - const LinearOp & invD, - const LinearOp & invMass) - : invF_(invF), invBQBtmC_(invBQBtmC), invD_(invD), invMass_(invMass) -{ } +// Staiblized constructor +StaticLSCStrategy::StaticLSCStrategy(const LinearOp& invF, const LinearOp& invBQBtmC, + const LinearOp& invD, const LinearOp& invMass) + : invF_(invF), invBQBtmC_(invBQBtmC), invD_(invD), invMass_(invMass) {} - // Stable constructor -StaticLSCStrategy::StaticLSCStrategy(const LinearOp & invF, - const LinearOp & invBQBtmC, - const LinearOp & invMass) - : invF_(invF), invBQBtmC_(invBQBtmC), invD_(Teuchos::null), invMass_(invMass) -{ } +// Stable constructor +StaticLSCStrategy::StaticLSCStrategy(const LinearOp& invF, const LinearOp& invBQBtmC, + const LinearOp& invMass) + : invF_(invF), invBQBtmC_(invBQBtmC), invD_(Teuchos::null), invMass_(invMass) {} -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_StaticLSCStrategy.hpp b/packages/teko/src/NS/Teko_StaticLSCStrategy.hpp index 14740ae56a5b..38a0ea6e4cc8 100644 --- a/packages/teko/src/NS/Teko_StaticLSCStrategy.hpp +++ b/packages/teko/src/NS/Teko_StaticLSCStrategy.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,125 +52,134 @@ namespace Teko { namespace NS { -class LSCPrecondState; // forward declaration +class LSCPrecondState; // forward declaration // constant, not very flexible strategy for driving LSCPreconditioenrFactory class StaticLSCStrategy : public LSCStrategy { -public: - - // Staiblized constructor - StaticLSCStrategy(const LinearOp & invF, - const LinearOp & invBQBtmC, - const LinearOp & invD, - const LinearOp & invMass); - - // Stable constructor - StaticLSCStrategy(const LinearOp & invF, - const LinearOp & invBQBtmC, - const LinearOp & invMass); - - /** This informs the strategy object to build the state associated - * with this operator. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - */ - virtual void buildState(BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const {} - - /** Get the inverse of the \f$F\f$ block. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$F\f$. - */ - virtual LinearOp getInvF(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return invF_; } - - /** Get the inverse of \f$B Q_u^{-1} B^T\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T\f$. - */ - virtual LinearOp getInvBQBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return invBQBtmC_; } - - /** Get the inverse of \f$B H B^T - \gamma C\f$. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. - */ - virtual LinearOp getInvBHBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return invBQBtmC_; } - - /** Get the inverse for stabilizing the whole Schur complement approximation. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The operator to stabilize the whole Schur complement (\f$\alpha D^{-1} \f$). - */ - virtual LinearOp getOuterStabilization(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return invD_; } - - virtual LinearOp getInnerStabilization(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return Teuchos::null; } - - /** Get the inverse mass matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The inverse of the mass matrix \f$Q_u\f$. - */ - virtual LinearOp getInvMass(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return invMass_; } - - /** Get the \f$H\f$ scaling matrix. - * - * \param[in] A The linear operator to be preconditioned by LSC. - * \param[in] state State object for storying reusable information about - * the operator A. - * - * \returns The \f$H\f$ scaling matrix. - */ - virtual LinearOp getHScaling(const BlockedLinearOp & /* A */,BlockPreconditionerState & /* state */) const - { return invMass_; } - - /** Should the approximation of the inverse use a full LDU decomposition, or - * is a upper triangular approximation sufficient. - * - * \returns True if the full LDU decomposition should be used, otherwise - * only an upper triangular version is used. - */ - virtual bool useFullLDU() const { return false; } - - /** Tell strategy that this operator is supposed to be symmetric. - * Behavior of LSC is slightly different for non-symmetric case. - * - * \param[in] isSymmetric Is this operator symmetric? - */ - virtual void setSymmetric(bool /* isSymmetric */) { } - -protected: - // protected memebers - LinearOp invF_; - LinearOp invBQBtmC_; - LinearOp invD_; - LinearOp invMass_; + public: + // Staiblized constructor + StaticLSCStrategy(const LinearOp& invF, const LinearOp& invBQBtmC, const LinearOp& invD, + const LinearOp& invMass); + + // Stable constructor + StaticLSCStrategy(const LinearOp& invF, const LinearOp& invBQBtmC, const LinearOp& invMass); + + /** This informs the strategy object to build the state associated + * with this operator. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + */ + virtual void buildState(BlockedLinearOp& /* A */, BlockPreconditionerState& /* state */) const {} + + /** Get the inverse of the \f$F\f$ block. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$F\f$. + */ + virtual LinearOp getInvF(const BlockedLinearOp& /* A */, + BlockPreconditionerState& /* state */) const { + return invF_; + } + + /** Get the inverse of \f$B Q_u^{-1} B^T\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B Q_u^{-1} B^T\f$. + */ + virtual LinearOp getInvBQBt(const BlockedLinearOp& /* A */, + BlockPreconditionerState& /* state */) const { + return invBQBtmC_; + } + + /** Get the inverse of \f$B H B^T - \gamma C\f$. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns An (approximate) inverse of \f$B H B^T - \gamma C\f$. + */ + virtual LinearOp getInvBHBt(const BlockedLinearOp& /* A */, + BlockPreconditionerState& /* state */) const { + return invBQBtmC_; + } + + /** Get the inverse for stabilizing the whole Schur complement approximation. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The operator to stabilize the whole Schur complement (\f$\alpha D^{-1} \f$). + */ + virtual LinearOp getOuterStabilization(const BlockedLinearOp& /* A */, + BlockPreconditionerState& /* state */) const { + return invD_; + } + + virtual LinearOp getInnerStabilization(const BlockedLinearOp& /* A */, + BlockPreconditionerState& /* state */) const { + return Teuchos::null; + } + + /** Get the inverse mass matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The inverse of the mass matrix \f$Q_u\f$. + */ + virtual LinearOp getInvMass(const BlockedLinearOp& /* A */, + BlockPreconditionerState& /* state */) const { + return invMass_; + } + + /** Get the \f$H\f$ scaling matrix. + * + * \param[in] A The linear operator to be preconditioned by LSC. + * \param[in] state State object for storying reusable information about + * the operator A. + * + * \returns The \f$H\f$ scaling matrix. + */ + virtual LinearOp getHScaling(const BlockedLinearOp& /* A */, + BlockPreconditionerState& /* state */) const { + return invMass_; + } + + /** Should the approximation of the inverse use a full LDU decomposition, or + * is a upper triangular approximation sufficient. + * + * \returns True if the full LDU decomposition should be used, otherwise + * only an upper triangular version is used. + */ + virtual bool useFullLDU() const { return false; } + + /** Tell strategy that this operator is supposed to be symmetric. + * Behavior of LSC is slightly different for non-symmetric case. + * + * \param[in] isSymmetric Is this operator symmetric? + */ + virtual void setSymmetric(bool /* isSymmetric */) {} + + protected: + // protected memebers + LinearOp invF_; + LinearOp invBQBtmC_; + LinearOp invD_; + LinearOp invMass_; }; -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/NS/Teko_TimingsSIMPLEPreconditionerFactory.cpp b/packages/teko/src/NS/Teko_TimingsSIMPLEPreconditionerFactory.cpp index e7a2f25d9e5d..7af5d7380829 100644 --- a/packages/teko/src/NS/Teko_TimingsSIMPLEPreconditionerFactory.cpp +++ b/packages/teko/src/NS/Teko_TimingsSIMPLEPreconditionerFactory.cpp @@ -62,362 +62,353 @@ namespace Teko { namespace NS { // Constructor definition -TimingsSIMPLEPreconditionerFactory - ::TimingsSIMPLEPreconditionerFactory(const RCP & inverse, - double alpha) - : invVelFactory_(inverse), invPrsFactory_(inverse), alpha_(alpha), fInverseType_(Diagonal), useMass_(false) - , constrTotal_("SIMPLE Constr: Total"), subTotal_("SIMPLE Constr: Subs"), constrCount_(0) -{ } - -TimingsSIMPLEPreconditionerFactory - ::TimingsSIMPLEPreconditionerFactory(const RCP & invVFact, - const RCP & invPFact, - double alpha) - : invVelFactory_(invVFact), invPrsFactory_(invPFact), alpha_(alpha), fInverseType_(Diagonal), useMass_(false) - , constrTotal_("SIMPLE Constr: Total"), subTotal_("SIMPLE Constr: Subs"), constrCount_(0) -{ } +TimingsSIMPLEPreconditionerFactory ::TimingsSIMPLEPreconditionerFactory( + const RCP& inverse, double alpha) + : invVelFactory_(inverse), + invPrsFactory_(inverse), + alpha_(alpha), + fInverseType_(Diagonal), + useMass_(false), + constrTotal_("SIMPLE Constr: Total"), + subTotal_("SIMPLE Constr: Subs"), + constrCount_(0) {} + +TimingsSIMPLEPreconditionerFactory ::TimingsSIMPLEPreconditionerFactory( + const RCP& invVFact, const RCP& invPFact, double alpha) + : invVelFactory_(invVFact), + invPrsFactory_(invPFact), + alpha_(alpha), + fInverseType_(Diagonal), + useMass_(false), + constrTotal_("SIMPLE Constr: Total"), + subTotal_("SIMPLE Constr: Subs"), + constrCount_(0) {} TimingsSIMPLEPreconditionerFactory::TimingsSIMPLEPreconditionerFactory() - : alpha_(1.0), fInverseType_(Diagonal), useMass_(false) - , constrTotal_("SIMPLE Constr: Total"), subTotal_("SIMPLE Constr: Subs"), constrCount_(0) -{ } - -TimingsSIMPLEPreconditionerFactory::~TimingsSIMPLEPreconditionerFactory() -{ - if(constrTotal_.totalElapsedTime()>0.0) { + : alpha_(1.0), + fInverseType_(Diagonal), + useMass_(false), + constrTotal_("SIMPLE Constr: Total"), + subTotal_("SIMPLE Constr: Subs"), + constrCount_(0) {} + +TimingsSIMPLEPreconditionerFactory::~TimingsSIMPLEPreconditionerFactory() { + if (constrTotal_.totalElapsedTime() > 0.0) { Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout)); out.setOutputToRootOnly(0); - out << "===========================================================================" << std::endl; + out << "===========================================================================" + << std::endl; out << std::endl; out << "SIMPLE Construction Count = " << constrCount_ << std::endl; out << "SIMPLE Construction Total = " << constrTotal_.totalElapsedTime() << std::endl; out << "SIMPLE Sub Components Total = " << subTotal_.totalElapsedTime() << std::endl; out << std::endl; - out << "===========================================================================" << std::endl; + out << "===========================================================================" + << std::endl; } } // Use the factory to build the preconditioner (this is where the work goes) -LinearOp TimingsSIMPLEPreconditionerFactory - ::buildPreconditionerOperator(BlockedLinearOp & blockOp, - BlockPreconditionerState & state) const -{ - constrTotal_.start(); - - Teko_DEBUG_SCOPE("TimingsSIMPLEPreconditionerFactory::buildPreconditionerOperator",10); - Teko_DEBUG_EXPR(Teuchos::Time timer("")); - - int rows = blockRowCount(blockOp); - int cols = blockColCount(blockOp); - - TEUCHOS_ASSERT(rows==2); // sanity checks - TEUCHOS_ASSERT(cols==2); - - bool buildExplicitSchurComplement = true; - - // extract subblocks - const LinearOp F = getBlock(0,0,blockOp); - const LinearOp Bt = getBlock(0,1,blockOp); - const LinearOp B = getBlock(1,0,blockOp); - const LinearOp C = getBlock(1,1,blockOp); - - LinearOp matF = F; - if(useMass_) { - TEUCHOS_ASSERT(massMatrix_!=Teuchos::null); - matF = massMatrix_; - } - - // get approximation of inv(F) name H - std::string fApproxStr = ""; - LinearOp H; - if(fInverseType_==NotDiag) { - H = buildInverse(*customHFactory_,matF); - fApproxStr = customHFactory_->toString(); - - // since H is now implicit, we must build an implicit Schur complement - buildExplicitSchurComplement = false; - } - else if(fInverseType_==BlkDiag) { +LinearOp TimingsSIMPLEPreconditionerFactory ::buildPreconditionerOperator( + BlockedLinearOp& blockOp, BlockPreconditionerState& state) const { + constrTotal_.start(); + + Teko_DEBUG_SCOPE("TimingsSIMPLEPreconditionerFactory::buildPreconditionerOperator", 10); + Teko_DEBUG_EXPR(Teuchos::Time timer("")); + + int rows = blockRowCount(blockOp); + int cols = blockColCount(blockOp); + + TEUCHOS_ASSERT(rows == 2); // sanity checks + TEUCHOS_ASSERT(cols == 2); + + bool buildExplicitSchurComplement = true; + + // extract subblocks + const LinearOp F = getBlock(0, 0, blockOp); + const LinearOp Bt = getBlock(0, 1, blockOp); + const LinearOp B = getBlock(1, 0, blockOp); + const LinearOp C = getBlock(1, 1, blockOp); + + LinearOp matF = F; + if (useMass_) { + TEUCHOS_ASSERT(massMatrix_ != Teuchos::null); + matF = massMatrix_; + } + + // get approximation of inv(F) name H + std::string fApproxStr = ""; + LinearOp H; + if (fInverseType_ == NotDiag) { + H = buildInverse(*customHFactory_, matF); + fApproxStr = customHFactory_->toString(); + + // since H is now implicit, we must build an implicit Schur complement + buildExplicitSchurComplement = false; + } else if (fInverseType_ == BlkDiag) { #ifdef TEKO_HAVE_EPETRA - // Block diagonal approximation for H - DiagonalPreconditionerFactory Hfact; - DiagonalPrecondState Hstate; - Hfact.initializeFromParameterList(BlkDiagList_); - H = Hfact.buildPreconditionerOperator(matF,Hstate); + // Block diagonal approximation for H + DiagonalPreconditionerFactory Hfact; + DiagonalPrecondState Hstate; + Hfact.initializeFromParameterList(BlkDiagList_); + H = Hfact.buildPreconditionerOperator(matF, Hstate); - buildExplicitSchurComplement = true; // NTS: Do I need this? + buildExplicitSchurComplement = true; // NTS: Do I need this? // Answer - no, but it is documenting whats going on here. #else - throw std::logic_error("TimingsSIMPLEPreconditionerFactory fInverseType_ == " - "BlkDiag but EPETRA is turned off!"); + throw std::logic_error( + "TimingsSIMPLEPreconditionerFactory fInverseType_ == " + "BlkDiag but EPETRA is turned off!"); #endif - } - else { - // get generic diagonal - subTotal_.start(); - H = getInvDiagonalOp(matF,fInverseType_); - subTotal_.stop(); - fApproxStr = getDiagonalName(fInverseType_); - } - - // adjust H for time scaling if it is a mass matrix - if(useMass_) { - RCP pl = state.getParameterList(); - - if(pl->isParameter("stepsize")) { - // get the step size - double stepsize = pl->get("stepsize"); - - // scale by stepsize only if it is larger than 0 - if(stepsize>0.0) - H = scale(stepsize,H); - } - } - - // build approximate Schur complement: hatS = -C + B*H*Bt - LinearOp HBt, hatS; - - if(buildExplicitSchurComplement) { - ModifiableLinearOp & mHBt = state.getModifiableOp("HBt"); - ModifiableLinearOp & mhatS = state.getModifiableOp("hatS"); - ModifiableLinearOp & BHBt = state.getModifiableOp("BHBt"); - - // build H*Bt - subTotal_.start(); - mHBt = explicitMultiply(H,Bt,mHBt); - subTotal_.stop(); - HBt = mHBt; - - // build B*H*Bt - subTotal_.start(); - BHBt = explicitMultiply(B,HBt,BHBt); - subTotal_.stop(); - - // build C-B*H*Bt - subTotal_.start(); - mhatS = explicitAdd(C,scale(-1.0,BHBt),mhatS); - subTotal_.stop(); - hatS = mhatS; - } - else { - // build an implicit Schur complement - HBt = multiply(H,Bt); - - hatS = add(C,scale(-1.0,multiply(B,HBt))); - } - - // time the application of HBt - if(timed_HBt_==Teuchos::null) { - timed_HBt_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(),HBt,"HBt")); - } - else { - timed_HBt_->setLinearOp(HBt); - } - - // time the application of B - if(timed_B_==Teuchos::null) { - timed_B_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(),B,"B")); - } - else { - timed_B_->setLinearOp(B); - } - - // build the inverse for F - ModifiableLinearOp & invF = state.getModifiableOp("invF"); - subTotal_.start(); - if(invF==Teuchos::null) { - invF = buildInverse(*invVelFactory_,F); - - timed_invF_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(),invF,"invF")); - } - else { - rebuildInverse(*invVelFactory_,F,invF); - - timed_invF_->setLinearOp(invF); - } - subTotal_.stop(); - - // build the approximate Schur complement - ModifiableLinearOp & invS = state.getModifiableOp("invS"); - subTotal_.start(); - if(invS==Teuchos::null) { - invS = buildInverse(*invPrsFactory_,hatS); - - timed_invS_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(),invS,"invS")); - } - else { - rebuildInverse(*invPrsFactory_,hatS,invS); - - timed_invS_->setLinearOp(invS); - } - subTotal_.stop(); - - std::vector invDiag(2); // vector storing inverses - - // build lower triangular inverse matrix - BlockedLinearOp L = zeroBlockedOp(blockOp); - setBlock(1,0,L,timed_B_); - endBlockFill(L); - - invDiag[0] = timed_invF_; - invDiag[1] = timed_invS_; - LinearOp invL = createBlockLowerTriInverseOp(L,invDiag); - - // build upper triangular matrix - BlockedLinearOp U = zeroBlockedOp(blockOp); - setBlock(0,1,U,scale(1.0/alpha_,timed_HBt_.getConst())); - endBlockFill(U); - - invDiag[0] = identity(rangeSpace(invF)); - invDiag[1] = scale(alpha_,identity(rangeSpace(invS))); - LinearOp invU = createBlockUpperTriInverseOp(U,invDiag); - - // return implicit product operator - Teko::LinearOp iU_t_iL = multiply(invU,invL,"SIMPLE_"+fApproxStr); - - // time the application of iU_t_iL - if(timed_iU_t_iL_==Teuchos::null) - timed_iU_t_iL_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(),iU_t_iL,"iU_t_iL")); - else - timed_iU_t_iL_->setLinearOp(iU_t_iL); - - constrCount_++; - - constrTotal_.stop(); - - return timed_iU_t_iL_; + } else { + // get generic diagonal + subTotal_.start(); + H = getInvDiagonalOp(matF, fInverseType_); + subTotal_.stop(); + fApproxStr = getDiagonalName(fInverseType_); + } + + // adjust H for time scaling if it is a mass matrix + if (useMass_) { + RCP pl = state.getParameterList(); + + if (pl->isParameter("stepsize")) { + // get the step size + double stepsize = pl->get("stepsize"); + + // scale by stepsize only if it is larger than 0 + if (stepsize > 0.0) H = scale(stepsize, H); + } + } + + // build approximate Schur complement: hatS = -C + B*H*Bt + LinearOp HBt, hatS; + + if (buildExplicitSchurComplement) { + ModifiableLinearOp& mHBt = state.getModifiableOp("HBt"); + ModifiableLinearOp& mhatS = state.getModifiableOp("hatS"); + ModifiableLinearOp& BHBt = state.getModifiableOp("BHBt"); + + // build H*Bt + subTotal_.start(); + mHBt = explicitMultiply(H, Bt, mHBt); + subTotal_.stop(); + HBt = mHBt; + + // build B*H*Bt + subTotal_.start(); + BHBt = explicitMultiply(B, HBt, BHBt); + subTotal_.stop(); + + // build C-B*H*Bt + subTotal_.start(); + mhatS = explicitAdd(C, scale(-1.0, BHBt), mhatS); + subTotal_.stop(); + hatS = mhatS; + } else { + // build an implicit Schur complement + HBt = multiply(H, Bt); + + hatS = add(C, scale(-1.0, multiply(B, HBt))); + } + + // time the application of HBt + if (timed_HBt_ == Teuchos::null) { + timed_HBt_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(), HBt, "HBt")); + } else { + timed_HBt_->setLinearOp(HBt); + } + + // time the application of B + if (timed_B_ == Teuchos::null) { + timed_B_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(), B, "B")); + } else { + timed_B_->setLinearOp(B); + } + + // build the inverse for F + ModifiableLinearOp& invF = state.getModifiableOp("invF"); + subTotal_.start(); + if (invF == Teuchos::null) { + invF = buildInverse(*invVelFactory_, F); + + timed_invF_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(), invF, "invF")); + } else { + rebuildInverse(*invVelFactory_, F, invF); + + timed_invF_->setLinearOp(invF); + } + subTotal_.stop(); + + // build the approximate Schur complement + ModifiableLinearOp& invS = state.getModifiableOp("invS"); + subTotal_.start(); + if (invS == Teuchos::null) { + invS = buildInverse(*invPrsFactory_, hatS); + + timed_invS_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(), invS, "invS")); + } else { + rebuildInverse(*invPrsFactory_, hatS, invS); + + timed_invS_->setLinearOp(invS); + } + subTotal_.stop(); + + std::vector invDiag(2); // vector storing inverses + + // build lower triangular inverse matrix + BlockedLinearOp L = zeroBlockedOp(blockOp); + setBlock(1, 0, L, timed_B_); + endBlockFill(L); + + invDiag[0] = timed_invF_; + invDiag[1] = timed_invS_; + LinearOp invL = createBlockLowerTriInverseOp(L, invDiag); + + // build upper triangular matrix + BlockedLinearOp U = zeroBlockedOp(blockOp); + setBlock(0, 1, U, scale(1.0 / alpha_, timed_HBt_.getConst())); + endBlockFill(U); + + invDiag[0] = identity(rangeSpace(invF)); + invDiag[1] = scale(alpha_, identity(rangeSpace(invS))); + LinearOp invU = createBlockUpperTriInverseOp(U, invDiag); + + // return implicit product operator + Teko::LinearOp iU_t_iL = multiply(invU, invL, "SIMPLE_" + fApproxStr); + + // time the application of iU_t_iL + if (timed_iU_t_iL_ == Teuchos::null) + timed_iU_t_iL_ = Teuchos::rcp(new DiagnosticLinearOp(getOutputStream(), iU_t_iL, "iU_t_iL")); + else + timed_iU_t_iL_->setLinearOp(iU_t_iL); + + constrCount_++; + + constrTotal_.stop(); + + return timed_iU_t_iL_; } //! Initialize from a parameter list -void TimingsSIMPLEPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList & pl) -{ - RCP invLib = getInverseLibrary(); - - // default conditions - useMass_ = false; - customHFactory_ = Teuchos::null; - fInverseType_ = Diagonal; - - // get string specifying inverse - std::string invStr="", invVStr="", invPStr=""; - alpha_ = 1.0; - - // "parse" the parameter list - if(pl.isParameter("Inverse Type")) - invStr = pl.get("Inverse Type"); - if(pl.isParameter("Inverse Velocity Type")) - invVStr = pl.get("Inverse Velocity Type"); - if(pl.isParameter("Inverse Pressure Type")) - invPStr = pl.get("Inverse Pressure Type"); - if(pl.isParameter("Alpha")) - alpha_ = pl.get("Alpha"); - if(pl.isParameter("Explicit Velocity Inverse Type")) { - std::string fInverseStr = pl.get("Explicit Velocity Inverse Type"); - - // build inverse types - fInverseType_ = getDiagonalType(fInverseStr); - if(fInverseType_==NotDiag) - customHFactory_ = invLib->getInverseFactory(fInverseStr); - - // Grab the sublist if we're using the block diagonal - if(fInverseType_==BlkDiag) - BlkDiagList_=pl.sublist("H options"); - } - if(pl.isParameter("Use Mass Scaling")) - useMass_ = pl.get("Use Mass Scaling"); - - Teko_DEBUG_MSG_BEGIN(5) - DEBUG_STREAM << "SIMPLE Parameters: " << std::endl; - DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; - DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; - DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; - DEBUG_STREAM << " alpha = " << alpha_ << std::endl; - DEBUG_STREAM << " use mass = " << useMass_ << std::endl; - DEBUG_STREAM << " vel scaling = " << getDiagonalName(fInverseType_) << std::endl; - DEBUG_STREAM << "SIMPLE Parameter list: " << std::endl; - pl.print(DEBUG_STREAM); - Teko_DEBUG_MSG_END() - - // set defaults as needed - if(invStr=="") invStr = "Amesos"; - if(invVStr=="") invVStr = invStr; - if(invPStr=="") invPStr = invStr; - - // two inverse factory objects - RCP invVFact, invPFact; - - // build velocity inverse factory - invVFact = invLib->getInverseFactory(invVStr); - invPFact = invVFact; // by default these are the same - if(invVStr!=invPStr) // if different, build pressure inverse factory - invPFact = invLib->getInverseFactory(invPStr); - - // based on parameter type build a strategy - invVelFactory_ = invVFact; - invPrsFactory_ = invPFact; - - if(useMass_) { - Teuchos::RCP rh = getRequestHandler(); - rh->preRequest(Teko::RequestMesg("Velocity Mass Matrix")); - Teko::LinearOp mass - = rh->request(Teko::RequestMesg("Velocity Mass Matrix")); - setMassMatrix(mass); - } +void TimingsSIMPLEPreconditionerFactory::initializeFromParameterList( + const Teuchos::ParameterList& pl) { + RCP invLib = getInverseLibrary(); + + // default conditions + useMass_ = false; + customHFactory_ = Teuchos::null; + fInverseType_ = Diagonal; + + // get string specifying inverse + std::string invStr = "", invVStr = "", invPStr = ""; + alpha_ = 1.0; + + // "parse" the parameter list + if (pl.isParameter("Inverse Type")) invStr = pl.get("Inverse Type"); + if (pl.isParameter("Inverse Velocity Type")) + invVStr = pl.get("Inverse Velocity Type"); + if (pl.isParameter("Inverse Pressure Type")) + invPStr = pl.get("Inverse Pressure Type"); + if (pl.isParameter("Alpha")) alpha_ = pl.get("Alpha"); + if (pl.isParameter("Explicit Velocity Inverse Type")) { + std::string fInverseStr = pl.get("Explicit Velocity Inverse Type"); + + // build inverse types + fInverseType_ = getDiagonalType(fInverseStr); + if (fInverseType_ == NotDiag) customHFactory_ = invLib->getInverseFactory(fInverseStr); + + // Grab the sublist if we're using the block diagonal + if (fInverseType_ == BlkDiag) BlkDiagList_ = pl.sublist("H options"); + } + if (pl.isParameter("Use Mass Scaling")) useMass_ = pl.get("Use Mass Scaling"); + + Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "SIMPLE Parameters: " << std::endl; + DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl; + DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl; + DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl; + DEBUG_STREAM << " alpha = " << alpha_ << std::endl; + DEBUG_STREAM << " use mass = " << useMass_ << std::endl; + DEBUG_STREAM << " vel scaling = " << getDiagonalName(fInverseType_) << std::endl; + DEBUG_STREAM << "SIMPLE Parameter list: " << std::endl; + pl.print(DEBUG_STREAM); + Teko_DEBUG_MSG_END() + + // set defaults as needed + if (invStr == "") invStr = "Amesos"; + if (invVStr == "") invVStr = invStr; + if (invPStr == "") invPStr = invStr; + + // two inverse factory objects + RCP invVFact, invPFact; + + // build velocity inverse factory + invVFact = invLib->getInverseFactory(invVStr); + invPFact = invVFact; // by default these are the same + if (invVStr != invPStr) // if different, build pressure inverse factory + invPFact = invLib->getInverseFactory(invPStr); + + // based on parameter type build a strategy + invVelFactory_ = invVFact; + invPrsFactory_ = invPFact; + + if (useMass_) { + Teuchos::RCP rh = getRequestHandler(); + rh->preRequest(Teko::RequestMesg("Velocity Mass Matrix")); + Teko::LinearOp mass = rh->request(Teko::RequestMesg("Velocity Mass Matrix")); + setMassMatrix(mass); + } } //! For assiting in construction of the preconditioner -Teuchos::RCP TimingsSIMPLEPreconditionerFactory::getRequestedParameters() const -{ - Teuchos::RCP result; - Teuchos::RCP pl = rcp(new Teuchos::ParameterList()); - - // grab parameters from F solver - RCP vList = invVelFactory_->getRequestedParameters(); - if(vList!=Teuchos::null) { - Teuchos::ParameterList::ConstIterator itr; - for(itr=vList->begin();itr!=vList->end();++itr) - pl->setEntry(itr->first,itr->second); - result = pl; - } +Teuchos::RCP TimingsSIMPLEPreconditionerFactory::getRequestedParameters() + const { + Teuchos::RCP result; + Teuchos::RCP pl = rcp(new Teuchos::ParameterList()); + + // grab parameters from F solver + RCP vList = invVelFactory_->getRequestedParameters(); + if (vList != Teuchos::null) { + Teuchos::ParameterList::ConstIterator itr; + for (itr = vList->begin(); itr != vList->end(); ++itr) pl->setEntry(itr->first, itr->second); + result = pl; + } - // grab parameters from S solver - RCP pList = invPrsFactory_->getRequestedParameters(); - if(pList!=Teuchos::null) { + // grab parameters from S solver + RCP pList = invPrsFactory_->getRequestedParameters(); + if (pList != Teuchos::null) { + Teuchos::ParameterList::ConstIterator itr; + for (itr = pList->begin(); itr != pList->end(); ++itr) pl->setEntry(itr->first, itr->second); + result = pl; + } + + // grab parameters from S solver + if (customHFactory_ != Teuchos::null) { + RCP hList = customHFactory_->getRequestedParameters(); + if (hList != Teuchos::null) { Teuchos::ParameterList::ConstIterator itr; - for(itr=pList->begin();itr!=pList->end();++itr) - pl->setEntry(itr->first,itr->second); + for (itr = hList->begin(); itr != hList->end(); ++itr) pl->setEntry(itr->first, itr->second); result = pl; - } - - // grab parameters from S solver - if(customHFactory_!=Teuchos::null) { - RCP hList = customHFactory_->getRequestedParameters(); - if(hList!=Teuchos::null) { - Teuchos::ParameterList::ConstIterator itr; - for(itr=hList->begin();itr!=hList->end();++itr) - pl->setEntry(itr->first,itr->second); - result = pl; - } - } - - return result; + } + } + + return result; } //! For assiting in construction of the preconditioner -bool TimingsSIMPLEPreconditionerFactory::updateRequestedParameters(const Teuchos::ParameterList & pl) -{ - Teko_DEBUG_SCOPE("InvLSCStrategy::updateRequestedParameters",10); - bool result = true; - - // update requested parameters in solvers - result &= invVelFactory_->updateRequestedParameters(pl); - result &= invPrsFactory_->updateRequestedParameters(pl); - if(customHFactory_!=Teuchos::null) - result &= customHFactory_->updateRequestedParameters(pl); - - return result; +bool TimingsSIMPLEPreconditionerFactory::updateRequestedParameters( + const Teuchos::ParameterList& pl) { + Teko_DEBUG_SCOPE("InvLSCStrategy::updateRequestedParameters", 10); + bool result = true; + + // update requested parameters in solvers + result &= invVelFactory_->updateRequestedParameters(pl); + result &= invPrsFactory_->updateRequestedParameters(pl); + if (customHFactory_ != Teuchos::null) result &= customHFactory_->updateRequestedParameters(pl); + + return result; } -} // end namespace NS -} // end namespace Teko +} // end namespace NS +} // end namespace Teko diff --git a/packages/teko/src/NS/Teko_TimingsSIMPLEPreconditionerFactory.hpp b/packages/teko/src/NS/Teko_TimingsSIMPLEPreconditionerFactory.hpp index 5478714b205a..58720a6bbbeb 100644 --- a/packages/teko/src/NS/Teko_TimingsSIMPLEPreconditionerFactory.hpp +++ b/packages/teko/src/NS/Teko_TimingsSIMPLEPreconditionerFactory.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -58,7 +58,7 @@ namespace NS { // Declaration of the preconditioner factory /** The basic XML parameter list for SIMPLE looks like. - + \code @@ -74,68 +74,65 @@ namespace NS { \endcode */ class TimingsSIMPLEPreconditionerFactory : public BlockPreconditionerFactory { -public: - // Constructor - TimingsSIMPLEPreconditionerFactory(const Teuchos::RCP & inverse, - double alpha); - - // Constructor - TimingsSIMPLEPreconditionerFactory(const Teuchos::RCP & invVelFactory, - const Teuchos::RCP & invPrsFactory, - double alpha); - - //! Default constructor - TimingsSIMPLEPreconditionerFactory(); - - //! Destructor that outputs construction timings - virtual ~TimingsSIMPLEPreconditionerFactory(); - - // Function inherited from BlockPreconditionerFactory - LinearOp buildPreconditionerOperator(BlockedLinearOp & blo, - BlockPreconditionerState & state) const; - - //! Set the mass matrix for this factory - virtual void setMassMatrix(Teko::LinearOp & mass) - { massMatrix_ = mass; } - - //! For assisting in construction of the preconditioner - virtual Teuchos::RCP getRequestedParameters() const; - - //! For assisting in construction of the preconditioner - virtual bool updateRequestedParameters(const Teuchos::ParameterList & pl); - - //! Initialize from a parameter list - virtual void initializeFromParameterList(const Teuchos::ParameterList & pl); - -protected: - using Teko::BlockPreconditionerFactory::buildPreconditionerOperator; - - // class members - Teuchos::RCP customHFactory_; - Teuchos::RCP invVelFactory_; - Teuchos::RCP invPrsFactory_; - double alpha_; - DiagonalType fInverseType_; - // enum FInverseType {Diagonal,Lumped,AbsRowSum,Custom} fInverseType_; - - bool useMass_; - Teko::LinearOp massMatrix_; - - // Info for the block-diagonal approximation to H if used. - mutable Teuchos::ParameterList BlkDiagList_; - - mutable Teuchos::Time constrTotal_; - mutable Teuchos::Time subTotal_; - mutable int constrCount_; - - mutable Teuchos::RCP timed_HBt_; - mutable Teuchos::RCP timed_B_; - mutable Teuchos::RCP timed_invF_; - mutable Teuchos::RCP timed_invS_; - mutable Teuchos::RCP timed_iU_t_iL_; + public: + // Constructor + TimingsSIMPLEPreconditionerFactory(const Teuchos::RCP& inverse, double alpha); + + // Constructor + TimingsSIMPLEPreconditionerFactory(const Teuchos::RCP& invVelFactory, + const Teuchos::RCP& invPrsFactory, + double alpha); + + //! Default constructor + TimingsSIMPLEPreconditionerFactory(); + + //! Destructor that outputs construction timings + virtual ~TimingsSIMPLEPreconditionerFactory(); + + // Function inherited from BlockPreconditionerFactory + LinearOp buildPreconditionerOperator(BlockedLinearOp& blo, BlockPreconditionerState& state) const; + + //! Set the mass matrix for this factory + virtual void setMassMatrix(Teko::LinearOp& mass) { massMatrix_ = mass; } + + //! For assisting in construction of the preconditioner + virtual Teuchos::RCP getRequestedParameters() const; + + //! For assisting in construction of the preconditioner + virtual bool updateRequestedParameters(const Teuchos::ParameterList& pl); + + //! Initialize from a parameter list + virtual void initializeFromParameterList(const Teuchos::ParameterList& pl); + + protected: + using Teko::BlockPreconditionerFactory::buildPreconditionerOperator; + + // class members + Teuchos::RCP customHFactory_; + Teuchos::RCP invVelFactory_; + Teuchos::RCP invPrsFactory_; + double alpha_; + DiagonalType fInverseType_; + // enum FInverseType {Diagonal,Lumped,AbsRowSum,Custom} fInverseType_; + + bool useMass_; + Teko::LinearOp massMatrix_; + + // Info for the block-diagonal approximation to H if used. + mutable Teuchos::ParameterList BlkDiagList_; + + mutable Teuchos::Time constrTotal_; + mutable Teuchos::Time subTotal_; + mutable int constrCount_; + + mutable Teuchos::RCP timed_HBt_; + mutable Teuchos::RCP timed_B_; + mutable Teuchos::RCP timed_invF_; + mutable Teuchos::RCP timed_invS_; + mutable Teuchos::RCP timed_iU_t_iL_; }; - -} // end namespace NS -} // end namespace Teko + +} // end namespace NS +} // end namespace Teko #endif diff --git a/packages/teko/src/Teko_AddPreconditionerFactory.cpp b/packages/teko/src/Teko_AddPreconditionerFactory.cpp index cc3266cb4526..28a375928508 100644 --- a/packages/teko/src/Teko_AddPreconditionerFactory.cpp +++ b/packages/teko/src/Teko_AddPreconditionerFactory.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -51,73 +51,69 @@ namespace Teko { using Teuchos::RCP; AddPreconditionerFactory::AddPreconditionerFactory( - const RCP & FirstFactory, - const RCP & SecondFactory) - : FirstFactory_(FirstFactory), SecondFactory_(SecondFactory) -{} + const RCP &FirstFactory, + const RCP &SecondFactory) + : FirstFactory_(FirstFactory), SecondFactory_(SecondFactory) {} -AddPreconditionerFactory::AddPreconditionerFactory() -{} +AddPreconditionerFactory::AddPreconditionerFactory() {} //! Build the AddPrecondState object -RCP AddPreconditionerFactory::buildPreconditionerState() const -{ - AddPrecondState* mystate = new AddPrecondState(); - mystate->StateOne_ = Teuchos::rcp_dynamic_cast(FirstFactory_->buildPreconditionerState()); - mystate->StateTwo_ = Teuchos::rcp_dynamic_cast(SecondFactory_->buildPreconditionerState()); - return rcp(mystate); +RCP AddPreconditionerFactory::buildPreconditionerState() const { + AddPrecondState *mystate = new AddPrecondState(); + mystate->StateOne_ = Teuchos::rcp_dynamic_cast( + FirstFactory_->buildPreconditionerState()); + mystate->StateTwo_ = Teuchos::rcp_dynamic_cast( + SecondFactory_->buildPreconditionerState()); + return rcp(mystate); } // Use the factory to build the preconditioner (this is where the work goes) -LinearOp AddPreconditionerFactory - ::buildPreconditionerOperator(BlockedLinearOp & blockOp, - BlockPreconditionerState & state) const -{ - // The main tricky thing here is that we have to take the 'state' object - // associated with AddPreconditionerFactory(), pull out the states for - // the individual preconditioners, and pass these on to - // buildPreconditionerOperator() for each subpreconditioner. - - AddPrecondState *MyState = dynamic_cast (&state); - TEUCHOS_ASSERT(MyState != 0); - - LinearOp M1 = FirstFactory_->buildPreconditionerOperator(blockOp, *MyState->StateOne_); - LinearOp M2 = SecondFactory_->buildPreconditionerOperator(blockOp, *MyState->StateTwo_); - - LinearOp invA = add(M1, M2); - - // return fully constructed preconditioner - return invA; +LinearOp AddPreconditionerFactory ::buildPreconditionerOperator( + BlockedLinearOp &blockOp, BlockPreconditionerState &state) const { + // The main tricky thing here is that we have to take the 'state' object + // associated with AddPreconditionerFactory(), pull out the states for + // the individual preconditioners, and pass these on to + // buildPreconditionerOperator() for each subpreconditioner. + + AddPrecondState *MyState = dynamic_cast(&state); + TEUCHOS_ASSERT(MyState != 0); + + LinearOp M1 = FirstFactory_->buildPreconditionerOperator(blockOp, *MyState->StateOne_); + LinearOp M2 = SecondFactory_->buildPreconditionerOperator(blockOp, *MyState->StateTwo_); + + LinearOp invA = add(M1, M2); + + // return fully constructed preconditioner + return invA; } //! Initialize from a parameter list -void AddPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList & pl) -{ - RCP invLib = getInverseLibrary(); +void AddPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList &pl) { + RCP invLib = getInverseLibrary(); - // get string specifying inverse - std::string aStr="", bStr=""; + // get string specifying inverse + std::string aStr = "", bStr = ""; - // "parse" the parameter list - aStr = pl.get("Preconditioner A"); - bStr = pl.get("Preconditioner B"); + // "parse" the parameter list + aStr = pl.get("Preconditioner A"); + bStr = pl.get("Preconditioner B"); - RCP aSettings = invLib->getParameterList(aStr); - RCP bSettings = invLib->getParameterList(bStr); + RCP aSettings = invLib->getParameterList(aStr); + RCP bSettings = invLib->getParameterList(bStr); - // build preconditioner from the parameters - std::string aType = aSettings->get("Preconditioner Type"); - RCP precA - = Teko::PreconditionerFactory::buildPreconditionerFactory(aType,aSettings->sublist("Preconditioner Settings"),invLib); + // build preconditioner from the parameters + std::string aType = aSettings->get("Preconditioner Type"); + RCP precA = Teko::PreconditionerFactory::buildPreconditionerFactory( + aType, aSettings->sublist("Preconditioner Settings"), invLib); - // build preconditioner from the parameters - std::string bType = bSettings->get("Preconditioner Type"); - RCP precB - = Teko::PreconditionerFactory::buildPreconditionerFactory(bType,bSettings->sublist("Preconditioner Settings"),invLib); + // build preconditioner from the parameters + std::string bType = bSettings->get("Preconditioner Type"); + RCP precB = Teko::PreconditionerFactory::buildPreconditionerFactory( + bType, bSettings->sublist("Preconditioner Settings"), invLib); - // set preconditioners - FirstFactory_ = Teuchos::rcp_dynamic_cast(precA); - SecondFactory_ = Teuchos::rcp_dynamic_cast(precB); + // set preconditioners + FirstFactory_ = Teuchos::rcp_dynamic_cast(precA); + SecondFactory_ = Teuchos::rcp_dynamic_cast(precB); } -} // end namespace Teko +} // end namespace Teko diff --git a/packages/teko/src/Teko_AddPreconditionerFactory.hpp b/packages/teko/src/Teko_AddPreconditionerFactory.hpp index 15151913e3cf..1c466aa5b46c 100644 --- a/packages/teko/src/Teko_AddPreconditionerFactory.hpp +++ b/packages/teko/src/Teko_AddPreconditionerFactory.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -53,48 +53,48 @@ namespace Teko { /** Preconditioning factories must supply a 'State' class which - * is where data specific to the preconditioner construction - * is stored. The constructor will be invoked elsewhere. - */ + * is where data specific to the preconditioner construction + * is stored. The constructor will be invoked elsewhere. + */ class AddPrecondState : public Teko::BlockPreconditionerState { -public: - AddPrecondState() {} + public: + AddPrecondState() {} - Teuchos::RCP StateOne_; - Teuchos::RCP StateTwo_; + Teuchos::RCP StateOne_; + Teuchos::RCP StateTwo_; }; /** Declaration of preconditioner factory that creates - * a preconditioner which is the sum (additive) of two - * other preconditioners. - */ -class AddPreconditionerFactory - : public Teko::BlockPreconditionerFactory { -public: - //! Constructor - AddPreconditionerFactory(const Teuchos::RCP & FirstFactory, - const Teuchos::RCP & SecondFactory); + * a preconditioner which is the sum (additive) of two + * other preconditioners. + */ +class AddPreconditionerFactory : public Teko::BlockPreconditionerFactory { + public: + //! Constructor + AddPreconditionerFactory( + const Teuchos::RCP& FirstFactory, + const Teuchos::RCP& SecondFactory); - AddPreconditionerFactory(); + AddPreconditionerFactory(); - //! Function inherited from Teko::BlockPreconditionerFactory - Teko::LinearOp buildPreconditionerOperator(Teko::BlockedLinearOp & blo, - Teko::BlockPreconditionerState & state) const; - - //! Build the AddPrecondState object - virtual Teuchos::RCP buildPreconditionerState() const; + //! Function inherited from Teko::BlockPreconditionerFactory + Teko::LinearOp buildPreconditionerOperator(Teko::BlockedLinearOp& blo, + Teko::BlockPreconditionerState& state) const; -protected: - using Teko::BlockPreconditionerFactory::buildPreconditionerOperator; + //! Build the AddPrecondState object + virtual Teuchos::RCP buildPreconditionerState() const; - // class members - Teuchos::RCP FirstFactory_; - Teuchos::RCP SecondFactory_; + protected: + using Teko::BlockPreconditionerFactory::buildPreconditionerOperator; - //! Initialize from a parameter list - virtual void initializeFromParameterList(const Teuchos::ParameterList & pl); + // class members + Teuchos::RCP FirstFactory_; + Teuchos::RCP SecondFactory_; + + //! Initialize from a parameter list + virtual void initializeFromParameterList(const Teuchos::ParameterList& pl); }; -} // end namespace Teko +} // end namespace Teko #endif diff --git a/packages/teko/src/Teko_BlockImplicitLinearOp.cpp b/packages/teko/src/Teko_BlockImplicitLinearOp.cpp index 6dacdd467b3d..4affd04d677d 100644 --- a/packages/teko/src/Teko_BlockImplicitLinearOp.cpp +++ b/packages/teko/src/Teko_BlockImplicitLinearOp.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -48,51 +48,42 @@ namespace Teko { -using Teuchos::rcpFromRef; -using Teuchos::rcp_dynamic_cast; -using Teuchos::rcp_const_cast; using Teuchos::RCP; +using Teuchos::rcp_const_cast; +using Teuchos::rcp_dynamic_cast; +using Teuchos::rcpFromRef; using Thyra::ProductMultiVectorBase; -void -BlockImplicitLinearOp:: -implicitApply(const Thyra::EOpTransp M_trans, - const BlockedMultiVector & x, BlockedMultiVector & y, - const double alpha, const double beta) const -{ - TEUCHOS_TEST_FOR_EXCEPTION(M_trans!=Thyra::NOTRANS, std::runtime_error, - "Linear operators of inherited type BlockImplicitLinearOp " - "cannot handle conjugation (yet!)"); +void BlockImplicitLinearOp::implicitApply(const Thyra::EOpTransp M_trans, + const BlockedMultiVector& x, BlockedMultiVector& y, + const double alpha, const double beta) const { + TEUCHOS_TEST_FOR_EXCEPTION(M_trans != Thyra::NOTRANS, std::runtime_error, + "Linear operators of inherited type BlockImplicitLinearOp " + "cannot handle conjugation (yet!)"); - // call apply - implicitApply(x,y,alpha,beta); + // call apply + implicitApply(x, y, alpha, beta); } -bool BlockImplicitLinearOp::opSupportedImpl(const Thyra::EOpTransp M_trans) const -{ +bool BlockImplicitLinearOp::opSupportedImpl(const Thyra::EOpTransp M_trans) const { return (M_trans == Thyra::NOTRANS); } -void BlockImplicitLinearOp::applyImpl( - const Thyra::EOpTransp M_trans, - const Thyra::MultiVectorBase & x, - const Teuchos::Ptr > & y, - const double alpha, - const double beta - ) const -{ - // cast source vector - RCP > src = - rcp_dynamic_cast >(rcpFromRef(x)); - BlockedMultiVector srcX = rcp_const_cast >(src); +void BlockImplicitLinearOp::applyImpl(const Thyra::EOpTransp M_trans, + const Thyra::MultiVectorBase& x, + const Teuchos::Ptr >& y, + const double alpha, const double beta) const { + // cast source vector + RCP > src = + rcp_dynamic_cast >(rcpFromRef(x)); + BlockedMultiVector srcX = rcp_const_cast >(src); - // cast destination vector - BlockedMultiVector destY = - rcp_dynamic_cast >(rcpFromPtr(y)); + // cast destination vector + BlockedMultiVector destY = rcp_dynamic_cast >(rcpFromPtr(y)); - // call apply - implicitApply(M_trans,srcX,destY,alpha,beta); + // call apply + implicitApply(M_trans, srcX, destY, alpha, beta); } - -} // end namespace Teko + +} // end namespace Teko diff --git a/packages/teko/src/Teko_BlockImplicitLinearOp.hpp b/packages/teko/src/Teko_BlockImplicitLinearOp.hpp index 2c0845daef76..dc9dbae781bc 100644 --- a/packages/teko/src/Teko_BlockImplicitLinearOp.hpp +++ b/packages/teko/src/Teko_BlockImplicitLinearOp.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,72 +52,66 @@ namespace Teko { /** \brief A virtual class that simplifies the construction - * of custom operators. - * - * A virtual class that simplifies the construction - * of custom operators. Good examples can be found in LU2x2InverseOp - * and in BlockUpperTriInverseOp. - */ + * of custom operators. + * + * A virtual class that simplifies the construction + * of custom operators. Good examples can be found in LU2x2InverseOp + * and in BlockUpperTriInverseOp. + */ class BlockImplicitLinearOp : public Thyra::LinearOpBase { -public: + public: + /** @brief Range space of this operator */ + virtual VectorSpace range() const = 0; - /** @brief Range space of this operator */ - virtual VectorSpace range() const = 0; + /** @brief Domain space of this operator */ + virtual VectorSpace domain() const = 0; - /** @brief Domain space of this operator */ - virtual VectorSpace domain() const = 0; + /** @brief Perform a matrix vector multiply with this implicitly + * defined blocked operator. + * + * The apply function takes one vector as input + * and applies a linear operator. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ + virtual void implicitApply(const BlockedMultiVector& x, BlockedMultiVector& y, + const double alpha = 1.0, const double beta = 0.0) const = 0; - /** @brief Perform a matrix vector multiply with this implicitly - * defined blocked operator. - * - * The apply function takes one vector as input - * and applies a linear operator. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ - virtual void implicitApply(const BlockedMultiVector & x, BlockedMultiVector & y, - const double alpha = 1.0, const double beta = 0.0) const = 0; + /** @brief Perform a matrix vector multiply with this implicitly + * defined blocked operator. + * + * The apply function takes one vector as input + * and applies a linear operator. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ + virtual void implicitApply(const Thyra::EOpTransp M_trans, const BlockedMultiVector& x, + BlockedMultiVector& y, const double alpha = 1.0, + const double beta = 0.0) const; - /** @brief Perform a matrix vector multiply with this implicitly - * defined blocked operator. - * - * The apply function takes one vector as input - * and applies a linear operator. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ - virtual void implicitApply(const Thyra::EOpTransp M_trans, - const BlockedMultiVector & x, BlockedMultiVector & y, - const double alpha = 1.0, const double beta = 0.0) const; - -protected: - - //! Functions required by Thyra::LinearOpBase - //@{ + protected: + //! Functions required by Thyra::LinearOpBase + //@{ virtual bool opSupportedImpl(const Thyra::EOpTransp M_trans) const; - virtual void applyImpl( - const Thyra::EOpTransp M_trans, - const Thyra::MultiVectorBase & x, - const Teuchos::Ptr > & y, - const double alpha, - const double beta - ) const; - - //@} + virtual void applyImpl(const Thyra::EOpTransp M_trans, const Thyra::MultiVectorBase& x, + const Teuchos::Ptr >& y, const double alpha, + const double beta) const; + + //@} }; -} // end namespace Teko +} // end namespace Teko #endif diff --git a/packages/teko/src/Teko_BlockInvDiagonalStrategy.cpp b/packages/teko/src/Teko_BlockInvDiagonalStrategy.cpp index b89e767b93db..985587f4eb40 100644 --- a/packages/teko/src/Teko_BlockInvDiagonalStrategy.cpp +++ b/packages/teko/src/Teko_BlockInvDiagonalStrategy.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -48,65 +48,62 @@ namespace Teko { -InvFactoryDiagStrategy::InvFactoryDiagStrategy(const Teuchos::RCP & factory) -{ - // only one factory to use! - invDiagFact_.resize(1,factory); - defaultInvFact_ = factory; +InvFactoryDiagStrategy::InvFactoryDiagStrategy(const Teuchos::RCP& factory) { + // only one factory to use! + invDiagFact_.resize(1, factory); + defaultInvFact_ = factory; } -InvFactoryDiagStrategy::InvFactoryDiagStrategy(const std::vector > & factories, - const Teuchos::RCP & defaultFact) -{ - invDiagFact_ = factories; +InvFactoryDiagStrategy::InvFactoryDiagStrategy( + const std::vector >& factories, + const Teuchos::RCP& defaultFact) { + invDiagFact_ = factories; - if(defaultFact==Teuchos::null) - defaultInvFact_ = invDiagFact_[0]; - else - defaultInvFact_ = defaultFact; + if (defaultFact == Teuchos::null) + defaultInvFact_ = invDiagFact_[0]; + else + defaultInvFact_ = defaultFact; } /** returns an (approximate) inverse of the diagonal blocks of A - * where A is closely related to the original source for invD0 and invD1 - */ -void InvFactoryDiagStrategy::getInvD(const BlockedLinearOp & A,BlockPreconditionerState & state,std::vector & invDiag) const -{ - Teko_DEBUG_SCOPE("InvFactoryDiagStrategy::getInvD",10); + * where A is closely related to the original source for invD0 and invD1 + */ +void InvFactoryDiagStrategy::getInvD(const BlockedLinearOp& A, BlockPreconditionerState& state, + std::vector& invDiag) const { + Teko_DEBUG_SCOPE("InvFactoryDiagStrategy::getInvD", 10); - // loop over diagonals, build an inverse operator for each - int diagCnt = A->productRange()->numBlocks(); - int invCnt = invDiagFact_.size(); + // loop over diagonals, build an inverse operator for each + int diagCnt = A->productRange()->numBlocks(); + int invCnt = invDiagFact_.size(); - Teko_DEBUG_MSG("# diags = " << diagCnt << ", # inverses = " << invCnt,6); + Teko_DEBUG_MSG("# diags = " << diagCnt << ", # inverses = " << invCnt, 6); - const std::string opPrefix = "JacobiDiagOp"; - if(diagCnt<=invCnt) { - for(int i=0;i & invDiag) const = 0; + public: + virtual ~BlockInvDiagonalStrategy() {} + //! returns an (approximate) inverse of the diagonal blocks of A + virtual void getInvD(const BlockedLinearOp &A, BlockPreconditionerState &state, + std::vector &invDiag) const = 0; }; /** This is a simple strategy for a [whatever]PreconditionerFactory - * it simply returns statically set RCP pointers to the passed in - * inv(D0) and inv(D1) operators. Not this will _not_ permit - * efficient implementations when the preconditioner has to be rebuilt - * or reused often. - */ + * it simply returns statically set RCP pointers to the passed in + * inv(D0) and inv(D1) operators. Not this will _not_ permit + * efficient implementations when the preconditioner has to be rebuilt + * or reused often. + */ class StaticInvDiagStrategy : public BlockInvDiagonalStrategy { -public: - StaticInvDiagStrategy(const LinearOp & invD0, - const LinearOp & invD1) - { invDiag_.push_back(invD0); invDiag_.push_back(invD1); } - - StaticInvDiagStrategy(const std::vector & invD) - : invDiag_(invD) - { } - - virtual ~StaticInvDiagStrategy() {} - - /** returns an (approximate) inverse of the diagonal blocks of A - * where A is closely related to the original source for invD0 and invD1 - */ - virtual void getInvD(const BlockedLinearOp & /* A */, BlockPreconditionerState & /* state */, - std::vector & invDiag) const - { invDiag.clear(); invDiag = invDiag_; } - -protected: - // stored inverse operators - std::vector > > invDiag_; + public: + StaticInvDiagStrategy(const LinearOp &invD0, const LinearOp &invD1) { + invDiag_.push_back(invD0); + invDiag_.push_back(invD1); + } + + StaticInvDiagStrategy(const std::vector &invD) : invDiag_(invD) {} + + virtual ~StaticInvDiagStrategy() {} + + /** returns an (approximate) inverse of the diagonal blocks of A + * where A is closely related to the original source for invD0 and invD1 + */ + virtual void getInvD(const BlockedLinearOp & /* A */, BlockPreconditionerState & /* state */, + std::vector &invDiag) const { + invDiag.clear(); + invDiag = invDiag_; + } + + protected: + // stored inverse operators + std::vector > > invDiag_; }; /** A simple class that takes a vector of the InverseFactory objects - * and pairs each with the diagonal element of the block matrix. This provides - * the operators needed to use Gauss-Seidel or Jacobi. - */ + * and pairs each with the diagonal element of the block matrix. This provides + * the operators needed to use Gauss-Seidel or Jacobi. + */ class InvFactoryDiagStrategy : public BlockInvDiagonalStrategy { -public: - /** Constructor accepting a single inverse factory that will be used - * to invert all diagonal blocks. - * - * \param[in] factory Factory to be used to invert each diagonal block. - */ - InvFactoryDiagStrategy(const Teuchos::RCP & factory); - - /** Constructor that lets the inverse of each block be set individually. - * - * \param[in] factories A vector of InverseFactory objects - * which should be the same length as the number of - * diagonal blocks. - * \param[in] defaultFact The default factory to use if none is specified. - */ - InvFactoryDiagStrategy(const std::vector > & factories, - const Teuchos::RCP & defaultFact=Teuchos::null); - - virtual ~InvFactoryDiagStrategy() {} - - /** returns an (approximate) inverse of the diagonal blocks of A - * where A is closely related to the original source for invD0 and invD1 - * - * \param[in] A Operator to extract the block diagonals from. - * \param[in] state State object for this operator. - * \param[in,out] invDiag Vector eventually containing the inverse operators - */ - virtual void getInvD(const BlockedLinearOp & A, BlockPreconditionerState & state, - std::vector & invDiag) const; - - //! Get factories for testing purposes. - const std::vector > & getFactories() const - { return invDiagFact_; } - -protected: - // stored inverse operators - std::vector > invDiagFact_; - Teuchos::RCP defaultInvFact_; - - //! Conveinence function for building inverse operators - LinearOp buildInverse(const InverseFactory & invFact,const LinearOp & matrix, - BlockPreconditionerState & state, - const std::string & opPrefix,int i) const; - -private: - InvFactoryDiagStrategy(); - InvFactoryDiagStrategy(const InvFactoryDiagStrategy &); + public: + /** Constructor accepting a single inverse factory that will be used + * to invert all diagonal blocks. + * + * \param[in] factory Factory to be used to invert each diagonal block. + */ + InvFactoryDiagStrategy(const Teuchos::RCP &factory); + + /** Constructor that lets the inverse of each block be set individually. + * + * \param[in] factories A vector of InverseFactory objects + * which should be the same length as the number of + * diagonal blocks. + * \param[in] defaultFact The default factory to use if none is specified. + */ + InvFactoryDiagStrategy(const std::vector > &factories, + const Teuchos::RCP &defaultFact = Teuchos::null); + + virtual ~InvFactoryDiagStrategy() {} + + /** returns an (approximate) inverse of the diagonal blocks of A + * where A is closely related to the original source for invD0 and invD1 + * + * \param[in] A Operator to extract the block diagonals from. + * \param[in] state State object for this operator. + * \param[in,out] invDiag Vector eventually containing the inverse operators + */ + virtual void getInvD(const BlockedLinearOp &A, BlockPreconditionerState &state, + std::vector &invDiag) const; + + //! Get factories for testing purposes. + const std::vector > &getFactories() const { return invDiagFact_; } + + protected: + // stored inverse operators + std::vector > invDiagFact_; + Teuchos::RCP defaultInvFact_; + + //! Conveinence function for building inverse operators + LinearOp buildInverse(const InverseFactory &invFact, const LinearOp &matrix, + BlockPreconditionerState &state, const std::string &opPrefix, int i) const; + + private: + InvFactoryDiagStrategy(); + InvFactoryDiagStrategy(const InvFactoryDiagStrategy &); }; -} // end namespace Teko +} // end namespace Teko #endif diff --git a/packages/teko/src/Teko_BlockLowerTriInverseOp.cpp b/packages/teko/src/Teko_BlockLowerTriInverseOp.cpp index b3b430ffa1d0..ed860406b87e 100644 --- a/packages/teko/src/Teko_BlockLowerTriInverseOp.cpp +++ b/packages/teko/src/Teko_BlockLowerTriInverseOp.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -52,126 +52,116 @@ namespace Teko { using Teuchos::RCP; -BlockLowerTriInverseOp::BlockLowerTriInverseOp(BlockedLinearOp & L,const std::vector & invDiag) - : L_(L) -{ - invDiag_ = invDiag; +BlockLowerTriInverseOp::BlockLowerTriInverseOp(BlockedLinearOp& L, + const std::vector& invDiag) + : L_(L) { + invDiag_ = invDiag; - // sanity check - int blocks = blockRowCount(L_); - TEUCHOS_ASSERT(blocks>0); - TEUCHOS_ASSERT(blocks==blockColCount(L_)); - TEUCHOS_ASSERT(blocks==(int) invDiag_.size()); + // sanity check + int blocks = blockRowCount(L_); + TEUCHOS_ASSERT(blocks > 0); + TEUCHOS_ASSERT(blocks == blockColCount(L_)); + TEUCHOS_ASSERT(blocks == (int)invDiag_.size()); - // create the range and product space - /////////////////////////////////////////////////// + // create the range and product space + /////////////////////////////////////////////////// - // just flip flop them! - productRange_ = L_->productDomain(); - productDomain_ = L_->productRange(); + // just flip flop them! + productRange_ = L_->productDomain(); + productDomain_ = L_->productRange(); } -/** @brief Perform a matrix vector multiply with this operator. - * - * The apply function takes one vector as input - * and applies the inverse \f$ LDU \f$ decomposition. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ -void BlockLowerTriInverseOp::implicitApply(const BlockedMultiVector & src, BlockedMultiVector & dst, - const double alpha, const double beta) const -{ - int blocks = blockCount(src); - - TEUCHOS_ASSERT(blocks==blockRowCount(L_)); - TEUCHOS_ASSERT(blocks==blockCount(dst)); - - // build a scrap vector for storing work - srcScrap_ = datacopy(src,srcScrap_); - BlockedMultiVector dstCopy; - if(beta!=0.0) { - dstScrap_ = datacopy(dst,dstScrap_); - dstCopy = dstScrap_; - } - else - dstCopy = dst; // shallow copy - - // extract the blocks componets from - // the source and destination vectors - std::vector dstVec; - std::vector scrapVec; - for(int b=0;bapply function takes one vector as input + * and applies the inverse \f$ LDU \f$ decomposition. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ +void BlockLowerTriInverseOp::implicitApply(const BlockedMultiVector& src, BlockedMultiVector& dst, + const double alpha, const double beta) const { + int blocks = blockCount(src); + + TEUCHOS_ASSERT(blocks == blockRowCount(L_)); + TEUCHOS_ASSERT(blocks == blockCount(dst)); + + // build a scrap vector for storing work + srcScrap_ = datacopy(src, srcScrap_); + BlockedMultiVector dstCopy; + if (beta != 0.0) { + dstScrap_ = datacopy(dst, dstScrap_); + dstCopy = dstScrap_; + } else + dstCopy = dst; // shallow copy + + // extract the blocks componets from + // the source and destination vectors + std::vector dstVec; + std::vector scrapVec; + for (int b = 0; b < blocks; b++) { + dstVec.push_back(getBlock(b, dstCopy)); + scrapVec.push_back(getBlock(b, srcScrap_)); + } + + // run forward-substituion: run over each column + // From Heath pg. 65 + for (int b = 0; b < blocks; b++) { + applyOp(invDiag_[b], scrapVec[b], dstVec[b]); + + // loop over each row + for (int i = b + 1; i < blocks; i++) { + LinearOp u_ib = getBlock(i, b, L_); + if (u_ib != Teuchos::null) { + applyOp(u_ib, dstVec[b], scrapVec[i], -1.0, 1.0); } - } + } + } - // scale result by alpha - if(beta!=0) - update(alpha,dstCopy,beta,dst); // dst = alpha * dstCopy + beta * dst - else if(alpha!=1.0) - scale(alpha,dst); // dst = alpha * dst + // scale result by alpha + if (beta != 0) + update(alpha, dstCopy, beta, dst); // dst = alpha * dstCopy + beta * dst + else if (alpha != 1.0) + scale(alpha, dst); // dst = alpha * dst } -void BlockLowerTriInverseOp::describe(Teuchos::FancyOStream & out_arg, - const Teuchos::EVerbosityLevel verbLevel) const -{ +void BlockLowerTriInverseOp::describe(Teuchos::FancyOStream& out_arg, + const Teuchos::EVerbosityLevel verbLevel) const { using Teuchos::OSTab; - RCP out = rcp(&out_arg,false); + RCP out = rcp(&out_arg, false); OSTab tab(out); - switch(verbLevel) { - case Teuchos::VERB_DEFAULT: - case Teuchos::VERB_LOW: - *out << this->description() << std::endl; - break; - case Teuchos::VERB_MEDIUM: - case Teuchos::VERB_HIGH: - case Teuchos::VERB_EXTREME: - { - *out << Teuchos::Describable::description() << "{" - << "rangeDim=" << this->range()->dim() - << ",domainDim=" << this->domain()->dim() - << ",rows=" << blockRowCount(L_) - << ",cols=" << blockColCount(L_) - << "}\n"; - { - OSTab tab2(out); - *out << "[L Operator] = "; - *out << Teuchos::describe(*L_,verbLevel); - } - { - OSTab tab2(out); - *out << "[invDiag Operators]:\n"; - tab.incrTab(); - for(int i=0;i & invDiag); - - //! @name Inherited methods from Thyra::LinearOpBase - //@{ - - /** @brief Range space of this operator */ - virtual VectorSpace range() const { return productRange_; } - - /** @brief Domain space of this operator */ - virtual VectorSpace domain() const { return productDomain_; } - - /** @brief Perform a matrix vector multiply with this operator. - * - * The apply function takes one vector as input - * and applies the inverse \f$ LDU \f$ decomposition. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ - virtual void implicitApply(const BlockedMultiVector & x, BlockedMultiVector & y, - const double alpha = 1.0, const double beta = 0.0) const; - //@} - - virtual void describe(Teuchos::FancyOStream &out_arg, - const Teuchos::EVerbosityLevel verbLevel) const; - -protected: - // fundamental operators to use - const BlockedLinearOp L_; ///< operator \f$ L \f$ - std::vector invDiag_; ///< (Approximate) Inverses of the diagonal operators - - Teuchos::RCP > productRange_; ///< Range vector space. - Teuchos::RCP > productDomain_; ///< Domain vector space. - - // scratch space...so we don't have to reallocate - mutable BlockedMultiVector srcScrap_; - mutable BlockedMultiVector dstScrap_; - -private: - // hide me! - BlockLowerTriInverseOp(); - BlockLowerTriInverseOp(const BlockLowerTriInverseOp &); + public: + using BlockImplicitLinearOp::implicitApply; + + /** \brief This constructor explicitly takes a lower triangular matrix + * and inverse diagonal operators and builds a forward substitution operator. + * + * This constructor explicitly takes a lower triangular matrix + * and inverse diagonal operators and builds a forward substitution operator. + * + * @param[in] L Lower triangular matrix object + * @param[in] invDiag Vector containing the inverse of the diagonal blocks + */ + BlockLowerTriInverseOp(BlockedLinearOp &L, const std::vector &invDiag); + + //! @name Inherited methods from Thyra::LinearOpBase + //@{ + + /** @brief Range space of this operator */ + virtual VectorSpace range() const { return productRange_; } + + /** @brief Domain space of this operator */ + virtual VectorSpace domain() const { return productDomain_; } + + /** @brief Perform a matrix vector multiply with this operator. + * + * The apply function takes one vector as input + * and applies the inverse \f$ LDU \f$ decomposition. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ + virtual void implicitApply(const BlockedMultiVector &x, BlockedMultiVector &y, + const double alpha = 1.0, const double beta = 0.0) const; + //@} + + virtual void describe(Teuchos::FancyOStream &out_arg, + const Teuchos::EVerbosityLevel verbLevel) const; + + protected: + // fundamental operators to use + const BlockedLinearOp L_; ///< operator \f$ L \f$ + std::vector invDiag_; ///< (Approximate) Inverses of the diagonal operators + + Teuchos::RCP > + productRange_; ///< Range vector space. + Teuchos::RCP > + productDomain_; ///< Domain vector space. + + // scratch space...so we don't have to reallocate + mutable BlockedMultiVector srcScrap_; + mutable BlockedMultiVector dstScrap_; + + private: + // hide me! + BlockLowerTriInverseOp(); + BlockLowerTriInverseOp(const BlockLowerTriInverseOp &); }; -inline LinearOp createBlockLowerTriInverseOp(BlockedLinearOp & U,const std::vector & invDiag) -{ - return Teuchos::rcp(new BlockLowerTriInverseOp(U,invDiag)); +inline LinearOp createBlockLowerTriInverseOp(BlockedLinearOp &U, + const std::vector &invDiag) { + return Teuchos::rcp(new BlockLowerTriInverseOp(U, invDiag)); } -inline LinearOp createBlockLowerTriInverseOp(BlockedLinearOp & L,const std::vector & invDiag,const std::string & str) -{ - Teuchos::RCP > result = Teuchos::rcp(new BlockLowerTriInverseOp(L,invDiag)); - result->setObjectLabel(str); +inline LinearOp createBlockLowerTriInverseOp(BlockedLinearOp &L, + const std::vector &invDiag, + const std::string &str) { + Teuchos::RCP > result = + Teuchos::rcp(new BlockLowerTriInverseOp(L, invDiag)); + result->setObjectLabel(str); - return result; + return result; } -} // end namespace Teko +} // end namespace Teko -#endif +#endif diff --git a/packages/teko/src/Teko_BlockPreconditionerFactory.cpp b/packages/teko/src/Teko_BlockPreconditionerFactory.cpp index daa055921094..694f4129accc 100644 --- a/packages/teko/src/Teko_BlockPreconditionerFactory.cpp +++ b/packages/teko/src/Teko_BlockPreconditionerFactory.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -57,23 +57,24 @@ namespace Teko { ///////////////////////////////////////////////////// -LinearOp BlockPreconditionerFactory::buildPreconditionerOperator(LinearOp & lo,PreconditionerState & state) const -{ - // get the blocked linear operator - RCP > loA = Teuchos::rcp_const_cast >(lo); - BlockedLinearOp A = Teuchos::rcp_dynamic_cast >(loA); +LinearOp BlockPreconditionerFactory::buildPreconditionerOperator(LinearOp &lo, + PreconditionerState &state) const { + // get the blocked linear operator + RCP > loA = Teuchos::rcp_const_cast >(lo); + BlockedLinearOp A = Teuchos::rcp_dynamic_cast >(loA); - state.setInitialized(false); + state.setInitialized(false); - return buildPreconditionerOperator(A,dynamic_cast(state)); + return buildPreconditionerOperator(A, dynamic_cast(state)); } //! is this operator compatiable with the preconditioner factory? -bool BlockPreconditionerFactory::isCompatible(const Thyra::LinearOpSourceBase &fwdOpSrc) const -{ - RCP > A - = Teuchos::rcp_dynamic_cast >(fwdOpSrc.getOp()); - return A!=Teuchos::null; +bool BlockPreconditionerFactory::isCompatible( + const Thyra::LinearOpSourceBase &fwdOpSrc) const { + RCP > A = + Teuchos::rcp_dynamic_cast >( + fwdOpSrc.getOp()); + return A != Teuchos::null; } -} // end namespace Teko +} // end namespace Teko diff --git a/packages/teko/src/Teko_BlockPreconditionerFactory.hpp b/packages/teko/src/Teko_BlockPreconditionerFactory.hpp index 1d6f2fae07b1..ff0ef13f8acf 100644 --- a/packages/teko/src/Teko_BlockPreconditionerFactory.hpp +++ b/packages/teko/src/Teko_BlockPreconditionerFactory.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -65,85 +65,88 @@ namespace Teko { -using Thyra::LinearOpBase; -using Thyra::DefaultPreconditioner; +using Teuchos::ParameterList; using Teuchos::rcp; using Teuchos::RCP; -using Teuchos::ParameterList; +using Thyra::DefaultPreconditioner; +using Thyra::LinearOpBase; /** \brief An implementation of a state object for block - * preconditioners. - * - * An implementation of the state object for block - * preconditioners. T - */ + * preconditioners. + * + * An implementation of the state object for block + * preconditioners. T + */ class BlockPreconditionerState : public PreconditionerState { -public: - //! Set the vector associated with this operator (think nonlinear system) - virtual void setBlockSourceVector(const Teko::BlockedMultiVector & srcVec) - { setSourceVector(srcVec); } - - //! Set the vector associated with this operator (think nonlinear system) - virtual const Teko::BlockedMultiVector getBlockedSourceVector() const - { return toBlockedMultiVector(getSourceVector()); } + public: + //! Set the vector associated with this operator (think nonlinear system) + virtual void setBlockSourceVector(const Teko::BlockedMultiVector &srcVec) { + setSourceVector(srcVec); + } + + //! Set the vector associated with this operator (think nonlinear system) + virtual const Teko::BlockedMultiVector getBlockedSourceVector() const { + return toBlockedMultiVector(getSourceVector()); + } }; /** \brief Abstract class which block preconditioner factories in Teko - * should be based on. - * - * Abstract class which block preconditioner factories in Teko should - * be based on. All that is needed is the implementation of - * "buildPreconditionerOperator". - */ -class BlockPreconditionerFactory - : public PreconditionerFactory { -public: - - /** \brief Function that is called to build the preconditioner - * for the linear operator that is passed in. - * - * This function builds a preconditioner based on the passed - * in BlockedLinearOp. - * - * \param[in] blo Source linear operator that is to be preconditioned. - * \param[in] state An object associated with this operator to store - * the preconditioner state. - * - * \returns The preconditioner as a linear operator (i.e. to perform - * a matrix-vector operation simply call "apply"). - */ - virtual LinearOp buildPreconditionerOperator(BlockedLinearOp & blo,BlockPreconditionerState & state) const = 0; - - /** \brief Function that permits the construction of an arbitrary - * BlockPreconditionerState object. - * - * Function that permits the construction of an arbitrary - * BlockPreconditionerState object. If the basic state object, - * which takes a parameter list, is sufficient the default behavior - * does precisely what is needed. Otherwise, an author of a - * PreconditionerFactory would need to reimplement this method to - * return a new state object. - * - * \returns A state object associated with this factory. - */ - virtual RCP buildPreconditionerState() const - { return rcp(new BlockPreconditionerState()); } - - /** \brief Function that constructs a BlockPreconditionerState object. - * - * This function is simply included for convenience. Its implementation - * just call "buildPreconditionerState" and returns a dynamically casted - * BlockPreconditionState poniter. - */ - RCP buildBlockPreconditionerState() const - { return Teuchos::rcp_dynamic_cast(buildPreconditionerState()); } - - virtual LinearOp buildPreconditionerOperator(LinearOp & blo,PreconditionerState & state) const; - - //! is this operator compatiable with the preconditioner factory? - bool isCompatible(const Thyra::LinearOpSourceBase &fwdOpSrc) const; + * should be based on. + * + * Abstract class which block preconditioner factories in Teko should + * be based on. All that is needed is the implementation of + * "buildPreconditionerOperator". + */ +class BlockPreconditionerFactory : public PreconditionerFactory { + public: + /** \brief Function that is called to build the preconditioner + * for the linear operator that is passed in. + * + * This function builds a preconditioner based on the passed + * in BlockedLinearOp. + * + * \param[in] blo Source linear operator that is to be preconditioned. + * \param[in] state An object associated with this operator to store + * the preconditioner state. + * + * \returns The preconditioner as a linear operator (i.e. to perform + * a matrix-vector operation simply call "apply"). + */ + virtual LinearOp buildPreconditionerOperator(BlockedLinearOp &blo, + BlockPreconditionerState &state) const = 0; + + /** \brief Function that permits the construction of an arbitrary + * BlockPreconditionerState object. + * + * Function that permits the construction of an arbitrary + * BlockPreconditionerState object. If the basic state object, + * which takes a parameter list, is sufficient the default behavior + * does precisely what is needed. Otherwise, an author of a + * PreconditionerFactory would need to reimplement this method to + * return a new state object. + * + * \returns A state object associated with this factory. + */ + virtual RCP buildPreconditionerState() const { + return rcp(new BlockPreconditionerState()); + } + + /** \brief Function that constructs a BlockPreconditionerState object. + * + * This function is simply included for convenience. Its implementation + * just call "buildPreconditionerState" and returns a dynamically casted + * BlockPreconditionState poniter. + */ + RCP buildBlockPreconditionerState() const { + return Teuchos::rcp_dynamic_cast(buildPreconditionerState()); + } + + virtual LinearOp buildPreconditionerOperator(LinearOp &blo, PreconditionerState &state) const; + + //! is this operator compatiable with the preconditioner factory? + bool isCompatible(const Thyra::LinearOpSourceBase &fwdOpSrc) const; }; -} // end namespace Teko +} // end namespace Teko #endif diff --git a/packages/teko/src/Teko_BlockUpperTriInverseOp.cpp b/packages/teko/src/Teko_BlockUpperTriInverseOp.cpp index 6420386b0c06..e3a852d6ba05 100644 --- a/packages/teko/src/Teko_BlockUpperTriInverseOp.cpp +++ b/packages/teko/src/Teko_BlockUpperTriInverseOp.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -53,161 +53,148 @@ namespace Teko { using Teuchos::RCP; /** @brief This constructor explicitly takes the parts of \f$ A \f$ required to - * build the inverse operator. - * - * This constructor explicitly takes the parts of \f$ A \f$ required to build - * the inverse operator. - * - * @param[in] A The block \f$ 2 \times 2 \f$ \f$A\f$ operator. - * @param[in] invA00 An approximate inverse of \f$ A_{00} \f$. - * @param[in] invS An approximate inverse of \f$ S = -A_{11} + A_{10} A_{00}^{-1} A_{01} \f$. - */ -BlockUpperTriInverseOp::BlockUpperTriInverseOp(BlockedLinearOp & U,const std::vector & invDiag) - : U_(U) -{ - invDiag_ = invDiag; - - // sanity check - int blocks = blockRowCount(U_); - TEUCHOS_ASSERT(blocks>0); - TEUCHOS_ASSERT(blocks==blockColCount(U_)); - TEUCHOS_ASSERT(blocks==(int) invDiag_.size()); - - // create the range and product space - /////////////////////////////////////////////////// - - // just flip flop them! - productRange_ = U->productDomain(); - productDomain_ = U->productRange(); + * build the inverse operator. + * + * This constructor explicitly takes the parts of \f$ A \f$ required to build + * the inverse operator. + * + * @param[in] A The block \f$ 2 \times 2 \f$ \f$A\f$ operator. + * @param[in] invA00 An approximate inverse of \f$ A_{00} \f$. + * @param[in] invS An approximate inverse of \f$ S = -A_{11} + A_{10} A_{00}^{-1} A_{01} \f$. + */ +BlockUpperTriInverseOp::BlockUpperTriInverseOp(BlockedLinearOp& U, + const std::vector& invDiag) + : U_(U) { + invDiag_ = invDiag; + + // sanity check + int blocks = blockRowCount(U_); + TEUCHOS_ASSERT(blocks > 0); + TEUCHOS_ASSERT(blocks == blockColCount(U_)); + TEUCHOS_ASSERT(blocks == (int)invDiag_.size()); + + // create the range and product space + /////////////////////////////////////////////////// + + // just flip flop them! + productRange_ = U->productDomain(); + productDomain_ = U->productRange(); } -void BlockUpperTriInverseOp::implicitApply(const BlockedMultiVector & src, BlockedMultiVector & dst, - const double alpha, const double beta) const -{ +void BlockUpperTriInverseOp::implicitApply(const BlockedMultiVector& src, BlockedMultiVector& dst, + const double alpha, const double beta) const { // call the no tranpose version - implicitApply(Thyra::NOTRANS,src,dst,alpha,beta); + implicitApply(Thyra::NOTRANS, src, dst, alpha, beta); } -/** @brief Perform a matrix vector multiply with this operator. - * - * The apply function takes one vector as input - * and applies the inverse \f$ LDU \f$ decomposition. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ +/** @brief Perform a matrix vector multiply with this operator. + * + * The apply function takes one vector as input + * and applies the inverse \f$ LDU \f$ decomposition. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ void BlockUpperTriInverseOp::implicitApply(const Thyra::EOpTransp M_trans, - const BlockedMultiVector & src, BlockedMultiVector & dst, - const double alpha, const double beta) const -{ - int blocks = blockCount(src); - - TEUCHOS_ASSERT(blocks==blockRowCount(U_)); - TEUCHOS_ASSERT(blocks==blockCount(dst)); - - // build a scrap vector for storing work - srcScrap_ = datacopy(src,srcScrap_); - BlockedMultiVector dstCopy; - if(beta!=0.0) { - dstScrap_ = datacopy(dst,dstScrap_); - dstCopy = dstScrap_; - } - else - dstCopy = dst; // shallow copy - - // extract the blocks components from - // the source and destination vectors - std::vector dstVec; - std::vector scrapVec; - for(int b=0;b=0;b--) { - applyOp(invDiag_[b], scrapVec[b], dstVec[b]); - - // loop over each row - for(int i=0;i dstVec; + std::vector scrapVec; + for (int b = 0; b < blocks; b++) { + dstVec.push_back(getBlock(b, dstCopy)); + scrapVec.push_back(getBlock(b, srcScrap_)); + } + + // run back-substituion: run over each column + // From Heath pg. 66 + if (M_trans == Thyra::NOTRANS) { + for (int b = blocks - 1; b >= 0; b--) { + applyOp(invDiag_[b], scrapVec[b], dstVec[b]); + + // loop over each row + for (int i = 0; i < b; i++) { + LinearOp u_ib = getBlock(i, b, U_); + if (u_ib != Teuchos::null) { + applyOp(u_ib, dstVec[b], scrapVec[i], -1.0, 1.0); + } } - } - else if(M_trans==Thyra::TRANS || M_trans==Thyra::CONJTRANS) { - for(int b=0;b out = rcp(&out_arg,false); + RCP out = rcp(&out_arg, false); OSTab tab(out); - switch(verbLevel) { - case Teuchos::VERB_DEFAULT: - case Teuchos::VERB_LOW: - *out << this->description() << std::endl; - break; - case Teuchos::VERB_MEDIUM: - case Teuchos::VERB_HIGH: - case Teuchos::VERB_EXTREME: - { - *out << Teuchos::Describable::description() << "{" - << "rangeDim=" << this->range()->dim() - << ",domainDim=" << this->domain()->dim() - << ",rows=" << blockRowCount(U_) - << ",cols=" << blockColCount(U_) - << "}\n"; - { - OSTab tab2(out); - *out << "[U Operator] = "; - *out << Teuchos::describe(*U_,verbLevel); - } - { - OSTab tab2(out); - *out << "[invDiag Operators]:\n"; - tab.incrTab(); - for(int i=0;i & invDiag); - - //! @name Inherited methods from Thyra::LinearOpBase - //@{ - - /** @brief Range space of this operator */ - virtual VectorSpace range() const { return productRange_; } - - /** @brief Domain space of this operator */ - virtual VectorSpace domain() const { return productDomain_; } - - /** @brief Perform a matrix vector multiply with this operator. - * - * The apply function takes one vector as input - * and applies the inverse \f$ LDU \f$ decomposition. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ - virtual void implicitApply(const BlockedMultiVector & x, BlockedMultiVector & y, - const double alpha = 1.0, const double beta = 0.0) const; - - /** @brief Perform a matrix vector multiply with this implicitly - * defined blocked operator. - * - * The apply function takes one vector as input - * and applies a linear operator. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ - virtual void implicitApply(const Thyra::EOpTransp M_trans, - const BlockedMultiVector & x, BlockedMultiVector & y, - const double alpha = 1.0, const double beta = 0.0) const; - //@} - - virtual void describe(Teuchos::FancyOStream &out_arg, - const Teuchos::EVerbosityLevel verbLevel) const; - -protected: - // fundamental operators to use - const BlockedLinearOp U_; ///< operator \f$ U \f$ - std::vector invDiag_; ///< (Approximate) Inverses of the diagonal operators - - Teuchos::RCP > productRange_; ///< Range vector space. - Teuchos::RCP > productDomain_; ///< Domain vector space. - - // scratch space...so we don't have to reallocate - mutable BlockedMultiVector srcScrap_; - mutable BlockedMultiVector dstScrap_; - -private: - // hide me! - BlockUpperTriInverseOp(); - BlockUpperTriInverseOp(const BlockUpperTriInverseOp &); + public: + /** \brief This constructor explicitly takes an upper triangular matrix + * and inverse diagonal operators and builds a back substitution operator. + * + * This constructor explicitly takes an upper triangular matrix + * and inverse diagonal operators and builds a back substitution operator. + * + * @param[in] U Upper triangular matrix object + * @param[in] invDiag Vector containing the inverse of the diagonal blocks + */ + BlockUpperTriInverseOp(BlockedLinearOp &U, const std::vector &invDiag); + + //! @name Inherited methods from Thyra::LinearOpBase + //@{ + + /** @brief Range space of this operator */ + virtual VectorSpace range() const { return productRange_; } + + /** @brief Domain space of this operator */ + virtual VectorSpace domain() const { return productDomain_; } + + /** @brief Perform a matrix vector multiply with this operator. + * + * The apply function takes one vector as input + * and applies the inverse \f$ LDU \f$ decomposition. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ + virtual void implicitApply(const BlockedMultiVector &x, BlockedMultiVector &y, + const double alpha = 1.0, const double beta = 0.0) const; + + /** @brief Perform a matrix vector multiply with this implicitly + * defined blocked operator. + * + * The apply function takes one vector as input + * and applies a linear operator. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ + virtual void implicitApply(const Thyra::EOpTransp M_trans, const BlockedMultiVector &x, + BlockedMultiVector &y, const double alpha = 1.0, + const double beta = 0.0) const; + //@} + + virtual void describe(Teuchos::FancyOStream &out_arg, + const Teuchos::EVerbosityLevel verbLevel) const; + + protected: + // fundamental operators to use + const BlockedLinearOp U_; ///< operator \f$ U \f$ + std::vector invDiag_; ///< (Approximate) Inverses of the diagonal operators + + Teuchos::RCP > + productRange_; ///< Range vector space. + Teuchos::RCP > + productDomain_; ///< Domain vector space. + + // scratch space...so we don't have to reallocate + mutable BlockedMultiVector srcScrap_; + mutable BlockedMultiVector dstScrap_; + + private: + // hide me! + BlockUpperTriInverseOp(); + BlockUpperTriInverseOp(const BlockUpperTriInverseOp &); }; -inline LinearOp createBlockUpperTriInverseOp(BlockedLinearOp & U,const std::vector & invDiag) -{ - return Teuchos::rcp(new BlockUpperTriInverseOp(U,invDiag)); +inline LinearOp createBlockUpperTriInverseOp(BlockedLinearOp &U, + const std::vector &invDiag) { + return Teuchos::rcp(new BlockUpperTriInverseOp(U, invDiag)); } -inline LinearOp createBlockUpperTriInverseOp(BlockedLinearOp & U,const std::vector & invDiag,const std::string & str) -{ - Teuchos::RCP > result = Teuchos::rcp(new BlockUpperTriInverseOp(U,invDiag)); - result->setObjectLabel(str); +inline LinearOp createBlockUpperTriInverseOp(BlockedLinearOp &U, + const std::vector &invDiag, + const std::string &str) { + Teuchos::RCP > result = + Teuchos::rcp(new BlockUpperTriInverseOp(U, invDiag)); + result->setObjectLabel(str); - return result; + return result; } -} // end namespace Teko +} // end namespace Teko -#endif +#endif diff --git a/packages/teko/src/Teko_BlockedReordering.cpp b/packages/teko/src/Teko_BlockedReordering.cpp index f77f2174acf3..f6f0beb675f1 100644 --- a/packages/teko/src/Teko_BlockedReordering.cpp +++ b/packages/teko/src/Teko_BlockedReordering.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -59,483 +59,456 @@ #include "Thyra_DefaultProductMultiVector.hpp" #include "Thyra_DefaultProductVectorSpace.hpp" +using Teuchos::Array; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcp_dynamic_cast; -using Teuchos::Array; namespace Teko { -void BlockReorderManager::SetBlock(int blockIndex,int reorder) -{ - TEUCHOS_ASSERT(blockIndex<(int) children_.size()); +void BlockReorderManager::SetBlock(int blockIndex, int reorder) { + TEUCHOS_ASSERT(blockIndex < (int)children_.size()); - RCP child = rcp(new BlockReorderLeaf(reorder)); + RCP child = rcp(new BlockReorderLeaf(reorder)); - children_[blockIndex] = child; + children_[blockIndex] = child; } /** \brief Set the subblock to a use a particular reorder - * manager. - * - * Set the subblock to a use a particular reorder - * manager. This facilitates recursive construction algorithms - * where the base case is not differentiated. - * - * \param[in] blockIndex Subblock to be set - * \param[in] reorder Reorder manager to be used in this block - * - * \pre blockIndexGetNumBlocks() - */ -void BlockReorderManager::SetBlock(int blockIndex,const RCP & reorder) -{ - TEUCHOS_ASSERT(blockIndex<(int) children_.size()); - - children_[blockIndex] = reorder; + * manager. + * + * Set the subblock to a use a particular reorder + * manager. This facilitates recursive construction algorithms + * where the base case is not differentiated. + * + * \param[in] blockIndex Subblock to be set + * \param[in] reorder Reorder manager to be used in this block + * + * \pre blockIndexGetNumBlocks() + */ +void BlockReorderManager::SetBlock(int blockIndex, const RCP &reorder) { + TEUCHOS_ASSERT(blockIndex < (int)children_.size()); + + children_[blockIndex] = reorder; } -const Teuchos::RCP BlockReorderManager::GetBlock(int blockIndex) -{ - TEUCHOS_ASSERT(blockIndex<(int) children_.size()); +const Teuchos::RCP BlockReorderManager::GetBlock(int blockIndex) { + TEUCHOS_ASSERT(blockIndex < (int)children_.size()); - if(children_[blockIndex]==Teuchos::null) - children_[blockIndex] = rcp(new BlockReorderManager()); + if (children_[blockIndex] == Teuchos::null) + children_[blockIndex] = rcp(new BlockReorderManager()); - return children_[blockIndex]; + return children_[blockIndex]; } -const Teuchos::RCP BlockReorderManager::GetBlock(int blockIndex) const -{ - TEUCHOS_ASSERT(blockIndex<(int) children_.size()); +const Teuchos::RCP BlockReorderManager::GetBlock(int blockIndex) const { + TEUCHOS_ASSERT(blockIndex < (int)children_.size()); - return children_[blockIndex]; + return children_[blockIndex]; } -std::string BlockReorderManager::toString() const -{ - // build the string by recursively calling each child - std::stringstream ss; - ss << "["; - for(unsigned int i=0;i "; - else - ss << " " << children_[i]->toString() << " "; - } - ss << "]"; - - return ss.str(); +std::string BlockReorderManager::toString() const { + // build the string by recursively calling each child + std::stringstream ss; + ss << "["; + for (unsigned int i = 0; i < children_.size(); i++) { + if (children_[i] == Teuchos::null) + ss << " "; + else + ss << " " << children_[i]->toString() << " "; + } + ss << "]"; + + return ss.str(); } -int BlockReorderManager::LargestIndex() const -{ - int max = 0; - for(unsigned int i=0;iLargestIndex(); - max = max > subMax ? max : subMax; - } - } - - return max; -} +int BlockReorderManager::LargestIndex() const { + int max = 0; + for (unsigned int i = 0; i < children_.size(); i++) { + // see if current child is larger + if (children_[i] != Teuchos::null) { + int subMax = children_[i]->LargestIndex(); + max = max > subMax ? max : subMax; + } + } + + return max; +} -Teuchos::RCP > -buildReorderedLinearOp(const BlockReorderManager & bmm, - const Teuchos::RCP > & blkOp) -{ - return buildReorderedLinearOp(bmm,bmm,blkOp); +Teuchos::RCP > buildReorderedLinearOp( + const BlockReorderManager &bmm, + const Teuchos::RCP > &blkOp) { + return buildReorderedLinearOp(bmm, bmm, blkOp); } -Teuchos::RCP > -buildReorderedLinearOp(const BlockReorderManager & rowMgr,const BlockReorderManager & colMgr, - const Teuchos::RCP > & blkOp) -{ - typedef RCP BRMptr; +Teuchos::RCP > buildReorderedLinearOp( + const BlockReorderManager &rowMgr, const BlockReorderManager &colMgr, + const Teuchos::RCP > &blkOp) { + typedef RCP BRMptr; - int rowSz = rowMgr.GetNumBlocks(); - int colSz = colMgr.GetNumBlocks(); + int rowSz = rowMgr.GetNumBlocks(); + int colSz = colMgr.GetNumBlocks(); - if(rowSz==0 && colSz==0) { - // both are leaf nodes - const BlockReorderLeaf & rowLeaf = dynamic_cast(rowMgr); - const BlockReorderLeaf & colLeaf = dynamic_cast(colMgr); + if (rowSz == 0 && colSz == 0) { + // both are leaf nodes + const BlockReorderLeaf &rowLeaf = dynamic_cast(rowMgr); + const BlockReorderLeaf &colLeaf = dynamic_cast(colMgr); - // simply return entry in matrix - Teko::LinearOp linOp = blkOp->getBlock(rowLeaf.GetIndex(),colLeaf.GetIndex()); + // simply return entry in matrix + Teko::LinearOp linOp = blkOp->getBlock(rowLeaf.GetIndex(), colLeaf.GetIndex()); - // somehow we need to set this operator up - if(linOp==Teuchos::null) { - linOp = Thyra::zero(blkOp->productRange()->getBlock(rowLeaf.GetIndex()), - blkOp->productDomain()->getBlock(colLeaf.GetIndex())); - } + // somehow we need to set this operator up + if (linOp == Teuchos::null) { + linOp = Thyra::zero(blkOp->productRange()->getBlock(rowLeaf.GetIndex()), + blkOp->productDomain()->getBlock(colLeaf.GetIndex())); + } - return linOp; - } - else if(rowSz==0) { - Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp(); - - // operator will be rowSz by colSz - reBlkOp->beginBlockFill(1,colSz); - - // fill the column entries - for(int col=0;colsetBlock(0,col,buildReorderedLinearOp(rowMgr,*colPtr,blkOp)); - } - - // done building - reBlkOp->endBlockFill(); - - return reBlkOp; - } - else if(colSz==0) { - Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp(); - - // operator will be rowSz by colSz - reBlkOp->beginBlockFill(rowSz,1); - - // fill the row entries - for(int row=0;rowsetBlock(row,0,buildReorderedLinearOp(*rowPtr,colMgr,blkOp)); - } - - // done building - reBlkOp->endBlockFill(); - - return reBlkOp; - } - else { - Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp(); - - // this is the general case - TEUCHOS_ASSERT(rowSz>0); - TEUCHOS_ASSERT(colSz>0); - - // operator will be rowSz by colSz - reBlkOp->beginBlockFill(rowSz,colSz); - - for(int row=0;rowsetBlock(row,col,buildReorderedLinearOp(*rowPtr,*colPtr,blkOp)); - } - } + return linOp; + } else if (rowSz == 0) { + Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp(); - // done building - reBlkOp->endBlockFill(); + // operator will be rowSz by colSz + reBlkOp->beginBlockFill(1, colSz); - return reBlkOp; - } -} + // fill the column entries + for (int col = 0; col < colSz; col++) { + BRMptr colPtr = colMgr.GetBlock(col); -/** \brief Use the BlockReorderManager to change a flat vector space - * into a composite vector space. - * - * Use the BlockReorderManager to chanage a flat vector space - * a more complex composite structure. The manager should not have any indicies - * larger then the size of the blocked operator. - * - * \param[in] mgr BlockReorderManager that specifies how the space is to - * be restructured. - * \param[in] blkSpc The block space to be reordered and restructured. Only the - * first level of the space will be considered. Each subspace - * (even if it is itself blocked) will be handed as an individual - * space. - * - * \returns The reordered blocked vector space. - * - * \pre The largest index in bmm is smaller then the dimension of the - * blkSpc. - * - * \relates BlockReorderManager - */ -Teuchos::RCP > -buildReorderedVectorSpace(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkSpc) -{ - typedef RCP BRMptr; - - int sz = mgr.GetNumBlocks(); - - if(sz==0) { - // its a leaf nodes - const BlockReorderLeaf & leaf = dynamic_cast(mgr); - - // simply return entry in matrix - return blkSpc->getBlock(leaf.GetIndex()); - } - else { - Array > > vecSpaces; - - // loop over each row - for(int i=0;i > lvs = buildReorderedVectorSpace(*blkMgr,blkSpc); - - vecSpaces.push_back(lvs); - } + reBlkOp->setBlock(0, col, buildReorderedLinearOp(rowMgr, *colPtr, blkOp)); + } - // build a vector space - const RCP > vs - = Thyra::productVectorSpace(vecSpaces); + // done building + reBlkOp->endBlockFill(); - // build the vector - return vs; - } -} + return reBlkOp; + } else if (colSz == 0) { + Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp(); -/** \brief Convert a flat multi vector into a reordered multivector. - * - * Convert a flat multi vector into a reordered multivector. - */ -Teuchos::RCP > -buildReorderedMultiVector(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkVec) -{ - typedef RCP BRMptr; - - int sz = mgr.GetNumBlocks(); - - if(sz==0) { - // its a leaf nodes - const BlockReorderLeaf & leaf = dynamic_cast(mgr); - - // simply return entry in matrix - return blkVec->getNonconstMultiVectorBlock(leaf.GetIndex()); - } - else { - Array > > multiVecs; - Array > > vecSpaces; - - // loop over each row - for(int i=0;i > lmv = buildReorderedMultiVector(*blkMgr,blkVec); - const RCP > lvs = lmv->range(); - - multiVecs.push_back(lmv); - vecSpaces.push_back(lvs); + // operator will be rowSz by colSz + reBlkOp->beginBlockFill(rowSz, 1); + + // fill the row entries + for (int row = 0; row < rowSz; row++) { + BRMptr rowPtr = rowMgr.GetBlock(row); + + reBlkOp->setBlock(row, 0, buildReorderedLinearOp(*rowPtr, colMgr, blkOp)); + } + + // done building + reBlkOp->endBlockFill(); + + return reBlkOp; + } else { + Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp(); + + // this is the general case + TEUCHOS_ASSERT(rowSz > 0); + TEUCHOS_ASSERT(colSz > 0); + + // operator will be rowSz by colSz + reBlkOp->beginBlockFill(rowSz, colSz); + + for (int row = 0; row < rowSz; row++) { + BRMptr rowPtr = rowMgr.GetBlock(row); + + for (int col = 0; col < colSz; col++) { + BRMptr colPtr = colMgr.GetBlock(col); + + reBlkOp->setBlock(row, col, buildReorderedLinearOp(*rowPtr, *colPtr, blkOp)); } + } - // build a vector space - const RCP > vs - = Thyra::productVectorSpace(vecSpaces); + // done building + reBlkOp->endBlockFill(); - // build the vector - return Thyra::defaultProductMultiVector(vs,multiVecs); - } + return reBlkOp; + } } -/** \brief Convert a flat multi vector into a reordered multivector. - * - * Convert a flat multi vector into a reordered multivector. - */ -Teuchos::RCP > -buildReorderedMultiVector(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkVec) -{ - typedef RCP BRMptr; - - int sz = mgr.GetNumBlocks(); - - if(sz==0) { - // its a leaf nodes - const BlockReorderLeaf & leaf = dynamic_cast(mgr); - - // simply return entry in matrix - return blkVec->getMultiVectorBlock(leaf.GetIndex()); - } - else { - Array > > multiVecs; - Array > > vecSpaces; - - // loop over each row - for(int i=0;i > lmv = buildReorderedMultiVector(*blkMgr,blkVec); - const RCP > lvs = lmv->range(); - - multiVecs.push_back(lmv); - vecSpaces.push_back(lvs); - } +/** \brief Use the BlockReorderManager to change a flat vector space + * into a composite vector space. + * + * Use the BlockReorderManager to chanage a flat vector space + * a more complex composite structure. The manager should not have any indicies + * larger then the size of the blocked operator. + * + * \param[in] mgr BlockReorderManager that specifies how the space is to + * be restructured. + * \param[in] blkSpc The block space to be reordered and restructured. Only the + * first level of the space will be considered. Each subspace + * (even if it is itself blocked) will be handed as an individual + * space. + * + * \returns The reordered blocked vector space. + * + * \pre The largest index in bmm is smaller then the dimension of the + * blkSpc. + * + * \relates BlockReorderManager + */ +Teuchos::RCP > buildReorderedVectorSpace( + const BlockReorderManager &mgr, + const Teuchos::RCP > &blkSpc) { + typedef RCP BRMptr; + + int sz = mgr.GetNumBlocks(); + + if (sz == 0) { + // its a leaf nodes + const BlockReorderLeaf &leaf = dynamic_cast(mgr); + + // simply return entry in matrix + return blkSpc->getBlock(leaf.GetIndex()); + } else { + Array > > vecSpaces; + + // loop over each row + for (int i = 0; i < sz; i++) { + BRMptr blkMgr = mgr.GetBlock(i); + + const RCP > lvs = + buildReorderedVectorSpace(*blkMgr, blkSpc); + + vecSpaces.push_back(lvs); + } + + // build a vector space + const RCP > vs = + Thyra::productVectorSpace(vecSpaces); + + // build the vector + return vs; + } +} - // build a vector space - const RCP > vs - = Thyra::productVectorSpace(vecSpaces); +/** \brief Convert a flat multi vector into a reordered multivector. + * + * Convert a flat multi vector into a reordered multivector. + */ +Teuchos::RCP > buildReorderedMultiVector( + const BlockReorderManager &mgr, + const Teuchos::RCP > &blkVec) { + typedef RCP BRMptr; + + int sz = mgr.GetNumBlocks(); + + if (sz == 0) { + // its a leaf nodes + const BlockReorderLeaf &leaf = dynamic_cast(mgr); + + // simply return entry in matrix + return blkVec->getNonconstMultiVectorBlock(leaf.GetIndex()); + } else { + Array > > multiVecs; + Array > > vecSpaces; + + // loop over each row + for (int i = 0; i < sz; i++) { + BRMptr blkMgr = mgr.GetBlock(i); + + const RCP > lmv = buildReorderedMultiVector(*blkMgr, blkVec); + const RCP > lvs = lmv->range(); + + multiVecs.push_back(lmv); + vecSpaces.push_back(lvs); + } + + // build a vector space + const RCP > vs = + Thyra::productVectorSpace(vecSpaces); + + // build the vector + return Thyra::defaultProductMultiVector(vs, multiVecs); + } +} - // build the vector - return Thyra::defaultProductMultiVector(vs,multiVecs); - } +/** \brief Convert a flat multi vector into a reordered multivector. + * + * Convert a flat multi vector into a reordered multivector. + */ +Teuchos::RCP > buildReorderedMultiVector( + const BlockReorderManager &mgr, + const Teuchos::RCP > &blkVec) { + typedef RCP BRMptr; + + int sz = mgr.GetNumBlocks(); + + if (sz == 0) { + // its a leaf nodes + const BlockReorderLeaf &leaf = dynamic_cast(mgr); + + // simply return entry in matrix + return blkVec->getMultiVectorBlock(leaf.GetIndex()); + } else { + Array > > multiVecs; + Array > > vecSpaces; + + // loop over each row + for (int i = 0; i < sz; i++) { + BRMptr blkMgr = mgr.GetBlock(i); + + const RCP > lmv = + buildReorderedMultiVector(*blkMgr, blkVec); + const RCP > lvs = lmv->range(); + + multiVecs.push_back(lmv); + vecSpaces.push_back(lvs); + } + + // build a vector space + const RCP > vs = + Thyra::productVectorSpace(vecSpaces); + + // build the vector + return Thyra::defaultProductMultiVector(vs, multiVecs); + } } /** Helper function to assist with the non-constant - * version of buildFlatMultiVector. - */ -void buildNonconstFlatMultiVector(const BlockReorderManager & mgr, - const RCP > & blkVec, - Array > > & multivecs, - Array > > & vecspaces) -{ - int sz = mgr.GetNumBlocks(); - - if(sz==0) { - // its a leaf nodes - const BlockReorderLeaf & leaf = dynamic_cast(mgr); - int index = leaf.GetIndex(); - - // simply return entry in matrix - multivecs[index] = blkVec; - vecspaces[index] = blkVec->range(); - } - else { - const RCP > prodMV - = rcp_dynamic_cast >(blkVec); - - // get flattened elements from each child - for(int i=0;i > mv = prodMV->getNonconstMultiVectorBlock(i); - buildNonconstFlatMultiVector(*mgr.GetBlock(i),mv,multivecs,vecspaces); - } - } - + * version of buildFlatMultiVector. + */ +void buildNonconstFlatMultiVector(const BlockReorderManager &mgr, + const RCP > &blkVec, + Array > > &multivecs, + Array > > &vecspaces) { + int sz = mgr.GetNumBlocks(); + + if (sz == 0) { + // its a leaf nodes + const BlockReorderLeaf &leaf = dynamic_cast(mgr); + int index = leaf.GetIndex(); + + // simply return entry in matrix + multivecs[index] = blkVec; + vecspaces[index] = blkVec->range(); + } else { + const RCP > prodMV = + rcp_dynamic_cast >(blkVec); + + // get flattened elements from each child + for (int i = 0; i < sz; i++) { + const RCP > mv = prodMV->getNonconstMultiVectorBlock(i); + buildNonconstFlatMultiVector(*mgr.GetBlock(i), mv, multivecs, vecspaces); + } + } } /** Helper function to assist with the function - * of the same name. - */ -void buildFlatMultiVector(const BlockReorderManager & mgr, - const RCP > & blkVec, - Array > > & multivecs, - Array > > & vecspaces) -{ - int sz = mgr.GetNumBlocks(); - - if(sz==0) { - // its a leaf nodes - const BlockReorderLeaf & leaf = dynamic_cast(mgr); - int index = leaf.GetIndex(); - - // simply return entry in matrix - multivecs[index] = blkVec; - vecspaces[index] = blkVec->range(); - } - else { - const RCP > prodMV - = rcp_dynamic_cast >(blkVec); - - // get flattened elements from each child - for(int i=0;i > mv = prodMV->getMultiVectorBlock(i); - buildFlatMultiVector(*mgr.GetBlock(i),mv,multivecs,vecspaces); - } - } - + * of the same name. + */ +void buildFlatMultiVector(const BlockReorderManager &mgr, + const RCP > &blkVec, + Array > > &multivecs, + Array > > &vecspaces) { + int sz = mgr.GetNumBlocks(); + + if (sz == 0) { + // its a leaf nodes + const BlockReorderLeaf &leaf = dynamic_cast(mgr); + int index = leaf.GetIndex(); + + // simply return entry in matrix + multivecs[index] = blkVec; + vecspaces[index] = blkVec->range(); + } else { + const RCP > prodMV = + rcp_dynamic_cast >(blkVec); + + // get flattened elements from each child + for (int i = 0; i < sz; i++) { + RCP > mv = prodMV->getMultiVectorBlock(i); + buildFlatMultiVector(*mgr.GetBlock(i), mv, multivecs, vecspaces); + } + } } /** \brief Convert a reordered multivector into a flat multivector. - * - * Convert a reordered multivector into a flat multivector. - */ -Teuchos::RCP > -buildFlatMultiVector(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkVec) -{ - int numBlocks = mgr.LargestIndex()+1; - - Array > > multivecs(numBlocks); - Array > > vecspaces(numBlocks); - - // flatten everything into a vector first - buildNonconstFlatMultiVector(mgr,blkVec,multivecs,vecspaces); - - // build a vector space - const RCP > vs - = Thyra::productVectorSpace(vecspaces); - - // build the vector - return Thyra::defaultProductMultiVector(vs,multivecs); + * + * Convert a reordered multivector into a flat multivector. + */ +Teuchos::RCP > buildFlatMultiVector( + const BlockReorderManager &mgr, + const Teuchos::RCP > &blkVec) { + int numBlocks = mgr.LargestIndex() + 1; + + Array > > multivecs(numBlocks); + Array > > vecspaces(numBlocks); + + // flatten everything into a vector first + buildNonconstFlatMultiVector(mgr, blkVec, multivecs, vecspaces); + + // build a vector space + const RCP > vs = + Thyra::productVectorSpace(vecspaces); + + // build the vector + return Thyra::defaultProductMultiVector(vs, multivecs); } /** \brief Convert a reordered multivector into a flat multivector. - * - * Convert a reordered multivector into a flat multivector. - */ -Teuchos::RCP > -buildFlatMultiVector(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkVec) -{ - int numBlocks = mgr.LargestIndex()+1; - - Array > > multivecs(numBlocks); - Array > > vecspaces(numBlocks); - - // flatten everything into a vector first - buildFlatMultiVector(mgr,blkVec,multivecs,vecspaces); - - // build a vector space - const RCP > vs - = Thyra::productVectorSpace(vecspaces); - - // build the vector - return Thyra::defaultProductMultiVector(vs,multivecs); + * + * Convert a reordered multivector into a flat multivector. + */ +Teuchos::RCP > buildFlatMultiVector( + const BlockReorderManager &mgr, + const Teuchos::RCP > &blkVec) { + int numBlocks = mgr.LargestIndex() + 1; + + Array > > multivecs(numBlocks); + Array > > vecspaces(numBlocks); + + // flatten everything into a vector first + buildFlatMultiVector(mgr, blkVec, multivecs, vecspaces); + + // build a vector space + const RCP > vs = + Thyra::productVectorSpace(vecspaces); + + // build the vector + return Thyra::defaultProductMultiVector(vs, multivecs); } /** Helper function to assist with the function - * of the same name. - */ -void buildFlatVectorSpace(const BlockReorderManager & mgr, - const RCP > & blkSpc, - Array > > & vecspaces) -{ - int sz = mgr.GetNumBlocks(); - - if(sz==0) { - // its a leaf nodes - const BlockReorderLeaf & leaf = dynamic_cast(mgr); - int index = leaf.GetIndex(); - - // simply return entry in matrix - vecspaces[index] = blkSpc; - } - else { - const RCP > prodSpc - = rcp_dynamic_cast >(blkSpc); - - // get flattened elements from each child - for(int i=0;i > space = prodSpc->getBlock(i); - buildFlatVectorSpace(*mgr.GetBlock(i),space,vecspaces); - } - } - + * of the same name. + */ +void buildFlatVectorSpace(const BlockReorderManager &mgr, + const RCP > &blkSpc, + Array > > &vecspaces) { + int sz = mgr.GetNumBlocks(); + + if (sz == 0) { + // its a leaf nodes + const BlockReorderLeaf &leaf = dynamic_cast(mgr); + int index = leaf.GetIndex(); + + // simply return entry in matrix + vecspaces[index] = blkSpc; + } else { + const RCP > prodSpc = + rcp_dynamic_cast >(blkSpc); + + // get flattened elements from each child + for (int i = 0; i < sz; i++) { + RCP > space = prodSpc->getBlock(i); + buildFlatVectorSpace(*mgr.GetBlock(i), space, vecspaces); + } + } } /** \brief Convert a reordered vector space into a flat vector space - */ -Teuchos::RCP > -buildFlatVectorSpace(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkSpc) -{ - int numBlocks = mgr.LargestIndex()+1; - - Array > > vecspaces(numBlocks); - - // flatten everything into a vector first - buildFlatVectorSpace(mgr,blkSpc,vecspaces); - - // build a vector space - return Thyra::productVectorSpace(vecspaces); + */ +Teuchos::RCP > buildFlatVectorSpace( + const BlockReorderManager &mgr, + const Teuchos::RCP > &blkSpc) { + int numBlocks = mgr.LargestIndex() + 1; + + Array > > vecspaces(numBlocks); + + // flatten everything into a vector first + buildFlatVectorSpace(mgr, blkSpc, vecspaces); + + // build a vector space + return Thyra::productVectorSpace(vecspaces); } //////////////////////////////////////////////////////////////// @@ -545,155 +518,146 @@ buildFlatVectorSpace(const BlockReorderManager & mgr, // this function tokenizes a string, breaking out whitespace but saving the // brackets [,] as special tokens. -static void tokenize(std::string srcInput,std::string whitespace,std::string prefer, - std::vector & tokens) -{ - std::string input = srcInput; - std::vector wsTokens; - std::size_t endPos = input.length()-1; - while(endPos0 && next &tokens) { + std::string input = srcInput; + std::vector wsTokens; + std::size_t endPos = input.length() - 1; + while (endPos < input.length()) { + std::size_t next = input.find_first_of(whitespace); + + // get the sub string + std::string s; + if (next != std::string::npos) { + s = input.substr(0, next); + + // break out the old substring + input = input.substr(next + 1, endPos); + } else { + s = input; + input = ""; + } + + endPos = input.length() - 1; + + // add it to the WS tokens list + if (s == "") continue; + wsTokens.push_back(s); + } + + for (unsigned int i = 0; i < wsTokens.size(); i++) { + // get string to break up + input = wsTokens[i]; + + endPos = input.length() - 1; + while (endPos < input.length()) { + std::size_t next = input.find_first_of(prefer); + + std::string s = input; + if (next > 0 && next < input.length()) { + // get the sub string + s = input.substr(0, next); + + input = input.substr(next, endPos); + } else if (next == 0) { + // get the sub string + s = input.substr(0, next + 1); + + input = input.substr(next + 1, endPos); + } else + input = ""; + + // break out the old substring + endPos = input.length() - 1; + + // add it to the tokens list + tokens.push_back(s); + } + } } // this function takes a set of tokens and returns the first "block", i.e. those // values (including) brackets that correspond to the first block -static std::vector::const_iterator -buildSubBlock(std::vector::const_iterator begin, - std::vector::const_iterator end, std::vector & subBlock) -{ - std::stack matched; - std::vector::const_iterator itr; - for(itr=begin;itr!=end;++itr) { - - subBlock.push_back(*itr); - - // push/pop brackets as they are discovered - if(*itr=="[") matched.push("["); - else if(*itr=="]") matched.pop(); - - // found all matching brackets - if(matched.empty()) - return itr; - } - - TEUCHOS_ASSERT(matched.empty()); - - return itr-1; +static std::vector::const_iterator buildSubBlock( + std::vector::const_iterator begin, std::vector::const_iterator end, + std::vector &subBlock) { + std::stack matched; + std::vector::const_iterator itr; + for (itr = begin; itr != end; ++itr) { + subBlock.push_back(*itr); + + // push/pop brackets as they are discovered + if (*itr == "[") + matched.push("["); + else if (*itr == "]") + matched.pop(); + + // found all matching brackets + if (matched.empty()) return itr; + } + + TEUCHOS_ASSERT(matched.empty()); + + return itr - 1; } // This function takes a tokenized vector and converts it to a block reorder manager -static RCP blockedReorderFromTokens(const std::vector & tokens) -{ - // base case - if(tokens.size()==1) - return rcp(new Teko::BlockReorderLeaf(Teuchos::StrUtils::atoi(tokens[0]))); - - // check first and last character - TEUCHOS_ASSERT(*(tokens.begin())=="[") - TEUCHOS_ASSERT(*(tokens.end()-1)=="]"); - - std::vector > vecRMgr; - std::vector::const_iterator itr = tokens.begin()+1; - while(itr!=tokens.end()-1) { - // figure out which tokens are relevant for this block - std::vector subBlock; - itr = buildSubBlock(itr,tokens.end()-1,subBlock); - - // build the child block reorder manager - vecRMgr.push_back(blockedReorderFromTokens(subBlock)); - - // move the iterator one more - itr++; - } - - // build the parent reorder manager - RCP rMgr = rcp(new Teko::BlockReorderManager(vecRMgr.size())); - for(unsigned int i=0;iSetBlock(i,vecRMgr[i]); - - return rMgr; +static RCP blockedReorderFromTokens(const std::vector &tokens) { + // base case + if (tokens.size() == 1) + return rcp(new Teko::BlockReorderLeaf(Teuchos::StrUtils::atoi(tokens[0]))); + + // check first and last character + TEUCHOS_ASSERT(*(tokens.begin()) == "[") + TEUCHOS_ASSERT(*(tokens.end() - 1) == "]"); + + std::vector > vecRMgr; + std::vector::const_iterator itr = tokens.begin() + 1; + while (itr != tokens.end() - 1) { + // figure out which tokens are relevant for this block + std::vector subBlock; + itr = buildSubBlock(itr, tokens.end() - 1, subBlock); + + // build the child block reorder manager + vecRMgr.push_back(blockedReorderFromTokens(subBlock)); + + // move the iterator one more + itr++; + } + + // build the parent reorder manager + RCP rMgr = rcp(new Teko::BlockReorderManager(vecRMgr.size())); + for (unsigned int i = 0; i < vecRMgr.size(); i++) rMgr->SetBlock(i, vecRMgr[i]); + + return rMgr; } //////////////////////////////////////////////////////////////// /** \brief Convert a string to a block reorder manager object - * - * Convert a string to a block reorder manager object. These - * strings have numbers delimted by [,]. For example, - * the string "[[2 1] 0]" will give a manager with [2 1] in the - * first block and 0 in the second block. - * - * \param[in] reorder Block structure corresponding to the manager - * - * \returns A block reorder manager with the requested structure - */ -Teuchos::RCP blockedReorderFromString(std::string & reorder) -{ - // vector of tokens to use - std::vector tokens; - - // manager to be returned - - // build tokens vector - tokenize(reorder," \t\n","[]",tokens); - - // parse recursively and build reorder manager - Teuchos::RCP mgr = blockedReorderFromTokens(tokens); - - return mgr; + * + * Convert a string to a block reorder manager object. These + * strings have numbers delimted by [,]. For example, + * the string "[[2 1] 0]" will give a manager with [2 1] in the + * first block and 0 in the second block. + * + * \param[in] reorder Block structure corresponding to the manager + * + * \returns A block reorder manager with the requested structure + */ +Teuchos::RCP blockedReorderFromString(std::string &reorder) { + // vector of tokens to use + std::vector tokens; + + // manager to be returned + + // build tokens vector + tokenize(reorder, " \t\n", "[]", tokens); + + // parse recursively and build reorder manager + Teuchos::RCP mgr = blockedReorderFromTokens(tokens); + + return mgr; } -} // end namespace Teko +} // end namespace Teko diff --git a/packages/teko/src/Teko_BlockedReordering.hpp b/packages/teko/src/Teko_BlockedReordering.hpp index 0a123131a9b0..0c4e09aa7447 100644 --- a/packages/teko/src/Teko_BlockedReordering.hpp +++ b/packages/teko/src/Teko_BlockedReordering.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -60,372 +60,379 @@ namespace Teko { /** \brief Class that describes how a flat blocked operator - * should be reordered. - * - * Class that describes how a flat blocked operator should - * be reordered. The semenatics are very similar to a - * Teuchos::ParameterList. Each level expects you to set the - * size of the level and define what each subblock is. For - * example, to change the blocked 3x3 matrix from - * - * \f$ Z = \left[\begin{array}{ccc} - * A & B & C \\ - * D & E & F \\ - * G & H & I - * \end{array}\right]\f$ - * - * to - * - * \f$ Z' = \left[\begin{array}{cc} - * \left[\begin{array}{cc} - * A & B \\ - * D & E - * \end{array}\right] & - * \left[\begin{array}{c} - * C \\ F \end{array}\right] \\ - * \left[\begin{array}{cc} - * G & H - * \end{array}\right] & I - * \end{array}\right]\f$ - * - * the algorithm to build the appropriate block manager is - * - * - * RCP bmm = rcp(new BlockReorderManager(2));\n - * bmm->GetBlock(0)->SetNumBlocks(2);\n - * bmm->GetBlock(0)->SetBlock(0,0);\n - * bmm->GetBlock(0)->SetBlock(1,1);\n - * bmm->SetBlock(1,2); - * - * - * Suppose now you want to take your \f$Z\f$ operator and build - * \f$Z'\f$. The relevant code is - * - * - * BlockedLinearOp Z = ... \n - * LinearOp Zprime = buildReorderedLinearOp(*bmm,Z); - * - */ + * should be reordered. + * + * Class that describes how a flat blocked operator should + * be reordered. The semenatics are very similar to a + * Teuchos::ParameterList. Each level expects you to set the + * size of the level and define what each subblock is. For + * example, to change the blocked 3x3 matrix from + * + * \f$ Z = \left[\begin{array}{ccc} + * A & B & C \\ + * D & E & F \\ + * G & H & I + * \end{array}\right]\f$ + * + * to + * + * \f$ Z' = \left[\begin{array}{cc} + * \left[\begin{array}{cc} + * A & B \\ + * D & E + * \end{array}\right] & + * \left[\begin{array}{c} + * C \\ F \end{array}\right] \\ + * \left[\begin{array}{cc} + * G & H + * \end{array}\right] & I + * \end{array}\right]\f$ + * + * the algorithm to build the appropriate block manager is + * + * + * RCP bmm = rcp(new BlockReorderManager(2));\n + * bmm->GetBlock(0)->SetNumBlocks(2);\n + * bmm->GetBlock(0)->SetBlock(0,0);\n + * bmm->GetBlock(0)->SetBlock(1,1);\n + * bmm->SetBlock(1,2); + * + * + * Suppose now you want to take your \f$Z\f$ operator and build + * \f$Z'\f$. The relevant code is + * + * + * BlockedLinearOp Z = ... \n + * LinearOp Zprime = buildReorderedLinearOp(*bmm,Z); + * + */ class BlockReorderManager { -public: - //! @name Constructors - //@{ - - //! Basic empty constructor - BlockReorderManager() : children_(0) {} - - //! Set this level to have size sz - BlockReorderManager(int sz) : children_(sz,Teuchos::null) {} - - //! Copy constructor - BlockReorderManager(const BlockReorderManager & bmm) - : children_(bmm.children_.size()) - { for(unsigned int i=0;iCopy(); } - - //! Do nothing destructor - virtual ~BlockReorderManager() {} - - //@} - - //! Returns a copy of this object - virtual Teuchos::RCP Copy() const - { return Teuchos::rcp(new BlockReorderManager(*this)); } - - //! Sets the number of subblocks - virtual void SetNumBlocks(int sz) - { children_.clear(); children_.resize(sz); } - - //! Gets the number of subblocks - virtual int GetNumBlocks() const - { return children_.size(); } - - /** \brief Sets the sublock to a specific index value - * - * Sets the sublock to a specific index value - * \param[in] blockIndex Subblock to be set - * \param[in] reorder The value of the index in this subblock - * - * \pre blockIndexGetNumBlocks() - */ - virtual void SetBlock(int blockIndex,int reorder); - - /** \brief Set the subblock to a use a particular reorder - * manager. - * - * Set the subblock to a use a particular reorder - * manager. This facilitates recursive construction algorithms - * where the base case is not differentiated. - * - * \param[in] blockIndex Subblock to be set - * \param[in] reorder Reorder manager to be used in this block - * - * \pre blockIndexGetNumBlocks() - */ - virtual void SetBlock(int blockIndex,const Teuchos::RCP & reorder); - - /** \brief Get a particular block. If there is no block at this - * index location return a new one. - * - * Get a particular block. If there is no block at this - * index location return a new one. - * - * \param[in] blockIndex The index queried. - * - * \returns A pointer to the BlockReorderManager object at this - * location, or if there is none, a new BlockReorderManager - * is created and returned. - * - * \pre blockIndexGetNumBlocks() - * \post return value is not null - */ - virtual const Teuchos::RCP GetBlock(int blockIndex); - - /** \brief Get a particular block. If there is no block at this - * index location return Teuchos::null - * - * Get a particular block. If there is no block at this - * index location return Teuchos::null - * - * \param[in] blockIndex The index queried. - * - * \returns A pointer to the BlockReorderManager object at this - * location, or if there is none Teuchos::null - * is returned. - * - * \pre blockIndexGetNumBlocks() - */ - virtual const Teuchos::RCP GetBlock(int blockIndex) const; - - //! For sanities sake, print a readable string - virtual std::string toString() const; - - //! Largest index in this manager - virtual int LargestIndex() const; - -protected: - //! Definitions of the subblocks. - std::vector > children_; + public: + //! @name Constructors + //@{ + + //! Basic empty constructor + BlockReorderManager() : children_(0) {} + + //! Set this level to have size sz + BlockReorderManager(int sz) : children_(sz, Teuchos::null) {} + + //! Copy constructor + BlockReorderManager(const BlockReorderManager& bmm) : children_(bmm.children_.size()) { + for (unsigned int i = 0; i < children_.size(); i++) children_[i] = bmm.children_[i]->Copy(); + } + + //! Do nothing destructor + virtual ~BlockReorderManager() {} + + //@} + + //! Returns a copy of this object + virtual Teuchos::RCP Copy() const { + return Teuchos::rcp(new BlockReorderManager(*this)); + } + + //! Sets the number of subblocks + virtual void SetNumBlocks(int sz) { + children_.clear(); + children_.resize(sz); + } + + //! Gets the number of subblocks + virtual int GetNumBlocks() const { return children_.size(); } + + /** \brief Sets the sublock to a specific index value + * + * Sets the sublock to a specific index value + * \param[in] blockIndex Subblock to be set + * \param[in] reorder The value of the index in this subblock + * + * \pre blockIndexGetNumBlocks() + */ + virtual void SetBlock(int blockIndex, int reorder); + + /** \brief Set the subblock to a use a particular reorder + * manager. + * + * Set the subblock to a use a particular reorder + * manager. This facilitates recursive construction algorithms + * where the base case is not differentiated. + * + * \param[in] blockIndex Subblock to be set + * \param[in] reorder Reorder manager to be used in this block + * + * \pre blockIndexGetNumBlocks() + */ + virtual void SetBlock(int blockIndex, const Teuchos::RCP& reorder); + + /** \brief Get a particular block. If there is no block at this + * index location return a new one. + * + * Get a particular block. If there is no block at this + * index location return a new one. + * + * \param[in] blockIndex The index queried. + * + * \returns A pointer to the BlockReorderManager object at this + * location, or if there is none, a new BlockReorderManager + * is created and returned. + * + * \pre blockIndexGetNumBlocks() + * \post return value is not null + */ + virtual const Teuchos::RCP GetBlock(int blockIndex); + + /** \brief Get a particular block. If there is no block at this + * index location return Teuchos::null + * + * Get a particular block. If there is no block at this + * index location return Teuchos::null + * + * \param[in] blockIndex The index queried. + * + * \returns A pointer to the BlockReorderManager object at this + * location, or if there is none Teuchos::null + * is returned. + * + * \pre blockIndexGetNumBlocks() + */ + virtual const Teuchos::RCP GetBlock(int blockIndex) const; + + //! For sanities sake, print a readable string + virtual std::string toString() const; + + //! Largest index in this manager + virtual int LargestIndex() const; + + protected: + //! Definitions of the subblocks. + std::vector > children_; }; /** A class that corresponds to the leaf, or stopping critera - * for BlockReorderManager. This class should not be used - * directly. - */ + * for BlockReorderManager. This class should not be used + * directly. + */ class BlockReorderLeaf : public BlockReorderManager { -public: - //! @name Constructors - //@{ - - //! Simple constructor that sets the index - BlockReorderLeaf(int ind) : value_(ind) { } + public: + //! @name Constructors + //@{ - //! Copy constructor - BlockReorderLeaf(const BlockReorderLeaf & brl) - : value_(brl.value_) {} - //@} + //! Simple constructor that sets the index + BlockReorderLeaf(int ind) : value_(ind) {} - //! Make a copy of this object - virtual Teuchos::RCP Copy() const - { return Teuchos::rcp(new BlockReorderLeaf(*this)); } + //! Copy constructor + BlockReorderLeaf(const BlockReorderLeaf& brl) : value_(brl.value_) {} + //@} - //! Get the number of subblocks (this one returns 0 b/c its a leaf) - virtual int GetNumBlocks() const { return 0; } + //! Make a copy of this object + virtual Teuchos::RCP Copy() const { + return Teuchos::rcp(new BlockReorderLeaf(*this)); + } - //! Set the number of subblocks (this one does nothing b/c its a leaf) - virtual void SetNumBlocks(int /* sz */) {} + //! Get the number of subblocks (this one returns 0 b/c its a leaf) + virtual int GetNumBlocks() const { return 0; } - //! Set the sub block, this does nothing b/c its a leaf - virtual void SetBlock(int /* blockIndex */,int /* reorder */) { } + //! Set the number of subblocks (this one does nothing b/c its a leaf) + virtual void SetNumBlocks(int /* sz */) {} - //! Get a particular subblock...this returns null - virtual const Teuchos::RCP GetBlock(int /* blockIndex */) - { return Teuchos::null; } + //! Set the sub block, this does nothing b/c its a leaf + virtual void SetBlock(int /* blockIndex */, int /* reorder */) {} - //! Get a particular subblock...this returns null - virtual const Teuchos::RCP GetBlock(int /* blockIndex */) const - { return Teuchos::null; } + //! Get a particular subblock...this returns null + virtual const Teuchos::RCP GetBlock(int /* blockIndex */) { + return Teuchos::null; + } - //! Get the the index that is stored in this block - int GetIndex() const { return value_; } + //! Get a particular subblock...this returns null + virtual const Teuchos::RCP GetBlock(int /* blockIndex */) const { + return Teuchos::null; + } - //! Return a string description of this leaf class - virtual std::string toString() const - { std::stringstream ss; ss << value_; return ss.str(); } + //! Get the the index that is stored in this block + int GetIndex() const { return value_; } - //! Largest index in this manager - virtual int LargestIndex() const { return value_; } + //! Return a string description of this leaf class + virtual std::string toString() const { + std::stringstream ss; + ss << value_; + return ss.str(); + } -protected: - using BlockReorderManager::SetBlock; + //! Largest index in this manager + virtual int LargestIndex() const { return value_; } - //! The value of the index for this leaf - int value_; + protected: + using BlockReorderManager::SetBlock; -private: - BlockReorderLeaf(); // hidden from users + //! The value of the index for this leaf + int value_; + + private: + BlockReorderLeaf(); // hidden from users }; /** \brief Use the BlockReorderManager to change a flat square blocked operator - * into a composite operator. - * - * Use the BlockReorderManager to chanage a flat square blocked operator into - * a more complex composite structure. The manager should not have any indicies - * larger then the size of the blocked operator. - * - * \param[in] bmm BlockReorderManager that specifies how the blocked operator - * is to be restructured. - * \param[in] blkOp The block operator to be reordered and restructured. Only the - * first level of the operator will be considered. Each subblock - * (even if it is itself blocked) will be handed as an individual - * operator. - * - * \returns The reordered blocked linear operator. - * - * \pre The largest index in bmm is smaller then the dimension of the - * blkOp. - * \pre The opertor is square. - * - * \relates BlockReorderManager - */ -Teuchos::RCP > -buildReorderedLinearOp(const BlockReorderManager & bmm, - const Teuchos::RCP > & blkOp); + * into a composite operator. + * + * Use the BlockReorderManager to chanage a flat square blocked operator into + * a more complex composite structure. The manager should not have any indicies + * larger then the size of the blocked operator. + * + * \param[in] bmm BlockReorderManager that specifies how the blocked operator + * is to be restructured. + * \param[in] blkOp The block operator to be reordered and restructured. Only the + * first level of the operator will be considered. Each subblock + * (even if it is itself blocked) will be handed as an individual + * operator. + * + * \returns The reordered blocked linear operator. + * + * \pre The largest index in bmm is smaller then the dimension of the + * blkOp. + * \pre The opertor is square. + * + * \relates BlockReorderManager + */ +Teuchos::RCP > buildReorderedLinearOp( + const BlockReorderManager& bmm, + const Teuchos::RCP >& blkOp); /** \brief Use the BlockReorderManager to change a flat blocked operator - * into a composite operator. - * - * Use the BlockReorderManager to chanage a flat square blocked operator into - * a more complex composite structure. The manager should not have any indicies - * larger then the size of the blocked operator. - * - * \param[in] rowMgr BlockReorderManager that specifies how the rows are to - * be restructured. - * \param[in] colMgr BlockReorderManager that specifies how the columns are to - * be restructured. - * \param[in] blkOp The block operator to be reordered and restructured. Only the - * first level of the operator will be considered. Each subblock - * (even if it is itself blocked) will be handed as an individual - * operator. - * - * \returns The reordered blocked linear operator. - * - * \pre The largest index in bmm is smaller then the dimension of the - * blkOp. - * - * \relates BlockReorderManager - */ -Teuchos::RCP > -buildReorderedLinearOp(const BlockReorderManager & rowMgr,const BlockReorderManager & colMgr, - const Teuchos::RCP > & blkOp); + * into a composite operator. + * + * Use the BlockReorderManager to chanage a flat square blocked operator into + * a more complex composite structure. The manager should not have any indicies + * larger then the size of the blocked operator. + * + * \param[in] rowMgr BlockReorderManager that specifies how the rows are to + * be restructured. + * \param[in] colMgr BlockReorderManager that specifies how the columns are to + * be restructured. + * \param[in] blkOp The block operator to be reordered and restructured. Only the + * first level of the operator will be considered. Each subblock + * (even if it is itself blocked) will be handed as an individual + * operator. + * + * \returns The reordered blocked linear operator. + * + * \pre The largest index in bmm is smaller then the dimension of the + * blkOp. + * + * \relates BlockReorderManager + */ +Teuchos::RCP > buildReorderedLinearOp( + const BlockReorderManager& rowMgr, const BlockReorderManager& colMgr, + const Teuchos::RCP >& blkOp); /** \brief Use the BlockReorderManager to change a flat vector space - * into a composite vector space. - * - * Use the BlockReorderManager to chanage a flat vector space - * a more complex composite structure. The manager should not have any indicies - * larger then the size of the blocked operator. - * - * \param[in] mgr BlockReorderManager that specifies how the space is to - * be restructured. - * \param[in] blkSpc The block space to be reordered and restructured. Only the - * first level of the space will be considered. Each subspace - * (even if it is itself blocked) will be handed as an individual - * space. - * - * \returns The reordered blocked vector space. - * - * \pre The largest index in bmm is smaller then the dimension of the - * blkSpc. - * - * \relates BlockReorderManager - */ -Teuchos::RCP > -buildReorderedVectorSpace(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkSpc); + * into a composite vector space. + * + * Use the BlockReorderManager to chanage a flat vector space + * a more complex composite structure. The manager should not have any indicies + * larger then the size of the blocked operator. + * + * \param[in] mgr BlockReorderManager that specifies how the space is to + * be restructured. + * \param[in] blkSpc The block space to be reordered and restructured. Only the + * first level of the space will be considered. Each subspace + * (even if it is itself blocked) will be handed as an individual + * space. + * + * \returns The reordered blocked vector space. + * + * \pre The largest index in bmm is smaller then the dimension of the + * blkSpc. + * + * \relates BlockReorderManager + */ +Teuchos::RCP > buildReorderedVectorSpace( + const BlockReorderManager& mgr, + const Teuchos::RCP >& blkSpc); /** \brief Convert a flat multi vector into a reordered multivector. - * - * Convert a flat multi vector into a reordered multivector. - * - * \param[in] mgr Block manager describing the reordered multivector. - * \param[in] blkVec The flat multivector. - * - * \returns A reordered multivector structured to be consistent with mgr. - * - * \relates BlockReorderManager - */ -Teuchos::RCP > -buildReorderedMultiVector(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkVec); + * + * Convert a flat multi vector into a reordered multivector. + * + * \param[in] mgr Block manager describing the reordered multivector. + * \param[in] blkVec The flat multivector. + * + * \returns A reordered multivector structured to be consistent with mgr. + * + * \relates BlockReorderManager + */ +Teuchos::RCP > buildReorderedMultiVector( + const BlockReorderManager& mgr, + const Teuchos::RCP >& blkVec); /** \brief Convert a flat multi vector into a reordered multivector. - * - * Convert a flat multi vector into a reordered multivector. - * - * \param[in] mgr Block manager describing the reordered multivector. - * \param[in] blkVec The flat multivector. - * - * \returns A reordered multivector structured to be consistent with mgr. - * - * \relates BlockReorderManager - */ -Teuchos::RCP > -buildReorderedMultiVector(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkVec); + * + * Convert a flat multi vector into a reordered multivector. + * + * \param[in] mgr Block manager describing the reordered multivector. + * \param[in] blkVec The flat multivector. + * + * \returns A reordered multivector structured to be consistent with mgr. + * + * \relates BlockReorderManager + */ +Teuchos::RCP > buildReorderedMultiVector( + const BlockReorderManager& mgr, + const Teuchos::RCP >& blkVec); /** \brief Convert a reordered multivector into a flat multivector. - * - * Convert a reordered multivector into a flat multivector. - * - * \param[in] mgr Block manager describing the reordered multivector. - * \param[in] blkVec The reordered multivector structured in a way that - * is consistent with by mgr - * - * \returns A flattened multivector. - * - * \relates BlockReorderManager - */ -Teuchos::RCP > -buildFlatMultiVector(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkVec); + * + * Convert a reordered multivector into a flat multivector. + * + * \param[in] mgr Block manager describing the reordered multivector. + * \param[in] blkVec The reordered multivector structured in a way that + * is consistent with by mgr + * + * \returns A flattened multivector. + * + * \relates BlockReorderManager + */ +Teuchos::RCP > buildFlatMultiVector( + const BlockReorderManager& mgr, + const Teuchos::RCP >& blkVec); /** \brief Convert a reordered multivector into a flat multivector. - * - * Convert a reordered multivector into a flat multivector. - * - * \param[in] mgr Block manager describing the reordered multivector. - * \param[in] blkVec The reordered multivector structured in a way that - * is consistent with by mgr - * - * \returns A flattened multivector. - * - * \relates BlockReorderManager - */ -Teuchos::RCP > -buildFlatMultiVector(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkVec); + * + * Convert a reordered multivector into a flat multivector. + * + * \param[in] mgr Block manager describing the reordered multivector. + * \param[in] blkVec The reordered multivector structured in a way that + * is consistent with by mgr + * + * \returns A flattened multivector. + * + * \relates BlockReorderManager + */ +Teuchos::RCP > buildFlatMultiVector( + const BlockReorderManager& mgr, + const Teuchos::RCP >& blkVec); /** \brief Convert a reordered vector space into a flat vector space - */ -Teuchos::RCP > -buildFlatVectorSpace(const BlockReorderManager & mgr, - const Teuchos::RCP > & blkSpc); + */ +Teuchos::RCP > buildFlatVectorSpace( + const BlockReorderManager& mgr, + const Teuchos::RCP >& blkSpc); /** \brief Convert a string to a block reorder manager object - * - * Convert a string to a block reorder manager object. These - * strings have numbers delimted by [,]. For example, - * the string "[[2 1] 0]" will give a manager with [2 1] in the - * first block and 0 in the second block. - * - * \param[in] reorder Block structure corresponding to the manager - * - * \returns A block reorder manager with the requested structure - * - * \relates BlockReorderManager - */ -Teuchos::RCP blockedReorderFromString(std::string & reorder); - -} // end namespace Teko + * + * Convert a string to a block reorder manager object. These + * strings have numbers delimted by [,]. For example, + * the string "[[2 1] 0]" will give a manager with [2 1] in the + * first block and 0 in the second block. + * + * \param[in] reorder Block structure corresponding to the manager + * + * \returns A block reorder manager with the requested structure + * + * \relates BlockReorderManager + */ +Teuchos::RCP blockedReorderFromString(std::string& reorder); + +} // end namespace Teko #endif diff --git a/packages/teko/src/Teko_CloneFactory.hpp b/packages/teko/src/Teko_CloneFactory.hpp index 3b54778b19fc..72698a784f7f 100644 --- a/packages/teko/src/Teko_CloneFactory.hpp +++ b/packages/teko/src/Teko_CloneFactory.hpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -53,143 +53,140 @@ namespace Teko { /** Base class for cloneable objects */ class Cloneable { -public: - virtual ~Cloneable() {} - - /** Function that clones this object. This - * is not neccessarily a copy, but it is an - * object of the same dynamic type. - * - * \returns A pointer to an object of the same - * type is returned - */ - virtual Teuchos::RCP clone() const = 0; + public: + virtual ~Cloneable() {} + + /** Function that clones this object. This + * is not neccessarily a copy, but it is an + * object of the same dynamic type. + * + * \returns A pointer to an object of the same + * type is returned + */ + virtual Teuchos::RCP clone() const = 0; }; /** Class that simply prevents the autoclone object - * from uneccessarily calling a constructor. - */ + * from uneccessarily calling a constructor. + */ class AutoCloneDummy {}; /** Class that provides an easy way to create a cloneable - * class. All that is required is that the user implements - * a default constructor. This also serves as a model for - * creating other AutoClone-like interfaces. - * - * The template parameter CloneType describes - * the type of cloned object to returned. An object returned - * from AutoClone::clone will be typed as - * CloneType. The BaseType is the - * parent type of the cloned object created. It is included, - * with default AutoCloneDummy, so that no - * instantiaions of CloneType are unnecessarily - * created. - * - * \note Use of this class assumes the CloneType and BaseType - * classes have a default constructor and does not - * override the clone method. - */ -template + * class. All that is required is that the user implements + * a default constructor. This also serves as a model for + * creating other AutoClone-like interfaces. + * + * The template parameter CloneType describes + * the type of cloned object to returned. An object returned + * from AutoClone::clone will be typed as + * CloneType. The BaseType is the + * parent type of the cloned object created. It is included, + * with default AutoCloneDummy, so that no + * instantiaions of CloneType are unnecessarily + * created. + * + * \note Use of this class assumes the CloneType and BaseType + * classes have a default constructor and does not + * override the clone method. + */ +template class AutoClone : public Cloneable, public BaseType { -public: - virtual ~AutoClone() {} - - /** Simple default constructor, calls the default - * constructor of BaseType - */ - AutoClone() - : BaseType() - { } - - /** Function that clones this object. This - * is not neccessarily a copy, but it is an - * object of the same dynamic type. - * - * \returns A pointer to an object of the same - * type is returned - */ - virtual Teuchos::RCP clone() const - { return Teuchos::rcp(new AutoClone()); } - -private: - // hidden - AutoClone(const AutoClone & ); + public: + virtual ~AutoClone() {} + + /** Simple default constructor, calls the default + * constructor of BaseType + */ + AutoClone() : BaseType() {} + + /** Function that clones this object. This + * is not neccessarily a copy, but it is an + * object of the same dynamic type. + * + * \returns A pointer to an object of the same + * type is returned + */ + virtual Teuchos::RCP clone() const { + return Teuchos::rcp(new AutoClone()); + } + + private: + // hidden + AutoClone(const AutoClone&); }; -/** This class eases the construction of clone factories. - * It takes any Cloneable object and associates it with - * a string. It will then perform the dynamic cast to - * whatever type the user specifies using the CloneBaseType - * template parameter. - * - * \note A word of warning. This class does not provide compile - * time type safety. - */ +/** This class eases the construction of clone factories. + * It takes any Cloneable object and associates it with + * a string. It will then perform the dynamic cast to + * whatever type the user specifies using the CloneBaseType + * template parameter. + * + * \note A word of warning. This class does not provide compile + * time type safety. + */ template class CloneFactory { -public: - //! Default constructor - CloneFactory() {} - - //! Copy constructor - CloneFactory(const CloneFactory & cf) : parentClones_(cf.parentClones_) {} - - virtual ~CloneFactory() {} - - /** Build a clone of the object associated with the string. This - * object is automatically cast to the desired base type. This will - * permit the easy use of the AutoClone class. - * - * \note This method will throw an exception if the clone is not the right - * type (i.e. the dynamic cast to CloneBaseType fails). Also, this method - * returns null if the clone associated with the string can't be - * found. - * - * \param[in] str String associated with object to build. - * - * \returns A cloned object, correctly casted to CloneBaseType. If the - * string cannot be found then null is returned. - */ - virtual Teuchos::RCP build(const std::string & str) const - { - std::map >::const_iterator itr - = parentClones_.find(str); - if(itr==parentClones_.end()) return Teuchos::null; - return Teuchos::rcp_dynamic_cast(itr->second->clone(),true); - } - - /** Add a string associated clone to the factory. This object can be used - * later to build a clone of itself. If this method is called twice with - * the same string, the later clone will be maintained. - * - * \note The object to be cloned is stored until the CloneFactory is destroyed. - * - * \param[in] str String associated with this object. - * \param[in] clone Object to be cloned. - */ - virtual void addClone(const std::string & str,const Teuchos::RCP & clone) - { parentClones_[str] = clone; } - - //! Return the number of clones stored in this factory - virtual int cloneCount() const - { return parentClones_.size(); } - - /** Get the label for all clones in this CloneFactory. - * - * \param[in,out] names Destination vector for the the clone names - */ - void getCloneNames(std::vector & names) const - { - std::map >::const_iterator itr; - for(itr=parentClones_.begin();itr!=parentClones_.end();++itr) - names.push_back(itr->first); - } - -protected: - //! stores the clonable objects - std::map > parentClones_; + public: + //! Default constructor + CloneFactory() {} + + //! Copy constructor + CloneFactory(const CloneFactory& cf) : parentClones_(cf.parentClones_) {} + + virtual ~CloneFactory() {} + + /** Build a clone of the object associated with the string. This + * object is automatically cast to the desired base type. This will + * permit the easy use of the AutoClone class. + * + * \note This method will throw an exception if the clone is not the right + * type (i.e. the dynamic cast to CloneBaseType fails). Also, this method + * returns null if the clone associated with the string can't be + * found. + * + * \param[in] str String associated with object to build. + * + * \returns A cloned object, correctly casted to CloneBaseType. If the + * string cannot be found then null is returned. + */ + virtual Teuchos::RCP build(const std::string& str) const { + std::map >::const_iterator itr = + parentClones_.find(str); + if (itr == parentClones_.end()) return Teuchos::null; + return Teuchos::rcp_dynamic_cast(itr->second->clone(), true); + } + + /** Add a string associated clone to the factory. This object can be used + * later to build a clone of itself. If this method is called twice with + * the same string, the later clone will be maintained. + * + * \note The object to be cloned is stored until the CloneFactory is destroyed. + * + * \param[in] str String associated with this object. + * \param[in] clone Object to be cloned. + */ + virtual void addClone(const std::string& str, const Teuchos::RCP& clone) { + parentClones_[str] = clone; + } + + //! Return the number of clones stored in this factory + virtual int cloneCount() const { return parentClones_.size(); } + + /** Get the label for all clones in this CloneFactory. + * + * \param[in,out] names Destination vector for the the clone names + */ + void getCloneNames(std::vector& names) const { + std::map >::const_iterator itr; + for (itr = parentClones_.begin(); itr != parentClones_.end(); ++itr) + names.push_back(itr->first); + } + + protected: + //! stores the clonable objects + std::map > parentClones_; }; -} +} // namespace Teko #endif diff --git a/packages/teko/src/Teko_ConfigDefs.hpp b/packages/teko/src/Teko_ConfigDefs.hpp index 46a454ba85bb..893e1b73958b 100644 --- a/packages/teko/src/Teko_ConfigDefs.hpp +++ b/packages/teko/src/Teko_ConfigDefs.hpp @@ -58,6 +58,6 @@ typedef Tpetra::Map<>::global_ordinal_type GO; typedef Tpetra::Map<>::local_ordinal_type LO; typedef Tpetra::Map<>::node_type NT; -} +} // namespace Teko #endif diff --git a/packages/teko/src/Teko_DiagnosticLinearOp.cpp b/packages/teko/src/Teko_DiagnosticLinearOp.cpp index 59dcab660d57..68218ed42545 100644 --- a/packages/teko/src/Teko_DiagnosticLinearOp.cpp +++ b/packages/teko/src/Teko_DiagnosticLinearOp.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -53,94 +53,103 @@ namespace Teko { /** \brief This constructor explicitly takes the linear operator - * that needs to be wrapped and a string for output that describes - * the diagnostics. - */ -DiagnosticLinearOp::DiagnosticLinearOp(const Teuchos::RCP & ostrm, const ModifiableLinearOp & A,const std::string & diagnosticString) - : outputStream_(ostrm), wrapOpA_(A), wrapOpA_lo_(A), diagString_(diagnosticString), timer_(diagnosticString) -{ -} - -DiagnosticLinearOp::DiagnosticLinearOp(const Teuchos::RCP & ostrm, const LinearOp & A,const std::string & diagnosticString) - : outputStream_(ostrm), wrapOpA_(Teuchos::null), wrapOpA_lo_(A), diagString_(diagnosticString), timer_(diagnosticString) -{ -} + * that needs to be wrapped and a string for output that describes + * the diagnostics. + */ +DiagnosticLinearOp::DiagnosticLinearOp(const Teuchos::RCP& ostrm, + const ModifiableLinearOp& A, + const std::string& diagnosticString) + : outputStream_(ostrm), + wrapOpA_(A), + wrapOpA_lo_(A), + diagString_(diagnosticString), + timer_(diagnosticString) {} + +DiagnosticLinearOp::DiagnosticLinearOp(const Teuchos::RCP& ostrm, const LinearOp& A, + const std::string& diagnosticString) + : outputStream_(ostrm), + wrapOpA_(Teuchos::null), + wrapOpA_lo_(A), + diagString_(diagnosticString), + timer_(diagnosticString) {} /** \brief This constructor explicitly takes the linear operator - * that needs to be wrapped and a string for output that describes - * the diagnostics. - */ -DiagnosticLinearOp::DiagnosticLinearOp(const Teuchos::RCP & ostrm,const LinearOp & fwdOp, - const ModifiableLinearOp & A,const std::string & diagnosticString) - : outputStream_(ostrm), wrapOpA_(A), wrapOpA_lo_(A), fwdOp_(fwdOp), diagString_(diagnosticString), timer_(diagnosticString) -{ -} - -DiagnosticLinearOp::~DiagnosticLinearOp() -{ - double elapsedTime = totalTime(); - int applications = numApplications(); - - (*outputStream_) << "DiagnosticLinearOp \"" << diagString_ << "\": " - << "elapsed = " << elapsedTime << ", " - << "applications = " << applications << ", "; - if(applications>0) - (*outputStream_) << "timer/app = " << elapsedTime / double(applications) << std::endl; - else - (*outputStream_) << "timer/app = " << "none" << std::endl; + * that needs to be wrapped and a string for output that describes + * the diagnostics. + */ +DiagnosticLinearOp::DiagnosticLinearOp(const Teuchos::RCP& ostrm, + const LinearOp& fwdOp, const ModifiableLinearOp& A, + const std::string& diagnosticString) + : outputStream_(ostrm), + wrapOpA_(A), + wrapOpA_lo_(A), + fwdOp_(fwdOp), + diagString_(diagnosticString), + timer_(diagnosticString) {} + +DiagnosticLinearOp::~DiagnosticLinearOp() { + double elapsedTime = totalTime(); + int applications = numApplications(); + + (*outputStream_) << "DiagnosticLinearOp \"" << diagString_ << "\": " + << "elapsed = " << elapsedTime << ", " + << "applications = " << applications << ", "; + if (applications > 0) + (*outputStream_) << "timer/app = " << elapsedTime / double(applications) << std::endl; + else + (*outputStream_) << "timer/app = " + << "none" << std::endl; } -/** @brief Perform a matrix vector multiply with this operator. - * - * The apply function takes one vector as input - * and applies the inverse \f$ LDU \f$ decomposition. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ -void DiagnosticLinearOp::implicitApply(const MultiVector & x, MultiVector & y, - const double alpha, const double beta) const -{ - Teko_DEBUG_SCOPE("DiagnosticLinearOp::implicityApply",10); - - // start timer on construction, end on destruction - Teuchos::TimeMonitor monitor(timer_,false); - - MultiVector z; // for temporary storage dealing with nozero beta - if(beta!=0.0) - z = deepcopy(y); - - wrapOpA_lo_->apply(Thyra::NOTRANS,*x,y.ptr(),alpha,beta); - - // print residual if there is a fwd Op - bool printResidual = (fwdOp_!=Teuchos::null); - if(printResidual) { - // compute residual - MultiVector residual = Teko::deepcopy(x); - // fwdOp_->apply(Thyra::NOTRANS,*y,residual.ptr(),-1.0,1.0); - - fwdOp_->apply(Thyra::NOTRANS,*y,residual.ptr(),-1.0,alpha); - if(beta!=0.0) - fwdOp_->apply(Thyra::NOTRANS,*z,residual.ptr(),beta,1.0); - - // calculate norms - std::vector norms(y->domain()->dim()); // size of column count - std::vector rhsNorms(x->domain()->dim()); // size of column count - Thyra::norms_2(*residual,Teuchos::arrayViewFromVector(norms)); - Thyra::norms_2(*x,Teuchos::arrayViewFromVector(rhsNorms)); - - // print out residual norms - (*outputStream_) << "DiagnosticLinearOp \"" << diagString_ << "\": residual = ["; - for(std::size_t i=0;iapply function takes one vector as input + * and applies the inverse \f$ LDU \f$ decomposition. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ +void DiagnosticLinearOp::implicitApply(const MultiVector& x, MultiVector& y, const double alpha, + const double beta) const { + Teko_DEBUG_SCOPE("DiagnosticLinearOp::implicityApply", 10); + + // start timer on construction, end on destruction + Teuchos::TimeMonitor monitor(timer_, false); + + MultiVector z; // for temporary storage dealing with nozero beta + if (beta != 0.0) z = deepcopy(y); + + wrapOpA_lo_->apply(Thyra::NOTRANS, *x, y.ptr(), alpha, beta); + + // print residual if there is a fwd Op + bool printResidual = (fwdOp_ != Teuchos::null); + if (printResidual) { + // compute residual + MultiVector residual = Teko::deepcopy(x); + // fwdOp_->apply(Thyra::NOTRANS,*y,residual.ptr(),-1.0,1.0); + + fwdOp_->apply(Thyra::NOTRANS, *y, residual.ptr(), -1.0, alpha); + if (beta != 0.0) fwdOp_->apply(Thyra::NOTRANS, *z, residual.ptr(), beta, 1.0); + + // calculate norms + std::vector norms(y->domain()->dim()); // size of column count + std::vector rhsNorms(x->domain()->dim()); // size of column count + Thyra::norms_2(*residual, Teuchos::arrayViewFromVector(norms)); + Thyra::norms_2(*x, Teuchos::arrayViewFromVector(rhsNorms)); + + // print out residual norms + (*outputStream_) << "DiagnosticLinearOp \"" << diagString_ << "\": residual = ["; + for (std::size_t i = 0; i < norms.size(); ++i) + (*outputStream_) << " " << std::scientific << std::setprecision(4) + << norms[i] / rhsNorms[i]; // << " (" < & ostrm,const ModifiableLinearOp & A,const std::string & diagnosticString); - - /** \brief This constructor explicitly takes the linear operator - * that needs to be wrapped and a string for output that describes - * the diagnostics. - */ - DiagnosticLinearOp(const Teuchos::RCP & ostrm,const LinearOp & A,const std::string & diagnosticString); - - /** \brief This constructor explicitly takes the linear operator - * that needs to be wrapped and a string for output that describes - * the diagnostics. - */ - DiagnosticLinearOp(const Teuchos::RCP & ostrm,const LinearOp & fwdOp,const ModifiableLinearOp & A,const std::string & diagnosticString); - - /** \brief Destructor prints out timing information about this operator. - */ - virtual ~DiagnosticLinearOp(); - - //! \name Inherited methods from Thyra::LinearOpBase - //@{ - - /** @brief Range space of this operator */ - virtual VectorSpace range() const { return wrapOpA_lo_->range(); } - - /** @brief Domain space of this operator */ - virtual VectorSpace domain() const { return wrapOpA_lo_->domain(); } - - /** @brief Perform a matrix vector multiply with this operator. - * - * The apply function takes one vector as input - * and applies the inverse \f$ LDU \f$ decomposition. The result - * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then - * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). - * - * @param[in] x - * @param[in,out] y - * @param[in] alpha (default=1) - * @param[in] beta (default=0) - */ - virtual void implicitApply(const MultiVector & x, MultiVector & y, - const double alpha = 1.0, const double beta = 0.0) const; - //@} - - virtual void describe(Teuchos::FancyOStream & out_arg, - const Teuchos::EVerbosityLevel verbLevel) const - { wrapOpA_lo_->describe(out_arg,verbLevel); } - - int numApplications() const { return timer_.numCalls(); } - double totalTime() const { return timer_.totalElapsedTime(); } - - ModifiableLinearOp getModifiableOp() const - { return wrapOpA_; } - - void setLinearOp(const LinearOp & lo) - { wrapOpA_lo_ = lo; wrapOpA_ = Teuchos::null; } - - LinearOp getLinearOp() const - { return wrapOpA_lo_; } - - void setForwardOp(const Teko::LinearOp & lo) - { fwdOp_ = lo; } - - /* Get the residual norm. Used purely for testing. - */ - double getResidualNorm() const - { return residualNorm_; } - -protected: - // fundamental operators to use - Teuchos::RCP outputStream_; - ModifiableLinearOp wrapOpA_; - LinearOp wrapOpA_lo_; - LinearOp fwdOp_; - std::string diagString_; - - mutable double residualNorm_; // for testing purposes - mutable Teuchos::Time timer_; - -private: - // hide me! - DiagnosticLinearOp(); - DiagnosticLinearOp(const DiagnosticLinearOp &); + public: + /** \brief This constructor explicitly takes the linear operator + * that needs to be wrapped and a string for output that describes + * the diagnostics. + */ + DiagnosticLinearOp(const Teuchos::RCP &ostrm, const ModifiableLinearOp &A, + const std::string &diagnosticString); + + /** \brief This constructor explicitly takes the linear operator + * that needs to be wrapped and a string for output that describes + * the diagnostics. + */ + DiagnosticLinearOp(const Teuchos::RCP &ostrm, const LinearOp &A, + const std::string &diagnosticString); + + /** \brief This constructor explicitly takes the linear operator + * that needs to be wrapped and a string for output that describes + * the diagnostics. + */ + DiagnosticLinearOp(const Teuchos::RCP &ostrm, const LinearOp &fwdOp, + const ModifiableLinearOp &A, const std::string &diagnosticString); + + /** \brief Destructor prints out timing information about this operator. + */ + virtual ~DiagnosticLinearOp(); + + //! \name Inherited methods from Thyra::LinearOpBase + //@{ + + /** @brief Range space of this operator */ + virtual VectorSpace range() const { return wrapOpA_lo_->range(); } + + /** @brief Domain space of this operator */ + virtual VectorSpace domain() const { return wrapOpA_lo_->domain(); } + + /** @brief Perform a matrix vector multiply with this operator. + * + * The apply function takes one vector as input + * and applies the inverse \f$ LDU \f$ decomposition. The result + * is returned in \f$y\f$. If this operator is reprsented as \f$M\f$ then + * \f$ y = \alpha M x + \beta y \f$ (ignoring conjugation!). + * + * @param[in] x + * @param[in,out] y + * @param[in] alpha (default=1) + * @param[in] beta (default=0) + */ + virtual void implicitApply(const MultiVector &x, MultiVector &y, const double alpha = 1.0, + const double beta = 0.0) const; + //@} + + virtual void describe(Teuchos::FancyOStream &out_arg, + const Teuchos::EVerbosityLevel verbLevel) const { + wrapOpA_lo_->describe(out_arg, verbLevel); + } + + int numApplications() const { return timer_.numCalls(); } + double totalTime() const { return timer_.totalElapsedTime(); } + + ModifiableLinearOp getModifiableOp() const { return wrapOpA_; } + + void setLinearOp(const LinearOp &lo) { + wrapOpA_lo_ = lo; + wrapOpA_ = Teuchos::null; + } + + LinearOp getLinearOp() const { return wrapOpA_lo_; } + + void setForwardOp(const Teko::LinearOp &lo) { fwdOp_ = lo; } + + /* Get the residual norm. Used purely for testing. + */ + double getResidualNorm() const { return residualNorm_; } + + protected: + // fundamental operators to use + Teuchos::RCP outputStream_; + ModifiableLinearOp wrapOpA_; + LinearOp wrapOpA_lo_; + LinearOp fwdOp_; + std::string diagString_; + + mutable double residualNorm_; // for testing purposes + mutable Teuchos::Time timer_; + + private: + // hide me! + DiagnosticLinearOp(); + DiagnosticLinearOp(const DiagnosticLinearOp &); }; /** \brief Constructor method for building DiagnosticLinearOp. - * - * Constructor method for building DiagnosticLinearOp. - * - * \param[in] os Output stream to print diagnostics to - * \param[in] A Operator to be wrapped - * \param[in] label String for outputing with diagnostics - * - * \returns A linear operator that wrapping A that will print diagnostics - * on descruction. - * - * \relates LU2x2InverseOp - */ -inline ModifiableLinearOp createDiagnosticLinearOp(const Teuchos::RCP & os,const ModifiableLinearOp & A,const std::string & label) -{ - return Teuchos::rcp(new DiagnosticLinearOp(os,A,label)); + * + * Constructor method for building DiagnosticLinearOp. + * + * \param[in] os Output stream to print diagnostics to + * \param[in] A Operator to be wrapped + * \param[in] label String for outputing with diagnostics + * + * \returns A linear operator that wrapping A that will print diagnostics + * on descruction. + * + * \relates LU2x2InverseOp + */ +inline ModifiableLinearOp createDiagnosticLinearOp(const Teuchos::RCP &os, + const ModifiableLinearOp &A, + const std::string &label) { + return Teuchos::rcp(new DiagnosticLinearOp(os, A, label)); } /** \brief Constructor method for building DiagnosticLinearOp. - * - * Constructor method for building DiagnosticLinearOp. - * - * \param[in] os Output stream to print diagnostics to - * \param[in] A Operator to be wrapped - * \param[in] label String for outputing with diagnostics - * - * \returns A linear operator that wrapping A that will print diagnostics - * on descruction. - * - * \relates LU2x2InverseOp - */ -inline ModifiableLinearOp createDiagnosticLinearOp(const Teuchos::RCP & os,const LinearOp & A,const std::string & label) -{ - return Teuchos::rcp(new DiagnosticLinearOp(os,A,label)); + * + * Constructor method for building DiagnosticLinearOp. + * + * \param[in] os Output stream to print diagnostics to + * \param[in] A Operator to be wrapped + * \param[in] label String for outputing with diagnostics + * + * \returns A linear operator that wrapping A that will print diagnostics + * on descruction. + * + * \relates LU2x2InverseOp + */ +inline ModifiableLinearOp createDiagnosticLinearOp(const Teuchos::RCP &os, + const LinearOp &A, const std::string &label) { + return Teuchos::rcp(new DiagnosticLinearOp(os, A, label)); } /** \brief Constructor method for building DiagnosticLinearOp. - * - * Constructor method for building DiagnosticLinearOp. - * - * \param[in] os Output stream to print diagnostics to - * \param[in] fwdOp Forward operator to compute residual with - * \param[in] A Operator to be wrapped - * \param[in] label String for outputing with diagnostics - * - * \returns A linear operator that wrapping A that will print diagnostics - * on descruction. - * - * \relates LU2x2InverseOp - */ -inline ModifiableLinearOp createDiagnosticLinearOp(const Teuchos::RCP & os,const Teko::LinearOp & fwdOp,const ModifiableLinearOp & A,const std::string & label) -{ - return Teuchos::rcp(new DiagnosticLinearOp(os,fwdOp,A,label)); + * + * Constructor method for building DiagnosticLinearOp. + * + * \param[in] os Output stream to print diagnostics to + * \param[in] fwdOp Forward operator to compute residual with + * \param[in] A Operator to be wrapped + * \param[in] label String for outputing with diagnostics + * + * \returns A linear operator that wrapping A that will print diagnostics + * on descruction. + * + * \relates LU2x2InverseOp + */ +inline ModifiableLinearOp createDiagnosticLinearOp(const Teuchos::RCP &os, + const Teko::LinearOp &fwdOp, + const ModifiableLinearOp &A, + const std::string &label) { + return Teuchos::rcp(new DiagnosticLinearOp(os, fwdOp, A, label)); } -} // end namespace Teko +} // end namespace Teko -#endif +#endif diff --git a/packages/teko/src/Teko_DiagnosticPreconditionerFactory.cpp b/packages/teko/src/Teko_DiagnosticPreconditionerFactory.cpp index c7726340f696..00aa5897475f 100644 --- a/packages/teko/src/Teko_DiagnosticPreconditionerFactory.cpp +++ b/packages/teko/src/Teko_DiagnosticPreconditionerFactory.cpp @@ -1,29 +1,29 @@ /* // @HEADER -// +// // *********************************************************************** -// +// // Teko: A package for block and physics based preconditioning -// Copyright 2010 Sandia Corporation -// +// Copyright 2010 Sandia Corporation +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: -// +// // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// +// this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -32,14 +32,14 @@ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) -// +// // *********************************************************************** -// +// // @HEADER */ @@ -56,173 +56,184 @@ namespace Teko { //! Default constructor, for use with the AutoClone class. DiagnosticPreconditionerFactory::DiagnosticPreconditionerFactory() - : outputStream_(Teko::getOutputStream()), invFactory_(Teuchos::null), diagString_("