00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "Teko_BlockUpperTriInverseOp.hpp"
00048
00049 #include "Teuchos_Utils.hpp"
00050
00051 namespace Teko {
00052
00053 using Teuchos::RCP;
00054
00065 BlockUpperTriInverseOp::BlockUpperTriInverseOp(BlockedLinearOp & U,const std::vector<LinearOp> & invDiag)
00066 : U_(U)
00067 {
00068 invDiag_ = invDiag;
00069
00070
00071 int blocks = blockRowCount(U_);
00072 TEUCHOS_ASSERT(blocks>0);
00073 TEUCHOS_ASSERT(blocks==blockColCount(U_));
00074 TEUCHOS_ASSERT(blocks==(int) invDiag_.size());
00075
00076
00078
00079
00080 productRange_ = U->productDomain();
00081 productDomain_ = U->productRange();
00082 }
00083
00096 void BlockUpperTriInverseOp::implicitApply(const BlockedMultiVector & src, BlockedMultiVector & dst,
00097 const double alpha, const double beta) const
00098 {
00099 int blocks = blockCount(src);
00100
00101 TEUCHOS_ASSERT(blocks==blockRowCount(U_));
00102 TEUCHOS_ASSERT(blocks==blockCount(dst));
00103
00104
00105 srcScrap_ = datacopy(src,srcScrap_);
00106 BlockedMultiVector dstCopy;
00107 if(beta!=0.0) {
00108 dstScrap_ = datacopy(dst,dstScrap_);
00109 dstCopy = dstScrap_;
00110 }
00111 else
00112 dstCopy = dst;
00113
00114
00115
00116 std::vector<MultiVector> dstVec;
00117 std::vector<MultiVector> scrapVec;
00118 for(int b=0;b<blocks;b++) {
00119 dstVec.push_back(getBlock(b,dstCopy));
00120 scrapVec.push_back(getBlock(b,srcScrap_));
00121 }
00122
00123
00124
00125 for(int b=blocks-1;b>=0;b--) {
00126 applyOp(invDiag_[b], scrapVec[b], dstVec[b]);
00127
00128
00129 for(int i=0;i<b;i++) {
00130 LinearOp u_ib = getBlock(i,b,U_);
00131 if(u_ib!=Teuchos::null) {
00132 applyOp(u_ib,dstVec[b],scrapVec[i],-1.0,1.0);
00133 }
00134 }
00135 }
00136
00137
00138 if(beta!=0)
00139 update(alpha,dstCopy,beta,dst);
00140 else if(alpha!=1.0)
00141 scale(alpha,dst);
00142 }
00143
00144 void BlockUpperTriInverseOp::describe(Teuchos::FancyOStream & out_arg,
00145 const Teuchos::EVerbosityLevel verbLevel) const
00146 {
00147 using Teuchos::OSTab;
00148
00149 RCP<Teuchos::FancyOStream> out = rcp(&out_arg,false);
00150 OSTab tab(out);
00151 switch(verbLevel) {
00152 case Teuchos::VERB_DEFAULT:
00153 case Teuchos::VERB_LOW:
00154 *out << this->description() << std::endl;
00155 break;
00156 case Teuchos::VERB_MEDIUM:
00157 case Teuchos::VERB_HIGH:
00158 case Teuchos::VERB_EXTREME:
00159 {
00160 *out << Teuchos::Describable::description() << "{"
00161 << "rangeDim=" << this->range()->dim()
00162 << ",domainDim=" << this->domain()->dim()
00163 << ",rows=" << blockRowCount(U_)
00164 << ",cols=" << blockColCount(U_)
00165 << "}\n";
00166 {
00167 OSTab tab(out);
00168 *out << "[U Operator] = ";
00169 *out << Teuchos::describe(*U_,verbLevel);
00170 }
00171 {
00172 OSTab tab(out);
00173 *out << "[invDiag Operators]:\n";
00174 tab.incrTab();
00175 for(int i=0;i<blockRowCount(U_);i++) {
00176 *out << "[invD(" << i << ")] = ";
00177 *out << Teuchos::describe(*invDiag_[i],verbLevel);
00178 }
00179 }
00180 break;
00181 }
00182 default:
00183 TEUCHOS_TEST_FOR_EXCEPT(true);
00184 }
00185 }
00186
00187 }