134 this->GetOStream(
Warnings0) <<
"MueLu::Amesos2Smoother::Setup(): Setup() has already been called" << std::endl;
136 RCP<Matrix> A = Factory::Get< RCP<Matrix> >(currentLevel,
"A");
139 RCP<const Map> rowMap = A->getRowMap();
141 Teuchos::ParameterList pL = this->GetParameterList();
142 if (pL.get<
bool>(
"fix nullspace")) {
143 this->GetOStream(
Runtime1) <<
"MueLu::Amesos2Smoother::Setup(): fixing nullspace" << std::endl;
145 rowMap = A->getRowMap();
146 size_t M = rowMap->getGlobalNumElements();
148 RCP<MultiVector> Nullspace = Factory::Get< RCP<MultiVector> >(currentLevel,
"Nullspace");
151 "MueLu::Amesos2Smoother::Setup Fixing nullspace for coarse matrix for Amesos2 for nullspace of dim > 1 has not been implemented yet.");
153 RCP<MultiVector> NullspaceImp;
154 RCP<const Map> colMap;
155 RCP<const Import> importer;
156 if (rowMap->getComm()->getSize() > 1) {
157 this->GetOStream(
Warnings0) <<
"MueLu::Amesos2Smoother::Setup(): Applying nullspace fix on distributed matrix. Try rebalancing to single rank!" << std::endl;
158 ArrayRCP<GO> elements_RCP;
159 elements_RCP.resize(M);
160 ArrayView<GO> elements = elements_RCP();
161 for (
size_t k = 0; k<M; k++)
162 elements[k] = Teuchos::as<GO>(k);
163 colMap = MapFactory::Build(rowMap->lib(),M*rowMap->getComm()->getSize(),elements,Teuchos::ScalarTraits<GO>::zero(),rowMap->getComm());
164 importer = ImportFactory::Build(rowMap,colMap);
165 NullspaceImp = MultiVectorFactory::Build(colMap, Nullspace->getNumVectors());
166 NullspaceImp->doImport(*Nullspace,*importer,Xpetra::INSERT);
168 NullspaceImp = Nullspace;
172 ArrayRCP<const SC> nullspaceRCP, nullspaceImpRCP;
173 RCP<CrsMatrixWrap> Acrs = rcp_dynamic_cast<CrsMatrixWrap>(A);
176 "MueLu::Amesos2Smoother::Setup Fixing nullspace for coarse matrix for Amesos2 when matrix is not a Crs matrix has not been implemented yet.");
178 ArrayRCP<const size_t> rowPointers;
179 ArrayRCP<const LO> colIndices;
180 ArrayRCP<const SC> values;
181 Acrs->getCrsMatrix()->getAllValues(rowPointers, colIndices, values);
183 ArrayRCP<size_t> newRowPointers_RCP;
184 ArrayRCP<LO> newColIndices_RCP;
185 ArrayRCP<SC> newValues_RCP;
187 size_t N = rowMap->getNodeNumElements();
188 newRowPointers_RCP.resize(N+1);
189 newColIndices_RCP.resize(N*M);
190 newValues_RCP.resize(N*M);
192 ArrayView<size_t> newRowPointers = newRowPointers_RCP();
193 ArrayView<LO> newColIndices = newColIndices_RCP();
194 ArrayView<SC> newValues = newValues_RCP();
196 SC normalization = Nullspace->getVector(0)->norm2();
197 normalization = Teuchos::ScalarTraits<Scalar>::one()/(normalization*normalization);
199 ArrayView<const SC> nullspace, nullspaceImp;
200 nullspaceRCP = Nullspace->getData(0);
201 nullspace = nullspaceRCP();
202 nullspaceImpRCP = NullspaceImp->getData(0);
203 nullspaceImp = nullspaceImpRCP();
206 for (
size_t i = 0; i < N; i++) {
207 newRowPointers[i] = i*M;
208 for (
size_t j = 0; j < M; j++) {
209 newColIndices[i*M+j] = Teuchos::as<LO>(j);
210 newValues[i*M+j] = normalization * nullspace[i]*Teuchos::ScalarTraits<Scalar>::conjugate(nullspaceImp[j]);
213 newRowPointers[N] = N*M;
216 for (
size_t i = 0; i < N; i++) {
217 for (
size_t jj = rowPointers[i]; jj < rowPointers[i+1]; jj++) {
218 LO j = colMap->getLocalElement(A->getColMap()->getGlobalElement(colIndices[jj]));
220 newValues[i*M+j] += v;
224 RCP<Matrix> newA = rcp(
new CrsMatrixWrap(rowMap, colMap, 0));
225 RCP<CrsMatrix> newAcrs = rcp_dynamic_cast<CrsMatrixWrap>(newA)->getCrsMatrix();
227 using Teuchos::arcp_const_cast;
228 newAcrs->setAllValues(arcp_const_cast<size_t>(newRowPointers_RCP), arcp_const_cast<LO>(newColIndices_RCP), arcp_const_cast<SC>(newValues_RCP));
229 newAcrs->expertStaticFillComplete(A->getDomainMap(), A->getRangeMap(),
230 importer, A->getCrsGraph()->getExporter());
239 prec_ = Amesos2::create<Tpetra_CrsMatrix,Tpetra_MultiVector>(type_, tA);
240 TEUCHOS_TEST_FOR_EXCEPTION(prec_ == Teuchos::null,
Exceptions::RuntimeError,
"Amesos2::create returns Teuchos::null");
241 if (rowMap->getGlobalNumElements() != as<size_t>((rowMap->getMaxAllGlobalIndex() - rowMap->getMinAllGlobalIndex())+1)) {
242 auto amesos2_params = Teuchos::rcp(
new Teuchos::ParameterList(
"Amesos2"));
243 amesos2_params->sublist(prec_->name()).set(
"IsContiguous",
false,
"Are GIDs Contiguous");
244 prec_->setParameters(amesos2_params);
254 RCP<Tpetra_MultiVector> tX, tB;
255 if (!useTransformation_) {
260 size_t numVectors = X.getNumVectors();
261 size_t length = X.getLocalLength();
264 "MueLu::Amesos2Smoother::Apply: Fixing coarse matrix for Amesos2 for multivectors has not been implemented yet.");
265 ArrayRCP<const SC> Xdata = X. getData(0), Bdata = B. getData(0);
266 ArrayRCP<SC> X_data = X_->getDataNonConst(0), B_data = B_->getDataNonConst(0);
268 for (
size_t i = 0; i < length; i++) {
269 X_data[i] = Xdata[i];
270 B_data[i] = Bdata[i];
282 prec_->setX(Teuchos::null);
283 prec_->setB(Teuchos::null);
285 if (useTransformation_) {
287 size_t length = X.getLocalLength();
289 ArrayRCP<SC> Xdata = X. getDataNonConst(0);
290 ArrayRCP<const SC> X_data = X_->getData(0);
292 for (
size_t i = 0; i < length; i++)
293 Xdata[i] = X_data[i];