10#ifndef IFPACK2_LINE_PARTITIONER_DEF_HPP
11#define IFPACK2_LINE_PARTITIONER_DEF_HPP
13#include "Tpetra_CrsGraph.hpp"
14#include "Tpetra_Util.hpp"
19inline typename Teuchos::ScalarTraits<T>::magnitudeType square(T x) {
20 return Teuchos::ScalarTraits<T>::magnitude(x) * Teuchos::ScalarTraits<T>::magnitude(x);
25template <
class GraphType,
class Scalar>
32template <
class GraphType,
class Scalar>
35template <
class GraphType,
class Scalar>
38 threshold_ = List.get(
"partitioner: line detection threshold", threshold_);
39 TEUCHOS_TEST_FOR_EXCEPTION(threshold_ < 0.0 || threshold_ > 1.0,
40 std::runtime_error,
"Ifpack2::LinePartitioner: threshold not valid");
42 NumEqns_ = List.get(
"partitioner: PDE equations", NumEqns_);
43 TEUCHOS_TEST_FOR_EXCEPTION(NumEqns_ < 1, std::runtime_error,
"Ifpack2::LinePartitioner: NumEqns not valid");
45 coord_ = List.get(
"partitioner: coordinates", coord_);
46 TEUCHOS_TEST_FOR_EXCEPTION(coord_.is_null(), std::runtime_error,
"Ifpack2::LinePartitioner: coordinates not defined");
49template <
class GraphType,
class Scalar>
51 const local_ordinal_type invalid = Teuchos::OrdinalTraits<local_ordinal_type>::invalid();
54 TEUCHOS_TEST_FOR_EXCEPTION(coord_.is_null(), std::runtime_error,
"Ifpack2::LinePartitioner: coordinates not defined");
55 TEUCHOS_TEST_FOR_EXCEPTION((
size_t)this->Partition_.size() != this->Graph_->getLocalNumRows(), std::runtime_error,
"Ifpack2::LinePartitioner: partition size error");
58 if (this->Partition_.size() == 0) {
59 this->NumLocalParts_ = 0;
64 for (
size_t i = 0; i < this->Graph_->getLocalNumRows(); i++)
65 this->Partition_[i] = invalid;
68 this->NumLocalParts_ = this->Compute_Blocks_AutoLine(this->Partition_());
71 this->Parts_.resize(this->NumLocalParts_);
75template <
class GraphType,
class Scalar>
77 typedef local_ordinal_type LO;
78 typedef magnitude_type MT;
79 const LO invalid = Teuchos::OrdinalTraits<LO>::invalid();
80 const MT zero = Teuchos::ScalarTraits<MT>::zero();
82 Teuchos::ArrayRCP<const MT> xvalsRCP, yvalsRCP, zvalsRCP;
83 Teuchos::ArrayView<const MT> xvals, yvals, zvals;
84 xvalsRCP = coord_->getData(0);
86 if (coord_->getNumVectors() > 1) {
87 yvalsRCP = coord_->getData(1);
90 if (coord_->getNumVectors() > 2) {
91 zvalsRCP = coord_->getData(2);
95 double tol = threshold_;
96 size_t N = this->Graph_->getLocalNumRows();
97 size_t allocated_space = this->Graph_->getLocalMaxNumRowEntries();
99 nonconst_local_inds_host_view_type cols(
"cols", allocated_space);
100 Teuchos::Array<LO> indices(allocated_space);
101 Teuchos::Array<MT> dist(allocated_space);
103 Teuchos::Array<LO> itemp(2 * allocated_space);
104 Teuchos::Array<MT> dtemp(allocated_space);
108 for (LO i = 0; i < (LO)N; i += NumEqns_) {
111 if (blockIndices[i] != invalid)
continue;
114 this->Graph_->getLocalRowCopy(i, cols, nz);
115 MT x0 = (!xvals.is_null()) ? xvals[i / NumEqns_] : zero;
116 MT y0 = (!yvals.is_null()) ? yvals[i / NumEqns_] : zero;
117 MT z0 = (!zvals.is_null()) ? zvals[i / NumEqns_] : zero;
120 for (
size_t j = 0; j < nz; j += NumEqns_) {
122 LO nn = cols[j] / NumEqns_;
123 if (cols[j] >= (LO)N)
continue;
124 if (!xvals.is_null()) mydist += square<MT>(x0 - xvals[nn]);
125 if (!yvals.is_null()) mydist += square<MT>(y0 - yvals[nn]);
126 if (!zvals.is_null()) mydist += square<MT>(z0 - zvals[nn]);
127 dist[neighbor_len] = Teuchos::ScalarTraits<MT>::squareroot(mydist);
128 indices[neighbor_len] = cols[j];
132 Teuchos::ArrayView<MT> dist_view = dist(0, neighbor_len);
133 Tpetra::sort2(dist_view.begin(), dist_view.end(), indices.begin());
136 for (LO k = 0; k < NumEqns_; k++)
137 blockIndices[i + k] = num_lines;
140 if (neighbor_len > 2 && dist[1] / dist[neighbor_len - 1] < tol) {
141 local_automatic_line_search(NumEqns_, blockIndices, i, indices[1], num_lines, tol, itemp, dtemp);
144 if (neighbor_len > 3 && dist[2] / dist[neighbor_len - 1] < tol) {
145 local_automatic_line_search(NumEqns_, blockIndices, i, indices[2], num_lines, tol, itemp, dtemp);
153template <
class GraphType,
class Scalar>
154void LinePartitioner<GraphType, Scalar>::local_automatic_line_search(
int NumEqns, Teuchos::ArrayView<local_ordinal_type> blockIndices, local_ordinal_type last, local_ordinal_type next, local_ordinal_type LineID,
double tol, Teuchos::Array<local_ordinal_type> itemp, Teuchos::Array<magnitude_type> dtemp)
const {
155 typedef local_ordinal_type LO;
156 typedef magnitude_type MT;
157 const LO invalid = Teuchos::OrdinalTraits<LO>::invalid();
158 const MT zero = Teuchos::ScalarTraits<MT>::zero();
160 Teuchos::ArrayRCP<const MT> xvalsRCP, yvalsRCP, zvalsRCP;
161 Teuchos::ArrayView<const MT> xvals, yvals, zvals;
162 xvalsRCP = coord_->getData(0);
164 if (coord_->getNumVectors() > 1) {
165 yvalsRCP = coord_->getData(1);
168 if (coord_->getNumVectors() > 2) {
169 zvalsRCP = coord_->getData(2);
173 size_t N = this->Graph_->getLocalNumRows();
174 size_t allocated_space = this->Graph_->getLocalMaxNumRowEntries();
176 nonconst_local_inds_host_view_type cols(itemp.data(), allocated_space);
177 Teuchos::ArrayView<LO> indices = itemp.view(allocated_space, allocated_space);
178 Teuchos::ArrayView<MT> dist = dtemp();
180 while (blockIndices[next] == invalid) {
183 LO neighbors_in_line = 0;
185 this->Graph_->getLocalRowCopy(next, cols, nz);
186 MT x0 = (!xvals.is_null()) ? xvals[next / NumEqns_] : zero;
187 MT y0 = (!yvals.is_null()) ? yvals[next / NumEqns_] : zero;
188 MT z0 = (!zvals.is_null()) ? zvals[next / NumEqns_] : zero;
192 for (
size_t i = 0; i < nz; i += NumEqns) {
194 if (cols[i] >= (LO)N)
continue;
195 LO nn = cols[i] / NumEqns;
196 if (blockIndices[nn] == LineID) neighbors_in_line++;
197 if (!xvals.is_null()) mydist += square<MT>(x0 - xvals[nn]);
198 if (!yvals.is_null()) mydist += square<MT>(y0 - yvals[nn]);
199 if (!zvals.is_null()) mydist += square<MT>(z0 - zvals[nn]);
200 dist[neighbor_len] = Teuchos::ScalarTraits<MT>::squareroot(mydist);
201 indices[neighbor_len] = cols[i];
206 if (neighbors_in_line > 1)
break;
209 for (LO k = 0; k < NumEqns; k++)
210 blockIndices[next + k] = LineID;
213 Teuchos::ArrayView<MT> dist_view = dist(0, neighbor_len);
214 Tpetra::sort2(dist_view.begin(), dist_view.end(), indices.begin());
216 if (neighbor_len > 2 && indices[1] != last && blockIndices[indices[1]] == -1 && dist[1] / dist[neighbor_len - 1] < tol) {
219 }
else if (neighbor_len > 3 && indices[2] != last && blockIndices[indices[2]] == -1 && dist[2] / dist[neighbor_len - 1] < tol) {
231#define IFPACK2_LINEPARTITIONER_INSTANT(S, LO, GO, N) \
232 template class Ifpack2::LinePartitioner<Tpetra::CrsGraph<LO, GO, N>, S>; \
233 template class Ifpack2::LinePartitioner<Tpetra::RowGraph<LO, GO, N>, S>;
Ifpack2::LinePartitioner: A class to define partitions into a set of lines.
Definition Ifpack2_LinePartitioner_decl.hpp:45
LinePartitioner(const Teuchos::RCP< const row_graph_type > &graph)
Constructor.
Definition Ifpack2_LinePartitioner_def.hpp:27
void setPartitionParameters(Teuchos::ParameterList &List)
Set the partitioner's parameters (none for linear partitioning).
Definition Ifpack2_LinePartitioner_def.hpp:37
virtual ~LinePartitioner()
Destructor.
Definition Ifpack2_LinePartitioner_def.hpp:33
void computePartitions()
Compute the partitions.
Definition Ifpack2_LinePartitioner_def.hpp:50
Create overlapping partitions of a local graph.
Definition Ifpack2_OverlappingPartitioner_decl.hpp:45
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40