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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef PLAYA_LINEAROPERATORIMPL_HPP
00043 #define PLAYA_LINEAROPERATORIMPL_HPP
00044
00045 #include "PlayaDefs.hpp"
00046 #include "PlayaLinearOperatorDecl.hpp"
00047 #include "Teuchos_RefCountPtr.hpp"
00048 #include "PlayaVectorDecl.hpp"
00049 #include "PlayaVectorSpaceDecl.hpp"
00050 #include "PlayaInverseOperatorDecl.hpp"
00051 #include "PlayaSimpleTransposedOpDecl.hpp"
00052 #include "PlayaBlockOperatorBaseDecl.hpp"
00053 #include "PlayaVectorType.hpp"
00054 #include "PlayaOut.hpp"
00055
00056 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00057 #include "PlayaVectorImpl.hpp"
00058 #endif
00059
00060
00061
00062 using namespace Playa;
00063 using namespace Teuchos;
00064
00065
00066 template <class Scalar>
00067 class InverseOperator;
00068
00069
00070
00071 template <class Scalar>
00072 LinearOperator<Scalar>::LinearOperator()
00073 : Handle<LinearOperatorBase<Scalar> >() {;}
00074
00075
00076
00077 template <class Scalar>
00078 LinearOperator<Scalar>::LinearOperator(const RCP<LinearOperatorBase<Scalar> >& smartPtr)
00079 : Handle<LinearOperatorBase<Scalar> >(smartPtr) {;}
00080
00081
00082
00083
00084
00085 template <class Scalar> inline
00086 void LinearOperator<Scalar>::apply(const Vector<Scalar>& in,
00087 Vector<Scalar>& out) const
00088 {
00089 Tabs tab(0);
00090 PLAYA_MSG1(this->verb(), tab << "Operator=" << this->description()
00091 << ", calling apply() function");
00092 Tabs tab1;
00093
00094 if (this->verb() > 2)
00095 {
00096 Tabs tab2;
00097 Out::os() << tab2 << "input vector = " << in << std::endl;
00098 }
00099 else if (this->verb() > 1)
00100 {
00101 Tabs tab2;
00102 Out::os() << tab2 << "input vector = " << in.description() << std::endl;
00103 }
00104
00105
00106
00107 if (out.ptr().get()==0)
00108 {
00109 Tabs tab2;
00110 PLAYA_MSG3(this->verb(), tab2 << "allocating output vector");
00111 out = this->range().createMember();
00112 }
00113 else
00114 {
00115 Tabs tab2;
00116 PLAYA_MSG3(this->verb(), tab2 << "using preallocated output vector");
00117 }
00118
00119 this->ptr()->apply(Teuchos::NO_TRANS, in, out);
00120
00121 if (this->verb() > 2)
00122 {
00123 Tabs tab2;
00124 Out::os() << tab2 << "output vector = " << out << std::endl;
00125 }
00126 else if (this->verb() > 1)
00127 {
00128 Tabs tab2;
00129 Out::os() << tab2 << "output vector = " << out.description() << std::endl;
00130 }
00131
00132 PLAYA_MSG1(this->verb(), tab << "Operator=" << this->description()
00133 << ", done with apply() function");
00134
00135 }
00136
00137
00138
00139
00140
00141 template <class Scalar> inline
00142 void LinearOperator<Scalar>::applyTranspose(const Vector<Scalar>& in,
00143 Vector<Scalar>& out) const
00144 {
00145 Tabs tab(0);
00146 PLAYA_MSG1(this->verb(), tab << "Operator=" << this->description()
00147 << ", calling applyTranspose() function");
00148 Tabs tab1;
00149
00150 if (this->verb() > 2)
00151 {
00152 Tabs tab2;
00153 Out::os() << tab2 << "input vector = " << in << std::endl;
00154 }
00155 else if (this->verb() > 1)
00156 {
00157 Tabs tab2;
00158 Out::os() << tab2 << "input vector = " << in.description() << std::endl;
00159 }
00160
00161
00162
00163
00164 if (out.ptr().get()==0)
00165 {
00166 Tabs tab2;
00167 PLAYA_MSG3(this->verb(), tab2 << "allocating output vector");
00168 out = this->domain().createMember();
00169 }
00170 else
00171 {
00172 Tabs tab2;
00173 PLAYA_MSG3(this->verb(), tab2 << "using preallocated output vector");
00174 }
00175
00176 this->ptr()->apply(Teuchos::TRANS, in, out);
00177
00178
00179
00180 if (this->verb() > 2)
00181 {
00182 Tabs tab2;
00183 Out::os() << tab2 << "output vector = " << out << std::endl;
00184 }
00185 else if (this->verb() > 1)
00186 {
00187 Tabs tab2;
00188 Out::os() << tab2 << "output vector = " << out.description() << std::endl;
00189 }
00190
00191 PLAYA_MSG1(this->verb(), tab << "Operator=" << this->description()
00192 << ", done with applyTranpose() function");
00193
00194 }
00195
00196
00197
00198 template <class Scalar>
00199 RCP<Time>& LinearOperator<Scalar>::opTimer()
00200 {
00201 static RCP<Time> rtn
00202 = TimeMonitor::getNewTimer("Low-level vector operations");
00203 return rtn;
00204 }
00205
00206
00207 template <class Scalar>
00208 LinearOperator<Scalar> LinearOperator<Scalar>::transpose() const
00209 {
00210 LinearOperator<Scalar> op = transposedOperator(*this);
00211 return op;
00212 }
00213
00214
00215
00216
00217
00218
00219 template <class Scalar>
00220 RCP<LoadableMatrix<Scalar> > LinearOperator<Scalar>::matrix()
00221 {
00222 RCP<LoadableMatrix<Scalar> > rtn
00223 = rcp_dynamic_cast<LoadableMatrix<Scalar> >(this->ptr());
00224 return rtn;
00225 }
00226
00227
00228 template <class Scalar>
00229 void LinearOperator<Scalar>::getRow(const int& row,
00230 Teuchos::Array<int>& indices,
00231 Teuchos::Array<Scalar>& values) const
00232 {
00233 const RowAccessibleOp<Scalar>* val =
00234 dynamic_cast<const RowAccessibleOp<Scalar>* >(this->ptr().get());
00235 TEUCHOS_TEST_FOR_EXCEPTION(val == 0, std::runtime_error,
00236 "Operator not row accessible; getRow() not defined.");
00237 val->getRow(row, indices, values);
00238 }
00239
00240
00241 template <class Scalar>
00242 int LinearOperator<Scalar>::numBlockRows() const
00243 {
00244 const BlockOperatorBase<Scalar>* b = dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00245 if (b==0) return 1;
00246 return b->numBlockRows();
00247 }
00248
00249
00250 template <class Scalar>
00251 int LinearOperator<Scalar>::numBlockCols() const
00252 {
00253 const BlockOperatorBase<Scalar>* b = dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00254 if (b==0) return 1;
00255 return b->numBlockCols();
00256 }
00257
00258
00259
00260 template <class Scalar>
00261 const VectorSpace<Scalar>
00262 LinearOperator<Scalar>::range() const
00263 {return this->ptr()->range();}
00264
00265
00266
00267 template <class Scalar>
00268 void LinearOperator<Scalar>::setBlock(int i, int j,
00269 const LinearOperator<Scalar>& sub)
00270 {
00271 SetableBlockOperatorBase<Scalar>* b =
00272 dynamic_cast<SetableBlockOperatorBase<Scalar>* >(this->ptr().get());
00273
00274 TEUCHOS_TEST_FOR_EXCEPTION(b == 0, std::runtime_error,
00275 "Can't call setBlock since operator not SetableBlockOperatorBase");
00276
00277 b->setBlock(i, j, sub);
00278 }
00279
00280
00281
00282
00283 template <class Scalar>
00284 const VectorSpace<Scalar>
00285 LinearOperator<Scalar>::domain() const
00286 {return this->ptr()->domain();}
00287
00288
00289
00290
00291 template <class Scalar>
00292 LinearOperator<Scalar> LinearOperator<Scalar>::getBlock(const int &i,
00293 const int &j) const
00294 {
00295 const BlockOperatorBase<Scalar>* b =
00296 dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00297
00298 if (b==0)
00299 {
00300 TEUCHOS_TEST_FOR_EXCEPTION(i != 0 || j != 0, std::runtime_error,
00301 "nonzero block index (" << i << "," << j << ") into "
00302 "non-block operator");
00303 return *this;
00304 }
00305 return b->getBlock(i, j);
00306 }
00307
00308
00309
00310 template <class Scalar>
00311 LinearOperator<Scalar> LinearOperator<Scalar>::getNonconstBlock(const int &i,
00312 const int &j)
00313 {
00314 BlockOperatorBase<Scalar>* b =
00315 dynamic_cast<BlockOperatorBase<Scalar>* >(this->ptr().get());
00316
00317 if (b==0)
00318 {
00319 TEUCHOS_TEST_FOR_EXCEPTION(i != 0 || j != 0, std::runtime_error,
00320 "nonzero block index (" << i << "," << j << ") into "
00321 "non-block operator");
00322 return *this;
00323 }
00324 return b->getNonconstBlock(i, j);
00325 }
00326
00327
00328
00329
00330 template <class Scalar>
00331 void LinearOperator<Scalar>::endBlockFill()
00332 {
00333 SetableBlockOperatorBase<Scalar>* b =
00334 dynamic_cast<SetableBlockOperatorBase<Scalar>* >(this->ptr().get());
00335
00336 TEUCHOS_TEST_FOR_EXCEPTION(b == 0, std::runtime_error,
00337 "Can't call endBlockFill because operator is not a SetableBlockOperator");
00338
00339
00340 b->endBlockFill();
00341 }
00342
00343
00344
00345
00346
00347
00348 #endif