Teko Version of the Day
Teko_LSCSIMPLECStrategy.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_LSCSIMPLECStrategy.hpp"
48
49#include "Thyra_DefaultDiagonalLinearOp.hpp"
50#include "Thyra_EpetraThyraWrappers.hpp"
51#include "Thyra_get_Epetra_Operator.hpp"
52#include "Thyra_EpetraLinearOp.hpp"
53#include "Thyra_VectorStdOps.hpp"
54
55#include "Epetra_Vector.h"
56#include "Epetra_Map.h"
57
58#include "EpetraExt_RowMatrixOut.h"
59#include "EpetraExt_MultiVectorOut.h"
60#include "EpetraExt_VectorOut.h"
61
62#include "Teuchos_Time.hpp"
63#include "Teuchos_TimeMonitor.hpp"
64
65// Teko includes
66#include "Teko_Utilities.hpp"
67#include "Teko_LSCPreconditionerFactory.hpp"
68#include "Teko_EpetraHelpers.hpp"
69#include "Teko_EpetraOperatorWrapper.hpp"
70
71using Teuchos::RCP;
72using Teuchos::rcp_dynamic_cast;
73using Teuchos::rcp_const_cast;
74
75namespace Teko {
76namespace NS {
77
79// LSCSIMPLECStrategy Implementation
81
82// constructors
84LSCSIMPLECStrategy::LSCSIMPLECStrategy()
85 : invFactoryF_(Teuchos::null), invFactoryS_(Teuchos::null)
86 , useFullLDU_(false), scaleType_(Diagonal)
87{ }
88
90
91void LSCSIMPLECStrategy::buildState(BlockedLinearOp & A,BlockPreconditionerState & state) const
92{
93 Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::buildState",10);
94
95 LSCPrecondState * lscState = dynamic_cast<LSCPrecondState*>(&state);
96 TEUCHOS_ASSERT(lscState!=0);
97
98 // if neccessary save state information
99 if(not lscState->isInitialized()) {
100 Teko_DEBUG_EXPR(Teuchos::Time timer(""));
101
102 // construct operators
103 {
104 Teko_DEBUG_SCOPE("LSC-SIMPLEC::buildState constructing operators",1);
105 Teko_DEBUG_EXPR(timer.start(true));
106
107 initializeState(A,lscState);
108
109 Teko_DEBUG_EXPR(timer.stop());
110 Teko_DEBUG_MSG("LSC-SIMPLEC::buildState BuildOpsTime = " << timer.totalElapsedTime(),1);
111 }
112
113 // Build the inverses
114 {
115 Teko_DEBUG_SCOPE("LSC-SIMPLEC::buildState calculating inverses",1);
116 Teko_DEBUG_EXPR(timer.start(true));
117
118 computeInverses(A,lscState);
119
120 Teko_DEBUG_EXPR(timer.stop());
121 Teko_DEBUG_MSG("LSC-SIMPLEC::buildState BuildInvTime = " << timer.totalElapsedTime(),1);
122 }
123 }
124}
125
126// functions inherited from LSCStrategy
127LinearOp LSCSIMPLECStrategy::getInvBQBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const
128{
129 return state.getInverse("invBQBtmC");
130}
131
132LinearOp LSCSIMPLECStrategy::getInvBHBt(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const
133{
134 return state.getInverse("invBQBtmC").getConst();
135}
136
137LinearOp LSCSIMPLECStrategy::getInvF(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const
138{
139 return state.getInverse("invF");
140}
141
142LinearOp LSCSIMPLECStrategy::getInnerStabilization(const BlockedLinearOp & A,BlockPreconditionerState & state) const
143{
144 LSCPrecondState * lscState = dynamic_cast<LSCPrecondState*>(&state);
145 TEUCHOS_ASSERT(lscState!=0);
146 TEUCHOS_ASSERT(lscState->isInitialized())
147
148 const LinearOp C = getBlock(1,1,A);
149 return scale(-1.0,C);
150}
151
152
153LinearOp LSCSIMPLECStrategy::getInvMass(const BlockedLinearOp & /* A */,BlockPreconditionerState & state) const
154{
155 LSCPrecondState * lscState = dynamic_cast<LSCPrecondState*>(&state);
156 TEUCHOS_ASSERT(lscState!=0);
157 TEUCHOS_ASSERT(lscState->isInitialized())
158
159 return lscState->invMass_;
160}
161
162LinearOp LSCSIMPLECStrategy::getHScaling(const BlockedLinearOp & A,BlockPreconditionerState & state) const
163{
164 return getInvMass(A,state);
165}
166
168void LSCSIMPLECStrategy::initializeState(const BlockedLinearOp & A,LSCPrecondState * state) const
169{
170 Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::initializeState",10);
171
172 const LinearOp F = getBlock(0,0,A);
173 const LinearOp Bt = getBlock(0,1,A);
174 const LinearOp B = getBlock(1,0,A);
175 const LinearOp C = getBlock(1,1,A);
176
177 bool isStabilized = (not isZeroOp(C));
178
179 state->invMass_ = getInvDiagonalOp(F,scaleType_);
180
181 // compute BQBt
182 state->BQBt_ = explicitMultiply(B,state->invMass_,Bt,state->BQBt_);
183 if(isStabilized) {
184 // now build B*Q*Bt-C
185 Teko::ModifiableLinearOp BQBtmC = state->getInverse("BQBtmC");
186 BQBtmC = explicitAdd(state->BQBt_,scale(-1.0,C),BQBtmC);
187 state->addInverse("BQBtmC",BQBtmC);
188 }
189 Teko_DEBUG_MSG("Computed BQBt",10);
190
191 state->setInitialized(true);
192}
193
199void LSCSIMPLECStrategy::computeInverses(const BlockedLinearOp & A,LSCPrecondState * state) const
200{
201 Teko_DEBUG_SCOPE("LSCSIMPLECStrategy::computeInverses",10);
202 Teko_DEBUG_EXPR(Teuchos::Time invTimer(""));
203
204 const LinearOp F = getBlock(0,0,A);
205
207
208 // (re)build the inverse of F
209 Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses Building inv(F)",1);
210 Teko_DEBUG_EXPR(invTimer.start(true));
211 InverseLinearOp invF = state->getInverse("invF");
212 if(invF==Teuchos::null) {
213 invF = buildInverse(*invFactoryF_,F);
214 state->addInverse("invF",invF);
215 } else {
216 rebuildInverse(*invFactoryF_,F,invF);
217 }
218 Teko_DEBUG_EXPR(invTimer.stop());
219 Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses GetInvF = " << invTimer.totalElapsedTime(),1);
220
222
223 // (re)build the inverse of BQBt
224 Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses Building inv(BQBtmC)",1);
225 Teko_DEBUG_EXPR(invTimer.start(true));
226 const LinearOp BQBt = state->getInverse("BQBtmC");
227 InverseLinearOp invBQBt = state->getInverse("invBQBtmC");
228 if(invBQBt==Teuchos::null) {
229 invBQBt = buildInverse(*invFactoryS_,BQBt);
230 state->addInverse("invBQBtmC",invBQBt);
231 } else {
232 rebuildInverse(*invFactoryS_,BQBt,invBQBt);
233 }
234 Teko_DEBUG_EXPR(invTimer.stop());
235 Teko_DEBUG_MSG("LSC-SIMPLEC::computeInverses GetInvBQBt = " << invTimer.totalElapsedTime(),1);
236}
237
239void LSCSIMPLECStrategy::initializeFromParameterList(const Teuchos::ParameterList & pl,const InverseLibrary & invLib)
240{
241 // get string specifying inverse
242 std::string invStr="", invVStr="", invPStr="";
243 bool useLDU = false;
244 scaleType_ = Diagonal;
245
246 // "parse" the parameter list
247 if(pl.isParameter("Inverse Type"))
248 invStr = pl.get<std::string>("Inverse Type");
249 if(pl.isParameter("Inverse Velocity Type"))
250 invVStr = pl.get<std::string>("Inverse Velocity Type");
251 if(pl.isParameter("Inverse Pressure Type"))
252 invPStr = pl.get<std::string>("Inverse Pressure Type");
253 if(pl.isParameter("Use LDU"))
254 useLDU = pl.get<bool>("Use LDU");
255 if(pl.isParameter("Scaling Type")) {
256 scaleType_ = getDiagonalType(pl.get<std::string>("Scaling Type"));
257 TEUCHOS_TEST_FOR_EXCEPT(scaleType_==NotDiag);
258 }
259
260 Teko_DEBUG_MSG_BEGIN(0)
261 DEBUG_STREAM << "LSC Inverse Strategy Parameters: " << std::endl;
262 DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl;
263 DEBUG_STREAM << " inv v type = \"" << invVStr << "\"" << std::endl;
264 DEBUG_STREAM << " inv p type = \"" << invPStr << "\"" << std::endl;
265 DEBUG_STREAM << " use ldu = " << useLDU << std::endl;
266 DEBUG_STREAM << " scale type = " << getDiagonalName(scaleType_) << std::endl;
267 DEBUG_STREAM << "LSC Inverse Strategy Parameter list: " << std::endl;
268 pl.print(DEBUG_STREAM);
269 Teko_DEBUG_MSG_END()
270
271 // set defaults as needed
272 if(invStr=="") invStr = "Amesos";
273 if(invVStr=="") invVStr = invStr;
274 if(invPStr=="") invPStr = invStr;
275
276 // build velocity inverse factory
277 invFactoryF_ = invLib.getInverseFactory(invVStr);
278 invFactoryS_ = invFactoryF_; // by default these are the same
279 if(invVStr!=invPStr) // if different, build pressure inverse factory
280 invFactoryS_ = invLib.getInverseFactory(invPStr);
281
282 // set other parameters
283 setUseFullLDU(useLDU);
284}
285
286} // end namespace NS
287} // end namespace Teko
void scale(const double alpha, MultiVector &x)
Scale a multivector by a constant.
@ NotDiag
For user convenience, if Teko recieves this value, exceptions will be thrown
@ Diagonal
Specifies that just the diagonal is used.
MultiVector getBlock(int i, const BlockedMultiVector &bmv)
Get the ith block from a BlockedMultiVector object.
An implementation of a state object for block preconditioners.
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, const LinearOp &precOp, InverseLinearOp &invA)
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A, const LinearOp &precOp)
Preconditioner state for the LSC factory.
LinearOp invMass_
Inverse mass operator ( )
virtual void addInverse(const std::string &name, const Teko::InverseLinearOp &ilo)
Add a named inverse to the state object.
virtual void setInitialized(bool init=true)
virtual Teko::InverseLinearOp getInverse(const std::string &name) const
Get a named inverse from the state object.