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>
36template<
class GraphType,
class Scalar>
40 threshold_ = List.get(
"partitioner: line detection threshold",threshold_);
41 TEUCHOS_TEST_FOR_EXCEPTION(threshold_ < 0.0 || threshold_ > 1.0,
42 std::runtime_error,
"Ifpack2::LinePartitioner: threshold not valid");
44 NumEqns_ = List.get(
"partitioner: PDE equations",NumEqns_);
45 TEUCHOS_TEST_FOR_EXCEPTION(NumEqns_<1,std::runtime_error,
"Ifpack2::LinePartitioner: NumEqns not valid");
47 coord_ = List.get(
"partitioner: coordinates",coord_);
48 TEUCHOS_TEST_FOR_EXCEPTION(coord_.is_null(),std::runtime_error,
"Ifpack2::LinePartitioner: coordinates not defined");
52template<
class GraphType,
class Scalar>
54 const local_ordinal_type invalid = Teuchos::OrdinalTraits<local_ordinal_type>::invalid();
57 TEUCHOS_TEST_FOR_EXCEPTION(coord_.is_null(),std::runtime_error,
"Ifpack2::LinePartitioner: coordinates not defined");
58 TEUCHOS_TEST_FOR_EXCEPTION((
size_t)this->
Partition_.size() != this->Graph_->getLocalNumRows(),std::runtime_error,
"Ifpack2::LinePartitioner: partition size error");
64 for(
size_t i=0; i<this->
Graph_->getLocalNumRows(); i++)
76template<
class GraphType,
class Scalar>
77int LinePartitioner<GraphType,Scalar>::Compute_Blocks_AutoLine(Teuchos::ArrayView<local_ordinal_type> blockIndices)
const {
79 typedef magnitude_type MT;
80 const LO invalid = Teuchos::OrdinalTraits<LO>::invalid();
81 const MT zero = Teuchos::ScalarTraits<MT>::zero();
83 Teuchos::ArrayRCP<const MT> xvalsRCP, yvalsRCP, zvalsRCP;
84 Teuchos::ArrayView<const MT> xvals, yvals, zvals;
85 xvalsRCP = coord_->getData(0); xvals = xvalsRCP();
86 if(coord_->getNumVectors() > 1) { yvalsRCP = coord_->getData(1); yvals = yvalsRCP(); }
87 if(coord_->getNumVectors() > 2) { zvalsRCP = coord_->getData(2); zvals = zvalsRCP(); }
89 double tol = threshold_;
90 size_t N = this->Graph_->getLocalNumRows();
91 size_t allocated_space = this->Graph_->getLocalMaxNumRowEntries();
93 nonconst_local_inds_host_view_type cols(
"cols",allocated_space);
94 Teuchos::Array<LO> indices(allocated_space);
95 Teuchos::Array<MT> dist(allocated_space);
97 Teuchos::Array<LO> itemp(2*allocated_space);
98 Teuchos::Array<MT> dtemp(allocated_space);
102 for(LO i=0; i<(LO)N; i+=NumEqns_) {
105 if(blockIndices[i] != invalid)
continue;
108 this->Graph_->getLocalRowCopy(i,cols,nz);
109 MT x0 = (!xvals.is_null()) ? xvals[i/NumEqns_] : zero;
110 MT y0 = (!yvals.is_null()) ? yvals[i/NumEqns_] : zero;
111 MT z0 = (!zvals.is_null()) ? zvals[i/NumEqns_] : zero;
114 for(
size_t j=0; j<nz; j+=NumEqns_) {
116 LO nn = cols[j] / NumEqns_;
117 if(cols[j] >=(LO)N)
continue;
118 if(!xvals.is_null()) mydist += square<MT>(x0 - xvals[nn]);
119 if(!yvals.is_null()) mydist += square<MT>(y0 - yvals[nn]);
120 if(!zvals.is_null()) mydist += square<MT>(z0 - zvals[nn]);
121 dist[neighbor_len] = Teuchos::ScalarTraits<MT>::squareroot(mydist);
122 indices[neighbor_len]=cols[j];
126 Teuchos::ArrayView<MT> dist_view = dist(0,neighbor_len);
127 Tpetra::sort2(dist_view.begin(),dist_view.end(),indices.begin());
130 for(LO k=0; k<NumEqns_; k++)
131 blockIndices[i + k] = num_lines;
134 if(neighbor_len > 2 && dist[1]/dist[neighbor_len-1] < tol) {
135 local_automatic_line_search(NumEqns_,blockIndices,i,indices[1],num_lines,tol,itemp,dtemp);
138 if(neighbor_len > 3 && dist[2]/dist[neighbor_len-1] < tol) {
139 local_automatic_line_search(NumEqns_,blockIndices,i,indices[2],num_lines,tol,itemp,dtemp);
147template<
class GraphType,
class Scalar>
148void 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 {
150 typedef magnitude_type MT;
151 const LO invalid = Teuchos::OrdinalTraits<LO>::invalid();
152 const MT zero = Teuchos::ScalarTraits<MT>::zero();
154 Teuchos::ArrayRCP<const MT> xvalsRCP, yvalsRCP, zvalsRCP;
155 Teuchos::ArrayView<const MT> xvals, yvals, zvals;
156 xvalsRCP = coord_->getData(0); xvals = xvalsRCP();
157 if(coord_->getNumVectors() > 1) { yvalsRCP = coord_->getData(1); yvals = yvalsRCP(); }
158 if(coord_->getNumVectors() > 2) { zvalsRCP = coord_->getData(2); zvals = zvalsRCP(); }
160 size_t N = this->Graph_->getLocalNumRows();
161 size_t allocated_space = this->Graph_->getLocalMaxNumRowEntries();
163 nonconst_local_inds_host_view_type cols(itemp.data(),allocated_space);
164 Teuchos::ArrayView<LO> indices = itemp.view(allocated_space,allocated_space);
165 Teuchos::ArrayView<MT> dist= dtemp();
167 while (blockIndices[next] == invalid) {
170 LO neighbors_in_line=0;
172 this->Graph_->getLocalRowCopy(next,cols,nz);
173 MT x0 = (!xvals.is_null()) ? xvals[next/NumEqns_] : zero;
174 MT y0 = (!yvals.is_null()) ? yvals[next/NumEqns_] : zero;
175 MT z0 = (!zvals.is_null()) ? zvals[next/NumEqns_] : zero;
179 for(
size_t i=0; i<nz; i+=NumEqns) {
181 if(cols[i] >=(LO)N)
continue;
182 LO nn = cols[i] / NumEqns;
183 if(blockIndices[nn]==LineID) neighbors_in_line++;
184 if(!xvals.is_null()) mydist += square<MT>(x0 - xvals[nn]);
185 if(!yvals.is_null()) mydist += square<MT>(y0 - yvals[nn]);
186 if(!zvals.is_null()) mydist += square<MT>(z0 - zvals[nn]);
187 dist[neighbor_len] = Teuchos::ScalarTraits<MT>::squareroot(mydist);
188 indices[neighbor_len]=cols[i];
193 if(neighbors_in_line > 1)
break;
196 for(LO k=0; k<NumEqns; k++)
197 blockIndices[next + k] = LineID;
200 Teuchos::ArrayView<MT> dist_view = dist(0,neighbor_len);
201 Tpetra::sort2(dist_view.begin(),dist_view.end(),indices.begin());
203 if(neighbor_len > 2 && indices[1] != last && blockIndices[indices[1]] == -1 && dist[1]/dist[neighbor_len-1] < tol) {
207 else if(neighbor_len > 3 && indices[2] != last && blockIndices[indices[2]] == -1 && dist[2]/dist[neighbor_len-1] < tol) {
222#define IFPACK2_LINEPARTITIONER_INSTANT(S,LO,GO,N) \
223 template class Ifpack2::LinePartitioner<Tpetra::CrsGraph< LO, GO, N >,S >; \
224 template class Ifpack2::LinePartitioner<Tpetra::RowGraph< LO, GO, N >,S >;
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:39
virtual ~LinePartitioner()
Destructor.
Definition Ifpack2_LinePartitioner_def.hpp:33
void computePartitions()
Compute the partitions.
Definition Ifpack2_LinePartitioner_def.hpp:53
Teuchos::Array< local_ordinal_type > Partition_
Mapping from local row to partition number.
Definition Ifpack2_OverlappingPartitioner_decl.hpp:145
OverlappingPartitioner(const Teuchos::RCP< const row_graph_type > &graph)
Constructor.
Definition Ifpack2_OverlappingPartitioner_def.hpp:24
Teuchos::RCP< const row_graph_type > Graph_
The graph to be partitioned.
Definition Ifpack2_OverlappingPartitioner_decl.hpp:155
Teuchos::Array< Teuchos::ArrayRCP< local_ordinal_type > > Parts_
Mapping from partition to all rows it contains.
Definition Ifpack2_OverlappingPartitioner_decl.hpp:152
int NumLocalParts_
Number of local subgraphs.
Definition Ifpack2_OverlappingPartitioner_decl.hpp:138
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:41