43 #ifndef IFPACK2_LINE_PARTITIONER_DEF_HPP 44 #define IFPACK2_LINE_PARTITIONER_DEF_HPP 46 #include "Tpetra_CrsGraph.hpp" 47 #include "Tpetra_Util.hpp" 52 inline typename Teuchos::ScalarTraits<T>::magnitudeType square(T x) {
53 return Teuchos::ScalarTraits<T>::magnitude(x) * Teuchos::ScalarTraits<T>::magnitude(x);
58 template<
class GraphType,
class Scalar>
65 template<
class GraphType,
class Scalar>
69 template<
class GraphType,
class Scalar>
73 threshold_ = List.get(
"partitioner: line detection threshold",threshold_);
74 TEUCHOS_TEST_FOR_EXCEPTION(threshold_ < Teuchos::ScalarTraits<MT>::zero() || threshold_ > Teuchos::ScalarTraits<MT>::one(),
75 std::runtime_error,
"Ifpack2::LinePartitioner: threshold not valid");
77 NumEqns_ = List.get(
"partitioner: PDE equations",NumEqns_);
78 TEUCHOS_TEST_FOR_EXCEPTION(NumEqns_<1,std::runtime_error,
"Ifpack2::LinePartitioner: NumEqns not valid");
80 coord_ = List.get(
"partitioner: coordinates",coord_);
81 TEUCHOS_TEST_FOR_EXCEPTION(coord_.is_null(),std::runtime_error,
"Ifpack2::LinePartitioner: coordinates not defined");
85 template<
class GraphType,
class Scalar>
87 const local_ordinal_type invalid = Teuchos::OrdinalTraits<local_ordinal_type>::invalid();
90 TEUCHOS_TEST_FOR_EXCEPTION(coord_.is_null(),std::runtime_error,
"Ifpack2::LinePartitioner: coordinates not defined");
91 TEUCHOS_TEST_FOR_EXCEPTION((
size_t)this->Partition_.size() != this->Graph_->getNodeNumRows(),std::runtime_error,
"Ifpack2::LinePartitioner: partition size error");
94 if(this->Partition_.size() == 0) {this->NumLocalParts_ = 0;
return;}
97 for(
size_t i=0; i<this->Graph_->getNodeNumRows(); i++)
98 this->Partition_[i] = invalid;
101 this->NumLocalParts_ = this->Compute_Blocks_AutoLine(this->Partition_());
104 this->Parts_.resize(this->NumLocalParts_);
109 template<
class GraphType,
class Scalar>
111 typedef local_ordinal_type LO;
112 const LO invalid = Teuchos::OrdinalTraits<LO>::invalid();
113 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
114 const MT mzero = Teuchos::ScalarTraits<MT>::zero();
116 Teuchos::ArrayRCP<const Scalar> xvalsRCP, yvalsRCP, zvalsRCP;
117 Teuchos::ArrayView<const Scalar> xvals, yvals, zvals;
118 xvalsRCP = coord_->getData(0); xvals = xvalsRCP();
119 if(coord_->getNumVectors() > 1) { yvalsRCP = coord_->getData(1); yvals = yvalsRCP(); }
120 if(coord_->getNumVectors() > 2) { zvalsRCP = coord_->getData(2); zvals = zvalsRCP(); }
123 size_t N = this->Graph_->getNodeNumRows();
124 size_t allocated_space = this->Graph_->getNodeMaxNumRowEntries();
126 Teuchos::Array<LO> cols(allocated_space);
127 Teuchos::Array<LO> indices(allocated_space);
128 Teuchos::Array<MT> dist(allocated_space);
130 Teuchos::Array<LO> itemp(2*allocated_space);
131 Teuchos::Array<MT> dtemp(allocated_space);
135 for(LO i=0; i<(LO)N; i+=NumEqns_) {
138 if(blockIndices[i] != invalid)
continue;
141 this->Graph_->getLocalRowCopy(i,cols(),nz);
142 Scalar x0 = (!xvals.is_null()) ? xvals[i/NumEqns_] : zero;
143 Scalar y0 = (!yvals.is_null()) ? yvals[i/NumEqns_] : zero;
144 Scalar z0 = (!zvals.is_null()) ? zvals[i/NumEqns_] : zero;
147 for(
size_t j=0; j<nz; j+=NumEqns_) {
149 LO nn = cols[j] / NumEqns_;
150 if(cols[j] >=(LO)N)
continue;
151 if(!xvals.is_null()) mydist += square<Scalar>(x0 - xvals[nn]);
152 if(!yvals.is_null()) mydist += square<Scalar>(y0 - yvals[nn]);
153 if(!zvals.is_null()) mydist += square<Scalar>(z0 - zvals[nn]);
154 dist[neighbor_len] = Teuchos::ScalarTraits<MT>::squareroot(mydist);
155 indices[neighbor_len]=cols[j];
159 Teuchos::ArrayView<MT> dist_view = dist(0,neighbor_len);
160 Tpetra::sort2(dist_view.begin(),dist_view.end(),indices.begin());
163 for(LO k=0; k<NumEqns_; k++)
164 blockIndices[i + k] = num_lines;
167 if(neighbor_len > 2 && dist[1]/dist[neighbor_len-1] < tol) {
168 local_automatic_line_search(NumEqns_,blockIndices,i,indices[1],num_lines,tol,itemp,dtemp);
171 if(neighbor_len > 3 && dist[2]/dist[neighbor_len-1] < tol) {
172 local_automatic_line_search(NumEqns_,blockIndices,i,indices[2],num_lines,tol,itemp,dtemp);
180 template<
class GraphType,
class Scalar>
181 void 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, MT tol, Teuchos::Array<local_ordinal_type> itemp, Teuchos::Array<MT> dtemp)
const {
182 typedef local_ordinal_type LO;
183 const LO invalid = Teuchos::OrdinalTraits<LO>::invalid();
184 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
185 const MT mzero = Teuchos::ScalarTraits<MT>::zero();
187 Teuchos::ArrayRCP<const Scalar> xvalsRCP, yvalsRCP, zvalsRCP;
188 Teuchos::ArrayView<const Scalar> xvals, yvals, zvals;
189 xvalsRCP = coord_->getData(0); xvals = xvalsRCP();
190 if(coord_->getNumVectors() > 1) { yvalsRCP = coord_->getData(1); yvals = yvalsRCP(); }
191 if(coord_->getNumVectors() > 2) { zvalsRCP = coord_->getData(2); zvals = zvalsRCP(); }
193 size_t N = this->Graph_->getNodeNumRows();
194 size_t allocated_space = this->Graph_->getNodeMaxNumRowEntries();
195 Teuchos::ArrayView<LO> cols = itemp();
196 Teuchos::ArrayView<LO> indices = itemp.view(allocated_space,allocated_space);
197 Teuchos::ArrayView<MT> dist= dtemp();
199 while (blockIndices[next] == invalid) {
202 LO neighbors_in_line=0;
204 this->Graph_->getLocalRowCopy(next,cols(),nz);
205 Scalar x0 = (!xvals.is_null()) ? xvals[next/NumEqns_] : zero;
206 Scalar y0 = (!yvals.is_null()) ? yvals[next/NumEqns_] : zero;
207 Scalar z0 = (!zvals.is_null()) ? zvals[next/NumEqns_] : zero;
211 for(
size_t i=0; i<nz; i+=NumEqns) {
213 if(cols[i] >=(LO)N)
continue;
214 LO nn = cols[i] / NumEqns;
215 if(blockIndices[nn]==LineID) neighbors_in_line++;
216 if(!xvals.is_null()) mydist += square<Scalar>(x0 - xvals[nn]);
217 if(!yvals.is_null()) mydist += square<Scalar>(y0 - yvals[nn]);
218 if(!zvals.is_null()) mydist += square<Scalar>(z0 - zvals[nn]);
219 dist[neighbor_len] = Teuchos::ScalarTraits<MT>::squareroot(mydist);
220 indices[neighbor_len]=cols[i];
225 if(neighbors_in_line > 1)
break;
228 for(LO k=0; k<NumEqns; k++)
229 blockIndices[next + k] = LineID;
232 Teuchos::ArrayView<MT> dist_view = dist(0,neighbor_len);
233 Tpetra::sort2(dist_view.begin(),dist_view.end(),indices.begin());
235 if(neighbor_len > 2 && indices[1] != last && blockIndices[indices[1]] == -1 && dist[1]/dist[neighbor_len-1] < tol) {
239 else if(neighbor_len > 3 && indices[2] != last && blockIndices[indices[2]] == -1 && dist[2]/dist[neighbor_len-1] < tol) {
254 #define IFPACK2_LINEPARTITIONER_INSTANT(S,LO,GO,N) \ 255 template class Ifpack2::LinePartitioner<Tpetra::CrsGraph< LO, GO, N >,S >; \ 256 template class Ifpack2::LinePartitioner<Tpetra::RowGraph< LO, GO, N >,S >; 258 #endif // IFPACK2_LINEPARTITIONER_DEF_HPP LinePartitioner(const Teuchos::RCP< const row_graph_type > &graph)
Constructor.
Definition: Ifpack2_LinePartitioner_def.hpp:60
void computePartitions()
Compute the partitions.
Definition: Ifpack2_LinePartitioner_def.hpp:86
virtual ~LinePartitioner()
Destructor.
Definition: Ifpack2_LinePartitioner_def.hpp:66
Definition: Ifpack2_Container.hpp:761
Create overlapping partitions of a local graph.
Definition: Ifpack2_OverlappingPartitioner_decl.hpp:78
void setPartitionParameters(Teuchos::ParameterList &List)
Set the partitioner's parameters (none for linear partitioning).
Definition: Ifpack2_LinePartitioner_def.hpp:72
Preconditioners and smoothers for Tpetra sparse matrices.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:72
Ifpack2::LinePartitioner: A class to define partitions into a set of lines.
Definition: Ifpack2_LinePartitioner_decl.hpp:77