PartitionedMatrixFactory::PartitionedMatrixFactory(
  const VectorSpace<double>& domain,
  int lowestLocalCol,
  const RCP<Array<int> >& isBCCol,
  const RCP<std::set<int> >& remoteBCCols,
  const VectorType<double>& domainVecType,
  const VectorSpace<double>& range,
  int lowestLocalRow,
  const RCP<Array<int> >& isBCRow,
  const VectorType<double>& rangeVecType
  )
  : 
  domain_(domain),
  internalDomain_(domain.getBlock(0)),
  bcDomain_(domain.getBlock(1)),
  isBCCol_(isBCCol),
  remoteBCCols_(remoteBCCols),
  domainVecType_(domainVecType),
  lowestLocalCol_(lowestLocalCol),
  highestLocalCol_(-1),
  range_(range),
  internalRange_(range.getBlock(0)),
  bcRange_(range.getBlock(1)),
  isBCRow_(isBCRow),
  rangeVecType_(rangeVecType),
  lowestLocalRow_(lowestLocalRow),
  highestLocalRow_(-1),
  blockFactory_(2),
  blockICMF_(2)
{
  highestLocalCol_ = lowestLocalCol_ + domain.numLocalElements();
  highestLocalRow_ = lowestLocalRow_ + range.numLocalElements();

  blockFactory_[0].resize(2);
  blockFactory_[1].resize(2);
  
  blockFactory_[0][0] = rangeVecType_.createMatrixFactory(internalDomain_, internalRange_);

  blockFactory_[0][1] = rangeVecType_.createMatrixFactory(bcDomain_, internalRange_);

  blockFactory_[1][1] = rangeVecType_.createMatrixFactory(bcDomain_, bcRange_);

  for (int i=0; i<2; i++)
  {
    blockICMF_[i].resize(2);
    for (int j=0; j<2; j++)
    {
      if (i==1 && j==0) continue;
      IncrementallyConfigurableMatrixFactory* icmf 
        = dynamic_cast<IncrementallyConfigurableMatrixFactory*>(blockFactory_[i][j].get());
      TEST_FOR_EXCEPTION(icmf==0, std::runtime_error,
        "block(" << i << ", " << j << ") is not an ICMF");
      blockICMF_[i][j] = icmf;
    }
  }
  
}
template <class Scalar> inline
SimpleBlockOp<Scalar>::SimpleBlockOp(
  const VectorSpace<Scalar>& domain,
  const VectorSpace<Scalar>& range)
  : LinearOpWithSpaces<Scalar>(domain, range), blocks_(range.numBlocks())
{
  for (int i=0; i<blocks_.size(); i++) 
  {
    blocks_[i] = Array<LinearOperator<Scalar> >(domain.numBlocks());
    for (int j=0; j<blocks_[i].size(); j++)
    {
      blocks_[i][j] = zeroOperator(domain.getBlock(j), range.getBlock(i));
    }
  }
}
template <class Scalar> inline
DefaultBlockVector<Scalar>
::DefaultBlockVector(const VectorSpace<Scalar>& space)
  : BlockVectorBase<Scalar>(), space_(space), blocks_(space.numBlocks())
{
  for (int i=0; i<space.numBlocks(); i++)
  {
    blocks_[i] = space.getBlock(i).createMember();
  }
}
template <class Scalar> inline
void BlockIterator<Scalar>
::goToStart(const VectorSpace<Scalar>& space,
  std::deque<int>& pos) const
{
  pos.push_back(0);
  if (space.isBlockSpace())
  {
    goToStart(space.getBlock(0), pos);
  }
}
Example #5
0
int main(int argc, char *argv[]) 
{
  int stat = 0;
  try
  {
    GlobalMPISession session(&argc, &argv);
    MPIComm::world().synchronize();

    Out::os() << "go!" << std::endl;
    VectorType<double> type = new EpetraVectorType();

    Array<int> domainBlockSizes = tuple(2,3,4);
    Array<int> rangeBlockSizes = tuple(2,2);

    Array<VectorSpace<double> > domainBlocks(domainBlockSizes.size());
    Array<VectorSpace<double> > rangeBlocks(rangeBlockSizes.size());

    for (int i=0; i<domainBlocks.size(); i++)
    {
      domainBlocks[i] = type.createEvenlyPartitionedSpace(MPIComm::world(),
        domainBlockSizes[i]);
    }

    for (int i=0; i<rangeBlocks.size(); i++)
    {
      rangeBlocks[i] = type.createEvenlyPartitionedSpace(MPIComm::world(),
        rangeBlockSizes[i]);
    }
      
    VectorSpace<double> domain = blockSpace(domainBlocks);
    VectorSpace<double> range = blockSpace(rangeBlocks);

    double blockDensity = 0.75;
    double onProcDensity = 0.5;
    double offProcDensity = 0.1;
      
    RandomBlockMatrixBuilder<double> builder(domain, range, 
      blockDensity,
      onProcDensity,
      offProcDensity,
      type);

    LinearOperator<double> A = builder.getOp();

    Out::os() << "A num block rows = " << A.numBlockRows() << std::endl;
    Out::os() << "A num block cols = " << A.numBlockCols() << std::endl;

    Vector<double> x = domain.createMember();
    Out::os() << "randomizing trial vector" << std::endl;
    x.randomize();

    Array<Vector<double> > xBlock(domain.numBlocks());
    for (int i=0; i<xBlock.size(); i++)
    {
      xBlock[i] = x.getBlock(i);
    }

    Vector<double> xx = x.copy();

      

    Out::os() << "------------------------------------------------------------" << std::endl;
    Out::os() << "computing A*x..." << std::endl;
    Vector<double> y0 = A * x;
    for (int i=0; i<y0.space().numBlocks(); i++)
    {
      Out::os() << "y0[" << i << "] = " << std::endl << y0.getBlock(i) << std::endl;
    }
      

    Vector<double> y1 = range.createMember();
    Out::os() << "------------------------------------------------------------" << std::endl;
    Out::os() << "computing A*x block-by-block..." << std::endl;
    Array<Vector<double> > yBlock(range.numBlocks());
    for (int i=0; i<yBlock.size(); i++)
    {
      yBlock[i] = range.getBlock(i).createMember();
      yBlock[i].zero();
      for (int j=0; j<xBlock.size(); j++)
      {
        LinearOperator<double> Aij = A.getBlock(i,j);
        if (Aij.ptr().get() != 0)
        {
          Out::os() << "A(" << i << ", " << j << ") = " << std::endl 
                    << Aij << std::endl;
        }
        else
        {
          Out::os() << "A(" << i << ", " << j << ") = 0 " << std::endl;
        }
        Out::os() << "x[" << j << "] = " << std::endl << xBlock[j] << std::endl;
        if (Aij.ptr().get()==0) continue;
        yBlock[i] = yBlock[i] + Aij * xBlock[j];
      }
      y1.setBlock(i, yBlock[i]);
    }

    for (int i=0; i<y1.space().numBlocks(); i++)
    {
      Out::os() << "y1[" << i << "] = " << std::endl << y1.getBlock(i) << std::endl;
    }
    double err = (y1 - y0).norm2();
    Out::os() << "error = " << err << std::endl;

    double tol = 1.0e-13;
    if (err < tol)
    {
      Out::os() << "block op test PASSED" << std::endl;
    }
    else
    {
      stat = -1;
      Out::os() << "block op test FAILED" << std::endl;
    }
  }
  catch(std::exception& e)
  {
    stat = -1;
    Out::os() << "Caught exception: " << e.what() << std::endl;
  }
  return stat;
}