TSFPartitionedMatrixFactory.cpp
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 #include "TSFPartitionedMatrixFactory.hpp"
00030 #include "TSFVectorType.hpp"
00031 #include "TSFLoadableBlockOperatorDecl.hpp"
00032 #include "Teuchos_MPIComm.hpp"
00033 
00034 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00035 #include "TSFVectorSpaceImpl.hpp"
00036 #include "TSFSequentialIteratorImpl.hpp"
00037 #include "TSFLoadableBlockOperatorImpl.hpp"
00038 #endif
00039 
00040 using namespace TSFExtended;
00041 using namespace Teuchos;
00042 
00043 PartitionedMatrixFactory::PartitionedMatrixFactory(
00044   const VectorSpace<double>& domain,
00045   int lowestLocalCol,
00046   const RCP<Array<int> >& isBCCol,
00047   const RCP<std::set<int> >& remoteBCCols,
00048   const VectorType<double>& domainVecType,
00049   const VectorSpace<double>& range,
00050   int lowestLocalRow,
00051   const RCP<Array<int> >& isBCRow,
00052   const VectorType<double>& rangeVecType
00053   )
00054   : 
00055   domain_(domain),
00056   internalDomain_(domain.getBlock(0)),
00057   bcDomain_(domain.getBlock(1)),
00058   isBCCol_(isBCCol),
00059   remoteBCCols_(remoteBCCols),
00060   domainVecType_(domainVecType),
00061   lowestLocalCol_(lowestLocalCol),
00062   highestLocalCol_(-1),
00063   range_(range),
00064   internalRange_(range.getBlock(0)),
00065   bcRange_(range.getBlock(1)),
00066   isBCRow_(isBCRow),
00067   rangeVecType_(rangeVecType),
00068   lowestLocalRow_(lowestLocalRow),
00069   highestLocalRow_(-1),
00070   blockFactory_(2),
00071   blockICMF_(2)
00072 {
00073   highestLocalCol_ = lowestLocalCol_ + domain.numLocalElements();
00074   highestLocalRow_ = lowestLocalRow_ + range.numLocalElements();
00075 
00076   blockFactory_[0].resize(2);
00077   blockFactory_[1].resize(2);
00078   
00079   blockFactory_[0][0] = rangeVecType_.createMatrixFactory(internalDomain_, internalRange_);
00080 
00081   blockFactory_[0][1] = rangeVecType_.createMatrixFactory(bcDomain_, internalRange_);
00082 
00083   blockFactory_[1][1] = rangeVecType_.createMatrixFactory(bcDomain_, bcRange_);
00084 
00085   for (int i=0; i<2; i++)
00086   {
00087     blockICMF_[i].resize(2);
00088     for (int j=0; j<2; j++)
00089     {
00090       if (i==1 && j==0) continue;
00091       IncrementallyConfigurableMatrixFactory* icmf 
00092         = dynamic_cast<IncrementallyConfigurableMatrixFactory*>(blockFactory_[i][j].get());
00093       TEST_FOR_EXCEPTION(icmf==0, std::runtime_error,
00094         "block(" << i << ", " << j << ") is not an ICMF");
00095       blockICMF_[i][j] = icmf;
00096     }
00097   }
00098   
00099 }
00100 
00101 void PartitionedMatrixFactory::initializeNonzerosInRow(int globalRowIndex,
00102   int nElemsToInsert,
00103   const int* globalColumnIndices)
00104 {
00105   if (globalRowIndex < lowestLocalRow_ || globalRowIndex >= highestLocalRow_) return;
00106 
00107   Array<int> bcCols;
00108   Array<int> intCols;
00109   bcCols.reserve(nElemsToInsert);
00110   intCols.reserve(nElemsToInsert);
00111 
00112   const Array<int>& isBCCol = *isBCCol_;
00113 
00114   for (int i=0; i<nElemsToInsert; i++)
00115   {
00116     int g = globalColumnIndices[i];
00117     if (g < lowestLocalCol_ || g >= highestLocalCol_)
00118     {
00119       if (remoteBCCols_->find(g) != remoteBCCols_->end()) bcCols.append(g);
00120       else intCols.append(g);
00121     }
00122     else
00123     {
00124       int localCol = g - lowestLocalCol_;
00125       if (isBCCol[localCol]) bcCols.append(g);
00126       else intCols.append(g);
00127     }
00128   }
00129 
00130 
00131   if ((*isBCRow_)[globalRowIndex - lowestLocalRow_])
00132   {
00133     if (intCols.size() > 0) /* do (BC, internal) block */
00134     {
00135       TEST_FOR_EXCEPTION(true, std::logic_error,
00136         "There should be no entries in the (BC, internal) block");
00137     }
00138     if (bcCols.size() > 0) /* do (BC, BC) block */
00139     {
00140       blockICMF_[1][1]->initializeNonzerosInRow(globalRowIndex, 
00141         bcCols.size(), &(bcCols[0]));
00142     }
00143   }
00144   else
00145   {
00146     if (intCols.size() > 0) /* do (internal, internal) block */
00147     {
00148       blockICMF_[0][0]->initializeNonzerosInRow(globalRowIndex, 
00149         intCols.size(), &(intCols[0]));
00150     }
00151     if (bcCols.size() > 0) /* do (internal, BC) block */
00152     {
00153       blockICMF_[0][1]->initializeNonzerosInRow(globalRowIndex, 
00154         bcCols.size(), &(bcCols[0]));
00155     }
00156   }
00157 }
00158 
00159 
00160 void PartitionedMatrixFactory::finalize() 
00161 {
00162   blockICMF_[0][0]->finalize();
00163   blockICMF_[1][1]->finalize();
00164   blockICMF_[0][1]->finalize();
00165 }
00166 
00167 
00168 LinearOperator<double> PartitionedMatrixFactory::createMatrix() const
00169 {
00170 
00171   RCP<LinearOpBase<double> > op 
00172     = rcp(new TSFExtended::LoadableBlockOperator<double>(domain_, lowestLocalCol_, isBCCol_, remoteBCCols_, range_, lowestLocalRow_, isBCRow_));
00173   LinearOperator<double> A = op;
00174 
00175   LinearOperator<double> A_ii = blockFactory_[0][0]->createMatrix();
00176   LinearOperator<double> A_ib = blockFactory_[0][1]->createMatrix();
00177   LinearOperator<double> A_bb = blockFactory_[1][1]->createMatrix();
00178 
00179   A.setBlock(0,0,A_ii);
00180   A.setBlock(0,1,A_ib);
00181   A.setBlock(1,1,A_bb);
00182 
00183   A.endBlockFill();
00184 
00185   return A;
00186 }

Site Contact