46 #ifndef MUELU_REFMAXWELL_DEF_HPP 47 #define MUELU_REFMAXWELL_DEF_HPP 53 #include "Xpetra_Map.hpp" 54 #include "Xpetra_MatrixMatrix.hpp" 57 #include "MueLu_UncoupledAggregationFactory.hpp" 58 #include "MueLu_TentativePFactory.hpp" 59 #include "MueLu_SaPFactory.hpp" 60 #include "MueLu_SmootherFactory.hpp" 61 #include "MueLu_Utilities.hpp" 63 #include "MueLu_MLParameterListInterpreter.hpp" 64 #include "MueLu_ParameterListInterpreter.hpp" 69 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
71 return SM_Matrix_->getDomainMap();
74 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
76 return SM_Matrix_->getRangeMap();
79 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
82 disable_addon_ = list.get(
"refmaxwell: disable add-on",
true);
83 mode_ = list.get(
"refmaxwell: mode",
"additive");
85 if(list.isSublist(
"refmaxwell: 11list"))
86 precList11_ = list.sublist(
"refmaxwell: 11list");
88 if(list.isSublist(
"refmaxwell: 22list"))
89 precList22_ = list.sublist(
"refmaxwell: 22list");
91 std::string ref(
"smoother:");
92 std::string replace(
"coarse:");
93 for(Teuchos::ParameterList::ConstIterator i=list.begin(); i !=list.end(); i++) {
94 const std::string & pname = list.name(i);
95 if(pname.find(ref)!=std::string::npos) {
96 smootherList_.setEntry(pname,list.entry(i));
97 std::string coarsename(pname);
98 coarsename.replace((
size_t)0,(
size_t)ref.length(),replace);
101 if(list.isSublist(
"smoother: params")) {
102 smootherList_.set(
"coarse: params",list.sublist(
"smoother: params"));
104 smootherList_.set(
"max levels",1);
108 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
111 Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
112 out.setOutputToRootOnly(0);
113 out.setShowProcRank(
true);
116 findDirichletRows(SM_Matrix_,BCrows_);
117 findDirichletCols(D0_Matrix_,BCrows_,BCcols_);
118 D0_Matrix_->resumeFill();
119 Apply_BCsToMatrixRows(D0_Matrix_,BCrows_);
120 Apply_BCsToMatrixCols(D0_Matrix_,BCcols_);
121 D0_Matrix_->fillComplete(D0_Matrix_->getDomainMap(),D0_Matrix_->getRangeMap());
125 Teuchos::RCP<Matrix> C1 = MatrixFactory::Build(SM_Matrix_->getRowMap(),0);
126 TMT_Matrix_=MatrixFactory::Build(D0_Matrix_->getDomainMap(),0);
127 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*SM_Matrix_,
false,*D0_Matrix_,
false,*C1,
true,
true);
128 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*D0_Matrix_,
true,*C1,
false,*TMT_Matrix_,
true,
true);
129 TMT_Matrix_->resumeFill();
130 Remove_Zeroed_Rows(TMT_Matrix_,1.0e-16);
131 TMT_Matrix_->SetFixedBlockSize(1);
135 if(Nullspace_ != Teuchos::null) {
138 else if(Nullspace_ == Teuchos::null && Coords_ != Teuchos::null) {
139 Nullspace_ = MultiVectorFactory::Build(SM_Matrix_->getRowMap(),Coords_->getNumVectors());
140 D0_Matrix_->apply(*Coords_,*Nullspace_);
143 std::cerr <<
"MueLu::RefMaxwell::compute(): either the nullspace or the nodal coordinates must be provided." << std::endl;
147 if(P11_==Teuchos::null) {
155 Teuchos::RCP<Matrix> C = MatrixFactory::Build(M1_Matrix_->getRowMap(),0);
156 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*M1_Matrix_,
false,*D0_Matrix_,
false,*C,
true,
true);
157 A22_=MatrixFactory::Build(D0_Matrix_->getDomainMap(),0);
158 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*D0_Matrix_,
true,*C,
false,*A22_,
true,
true);
160 Remove_Zeroed_Rows(A22_,1.0e-16);
161 A22_->SetFixedBlockSize(1);
165 RCP<HierarchyManager> Manager11, Manager22, ManagerSmoother;
166 std::string syntaxStr =
"parameterlist: syntax";
167 if (parameterList_.isParameter(syntaxStr) && parameterList_.get<std::string>(syntaxStr) ==
"ml") {
168 parameterList_.remove(syntaxStr);
178 Hierarchy11_=Manager11->CreateHierarchy();
179 Hierarchy11_->setlib(Xpetra::UseTpetra);
180 Hierarchy11_->GetLevel(0)->Set(
"A", A11_);
181 Manager11->SetupHierarchy(*Hierarchy11_);
183 Hierarchy22_=Manager22->CreateHierarchy();
184 Hierarchy22_->setlib(Xpetra::UseTpetra);
185 Hierarchy22_->GetLevel(0)->Set(
"A", A22_);
186 Manager22->SetupHierarchy(*Hierarchy22_);
189 HierarchySmoother_=ManagerSmoother->CreateHierarchy();
190 HierarchySmoother_->setlib(Xpetra::UseTpetra);
191 HierarchySmoother_->GetLevel(0)->Set(
"A", SM_Matrix_);
192 ManagerSmoother->SetupHierarchy(*HierarchySmoother_);
196 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
199 Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
200 out.setOutputToRootOnly(0);
201 out.setShowProcRank(
true);
205 Teuchos::RCP<Hierarchy> auxHierarchy
206 = Teuchos::rcp(
new Hierarchy(TMT_Matrix_) );
207 Teuchos::RCP<FactoryManager> auxManager
209 Teuchos::RCP<TentativePFactory> TentPfact
211 Teuchos::RCP<SaPFactory> Pfact
213 Teuchos::RCP<UncoupledAggregationFactory> Aggfact
215 Teuchos::ParameterList params;
216 params.set(
"sa: damping factor",0.0);
217 Pfact -> SetParameterList(params);
218 auxManager -> SetFactory(
"P", Pfact);
219 auxManager -> SetFactory(
"Ptent", TentPfact);
220 auxManager -> SetFactory(
"Aggregates", Aggfact);
221 auxManager -> SetFactory(
"Smoother", Teuchos::null);
222 auxManager -> SetFactory(
"CoarseSolver", Teuchos::null);
223 auxHierarchy ->
Keep(
"P", Pfact.get());
224 auxHierarchy -> SetMaxCoarseSize(1);
225 auxHierarchy -> Setup(*auxManager, 0, 2);
228 Teuchos::RCP<Level> Level1 = auxHierarchy -> GetLevel(1);
229 Teuchos::RCP<Matrix> P = Level1 -> Get< Teuchos::RCP<Matrix> >(
"P",Pfact.get());
232 Teuchos::RCP<Matrix> D0_Matrix_Abs=MatrixFactory2::BuildCopy(D0_Matrix_);
233 D0_Matrix_Abs -> resumeFill();
234 D0_Matrix_Abs -> setAllToScalar((Scalar)0.5);
235 Apply_BCsToMatrixRows(D0_Matrix_Abs,BCrows_);
236 Apply_BCsToMatrixCols(D0_Matrix_Abs,BCcols_);
237 D0_Matrix_Abs -> fillComplete(D0_Matrix_->getDomainMap(),D0_Matrix_->getRangeMap());
238 Teuchos::RCP<Matrix> Ptent = MatrixFactory::Build(D0_Matrix_Abs->getRowMap(),0);
239 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*D0_Matrix_Abs,
false,*P,
false,*Ptent,
true,
true);
242 size_t dim = Nullspace_->getNumVectors();
243 size_t numLocalRows = SM_Matrix_->getNodeNumRows();
244 Teuchos::RCP<Map> BlockColMap
245 = Xpetra::MapFactory<LocalOrdinal,GlobalOrdinal,Node>::Build(Ptent->getColMap(),dim);
246 P11_ = Teuchos::rcp(
new CrsMatrixWrap(Ptent->getRowMap(),BlockColMap,0,Xpetra::StaticProfile));
248 std::vector< Teuchos::ArrayRCP<const Scalar> > nullspace(dim);
249 for(
size_t i=0; i<dim; i++) {
250 Teuchos::ArrayRCP<const Scalar> datavec = Nullspace_->getData(i);
251 nullspace[i]=datavec;
255 std::vector<size_t> rowPtrs;
256 std::vector<LocalOrdinal> blockCols;
257 std::vector<Scalar> blockVals;
258 for(
size_t i=0; i<numLocalRows; i++) {
259 rowPtrs.push_back(nnz);
260 Teuchos::ArrayView<const LocalOrdinal> localCols;
261 Teuchos::ArrayView<const Scalar> localVals;
262 Ptent->getLocalRowView(i,localCols,localVals);
263 size_t numCols = localCols.size();
264 for(
size_t j=0; j<numCols; j++) {
265 for(
size_t k=0; k<dim; k++) {
266 blockCols.push_back(localCols[j]*dim+k);
267 blockVals.push_back(localVals[j]*nullspace[k][i]);
272 rowPtrs.push_back(nnz);
274 ArrayRCP<size_t> rcpRowPtr;
275 ArrayRCP<LocalOrdinal> rcpColumns;
276 ArrayRCP<Scalar> rcpValues;
278 RCP<CrsMatrix> TP11 = rcp_dynamic_cast<CrsMatrixWrap>(P11_)->getCrsMatrix();
279 TP11->allocateAllValues(nnz, rcpRowPtr, rcpColumns, rcpValues);
281 ArrayView<size_t> rows = rcpRowPtr();
282 ArrayView<LocalOrdinal> columns = rcpColumns();
283 ArrayView<Scalar> values = rcpValues();
285 for (
size_t ii = 0; ii < rowPtrs.size(); ii++) rows[ii] = rowPtrs[ii];
286 for (
size_t ii = 0; ii < blockCols.size(); ii++) columns[ii] = blockCols[ii];
287 for (
size_t ii = 0; ii < blockVals.size(); ii++) values[ii] = blockVals[ii];
288 TP11->setAllValues(rcpRowPtr, rcpColumns, rcpValues);
289 Teuchos::RCP<Map> blockCoarseMap
290 = Xpetra::MapFactory<LocalOrdinal,GlobalOrdinal,Node>::Build(Ptent->getDomainMap(),dim);
291 TP11->expertStaticFillComplete(blockCoarseMap,SM_Matrix_->getDomainMap());
295 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
299 Teuchos::RCP<Matrix> C = MatrixFactory::Build(SM_Matrix_->getRowMap(),0);
300 Teuchos::RCP<Matrix> Matrix1 = MatrixFactory::Build(P11_->getDomainMap(),0);
303 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*SM_Matrix_,
false,*P11_,
false,*C,
true,
true);
306 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*P11_,
true,*C,
false,*Matrix1,
true,
true);
308 if(disable_addon_==
true) {
314 TEUCHOS_TEST_FOR_EXCEPTION(M0inv_Matrix_==Teuchos::null,std::invalid_argument,
315 "MueLu::RefMaxwell::formCoarseMatrix(): Inverse of " 316 "lumped mass matrix required for add-on (i.e. M0inv_Matrix is null)");
319 Teuchos::RCP<Matrix> Zaux = MatrixFactory::Build(M1_Matrix_->getRowMap(),0);
320 Teuchos::RCP<Matrix> Z = MatrixFactory::Build(D0_Matrix_->getDomainMap(),0);
321 Teuchos::RCP<Matrix> C2 = MatrixFactory::Build(M0inv_Matrix_->getRowMap(),0);
323 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*M1_Matrix_,
false,*P11_,
false,*Zaux,
true,
true);
325 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*D0_Matrix_,
true,*Zaux,
false,*Z,
true,
true);
327 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*M0inv_Matrix_,
false,*Z,
false,*C2,
true,
true);
329 Teuchos::RCP<Matrix> Matrix2 = MatrixFactory::Build(Z->getDomainMap(),0);
330 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Multiply(*Z,
true,*C2,
false,*Matrix2,
true,
true);
332 RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
333 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::TwoMatrixAdd(*Matrix1,
false,(Scalar)1.0,*Matrix2,
false,(Scalar)1.0,A11_,*out);
334 A11_->fillComplete();
338 size_t dim = Nullspace_->getNumVectors();
339 A11_->SetFixedBlockSize(dim);
343 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
345 SM_Matrix_ = SM_Matrix_new;
348 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
353 RCP<MultiVector> P11res = MultiVectorFactory::Build(P11_->getDomainMap(),X.getNumVectors());
354 RCP<MultiVector> P11x = MultiVectorFactory::Build(P11_->getDomainMap(),X.getNumVectors());
355 RCP<MultiVector> D0res = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(),X.getNumVectors());
356 RCP<MultiVector> D0x = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(),X.getNumVectors());
357 P11_->apply(*residual,*P11res,Teuchos::TRANS);
358 D0_Matrix_->apply(*residual,*D0res,Teuchos::TRANS);
361 Hierarchy11_->Iterate(*P11res, *P11x, 1,
true);
362 Hierarchy22_->Iterate(*D0res, *D0x, 1,
true);
365 P11_->apply(*P11x,*residual,Teuchos::NO_TRANS);
366 D0_Matrix_->apply(*D0x,*residual,Teuchos::NO_TRANS,(Scalar)1.0,(Scalar)1.0);
367 X.update((Scalar) 1.0, *residual, (Scalar) 1.0);
371 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
374 RCP<MultiVector> P11res = MultiVectorFactory::Build(P11_->getDomainMap(),X.getNumVectors());
375 RCP<MultiVector> P11x = MultiVectorFactory::Build(P11_->getDomainMap(),X.getNumVectors());
376 RCP<MultiVector> D0res = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(),X.getNumVectors());
377 RCP<MultiVector> D0x = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(),X.getNumVectors());
381 P11_->apply(*residual,*P11res,Teuchos::TRANS);
382 Hierarchy11_->Iterate(*P11res, *P11x, 1,
true);
383 P11_->apply(*P11x,*residual,Teuchos::NO_TRANS);
384 X.update((Scalar) 1.0, *residual, (Scalar) 1.0);
388 D0_Matrix_->apply(*residual,*D0res,Teuchos::TRANS);
389 Hierarchy22_->Iterate(*D0res, *D0x, 1,
true);
390 D0_Matrix_->apply(*D0x,*residual,Teuchos::NO_TRANS);
391 X.update((Scalar) 1.0, *residual, (Scalar) 1.0);
395 P11_->apply(*residual,*P11res,Teuchos::TRANS);
396 Hierarchy11_->Iterate(*P11res, *P11x, 1,
true);
397 P11_->apply(*P11x,*residual,Teuchos::NO_TRANS);
398 X.update((Scalar) 1.0, *residual, (Scalar) 1.0);
402 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
405 RCP<MultiVector> P11res = MultiVectorFactory::Build(P11_->getDomainMap(),X.getNumVectors());
406 RCP<MultiVector> P11x = MultiVectorFactory::Build(P11_->getDomainMap(),X.getNumVectors());
407 RCP<MultiVector> D0res = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(),X.getNumVectors());
408 RCP<MultiVector> D0x = MultiVectorFactory::Build(D0_Matrix_->getDomainMap(),X.getNumVectors());
412 D0_Matrix_->apply(*residual,*D0res,Teuchos::TRANS);
413 Hierarchy22_->Iterate(*D0res, *D0x, 1,
true);
414 D0_Matrix_->apply(*D0x,*residual,Teuchos::NO_TRANS);
415 X.update((Scalar) 1.0, *residual, (Scalar) 1.0);
419 P11_->apply(*residual,*P11res,Teuchos::TRANS);
420 Hierarchy11_->Iterate(*P11res, *P11x, 1,
true);
421 P11_->apply(*P11x,*residual,Teuchos::NO_TRANS);
422 X.update((Scalar) 1.0, *residual, (Scalar) 1.0);
426 D0_Matrix_->apply(*residual,*D0res,Teuchos::TRANS);
427 Hierarchy22_->Iterate(*D0res, *D0x, 1,
true);
428 D0_Matrix_->apply(*D0x,*residual,Teuchos::NO_TRANS);
429 X.update((Scalar) 1.0, *residual, (Scalar) 1.0);
438 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
440 Teuchos::ETransp mode,
450 Y.putScalar(Teuchos::ScalarTraits<Scalar>::zero());
453 HierarchySmoother_->Iterate(X,Y,1);
457 if(mode_==
"additive")
458 applyInverseAdditive(X,Y);
459 else if(mode_==
"121")
460 applyInverse121(X,Y);
461 else if(mode_==
"212")
462 applyInverse212(X,Y);
464 applyInverseAdditive(X,Y);
467 HierarchySmoother_->Iterate(X,Y,1);
469 }
catch (std::exception& e) {
472 std::cerr <<
"Caught an exception in MueLu::RefMaxwell::ApplyInverse():" << std::endl
473 << e.what() << std::endl;
478 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
483 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
486 const Teuchos::RCP<Matrix> & M0inv_Matrix,
487 const Teuchos::RCP<Matrix> & M1_Matrix,
488 const Teuchos::RCP<MultiVector> & Nullspace,
489 const Teuchos::RCP<MultiVector> & Coords,
490 Teuchos::ParameterList& List)
493 TEUCHOS_ASSERT(D0_Matrix!=Teuchos::null);
494 TEUCHOS_ASSERT(M1_Matrix!=Teuchos::null);
496 Hierarchy11_ = Teuchos::null;
497 Hierarchy22_ = Teuchos::null;
498 HierarchySmoother_ = Teuchos::null;
499 parameterList_ = List;
500 disable_addon_ =
false;
506 D0_Matrix_ = D0_Matrix;
507 M0inv_Matrix_ = M0inv_Matrix;
508 M1_Matrix_ = M1_Matrix;
510 Nullspace_ = Nullspace;
515 #define MUELU_REFMAXWELL_SHORT 516 #endif //ifdef MUELU_REFMAXWELL_DEF_HPP This class specifies the default factory that should generate some data on a Level if the data does n...
void initialize(const Teuchos::RCP< Matrix > &D0_Matrix, const Teuchos::RCP< Matrix > &M0inv_Matrix, const Teuchos::RCP< Matrix > &M1_Matrix, const Teuchos::RCP< MultiVector > &Nullspace, const Teuchos::RCP< MultiVector > &Coords, Teuchos::ParameterList &List)
Namespace for MueLu classes and methods.
void setParameters(Teuchos::ParameterList &list)
Set parameters.
void applyInverseAdditive(const MultiVector &RHS, MultiVector &X) const
apply additive algorithm for 2x2 solve
void buildProlongator()
Setup the prolongator for the (1,1)-block.
Factory for building tentative prolongator.
static RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Residual(const Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &RHS)
void applyInverse121(const MultiVector &RHS, MultiVector &X) const
apply 1-2-1 algorithm for 2x2 solve
void compute()
Setup the preconditioner.
Teuchos::RCP< const Map > getRangeMap() const
Returns the Xpetra::Map object associated with the range of this operator.
Always keep data, even accross run. This flag is set by Level::Keep(). This flag is propagated to coa...
Class that accepts ML-style parameters and builds a MueLu preconditioner. This interpreter uses the s...
bool hasTransposeApply() const
Indicates whether this operator supports applying the adjoint operator.
void applyInverse212(const MultiVector &RHS, MultiVector &X) const
apply 2-1-2 algorithm for 2x2 solve
void formCoarseMatrix()
Compute P11^{T}*A*P11 efficiently.
void apply(const MultiVector &X, MultiVector &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Factory for building Smoothed Aggregation prolongators.
Factory for building uncoupled aggregates.
void resetMatrix(Teuchos::RCP< Matrix > SM_Matrix_new)
Reset system matrix.
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
Teuchos::RCP< const Map > getDomainMap() const
Returns the Xpetra::Map object associated with the domain of this operator.