Do not use expensive aggregation when forming pressure system unless requested.

That means that for traditional CPR no aggregation is used and we simply extract
the pressure component.
This commit is contained in:
Markus Blatt
2018-01-29 11:40:14 +00:00
parent 5d8da52679
commit abacbe2cfc

View File

@@ -576,18 +576,20 @@ public:
public:
OneComponentAggregationLevelTransferPolicy(const Criterion& crit, const Communication& comm)
: criterion_(crit), communication_(&const_cast<Communication&>(comm))
: criterion_(crit), communication_(&const_cast<Communication&>(comm)), use_aggregation_(false)
{}
void createCoarseLevelSystem(const Operator& fineOperator)
{
prolongDamp_ = 1;
if ( use_aggregation_ )
{
#if DUNE_VERSION_NEWER(DUNE_ISTL, 2, 6)
typedef Dune::Amg::PropertiesGraphCreator<Operator,Communication> GraphCreator;
#else
typedef Dune::Amg::PropertiesGraphCreator<Operator> GraphCreator;
#endif
typedef typename GraphCreator::PropertiesGraph PropertiesGraph;
typedef typename GraphCreator::GraphTuple GraphTuple;
@@ -606,8 +608,7 @@ public:
std::tie(noAggregates, isoAggregates, oneAggregates, skippedAggregates) =
aggregatesMap_->buildAggregates(fineOperator.getmat(), *(get<1>(graphs)),
criterion_, true);
std::cout<<"no aggregates="<<noAggregates<<" iso="<<isoAggregates<<" one="<<oneAggregates<<" skipped="<<skippedAggregates<<std::endl;
//std::cout<<"no aggregates="<<noAggregates<<" iso="<<isoAggregates<<" one="<<oneAggregates<<" skipped="<<skippedAggregates<<std::endl;
using CommunicationArgs = typename Dune::Amg::ConstructionTraits<Communication>::Arguments;
CommunicationArgs commArgs(communication_->communicator(), communication_->getSolverCategory());
coarseLevelCommunication_.reset(Dune::Amg::ConstructionTraits<Communication>::construct(commArgs));
@@ -647,6 +648,38 @@ public:
coarseLevelCommunication_->freeGlobalLookup();
}
calculateCoarseEntries(fineOperator.getmat());
}
else
{
using CoarseMatrix = typename CoarseOperator::matrix_type;
const auto& fineLevelMatrix = fineOperator.getmat();
coarseLevelMatrix_.reset(new CoarseMatrix(fineLevelMatrix.N(), fineLevelMatrix.M(), CoarseMatrix::row_wise));
auto createIter = coarseLevelMatrix_->createbegin();
for ( const auto& row: fineLevelMatrix )
{
for ( auto col = row.begin(), cend = row.end(); col != cend; ++col)
{
createIter.insert(col.index());
}
++createIter;
}
auto coarseRow = coarseLevelMatrix_->begin();
for ( const auto& row: fineLevelMatrix )
{
auto coarseCol = coarseRow->begin();
for ( auto col = row.begin(), cend = row.end(); col != cend; ++col, ++coarseCol )
{
assert( col.index() == coarseCol.index() );
*coarseCol = (*col)[COMPONENT_INDEX][COMPONENT_INDEX];
}
++coarseRow;
}
coarseLevelCommunication_.reset(communication_, [](Communication*){});
}
this->lhs_.resize(this->coarseLevelMatrix_->M());
this->rhs_.resize(this->coarseLevelMatrix_->N());
using OperatorArgs = typename Dune::Amg::ConstructionTraits<CoarseOperator>::Arguments;
@@ -682,7 +715,10 @@ public:
// Set coarse vector to zero
this->rhs_=0;
if ( use_aggregation_ )
{
auto end = fine.end(), begin=fine.begin();
for(auto block=begin; block != end; ++block)
{
const auto& vertex = (*aggregatesMap_)[block-begin];
@@ -691,13 +727,24 @@ public:
this->rhs_[vertex] += (*block)[COMPONENT_INDEX];
}
}
}
else
{
auto end = fine.end(), begin=fine.begin();
for(auto block=begin; block != end; ++block)
{
this->rhs_[block-begin] = (*block)[COMPONENT_INDEX];
}
}
this->lhs_=0;
}
void moveToFineLevel(typename FatherType::FineDomainType& fine)
{
//for(auto& entry: this->lhs_)
// entry*=prolongDamp_;
if( use_aggregation_ )
{
this->lhs_ *= prolongDamp_;
auto end=fine.end(), begin=fine.begin();
@@ -709,6 +756,16 @@ public:
}
communication_->copyOwnerToAll(fine,fine);
}
else
{
auto end=fine.end(), begin=fine.begin();
for(auto block=begin; block != end; ++block)
{
(*block)[COMPONENT_INDEX] = this->lhs_[block-begin];
}
}
}
OneComponentAggregationLevelTransferPolicy* clone() const
{
@@ -726,6 +783,7 @@ private:
Communication* communication_;
std::shared_ptr<Communication> coarseLevelCommunication_;
std::shared_ptr<typename CoarseOperator::matrix_type> coarseLevelMatrix_;
bool use_aggregation_;
};
template<typename O, typename S, typename C,