TSFSimpleAddedOpImpl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // **********************************************************************/
00027  /* @HEADER@ */
00028 
00029 #ifndef TSF_SIMPLE_ADDED_OP_IMPL_HPP
00030 #define TSF_SIMPLE_ADDED_OP_IMPL_HPP
00031 
00032 
00033 
00034 #include "TSFSimpleAddedOpDecl.hpp"
00035 #include "TSFSimpleZeroOpDecl.hpp"
00036 #include "TSFLinearCombinationImpl.hpp"
00037 #include "SundanceOut.hpp"
00038 #include "SundanceTabs.hpp"
00039 #include "Teuchos_Array.hpp"
00040 
00041 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00042 #include "TSFSimpleZeroOpImpl.hpp"
00043 #include "TSFLinearOperatorImpl.hpp"
00044 #include "TSFSimplifiedLinearOpBaseImpl.hpp"
00045 #include "TSFSimpleTransposedOpImpl.hpp"
00046 #endif
00047 
00048 
00049 namespace TSFExtended
00050 {
00051 using namespace Teuchos;
00052 using namespace Sundance;
00053 
00054 
00055 /*
00056  * Represent a sum of operators A_0 + A_1 + ... + A_n.
00057  */
00058 template <class Scalar> inline
00059 SimpleAddedOp<Scalar>::SimpleAddedOp(
00060   const Array<LinearOperator<Scalar> >& ops)
00061   : SimplifiedLinearOpWithSpaces<Scalar>(
00062     ops[0].domain(), ops[0].range()
00063     ) 
00064   , ops_(ops)
00065 {
00066   TEST_FOR_EXCEPT(ops_.size() <= 1);
00067   for (int i=1; i<ops_.size(); i++)
00068   {
00069     TEST_FOR_EXCEPT(!(ops[i].range() == ops[0].range()));
00070     TEST_FOR_EXCEPT(!(ops[i].domain() == ops[0].domain()));
00071   }
00072 }
00073   
00074 /* */
00075 template <class Scalar> inline
00076 void SimpleAddedOp<Scalar>::applyOp(const Thyra::EOpTransp M_trans,
00077   const Vector<Scalar>& in,
00078   Vector<Scalar> out) const
00079 {
00080   Tabs tab(0);
00081   SUNDANCE_MSG2(this->verb(), tab << "SimpleAddedOp::applyOp()");
00082 
00083   Vector<Scalar> tmp=out.copy();
00084   tmp.zero();
00085   for (int i=0; i<ops_.size(); i++)
00086   {
00087     Tabs tab1;
00088     Out::os() << tab1 << "applying term i=" << i << " of " 
00089               << ops_.size() << std::endl;
00090     if (M_trans == Thyra::NOTRANS)
00091       tmp = tmp + ops_[i] * in;
00092     else if (M_trans == Thyra::TRANS)
00093       tmp = tmp + ops_[i].transpose() * in;
00094     else 
00095       TEST_FOR_EXCEPT(M_trans != Thyra::TRANS && M_trans != Thyra::NOTRANS);
00096   }
00097   out.acceptCopyOf(tmp);
00098 
00099   SUNDANCE_MSG2(this->verb(), tab << "done SimpleAddedOp::applyOp()");
00100 }
00101   
00102 /* */
00103 template <class Scalar> inline
00104 std::string SimpleAddedOp<Scalar>::description() const 
00105 {
00106   std::string rtn="(";
00107   for (int i=0; i<ops_.size(); i++)
00108   {
00109     if (i > 0) rtn += "+";
00110     rtn += ops_[i].description();
00111   }
00112   rtn += ")";
00113   return rtn;
00114 }
00115 
00116 
00117 
00118 template <class Scalar> inline
00119 LinearOperator<Scalar> addedOperator(
00120   const Array<LinearOperator<Scalar> >& ops)
00121 {
00122   /* We will strip out any zero operators */
00123   Array<LinearOperator<Scalar> > strippedOps;
00124 
00125   for (int i=0; i<ops.size(); i++)
00126   {
00127     LinearOperator<Scalar> op_i = ops[i];
00128 
00129     /* Ignore any zero operators */
00130     const SimpleZeroOp<Scalar>* zPtr 
00131       = dynamic_cast<const SimpleZeroOp<Scalar>*>(op_i.ptr().get());
00132 
00133     if (zPtr != 0) continue;
00134 
00135     strippedOps.append(op_i);
00136   }
00137   
00138   TEST_FOR_EXCEPT(strippedOps.size() < 1);
00139   if (strippedOps.size()==1) return strippedOps[0];
00140   
00141   RCP<LinearOpBase<Scalar> > op 
00142     = rcp(new SimpleAddedOp<Scalar>(strippedOps));
00143   
00144   return op;
00145 }
00146 
00147 template <class Scalar> inline
00148 LinearOperator<Scalar> operator+(const LinearOperator<Scalar>& A,
00149   const LinearOperator<Scalar>& B)
00150 {
00151   return addedOperator(Array<LinearOperator<Scalar> >(tuple(A, B)));
00152 }
00153 
00154 }
00155 
00156 #endif

Site Contact