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 #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)
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)
00139 {
00140 blockICMF_[1][1]->initializeNonzerosInRow(globalRowIndex,
00141 bcCols.size(), &(bcCols[0]));
00142 }
00143 }
00144 else
00145 {
00146 if (intCols.size() > 0)
00147 {
00148 blockICMF_[0][0]->initializeNonzerosInRow(globalRowIndex,
00149 intCols.size(), &(intCols[0]));
00150 }
00151 if (bcCols.size() > 0)
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 }