49 #ifndef IFPACK2_ILUK_GRAPH_HPP
50 #define IFPACK2_ILUK_GRAPH_HPP
55 #include <Ifpack2_ConfigDefs.hpp>
57 #include <Teuchos_CommHelpers.hpp>
58 #include <Tpetra_CrsGraph.hpp>
59 #include <Tpetra_Import.hpp>
60 #include <Ifpack2_CreateOverlapGraph.hpp>
61 #include <Ifpack2_Parameters.hpp>
96 template<
class GraphType>
99 typedef typename GraphType::local_ordinal_type local_ordinal_type;
100 typedef typename GraphType::global_ordinal_type global_ordinal_type;
101 typedef typename GraphType::node_type node_type;
104 typedef Tpetra::RowGraph<local_ordinal_type,
108 typedef Tpetra::CrsGraph<local_ordinal_type,
124 const int levelOverlap);
167 return OverlapGraph_;
174 typedef typename GraphType::map_type map_type;
197 void constructOverlapGraph();
205 size_t NumMyDiagonals_;
206 size_t NumGlobalDiagonals_;
210 template<
class GraphType>
214 const int levelOverlap)
216 LevelFill_ (levelFill),
217 LevelOverlap_ (levelOverlap),
219 NumGlobalDiagonals_ (0)
223 template<
class GraphType>
228 template<
class GraphType>
232 getParameter (parameterlist,
"iluk level-of-fill", LevelFill_);
233 getParameter (parameterlist,
"iluk level-of-overlap", LevelOverlap_);
237 template<
class GraphType>
242 if (OverlapGraph_ == Teuchos::null) {
243 OverlapGraph_ = createOverlapGraph<GraphType> (Graph_, LevelOverlap_);
248 template<
class GraphType>
258 size_t NumIn, NumL, NumU;
261 constructOverlapGraph();
264 OverlapGraph_->getRowMap (), 0));
266 OverlapGraph_->getRowMap (), 0));
269 const int MaxNumIndices = OverlapGraph_->getNodeMaxNumRowEntries ();
271 Array<local_ordinal_type> L (MaxNumIndices);
272 Array<local_ordinal_type> U (MaxNumIndices);
278 const int NumMyRows = OverlapGraph_->getRowMap ()->getNodeNumElements ();
281 for (
int i = 0; i< NumMyRows; ++i) {
282 ArrayView<const local_ordinal_type> my_indices;
283 OverlapGraph_->getLocalRowView (i, my_indices);
290 NumIn = my_indices.size();
292 for (
size_t j = 0; j < NumIn; ++j) {
293 const local_ordinal_type k = my_indices[j];
317 ArrayView<const local_ordinal_type> L_view = L.view (0, NumL);
318 L_Graph_->insertLocalIndices (i, L_view);
321 ArrayView<const local_ordinal_type> U_view = U.view (0, NumU);
322 U_Graph_->insertLocalIndices (i, U_view);
326 if (LevelFill_ > 0) {
328 RCP<const map_type> L_DomainMap = OverlapGraph_->getRowMap ();
329 RCP<const map_type> L_RangeMap = Graph_->getRangeMap ();
330 RCP<const map_type> U_DomainMap = Graph_->getDomainMap ();
331 RCP<const map_type> U_RangeMap = OverlapGraph_->getRowMap ();
332 RCP<Teuchos::ParameterList> params = Teuchos::parameterList ();
333 params->set (
"Optimize Storage",
false);
334 L_Graph_->fillComplete (L_DomainMap, L_RangeMap, params);
335 U_Graph_->fillComplete (U_DomainMap, U_RangeMap, params);
336 L_Graph_->resumeFill ();
337 U_Graph_->resumeFill ();
343 int MaxRC = NumMyRows;
344 std::vector<std::vector<int> > Levels(MaxRC);
345 std::vector<int> LinkList(MaxRC);
346 std::vector<int> CurrentLevel(MaxRC);
347 Array<local_ordinal_type> CurrentRow (MaxRC + 1);
348 std::vector<int> LevelsRowU(MaxRC);
350 for (
int i = 0; i < NumMyRows; ++i) {
355 size_t LenL = L_Graph_->getNumEntriesInLocalRow(i);
356 size_t LenU = U_Graph_->getNumEntriesInLocalRow(i);
357 size_t Len = LenL + LenU + 1;
359 CurrentRow.resize(Len);
361 L_Graph_->getLocalRowCopy(i, CurrentRow(), LenL);
362 CurrentRow[LenL] = i;
364 ArrayView<local_ordinal_type> URowView = CurrentRow.view (LenL+1, LenU);
366 U_Graph_->getLocalRowCopy (i, URowView, LenU);
371 for (
size_t j=0; j<Len-1; j++) {
372 LinkList[CurrentRow[j]] = CurrentRow[j+1];
373 CurrentLevel[CurrentRow[j]] = 0;
376 LinkList[CurrentRow[Len-1]] = NumMyRows;
377 CurrentLevel[CurrentRow[Len-1]] = 0;
381 First = CurrentRow[0];
384 int PrevInList = Next;
385 int NextInList = LinkList[Next];
388 ArrayView<const local_ordinal_type> IndicesU;
389 U_Graph_->getLocalRowView (RowU, IndicesU);
391 int LengthRowU = IndicesU.size ();
397 for (ii = 0; ii < LengthRowU; ) {
398 int CurInList = IndicesU[ii];
399 if (CurInList < NextInList) {
401 int NewLevel = CurrentLevel[RowU] + Levels[RowU][ii+1] + 1;
402 if (NewLevel <= LevelFill_) {
403 LinkList[PrevInList] = CurInList;
404 LinkList[CurInList] = NextInList;
405 PrevInList = CurInList;
406 CurrentLevel[CurInList] = NewLevel;
410 else if (CurInList == NextInList) {
411 PrevInList = NextInList;
412 NextInList = LinkList[PrevInList];
413 int NewLevel = CurrentLevel[RowU] + Levels[RowU][ii+1] + 1;
414 CurrentLevel[CurInList] = std::min (CurrentLevel[CurInList], NewLevel);
418 PrevInList = NextInList;
419 NextInList = LinkList[PrevInList];
422 Next = LinkList[Next];
427 CurrentRow.resize (0);
434 CurrentRow.push_back (Next);
435 Next = LinkList[Next];
441 L_Graph_->removeLocalIndices (i);
442 if (CurrentRow.size() > 0) {
443 L_Graph_->insertLocalIndices (i, CurrentRow ());
449 Next != i, std::runtime_error,
450 "Ifpack2::IlukGraph::initialize: FATAL: U has zero diagonal")
452 LevelsRowU[0] = CurrentLevel[Next];
453 Next = LinkList[Next];
457 CurrentRow.resize (0);
460 while (Next < NumMyRows) {
461 LevelsRowU[LenU+1] = CurrentLevel[Next];
462 CurrentRow.push_back (Next);
464 Next = LinkList[Next];
471 U_Graph_->removeLocalIndices (i);
473 U_Graph_->insertLocalIndices (i, CurrentRow ());
477 Levels[i] = std::vector<int> (LenU+1);
478 for (
size_t jj=0; jj<LenU+1; jj++) {
479 Levels[i][jj] = LevelsRowU[jj];
485 RCP<const map_type> L_DomainMap = OverlapGraph_->getRowMap ();
486 RCP<const map_type> L_RangeMap = Graph_->getRangeMap ();
487 RCP<const map_type> U_DomainMap = Graph_->getDomainMap ();
488 RCP<const map_type> U_RangeMap = OverlapGraph_->getRowMap ();
489 L_Graph_->fillComplete (L_DomainMap, L_RangeMap);
490 U_Graph_->fillComplete (U_DomainMap, U_RangeMap);
492 reduceAll<int, size_t> (* (L_DomainMap->getComm ()), REDUCE_SUM, 1,
493 &NumMyDiagonals_, &NumGlobalDiagonals_);
void initialize()
Set up the graph structure of the L and U factors.
Definition: Ifpack2_IlukGraph.hpp:249
void setParameters(const Teuchos::ParameterList ¶meterlist)
Set parameters.
Definition: Ifpack2_IlukGraph.hpp:230
Tpetra::CrsGraph< local_ordinal_type, global_ordinal_type, node_type > crs_graph_type
Tpetra::CrsGraph specialization used by this class.
Definition: Ifpack2_IlukGraph.hpp:110
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void getParameter(const Teuchos::ParameterList ¶ms, const std::string &name, T &value)
Set a value from a ParameterList if a parameter with the specified name exists.
Definition: Ifpack2_Parameters.hpp:59
Tpetra::RowGraph< local_ordinal_type, global_ordinal_type, node_type > row_graph_type
Tpetra::RowGraph specialization used by this class.
Definition: Ifpack2_IlukGraph.hpp:106
virtual ~IlukGraph()
IlukGraph Destructor.
Definition: Ifpack2_IlukGraph.hpp:224
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< crs_graph_type > getL_Graph() const
Returns the graph of lower triangle of the ILU(k) graph as a Tpetra::CrsGraph.
Definition: Ifpack2_IlukGraph.hpp:156
IlukGraph(const Teuchos::RCP< const GraphType > &G, const int levelFill, const int levelOverlap)
Constructor.
Definition: Ifpack2_IlukGraph.hpp:212
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
int getLevelFill() const
The level of fill used to construct this graph.
Definition: Ifpack2_IlukGraph.hpp:150
int getLevelOverlap() const
The level of overlap used to construct this graph.
Definition: Ifpack2_IlukGraph.hpp:153
Construct a level filled graph for use in computing an ILU(k) incomplete factorization.
Definition: Ifpack2_IlukGraph.hpp:97
size_t getNumGlobalDiagonals() const
Returns the global number of diagonals in the ILU(k) graph.
Definition: Ifpack2_IlukGraph.hpp:171
Teuchos::RCP< const crs_graph_type > getOverlapGraph() const
Returns the the overlapped graph.
Definition: Ifpack2_IlukGraph.hpp:166
Teuchos::RCP< crs_graph_type > getU_Graph() const
Returns the graph of upper triangle of the ILU(k) graph as a Tpetra::CrsGraph.
Definition: Ifpack2_IlukGraph.hpp:161