Go to the documentation of this file.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 #ifndef TSF_SIMPLEBLOCKOP_IMPL_HPP
00030 #define TSF_SIMPLEBLOCKOP_IMPL_HPP
00031
00032 #include "SundanceTabs.hpp"
00033 #include "SundanceExceptions.hpp"
00034 #include "TSFSimpleBlockOpDecl.hpp"
00035 #include "TSFSimpleZeroOpDecl.hpp"
00036
00037 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00038 #include "TSFLinearOperatorImpl.hpp"
00039 #include "TSFSimpleZeroOpImpl.hpp"
00040 #include "TSFSimplifiedLinearOpBaseImpl.hpp"
00041 #endif
00042
00043
00044
00045
00046 namespace TSFExtended
00047 {
00048 using namespace Teuchos;
00049 using namespace Sundance;
00050
00051
00052
00053
00054 template <class Scalar> inline
00055 SimpleBlockOp<Scalar>::SimpleBlockOp(
00056 const VectorSpace<Scalar>& domain,
00057 const VectorSpace<Scalar>& range)
00058 : SimplifiedLinearOpWithSpaces<Scalar>(domain, range), blocks_(range.numBlocks())
00059 {
00060 for (int i=0; i<blocks_.size(); i++)
00061 {
00062 blocks_[i] = Array<LinearOperator<Scalar> >(domain.numBlocks());
00063 for (int j=0; j<blocks_[i].size(); j++)
00064 {
00065 blocks_[i][j] = zeroOperator(domain.getBlock(j), range.getBlock(i));
00066 }
00067 }
00068 }
00069
00070 template <class Scalar> inline
00071 int SimpleBlockOp<Scalar>::numBlockRows() const
00072 {
00073 return blocks_.size();
00074 }
00075
00076 template <class Scalar> inline
00077 int SimpleBlockOp<Scalar>::numBlockCols() const
00078 {
00079 return blocks_[0].size();
00080 }
00081
00082 template <class Scalar> inline
00083 const LinearOperator<Scalar>& SimpleBlockOp<Scalar>::getBlock(int i, int j) const
00084 {
00085 return blocks_[i][j];
00086 }
00087
00088 template <class Scalar> inline
00089 LinearOperator<Scalar> SimpleBlockOp<Scalar>::getNonconstBlock(int i, int j)
00090 {
00091 return blocks_[i][j];
00092 }
00093
00094
00095 template <class Scalar> inline
00096 void SimpleBlockOp<Scalar>::setBlock(int i, int j,
00097 const LinearOperator<Scalar>& Aij)
00098 {
00099 blocks_[i][j] = Aij;
00100 }
00101
00102 template <class Scalar> inline
00103 void SimpleBlockOp<Scalar>::applyOp(const Thyra::EOpTransp M_trans,
00104 const Vector<Scalar>& in,
00105 Vector<Scalar> out) const
00106 {
00107 Tabs tab(0);
00108 SUNDANCE_MSG2(this->verb(), tab << "SimpleBlockOp::applyOp()");
00109 if (M_trans == Thyra::NOTRANS)
00110 {
00111 out.zero();
00112 for (int i=0; i<this->numBlockRows(); i++)
00113 {
00114 for (int j=0; j<this->numBlockCols(); j++)
00115 {
00116 Vector<Scalar> tmp;
00117 blocks_[i][j].apply(in.getBlock(j), tmp);
00118 out.getBlock(i).update(1.0, tmp);
00119 }
00120 }
00121 }
00122
00123 else if (M_trans == Thyra::TRANS)
00124 {
00125 for (int i=0; i<this->numBlockCols(); i++)
00126 {
00127 out.zero();
00128 for (int j=0; j<this->numBlockRows(); j++)
00129 {
00130 Vector<Scalar> tmp;
00131 blocks_[j][i].applyTranspose(in.getBlock(j),tmp);
00132 out.getBlock(i).update(1.0, tmp);
00133 }
00134 }
00135 }
00136 else
00137 {
00138 TEST_FOR_EXCEPT(M_trans != Thyra::TRANS && M_trans != Thyra::NOTRANS);
00139 }
00140 SUNDANCE_MSG2(this->verb(), tab << "done SimpleBlockOp::applyOp()");
00141 }
00142
00143
00144 template <class Scalar> inline
00145 LinearOperator<Scalar> makeBlockOperator(
00146 const VectorSpace<Scalar>& domain,
00147 const VectorSpace<Scalar>& range
00148 )
00149 {
00150 RCP<SimpleBlockOp<Scalar> > b =
00151 rcp(new SimpleBlockOp<Scalar>(domain, range));
00152 RCP<Thyra::LinearOpBase<Scalar> > p = b;
00153 return p;
00154 }
00155
00156
00157
00158 }
00159
00160 #endif