109 initializePrec(
const RCP<
const LinearOpSourceBase<Scalar> >& fwdOpSrc, PreconditionerBase<Scalar>* prec,
const ESupportSolveUse supportSolveUse)
const {
111 TEUCHOS_ASSERT(Teuchos::nonnull(fwdOpSrc));
112 TEUCHOS_ASSERT(this->isCompatible(*fwdOpSrc));
113 TEUCHOS_ASSERT(prec);
116 const RCP<const LinearOpBase<SC> > fwdOp = fwdOpSrc->getOp();
117 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(fwdOp));
119 typedef Thyra::TpetraLinearOp<SC, LO, GO, NO> ThyraTpetraLinOp;
120 const RCP<const ThyraTpetraLinOp> thyraTpetraFwdOp = rcp_dynamic_cast<const ThyraTpetraLinOp>(fwdOp);
121 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thyraTpetraFwdOp));
123 typedef Tpetra::Operator<SC, LO, GO, NO> TpetraLinOp;
124 const RCP<const TpetraLinOp> tpetraFwdOp = thyraTpetraFwdOp->getConstTpetraOperator();
125 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(tpetraFwdOp));
127 typedef Tpetra::CrsMatrix<SC, LO, GO, NO> TpetraCrsMat;
128 const RCP<const TpetraCrsMat> tpetraFwdCrsMat = rcp_dynamic_cast<const TpetraCrsMat>(tpetraFwdOp);
129 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(tpetraFwdCrsMat));
132 const Teuchos::Ptr<DefaultPreconditioner<SC> > defaultPrec = Teuchos::ptr(
dynamic_cast<DefaultPreconditioner<SC>*
>(prec));
133 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(defaultPrec));
136 const RCP<TpetraCrsMat> tpetraFwdCrsMatNonConst = rcp_const_cast<TpetraCrsMat>(tpetraFwdCrsMat);
141 ParameterList paramList = *paramList_;
143 typedef Tpetra::MultiVector<SC, LO, GO, NO> MultiVector;
144 RCP<MultiVector> coords, nullspace, velCoords, presCoords;
146 Teko::LinearOp thA11, thA12, thA21, thA11_9Pt;
147 if (paramList.isType<RCP<MultiVector> >(
"Coordinates")) {
148 coords = paramList.get<RCP<MultiVector> >(
"Coordinates");
149 paramList.remove(
"Coordinates");
151 if (paramList.isType<RCP<MultiVector> >(
"Nullspace")) {
152 nullspace = paramList.get<RCP<MultiVector> >(
"Nullspace");
153 paramList.remove(
"Nullspace");
155 if (paramList.isType<RCP<MultiVector> >(
"Velcoords")) {
156 velCoords = paramList.get<RCP<MultiVector> >(
"Velcoords");
157 paramList.remove(
"Velcoords");
159 if (paramList.isType<RCP<MultiVector> >(
"Prescoords")) {
160 presCoords = paramList.get<RCP<MultiVector> >(
"Prescoords");
161 paramList.remove(
"Prescoords");
163 if (paramList.isType<ArrayRCP<LO> >(
"p2vMap")) {
164 p2vMap = paramList.get<ArrayRCP<LO> >(
"p2vMap");
165 paramList.remove(
"p2vMap");
167 if (paramList.isType<Teko::LinearOp>(
"A11")) {
168 thA11 = paramList.get<Teko::LinearOp>(
"A11");
169 paramList.remove(
"A11");
171 if (paramList.isType<Teko::LinearOp>(
"A12")) {
172 thA12 = paramList.get<Teko::LinearOp>(
"A12");
173 paramList.remove(
"A12");
175 if (paramList.isType<Teko::LinearOp>(
"A21")) {
176 thA21 = paramList.get<Teko::LinearOp>(
"A21");
177 paramList.remove(
"A21");
179 if (paramList.isType<Teko::LinearOp>(
"A11_9Pt")) {
180 thA11_9Pt = paramList.get<Teko::LinearOp>(
"A11_9Pt");
181 paramList.remove(
"A11_9Pt");
185 const RCP<MueLuOperator> mueluPrecOp = Q2Q1MkPrecond(paramList, velCoords, presCoords, p2vMap, thA11, thA12, thA21, thA11_9Pt);
187 const RCP<LinearOpBase<SC> > thyraPrecOp = Thyra::createLinearOp(RCP<TpetraLinOp>(mueluPrecOp));
188 defaultPrec->initializeUnspecified(thyraPrecOp);
256 const RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& velCoords,
257 const RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& presCoords,
258 const ArrayRCP<LocalOrdinal>& p2vMap,
259 const Teko::LinearOp& thA11,
const Teko::LinearOp& thA12,
const Teko::LinearOp& thA21,
const Teko::LinearOp& thA11_9Pt)
const {
262 typedef Tpetra::CrsMatrix<SC, LO, GO, NO> TP_Crs;
263 typedef Tpetra::Operator<SC, LO, GO, NO> TP_Op;
265 typedef Xpetra::BlockedCrsMatrix<SC, LO, GO, NO> BlockedCrsMatrix;
266 typedef Xpetra::CrsMatrix<SC, LO, GO, NO> CrsMatrix;
267 typedef Xpetra::CrsMatrixWrap<SC, LO, GO, NO> CrsMatrixWrap;
268 typedef Xpetra::MapExtractorFactory<SC, LO, GO, NO> MapExtractorFactory;
269 typedef Xpetra::MapExtractor<SC, LO, GO, NO> MapExtractor;
270 typedef Xpetra::Map<LO, GO, NO> Map;
271 typedef Xpetra::MapFactory<LO, GO, NO> MapFactory;
272 typedef Xpetra::Matrix<SC, LO, GO, NO> Matrix;
273 typedef Xpetra::MatrixFactory<SC, LO, GO, NO> MatrixFactory;
274 typedef Xpetra::StridedMapFactory<LO, GO, NO> StridedMapFactory;
278 const RCP<const Teuchos::Comm<int> > comm = velCoords->getMap()->getComm();
281 RCP<Thyra::LinearOpBase<SC> > ThNonConstA11 = rcp_const_cast<Thyra::LinearOpBase<double> >(thA11);
282 RCP<Thyra::LinearOpBase<SC> > ThNonConstA21 = rcp_const_cast<Thyra::LinearOpBase<double> >(thA21);
283 RCP<Thyra::LinearOpBase<SC> > ThNonConstA12 = rcp_const_cast<Thyra::LinearOpBase<double> >(thA12);
284 RCP<Thyra::LinearOpBase<SC> > ThNonConstA11_9Pt = rcp_const_cast<Thyra::LinearOpBase<double> >(thA11_9Pt);
286 RCP<TP_Op> TpetA11 = Thyra::TpetraOperatorVectorExtraction<SC, LO, GO, NO>::getTpetraOperator(ThNonConstA11);
287 RCP<TP_Op> TpetA21 = Thyra::TpetraOperatorVectorExtraction<SC, LO, GO, NO>::getTpetraOperator(ThNonConstA21);
288 RCP<TP_Op> TpetA12 = Thyra::TpetraOperatorVectorExtraction<SC, LO, GO, NO>::getTpetraOperator(ThNonConstA12);
289 RCP<TP_Op> TpetA11_9Pt = Thyra::TpetraOperatorVectorExtraction<SC, LO, GO, NO>::getTpetraOperator(ThNonConstA11_9Pt);
291 RCP<TP_Crs> TpetCrsA11 = rcp_dynamic_cast<TP_Crs>(TpetA11);
292 RCP<TP_Crs> TpetCrsA21 = rcp_dynamic_cast<TP_Crs>(TpetA21);
293 RCP<TP_Crs> TpetCrsA12 = rcp_dynamic_cast<TP_Crs>(TpetA12);
294 RCP<TP_Crs> TpetCrsA11_9Pt = rcp_dynamic_cast<TP_Crs>(TpetA11_9Pt);
296 RCP<Matrix> A_11 = Xpetra::toXpetra(TpetCrsA11);
297 RCP<Matrix> tmp_A_21 = Xpetra::toXpetra(TpetCrsA21);
298 RCP<Matrix> tmp_A_12 = Xpetra::toXpetra(TpetCrsA12);
299 RCP<Matrix> A_11_9Pt = Xpetra::toXpetra(TpetCrsA11_9Pt);
301 Xpetra::global_size_t numVel = A_11->getRowMap()->getLocalNumElements();
302 Xpetra::global_size_t numPres = tmp_A_21->getRowMap()->getLocalNumElements();
306 RCP<const Map> domainMap2 = tmp_A_12->getDomainMap();
307 RCP<const Map> rangeMap2 = tmp_A_21->getRangeMap();
308 Xpetra::global_size_t numRows2 = rangeMap2->getLocalNumElements();
309 Xpetra::global_size_t numCols2 = domainMap2->getLocalNumElements();
310 ArrayView<const GO> rangeElem2 = rangeMap2->getLocalElementList();
311 ArrayView<const GO> domainElem2 = domainMap2->getLocalElementList();
312 ArrayView<const GO> rowElem1 = tmp_A_12->getRowMap()->getLocalElementList();
313 ArrayView<const GO> colElem1 = tmp_A_21->getColMap()->getLocalElementList();
315 Xpetra::UnderlyingLib lib = domainMap2->lib();
316 GO indexBase = domainMap2->getIndexBase();
318 Array<GO> newRowElem2(numRows2, 0);
319 for (Xpetra::global_size_t i = 0; i < numRows2; i++)
320 newRowElem2[i] = numVel + rangeElem2[i];
322 RCP<const Map> newRangeMap2 = MapFactory::Build(lib, numRows2, newRowElem2, indexBase, comm);
325 Array<GO> newColElem2(numCols2, 0);
326 for (Xpetra::global_size_t i = 0; i < numCols2; i++)
327 newColElem2[i] = numVel + domainElem2[i];
329 RCP<const Map> newDomainMap2 = MapFactory::Build(lib, numCols2, newColElem2, indexBase, comm);
331 RCP<Matrix> A_12 = MatrixFactory::Build(tmp_A_12->getRangeMap(), newDomainMap2, tmp_A_12->getLocalMaxNumRowEntries());
332 RCP<Matrix> A_21 = MatrixFactory::Build(newRangeMap2, tmp_A_21->getDomainMap(), tmp_A_21->getLocalMaxNumRowEntries());
334 RCP<CrsMatrix> A_11_crs = rcp_dynamic_cast<CrsMatrixWrap>(A_11)->getCrsMatrix();
335 RCP<CrsMatrix> A_12_crs = rcp_dynamic_cast<CrsMatrixWrap>(A_12)->getCrsMatrix();
336 RCP<CrsMatrix> A_21_crs = rcp_dynamic_cast<CrsMatrixWrap>(A_21)->getCrsMatrix();
337 RCP<CrsMatrix> A_11_crs_9Pt = rcp_dynamic_cast<CrsMatrixWrap>(A_11_9Pt)->getCrsMatrix();
340 RCP<Matrix> A_22 = MatrixFactory::Build(newRangeMap2, newDomainMap2, 1);
341 RCP<CrsMatrix> A_22_crs = rcp_dynamic_cast<CrsMatrixWrap>(A_22) ->getCrsMatrix();
344 Array<SC> smallVal(1, 1.0e-10);
349 ArrayView<const LO> inds;
350 ArrayView<const SC> vals;
351 for (
LO row = 0; row < as<LO>(numRows2); ++row) {
352 tmp_A_21->getLocalRowView(row, inds, vals);
354 size_t nnz = inds.size();
355 Array<GO> newInds(nnz, 0);
356 for (
LO colID = 0; colID < as<LO>(nnz); colID++)
357 newInds[colID] = colElem1[inds[colID]];
359 A_21_crs->insertGlobalValues(newRowElem2[row], newInds, vals);
360 A_22_crs->insertGlobalValues(newRowElem2[row], Array<LO>(1, newRowElem2[row]), smallVal);
362 A_21_crs->fillComplete(tmp_A_21->getDomainMap(), newRangeMap2);
363 A_22_crs->fillComplete(newDomainMap2, newRangeMap2);
365 RCP<Matrix> A_22 = Teuchos::null;
366 RCP<CrsMatrix> A_22_crs = Teuchos::null;
368 ArrayView<const LO> inds;
369 ArrayView<const SC> vals;
370 for (
LO row = 0; row < as<LO>(numRows2); ++row) {
371 tmp_A_21->getLocalRowView(row, inds, vals);
373 size_t nnz = inds.size();
374 Array<GO> newInds(nnz, 0);
375 for (
LO colID = 0; colID < as<LO>(nnz); colID++)
376 newInds[colID] = colElem1[inds[colID]];
378 A_21_crs->insertGlobalValues(newRowElem2[row], newInds, vals);
380 A_21_crs->fillComplete(tmp_A_21->getDomainMap(), newRangeMap2);
385 for (
LO row = 0; row < as<LO>(tmp_A_12->getRowMap()->getLocalNumElements()); ++row) {
386 tmp_A_12->getLocalRowView(row, inds, vals);
388 size_t nnz = inds.size();
389 Array<GO> newInds(nnz, 0);
390 for (
LO colID = 0; colID < as<LO>(nnz); colID++)
391 newInds[colID] = newColElem2[inds[colID]];
393 A_12_crs->insertGlobalValues(rowElem1[row], newInds, vals);
395 A_12_crs->fillComplete(newDomainMap2, tmp_A_12->getRangeMap());
397 RCP<Matrix> A_12_abs = Absolute(*A_12);
398 RCP<Matrix> A_21_abs = Absolute(*A_21);
403 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
404 Teuchos::FancyOStream& out = *fancy;
405 out.setOutputToRootOnly(0);
406 RCP<Matrix> BBt = Xpetra::MatrixMatrix<SC, LO, GO, NO>::Multiply(*A_21,
false, *A_12,
false, out);
407 RCP<Matrix> BBt_abs = Xpetra::MatrixMatrix<SC, LO, GO, NO>::Multiply(*A_21_abs,
false, *A_12_abs,
false, out);
409 SC dropTol = (paramList.get<
int>(
"useFilters") ? paramList.get<
double>(
"tau_1") : 0.00);
410 RCP<Matrix> filteredA = FilterMatrix(*A_11, *A_11, dropTol);
411 RCP<Matrix> filteredB = FilterMatrix(*BBt, *BBt_abs, dropTol);
413 RCP<Matrix> fA_11_crs = rcp_dynamic_cast<CrsMatrixWrap>(filteredA);
414 RCP<Matrix> fA_12_crs = Teuchos::null;
415 RCP<Matrix> fA_21_crs = Teuchos::null;
416 RCP<Matrix> fA_22_crs = rcp_dynamic_cast<CrsMatrixWrap>(filteredB);
419 std::vector<size_t> stridingInfo(1, 1);
420 int stridedBlockId = -1;
422 Array<GO> elementList(numVel + numPres);
423 Array<GO> velElem = A_12_crs->getRangeMap()->getLocalElementList();
424 Array<GO> presElem = A_21_crs->getRangeMap()->getLocalElementList();
426 for (Xpetra::global_size_t i = 0; i < numVel; i++) elementList[i] = velElem[i];
427 for (Xpetra::global_size_t i = numVel; i < numVel + numPres; i++) elementList[i] = presElem[i - numVel];
428 RCP<const Map> fullMap = StridedMapFactory::Build(Xpetra::UseTpetra, numVel + numPres, elementList(), indexBase, stridingInfo, comm);
430 std::vector<RCP<const Map> > partMaps(2);
431 partMaps[0] = StridedMapFactory::Build(Xpetra::UseTpetra, numVel, velElem, indexBase, stridingInfo, comm);
432 partMaps[1] = StridedMapFactory::Build(Xpetra::UseTpetra, numPres, presElem, indexBase, stridingInfo, comm, stridedBlockId, numVel);
435 RCP<const MapExtractor> mapExtractor = MapExtractorFactory::Build(fullMap, partMaps);
436 RCP<BlockedCrsMatrix> fA = rcp(
new BlockedCrsMatrix(mapExtractor, mapExtractor, 10));
437 fA->setMatrix(0, 0, fA_11_crs);
438 fA->setMatrix(0, 1, fA_12_crs);
439 fA->setMatrix(1, 0, fA_21_crs);
440 fA->setMatrix(1, 1, fA_22_crs);
447 SetDependencyTree(M, paramList);
449 RCP<Hierarchy> H = rcp(
new Hierarchy);
450 RCP<MueLu::Level> finestLevel = H->GetLevel(0);
451 finestLevel->Set(
"A", rcp_dynamic_cast<Matrix>(fA));
452 finestLevel->Set(
"p2vMap", p2vMap);
453 finestLevel->Set(
"CoordinatesVelocity", Xpetra::toXpetra(velCoords));
454 finestLevel->Set(
"CoordinatesPressure", Xpetra::toXpetra(presCoords));
455 finestLevel->Set(
"AForPat", A_11_9Pt);
456 H->SetMaxCoarseSize(
MUELU_GPD(
"coarse: max size",
int, 1));
466 H->Keep(
"Ptent", M.
GetFactory(
"Ptent").get());
467 H->Setup(M, 0,
MUELU_GPD(
"max levels",
int, 3));
470 for (
int i = 1; i < H->GetNumLevels(); i++) {
471 RCP<Matrix> P = H->GetLevel(i)->template Get<RCP<Matrix> >(
"P");
472 RCP<BlockedCrsMatrix> Pcrs = rcp_dynamic_cast<BlockedCrsMatrix>(P);
473 RCP<Matrix> Pp = Pcrs->getMatrix(1,1);
474 RCP<Matrix> Pv = Pcrs->getMatrix(0,0);
476 Xpetra::IO<SC,LO,GO,NO>::Write(
"Pp_l" +
MueLu::toString(i) +
".mm", *Pp);
477 Xpetra::IO<SC,LO,GO,NO>::Write(
"Pv_l" +
MueLu::toString(i) +
".mm", *Pv);
484 std::string smootherType =
MUELU_GPD(
"smoother: type", std::string,
"vanka");
485 ParameterList smootherParams;
486 if (paramList.isSublist(
"smoother: params"))
487 smootherParams = paramList.sublist(
"smoother: params");
488 M.
SetFactory(
"Smoother", GetSmoother(smootherType, smootherParams,
false ));
490 std::string coarseType =
MUELU_GPD(
"coarse: type", std::string,
"direct");
491 ParameterList coarseParams;
492 if (paramList.isSublist(
"coarse: params"))
493 coarseParams = paramList.sublist(
"coarse: params");
494 M.
SetFactory(
"CoarseSolver", GetSmoother(coarseType, coarseParams,
true ));
496#ifdef HAVE_MUELU_DEBUG
500 RCP<BlockedCrsMatrix> A = rcp(
new BlockedCrsMatrix(mapExtractor, mapExtractor, 10));
501 A->setMatrix(0, 0, A_11);
502 A->setMatrix(0, 1, A_12);
503 A->setMatrix(1, 0, A_21);
504 A->setMatrix(1, 1, A_22);
507 H->GetLevel(0)->Set(
"A", rcp_dynamic_cast<Matrix>(A));
509 H->Setup(M, 0, H->GetNumLevels());