Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_GaussSeidelPreconditionerFactory.cpp
1 /*
2 // @HEADER
3 //
4 // ***********************************************************************
5 //
6 // Teko: A package for block and physics based preconditioning
7 // Copyright 2010 Sandia Corporation
8 //
9 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Eric C. Cyr (eccyr@sandia.gov)
40 //
41 // ***********************************************************************
42 //
43 // @HEADER
44 
45 */
46 
47 #include "Teko_GaussSeidelPreconditionerFactory.hpp"
48 
49 #include "Teko_BlockUpperTriInverseOp.hpp"
50 #include "Teko_BlockLowerTriInverseOp.hpp"
51 
52 using Teuchos::rcp;
53 using Teuchos::RCP;
54 
55 namespace Teko {
56 
58  const LinearOp& invD0,
59  const LinearOp& invD1)
60  : invOpsStrategy_(rcp(new StaticInvDiagStrategy(invD0, invD1))), solveType_(solveType) {}
61 
63  TriSolveType solveType, const RCP<const BlockInvDiagonalStrategy>& strategy)
64  : invOpsStrategy_(strategy), solveType_(solveType) {}
65 
67  : solveType_(GS_UseLowerTriangle) {}
68 
70  BlockedLinearOp& blo, BlockPreconditionerState& state) const {
71  int rows = blockRowCount(blo);
72  int cols = blockColCount(blo);
73 
74  TEUCHOS_ASSERT(rows == cols);
75 
76  // get diagonal blocks
77  std::vector<LinearOp> invDiag;
78  invOpsStrategy_->getInvD(blo, state, invDiag);
79  TEUCHOS_ASSERT(rows == (int)invDiag.size());
80 
81  if (solveType_ == GS_UseUpperTriangle) {
82  // create a blocked linear operator
83  BlockedLinearOp U = getUpperTriBlocks(blo);
84 
85  return createBlockUpperTriInverseOp(U, invDiag, "Gauss Seidel");
86  } else if (solveType_ == GS_UseLowerTriangle) {
87  // create a blocked linear operator
88  BlockedLinearOp L = getLowerTriBlocks(blo);
89 
90  return createBlockLowerTriInverseOp(L, invDiag, "Gauss Seidel");
91  }
92 
93  TEUCHOS_ASSERT(false); // we should never make it here!
94 }
95 
98  const Teuchos::ParameterList& pl) {
99  Teko_DEBUG_SCOPE("GaussSeidelPreconditionerFactory::initializeFromParameterList", 10);
100  Teko_DEBUG_MSG_BEGIN(9);
101  DEBUG_STREAM << "Parameter list: " << std::endl;
102  pl.print(DEBUG_STREAM);
103  Teko_DEBUG_MSG_END();
104 
105  const std::string inverse_type = "Inverse Type";
106  const std::string preconditioner_type = "Preconditioner Type";
107  std::vector<RCP<InverseFactory> > inverses;
108  std::vector<RCP<InverseFactory> > preconditioners;
109 
110  RCP<const InverseLibrary> invLib = getInverseLibrary();
111 
112  // get string specifying default inverse
113  std::string invStr = "";
114 #if defined(Teko_ENABLE_Amesos)
115  invStr = "Amesos";
116 #elif defined(Teko_ENABLE_Amesos2)
117  invStr = "Amesos2";
118 #endif
119  std::string precStr = "None";
120  if (pl.isParameter(inverse_type)) invStr = pl.get<std::string>(inverse_type);
121  if (pl.isParameter(preconditioner_type)) precStr = pl.get<std::string>(preconditioner_type);
122  if (pl.isParameter("Use Upper Triangle"))
123  solveType_ = pl.get<bool>("Use Upper Triangle") ? GS_UseUpperTriangle : GS_UseLowerTriangle;
124 
125  Teko_DEBUG_MSG("GSPrecFact: Building default inverse \"" << invStr << "\"", 5);
126  RCP<InverseFactory> defaultInverse = invLib->getInverseFactory(invStr);
127  RCP<InverseFactory> defaultPrec;
128  if (precStr != "None") defaultPrec = invLib->getInverseFactory(precStr);
129 
130  // now check individual solvers
131  Teuchos::ParameterList::ConstIterator itr;
132  for (itr = pl.begin(); itr != pl.end(); ++itr) {
133  std::string fieldName = itr->first;
134  Teko_DEBUG_MSG("GSPrecFact: checking fieldName = \"" << fieldName << "\"", 9);
135 
136  // figure out what the integer is
137  if (fieldName.compare(0, inverse_type.length(), inverse_type) == 0 &&
138  fieldName != inverse_type) {
139  int position = -1;
140  std::string inverse, type;
141 
142  // figure out position
143  std::stringstream ss(fieldName);
144  ss >> inverse >> type >> position;
145 
146  if (position <= 0) {
147  Teko_DEBUG_MSG("Gauss-Seidel \"Inverse Type\" must be a (strictly) positive integer", 1);
148  }
149 
150  // inserting inverse factory into vector
151  std::string invStr2 = pl.get<std::string>(fieldName);
152  Teko_DEBUG_MSG("GSPrecFact: Building inverse " << position << " \"" << invStr2 << "\"", 5);
153  if (position > (int)inverses.size()) {
154  inverses.resize(position, defaultInverse);
155  inverses[position - 1] = invLib->getInverseFactory(invStr2);
156  } else
157  inverses[position - 1] = invLib->getInverseFactory(invStr2);
158  } else if (fieldName.compare(0, preconditioner_type.length(), preconditioner_type) == 0 &&
159  fieldName != preconditioner_type) {
160  int position = -1;
161  std::string preconditioner, type;
162 
163  // figure out position
164  std::stringstream ss(fieldName);
165  ss >> preconditioner >> type >> position;
166 
167  if (position <= 0) {
168  Teko_DEBUG_MSG("Gauss-Seidel \"Preconditioner Type\" must be a (strictly) positive integer",
169  1);
170  }
171 
172  // inserting preconditioner factory into vector
173  std::string precStr2 = pl.get<std::string>(fieldName);
174  Teko_DEBUG_MSG(
175  "GSPrecFact: Building preconditioner " << position << " \"" << precStr2 << "\"", 5);
176  if (position > (int)preconditioners.size()) {
177  preconditioners.resize(position, defaultPrec);
178  preconditioners[position - 1] = invLib->getInverseFactory(precStr2);
179  } else
180  preconditioners[position - 1] = invLib->getInverseFactory(precStr2);
181  }
182  }
183 
184  // use default inverse
185  if (inverses.size() == 0) inverses.push_back(defaultInverse);
186 
187  // based on parameter type build a strategy
189  rcp(new InvFactoryDiagStrategy(inverses, preconditioners, defaultInverse, defaultPrec));
190 }
191 
192 } // namespace Teko
An implementation of a state object for block preconditioners.
Teuchos::RCP< const BlockInvDiagonalStrategy > invOpsStrategy_
some members
LinearOp buildPreconditionerOperator(BlockedLinearOp &blo, BlockPreconditionerState &state) const
Create the Gauss-Seidel preconditioner operator.
Teuchos::RCP< const InverseLibrary > getInverseLibrary() const
Get the inverse library used by this preconditioner factory.
virtual void initializeFromParameterList(const Teuchos::ParameterList &pl)
Initialize from a parameter list.