TSFLoadableBlockOperatorImpl.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 TSFLOADABLEBLOCKOPERATOR_IMPL_HPP
00030 #define TSFLOADABLEBLOCKOPERATOR_IMPL_HPP
00031 
00032 #include "SundanceDefs.hpp"
00033 #include "TSFLoadableBlockOperatorDecl.hpp"
00034 
00035 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00036 #include "TSFSimpleBlockOpImpl.hpp"
00037 #endif
00038 
00039 
00040 
00041 namespace TSFExtended
00042 {
00043 using namespace Teuchos;
00044 
00045 template <class Scalar> inline
00046 LoadableBlockOperator<Scalar>:: LoadableBlockOperator(
00047   const VectorSpace<Scalar>& domain,
00048   int lowestLocalCol,
00049   const RCP<Array<int> >& isBCCol,
00050   const RCP<std::set<int> >& remoteBCCols,
00051   const VectorSpace<Scalar>& range,
00052   int lowestLocalRow,
00053   const RCP<Array<int> >& isBCRow)
00054   : SimpleBlockOp<Scalar>(domain, range),
00055     isBCCol_(isBCCol),
00056     isBCRow_(isBCRow),
00057     remoteBCCols_(remoteBCCols),
00058     lowestLocalRow_(lowestLocalRow),
00059     lowestLocalCol_(lowestLocalCol),
00060     highestLocalRow_(lowestLocalRow + range.numLocalElements()),
00061     highestLocalCol_(lowestLocalCol + domain.numLocalElements())
00062 {
00063 }
00064       
00065 template <class Scalar> inline
00066 void LoadableBlockOperator<Scalar>::addToRow(int globalRowIndex,
00067   int nElemsToInsert,
00068   const int* globalColumnIndices,
00069   const Scalar* elementValues) 
00070 {
00071   if (globalRowIndex < lowestLocalRow_ || globalRowIndex >= highestLocalRow_) return;
00072   Array<int> bcCols;
00073   Array<int> intCols;
00074   Array<Scalar> bcVals;
00075   Array<Scalar> intVals;
00076   bcCols.reserve(nElemsToInsert);
00077   intCols.reserve(nElemsToInsert);
00078   bcVals.reserve(nElemsToInsert);
00079   intVals.reserve(nElemsToInsert);
00080         
00081   const Array<int>& isBCCol = *isBCCol_;
00082         
00083   for (int i=0; i<nElemsToInsert; i++)
00084   {
00085     int g = globalColumnIndices[i];
00086     if (g < lowestLocalCol_ || g >= highestLocalCol_)
00087     {
00088       if (remoteBCCols_->find(g) != remoteBCCols_->end()) bcCols.append(g);
00089       else intCols.append(g);
00090     }
00091     else
00092     {
00093       int localCol = g - lowestLocalCol_;
00094       if (isBCCol[localCol]) 
00095       {
00096         bcCols.append(g);
00097         bcVals.append(elementValues[i]);
00098       }
00099       else 
00100       {
00101         intCols.append(g);
00102         intVals.append(elementValues[i]);
00103       }
00104     }
00105   }
00106         
00107   if ((*isBCRow_)[globalRowIndex - lowestLocalRow_])
00108   {
00109     if (intCols.size() > 0) /* do (BC, internal) block */
00110     {
00111       TEST_FOR_EXCEPTION(true, std::logic_error,
00112         "There should be no entries in the (BC, internal) block");
00113     }
00114     if (bcCols.size() > 0) /* do (BC, BC) block */
00115     {
00116       loadableBlock(1,1)->addToRow(globalRowIndex, bcCols.size(), 
00117         &(bcCols[0]), &(bcVals[0]));
00118     }
00119   }
00120   else
00121   {
00122     if (intCols.size() > 0) /* do (internal, internal) block */
00123     {
00124       loadableBlock(0,0)->addToRow(globalRowIndex, intCols.size(), 
00125         &(intCols[0]), &(intVals[0]));
00126     }
00127     if (bcCols.size() > 0) /* do (internal, BC) block */
00128     {
00129       loadableBlock(0,1)->addToRow(globalRowIndex, bcCols.size(), 
00130         &(bcCols[0]), &(bcVals[0]));
00131     }
00132   }
00133 }
00134 
00135 
00136 template <class Scalar> inline
00137 void  LoadableBlockOperator<Scalar>::zero() 
00138 {
00139   for (int i=0; i<this->numBlockRows(); i++)
00140   {
00141     for (int j=0; j<this->numBlockCols(); j++)
00142     {
00143       if (i==1 && j==0) continue;
00144       this->loadableBlock(i,j)->zero();
00145     }
00146   }
00147 }
00148 
00149     
00150 
00151 template <class Scalar> inline
00152 RCP<LoadableMatrix<Scalar> > 
00153 LoadableBlockOperator<Scalar>::loadableBlock(int i, int j)
00154 {
00155   return this->getNonconstBlock(i,j).matrix();
00156 }
00157 
00158 
00159 }
00160 
00161 #endif

Site Contact