7 #ifndef BELOSLINEARPROBLEM_HH_
8 #define BELOSLINEARPROBLEM_HH_
13 #include <BelosLinearProblem.hpp>
14 #include <Tpetra_CrsMatrix.hpp>
24 template<
class T,
class MV = Tpetra::MultiVector<T,
int>,
25 class OP = Tpetra::Operator<T> >
49 BelosLinProb(Teuchos::RCP<
const Teuchos::Comm<int> > comm);
62 Teuchos::RCP<
const Teuchos::Comm<int> > comm);
75 Teuchos::RCP<
const Teuchos::Comm<int> > comm);
96 Teuchos::RCP<
const Teuchos::Comm<int> > comm);
106 void writeSolution(Teuchos::RCP<
const Teuchos::Comm<int> > comm);
109 Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> >
getCrsMat() {
114 void setCrsMat(Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> > A) {
116 this->setOperator(
A_);
122 Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> >
A_;
125 template<
class T,
class MV,
class OP>
127 Teuchos::RCP<
const Teuchos::Comm<int> > Comm) {
130 int MyPID = Comm->getRank();
131 int NumProc = Comm->getSize();
157 globalSize = sparse.nofRows();
160 Comm->broadcast(0,
sizeof(
int), (
char*) (&globalSize));
164 int restsize = globalSize;
165 for(
int i = 0; i < NumProc; ++i)
166 restsize -= (localSizes[i] = restsize / (NumProc - i));
167 DEBUGL(0,
"localSizes = " << localSizes);
170 int bias = localSizes[MyPID];
173 for (
int i = 1; i < NumProc; ++i) {
175 localSize = localSizes[i];
177 nnzPerRow =
new int[localSize];
180 nnzPerRowIter = nnzPerRow;
182 DEBUGL(0,
"localSize = " << localSize);
183 DEBUGL(0,
"bias = " << bias);
186 for (uint j = 0; j < (uint) localSize; ++j) {
188 iter = sparse.
begin(j + bias);
189 while (iter != sparse.
end() && (iter++).row() == (j + bias))
195 Comm->send(localSize *
sizeof(
int), (
char*) nnzPerRow, i);
198 nnzPerRowIter = nnzPerRow;
199 for (
int j = 0; j < localSize; ++j)
200 localNnz += *nnzPerRowIter++;
205 val =
new T[localNnz];
206 col =
new int[localNnz];
211 for (uint j = 0; j < (uint) localSize; ++j) {
212 iter = sparse.
begin(j + bias);
213 while (iter.
row() == (j + bias) && (iter != sparse.
end())) {
214 *colIter++ = iter.
col();
215 *valIter++ = *iter++;
220 Comm->send(localNnz *
sizeof(T), (
char*) val, i);
221 Comm->send(localNnz *
sizeof(
int), (
char*) col, i);
235 localSize = localSizes[0];
238 nnzPerRow =
new int[localSize];
241 nnzPerRowIter = nnzPerRow;
242 iter = sparse.
begin(0);
245 for (uint i = 0; i < (uint) localSize; ++i) {
247 iter = sparse.
begin(i);
248 while (iter != sparse.
end() && (iter++).row() == i)
254 nnzPerRowIter = nnzPerRow;
255 for (
int i = 0; i < localSize; ++i) {
256 max_ = std::max(max_, *nnzPerRowIter);
257 localNnz += *nnzPerRowIter++;
260 val =
new T[localNnz];
261 col =
new int[localNnz];
266 for (uint i = 0; i < (uint) localSize; ++i) {
267 iter = sparse.
begin(i);
268 while (iter.
row() == i && (iter != sparse.
end())) {
269 *colIter++ = iter.
col();
270 *valIter++ = *iter++;
280 Teuchos::RCP<const Tpetra::Map<int, int> > mapStiffRow =
281 Tpetra::createContigMap<int, int>(globalSize, localSize, Comm);
284 A_ = Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> >(
285 new Tpetra::CrsMatrix<T, int, int>(mapStiffRow, max_));
287 Teuchos::RCP<Tpetra::MultiVector<T, int> > sol(
288 new Tpetra::MultiVector<T, int>(mapStiffRow, 1));
289 Teuchos::RCP<Tpetra::MultiVector<T, int> > rhs2(
290 new Tpetra::MultiVector<T, int>(mapStiffRow, 1));
293 nnzPerRowIter = nnzPerRow;
299 for (
int k = 0; k < localSize; ++k) {
300 globalIndex = mapStiffRow->getGlobalElement(k);
301 currNnz = *nnzPerRowIter;
303 A_->insertGlobalValues(globalIndex,
304 Teuchos::ArrayView<int>(colIter, currNnz),
305 Teuchos::ArrayView<T>(valIter, currNnz));
318 this->setOperator(A_);
322 template<
class T,
class MV,
class OP>
324 Teuchos::RCP<
const Teuchos::Comm<int> > Comm) {
327 int MyPID = Comm->getRank();
328 int NumProc = Comm->getSize();
332 throw std::logic_error(
"The first thread needs a Matrix");
352 Comm->broadcast(0,
sizeof(
int), (
char*) (&globalSize));
356 int restsize = globalSize;
357 for(
int i = 0; i < NumProc; ++i)
358 restsize -= (localSizes[i] = restsize / (NumProc - i));
359 DEBUGL(0,
"localSizes = " << localSizes);
362 localSize = localSizes[MyPID];
365 nnzPerRow =
new int[localSize];
366 nnzPerRowIter = nnzPerRow;
367 Comm->receive(0, localSize *
sizeof(
int), (
char*) nnzPerRow);
368 max_ = *nnzPerRowIter;
369 for (
int i = 0; i < localSize; ++i) {
370 max_ = std::max(max_, *nnzPerRowIter);
371 localNnz += *nnzPerRowIter++;
374 col =
new int[localNnz];
375 val =
new T[localNnz];
378 Comm->receive(0, localNnz *
sizeof(T), (
char*) val);
379 Comm->receive(0, localNnz *
sizeof(
int), (
char*) col);
387 Teuchos::RCP<const Tpetra::Map<int, int> > mapStiffRow =
388 Tpetra::createContigMap<int, int>(globalSize, localSize, Comm);
391 A_ = Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> >(
392 new Tpetra::CrsMatrix<T, int, int>(mapStiffRow, max_));
395 nnzPerRowIter = nnzPerRow;
401 for (
int k = 0; k < localSize; ++k) {
402 globalIndex = mapStiffRow->getGlobalElement(k);
403 currNnz = *nnzPerRowIter;
405 A_->insertGlobalValues(globalIndex,
406 Teuchos::ArrayView<int>(colIter, currNnz),
407 Teuchos::ArrayView<T>(valIter, currNnz));
420 this->setOperator(A_);
424 template<
class T,
class MV,
class OP>
426 Teuchos::RCP<
const Teuchos::Comm<int> > Comm) {
429 int MyPID = Comm->getRank();
430 int NumProc = Comm->getSize();
435 int globalSize = vec.
size();
438 Comm->broadcast(0,
sizeof(
int), (
char*) (&globalSize));
442 int restsize = globalSize;
443 for(
int i = 0; i < NumProc; ++i)
444 restsize -= (localSizes[i] = restsize / (NumProc - i));
445 DEBUGL(0,
"localSizes = " << localSizes);
448 int bias = localSizes[MyPID];
450 for (
int i = 1; i < NumProc; ++i) {
451 int localSize = localSizes[i];;
452 rhsVal =
new T[localSize];
454 vecIter = &(vec[bias]);
455 for (
int j = 0; j < localSize; ++j)
456 *rhsValIter++ = *vecIter++;
458 Comm->send(localSize *
sizeof(T), (
char*) rhsVal, i);
465 int localSize = localSizes[MyPID];
466 rhsVal =
new T[localSize];
469 for (
int j = 0; j < localSize; ++j)
470 *rhsValIter++ = *vecIter++;
472 Teuchos::RCP<Tpetra::MultiVector<T, int> > rhs2(
473 new Tpetra::MultiVector<T, int>(A_->getRowMap(), 1));
475 Teuchos::RCP<Tpetra::MultiVector<T, int> > sol(
476 new Tpetra::MultiVector<T, int>(A_->getRowMap(), 1));
479 for (
int k = 0; k < localSize; ++k) {
480 sol->replaceGlobalValue((A_->getRowMap())->getGlobalElement(k), 0,
482 rhs2->replaceGlobalValue((A_->getRowMap())->getGlobalElement(k), 0,
493 template<
class T,
class MV,
class OP>
495 Teuchos::RCP<
const Teuchos::Comm<int> > Comm) {
498 int MyPID = Comm->getRank();
499 int NumProc = Comm->getSize();
506 Comm->broadcast(0,
sizeof(
int), (
char*) (&globalSize));
510 int restsize = globalSize;
511 for(
int i = 0; i < NumProc; ++i)
512 restsize -= (localSizes[i] = restsize / (NumProc - i));
513 DEBUGL(0,
"localSizes = " << localSizes);
516 int localSize = localSizes[MyPID];
518 rhsVal =
new T[localSize];
519 Comm->receive(0, localSize *
sizeof(T), (
char*) rhsVal);
521 Teuchos::RCP<Tpetra::MultiVector<T, int> > rhs2(
522 new Tpetra::MultiVector<T, int>(A_->getRowMap(), 1));
524 Teuchos::RCP<Tpetra::MultiVector<T, int> > sol(
525 new Tpetra::MultiVector<T, int>(A_->getRowMap(), 1));
528 for (
int k = 0; k < localSize; ++k) {
529 sol->replaceGlobalValue((A_->getRowMap())->getGlobalElement(k), 0,
531 rhs2->replaceGlobalValue((A_->getRowMap())->getGlobalElement(k), 0,
542 template<
class T,
class MV,
class OP>
544 Teuchos::RCP<
const Teuchos::Comm<int> > Comm) {
546 int MyPID = Comm->getRank();
547 int NumProc = Comm->getSize();
548 int globalSize = sol.
size();
552 int restsize = globalSize;
553 for(
int i = 0; i < NumProc; ++i)
554 restsize -= (localSizes[i] = restsize / (NumProc - i));
555 DEBUGL(0,
"localSizes = " << localSizes);
558 int localSize = localSizes[MyPID];
560 T *solutionData =
new T[globalSize];
561 memcpy(solutionData, (this->getLHS()->get1dViewNonConst()).get(),
562 sizeof(T) * localSize);
566 int bias = localSize;
567 for (
int i = 1; i < NumProc; ++i) {
568 ith_size = localSizes[i];
569 Comm->receive(i,
sizeof(T) * ith_size,
570 (
char*) (solutionData + bias));
573 T * solutionDataIter = solutionData;
574 for (
int i = 0; i < sol.
size(); ++i) {
575 sol[i] = *solutionDataIter++;
577 delete[] solutionData;
580 template<
class T,
class MV,
class OP>
582 Teuchos::RCP<
const Teuchos::Comm<int> > Comm) {
584 int MyPID = Comm->getRank();
585 int NumProc = Comm->getSize();
586 int globalSize = A_->getRowMap()->getGlobalNumElements();
590 int restsize = globalSize;
591 for(
int i = 0; i < NumProc; ++i)
592 restsize -= (localSizes[i] = restsize / (NumProc - i));
593 DEBUGL(0,
"localSizes = " << localSizes);
596 int localSize = localSizes[MyPID];
598 Comm->send(
sizeof(T) * localSize,
599 (
const char*) (this->getLHS()->get1dViewNonConst()).get(), 0);