39 #include <lifev/core/algorithm/PreconditionerIfpack.hpp> 40 #include <lifev/core/algorithm/PreconditionerML.hpp> 42 #include <lifev/core/util/LifeChrono.hpp> 43 #include <lifev/core/fem/BCManage.hpp> 44 #include <lifev/core/fem/BCBase.hpp> 45 #include <lifev/core/fem/BCIdentifier.hpp> 46 #include <lifev/core/array/MatrixEpetraStructured.hpp> 47 #include <lifev/core/array/MatrixEpetraStructuredView.hpp> 48 #include <lifev/core/array/MatrixEpetraStructuredUtility.hpp> 49 #include <lifev/core/array/VectorBlockStructure.hpp> 52 #include <EpetraExt_MatrixMatrix.h> 58 PreconditionerComposition ( comm ),
64 M_pressureLaplacianOperator (
"standard" ),
65 M_pressureMassOperator (
"lumped" ),
75 M_inflowBoundaryType (
"Robin" ),
76 M_outflowBoundaryType (
"Neumann" ),
77 M_characteristicBoundaryType (
"Neumann" )
92 const std::string& section,
93 const std::string& subsection )
95 const bool verbose ( M_comm->MyPID() == 0 );
97 bool displayList = dataFile ( ( section +
"/displayList" ).data(),
false );
99 std::string precType = dataFile ( ( section +
"/prectype" ).data(),
"PCD" );
100 list.set (
"prectype", precType );
102 std::string fluidPrec = dataFile ( ( section +
"/" + subsection +
"/subprecs/fluid_prec" ).data(),
"ML" );
103 list.set (
"subprecs: fluid prec", fluidPrec );
104 std::string fluidPrecDataSection = dataFile ( ( section +
"/" + subsection +
"/subprecs/fluid_prec_data_section" ).data(),
"" );
105 list.set (
"subprecs: fluid prec data section", ( fluidPrecDataSection ).data() );
107 std::string pressureLaplacianPrec = dataFile ( ( section +
"/" + subsection +
"/subprecs/pressure_laplacian_prec" ).data(),
"ML" );
108 list.set (
"subprecs: pressure laplacian prec", pressureLaplacianPrec );
109 std::string pressureLaplacianPrecDataSection = dataFile ( ( section +
"/" + subsection +
"/subprecs/pressure_laplacian_prec_data_section" ).data(),
"" );
110 list.set (
"subprecs: pressure laplacian prec data section", ( pressureLaplacianPrecDataSection ).data() );
112 std::string pressureMassPrec = dataFile ( ( section +
"/" + subsection +
"/subprecs/pressure_mass_prec" ).data(),
"ML" );
113 list.set (
"subprecs: pressure mass prec", pressureMassPrec );
114 std::string pressureMassPrecDataSection = dataFile ( ( section +
"/" + subsection +
"/subprecs/pressure_mass_prec_data_section" ).data(),
"" );
115 list.set (
"subprecs: pressure mass prec data section", ( pressureMassPrecDataSection ).data() );
117 std::string pressureBoundaryConditions = dataFile ( ( section +
"/" + subsection +
"/pressure_boundary_conditions").data(),
"none" );
118 list.set (
"pressure boundary conditions", pressureBoundaryConditions );
120 std::string pressureLaplacianOperator = dataFile ( ( section +
"/" + subsection +
"/pressure_laplacian_operator").data(),
"standard" );
121 list.set (
"pressure laplacian operator", pressureLaplacianOperator );
123 std::string pressureMassOperator = dataFile ( ( section +
"/" + subsection +
"/pressure_mass_operator").data(),
"lumped" );
124 list.set (
"pressure mass operator", pressureMassOperator );
126 bool setApBoundaryConditions = dataFile ( ( section +
"/" + subsection +
"/set_Ap_boundary_conditions" ).data(),
false );
127 list.set (
"set Ap boundary conditions", setApBoundaryConditions );
129 bool setFpBoundaryConditions = dataFile ( ( section +
"/" + subsection +
"/set_Fp_boundary_conditions" ).data(),
false );
130 list.set (
"set Fp boundary conditions", setFpBoundaryConditions );
132 bool setMpBoundaryConditions = dataFile ( ( section +
"/" + subsection +
"/set_Mp_boundary_conditions" ).data(),
false );
133 list.set (
"set Mp boundary conditions", setMpBoundaryConditions );
135 bool fullFactorization = dataFile ( ( section +
"/" + subsection +
"/full_factorization" ).data(),
false );
136 list.set (
"full factorization", fullFactorization );
138 bool useStiffStrain = dataFile ( ( section +
"/" + subsection +
"/use_StiffStrain" ).data(),
false );
139 list.set (
"use stiff strain", useStiffStrain );
141 bool enableTransient = dataFile ( ( section +
"/" + subsection +
"/enable_transient" ).data(),
true );
142 list.set (
"enable transient", enableTransient );
144 bool useMinusDivergence = dataFile ( ( section +
"/" + subsection +
"/use_minus_divergence" ).data(),
false );
145 list.set (
"use minus divergence", useMinusDivergence );
147 bool recomputeNormalVectors = dataFile ( ( section +
"/" + subsection +
"/recompute_normal_vectors" ).data(),
true );
148 list.set (
"recompute normal vectors", recomputeNormalVectors );
150 bool schurOperatorReverseOrder = dataFile ( ( section +
"/" + subsection +
"/Schur_operator_reverse_order" ).data(),
false );
151 list.set (
"Schur operator reverse order", schurOperatorReverseOrder );
153 std::string inflowBoundaryType = dataFile ( ( section +
"/" + subsection +
"/inflow_boundary_type" ).data(),
"Robin" );
154 list.set (
"inflow boundary type", inflowBoundaryType );
156 std::string outflowBoundaryType = dataFile ( ( section +
"/" + subsection +
"/outflow_boundary_type" ).data(),
"Neumann" );
157 list.set (
"outflow boundary type", outflowBoundaryType );
159 std::string characteristicBoundaryType = dataFile ( ( section +
"/" + subsection +
"/characteristic_boundary_type" ).data(),
"Neumann" );
160 list.set (
"characteristic boundary type", characteristicBoundaryType );
162 if ( displayList && verbose )
164 std::cout <<
"PCD parameters list:" << std::endl;
165 std::cout <<
"-----------------------------" << std::endl;
166 list.print ( std::cout );
167 std::cout <<
"-----------------------------" << std::endl;
186 if ( ( M_uFESpace.get() == NULL ) || ( M_pFESpace.get() == NULL ) )
188 std::cout <<
"You must specified manually the pointers to the FESpaces" << std::endl;
192 const bool verbose ( M_comm->MyPID() == 0 );
195 this->resetPreconditioner();
197 std::vector<UInt> blockNumRows ( 2, 0 );
198 blockNumRows[0] = M_velocityBlockSize;
199 blockNumRows[1] = M_pressureBlockSize;
200 std::vector<UInt> blockNumColumns ( blockNumRows );
202 vectorStructure.setBlockStructure ( blockNumColumns );
204 const bool inversed (
true );
205 const bool notInversed (
false );
206 const bool notTransposed (
false );
209 map_Type velocityMap ( M_uFESpace->map() );
210 map_Type pressureMap ( M_pFESpace->map() );
221 std::cout <<
" >Getting the structure of A... ";
226 F.setup ( 0 , 0, blockNumRows[0], blockNumColumns[0], oper.get() );
229 Bt.setup ( 0, blockNumColumns[0], blockNumRows[0], blockNumColumns[1], oper.get() );
232 B.setup ( blockNumRows[0], 0, blockNumRows[1], blockNumColumns[0], oper.get() );
235 C.setup ( blockNumRows[0], blockNumColumns[0], blockNumRows[1], blockNumColumns[1], oper.get() );
238 std::cout <<
"done in " << timer.diff() <<
" s." << std::endl;
254 std::shared_ptr<matrix_Type> p3;
256 std::shared_ptr<matrixBlock_Type> P3;
257 if ( M_fluidPrec ==
"LinearSolver" )
259 MatrixEpetraStructuredUtility::createMatrixFromBlock ( F, P3, velocityMap,
true );
263 P3.reset (
new matrixBlock_Type ( map ) );
264 P3->setBlockStructure ( blockNumRows, blockNumColumns );
265 P3->blockView ( 0, 0, B11 );
266 P3->blockView ( 1, 1, B22 );
267 MatrixEpetraStructuredUtility::copyBlock ( F, B11 );
268 MatrixEpetraStructuredUtility::createIdentityBlock ( B22 );
269 P3->globalAssemble();
288 std::cout <<
" >Fluid block... ";
291 precForBlock3.reset ( PRECFactory::instance().createObject ( M_fluidPrec ) );
292 precForBlock3->setDataFromGetPot ( M_dataFile, M_fluidPrecDataSection );
298 if ( M_fluidPrec ==
"LinearSolver" )
300 this->pushBack ( p3, precForBlock3, vectorStructure, 0, oper->map(), notInversed, notTransposed );
304 this->pushBack ( p3, precForBlock3, notInversed, notTransposed );
308 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
318 std::cout <<
" >Divergence block... ";
321 std::shared_ptr<matrixBlock_Type> P2e (
new matrixBlock_Type ( map ) );
322 P2e->setBlockStructure ( blockNumRows, blockNumColumns );
323 P2e->blockView ( 0, 0, B11 );
324 P2e->blockView ( 1, 0, B21 );
325 P2e->blockView ( 1, 1, B22 );
326 MatrixEpetraStructuredUtility::copyBlock ( B, B21 );
328 MatrixEpetraStructuredUtility::createIdentityBlock ( B11 );
329 MatrixEpetraStructuredUtility::createIdentityBlock ( B22 );
330 P2e->globalAssemble();
331 std::shared_ptr<matrix_Type> p2e = P2e;
332 this->pushBack ( p2e, inversed, notTransposed );
335 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
345 std::cout <<
" >Fluid block... ";
347 this->pushBack ( p3, inversed, notTransposed );
350 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
365 std::cout <<
" >Building Fp... ";
368 std::shared_ptr<matrixBlock_Type> PFp;
369 PFp.reset (
new matrixBlock_Type ( map ) );
370 PFp->setBlockStructure ( blockNumRows, blockNumColumns );
372 PFp->blockView ( 0, 0, B11 );
373 PFp->blockView ( 1, 1, B22 );
374 MatrixEpetraStructuredUtility::createScalarBlock ( B11, 1.0 );
377 M_adrPressureAssembler.addStiffStrain ( PFp, M_viscosity / M_density, B22.firstRowIndex(), B22.firstColumnIndex() );
381 M_adrPressureAssembler.addDiffusion ( PFp, M_viscosity / M_density, B22.firstRowIndex(), B22.firstColumnIndex() );
383 M_adrPressureAssembler.addAdvection ( PFp, *M_beta, B22.firstRowIndex(), B22.firstColumnIndex() );
386 M_adrPressureAssembler.addMass ( PFp, 1.0 / M_timestep, B22.firstRowIndex(), B22.firstColumnIndex() );
388 std::shared_ptr<matrix_Type> pFp = PFp;
389 FpOffset = B22.firstRowIndex();
392 std::cout <<
"done in " << timer.diff() <<
" s." << std::endl;
397 std::cout <<
" >Building Ap";
400 std::shared_ptr<matrixBlock_Type> PAp;
401 if ( M_pressureLaplacianPrec ==
"LinearSolver" )
403 PAp.reset (
new matrixBlock_Type ( pressureMap ) );
405 PAp->blockView ( 0, 0, B22 );
406 ApOffset = B22.firstRowIndex();
410 PAp.reset (
new matrixBlock_Type ( map ) );
411 PAp->setBlockStructure ( blockNumRows, blockNumColumns );
413 PAp->blockView ( 0, 0, B11 );
414 PAp->blockView ( 1, 1, B22 );
415 MatrixEpetraStructuredUtility::createScalarBlock ( B11, 1.0 );
416 ApOffset = B22.firstRowIndex();
419 if ( M_pressureLaplacianOperator ==
"symmetric" )
423 std::cout <<
" (Symm(Fp) version)... ";
425 Epetra_CrsMatrix* tmpCrsMatrix ( NULL );
426 tmpCrsMatrix = PAp->matrixPtr().get();
427 EpetraExt::MatrixMatrix::Add ( * ( pFp->matrixPtr() ),
false, 0.5 * M_density / M_viscosity,
428 * ( pFp->matrixPtr() ),
true, 0.5 * M_density / M_viscosity,
430 *PAp *= M_divergenceCoeff;
432 else if ( M_pressureLaplacianOperator ==
"BBt" )
436 std::cout <<
" (BBt version)... ";
438 std::shared_ptr<matrixBlock_Type> BMat (
new matrixBlock_Type ( map ) );
439 BMat->setBlockStructure ( blockNumRows, blockNumColumns );
440 MatrixEpetraStructuredUtility::copyBlock ( B, * ( BMat->block ( 1, 0 ) ) );
441 BMat->globalAssemble();
442 std::shared_ptr<matrixBlock_Type> BtMat (
new matrixBlock_Type ( map ) );
443 BtMat->setBlockStructure ( blockNumRows, blockNumColumns );
444 MatrixEpetraStructuredUtility::copyBlock ( Bt, * ( BtMat->block ( 0, 1 ) ) );
445 BtMat->globalAssemble();
446 std::shared_ptr<matrixBlock_Type> BBtMat (
new matrixBlock_Type ( map ) );
447 BBtMat->setBlockStructure ( blockNumRows, blockNumColumns );
448 BMat->multiply (
false,
451 MatrixEpetraStructuredUtility::copyBlock ( * ( BBtMat->block ( 1, 1 ) ), B22 );
453 else if ( M_pressureLaplacianOperator ==
"BinvDBt" )
457 std::cout <<
" (BinvDBt version)... ";
460 std::shared_ptr<matrixBlock_Type> BMat (
new matrixBlock_Type ( map ) );
461 BMat->setBlockStructure ( blockNumRows, blockNumColumns );
462 MatrixEpetraStructuredUtility::copyBlock ( B, * ( BMat->block ( 1, 0 ) ) );
463 BMat->globalAssemble();
466 std::shared_ptr<matrixBlock_Type> tmpVelocityMass (
new matrixBlock_Type ( map ) );
467 tmpVelocityMass->setBlockStructure ( blockNumRows, blockNumColumns );
468 M_adrVelocityAssembler.addMass ( tmpVelocityMass, 1.0 );
469 tmpVelocityMass->globalAssemble();
470 std::shared_ptr<matrixBlock_Type> invDMat (
new matrixBlock_Type ( map ) );
471 invDMat->setBlockStructure ( blockNumRows, blockNumColumns );
472 MatrixEpetraStructuredUtility::createInvDiagBlock ( * ( tmpVelocityMass->block ( 0, 0 ) ), * ( invDMat->block ( 0, 0 ) ) );
473 invDMat->globalAssemble();
474 tmpVelocityMass.reset();
477 std::shared_ptr<matrixBlock_Type> BinvDMat (
new matrixBlock_Type ( map ) );
478 BinvDMat->setBlockStructure ( blockNumRows, blockNumColumns );
479 BMat->multiply (
false,
486 std::shared_ptr<matrixBlock_Type> BtMat (
new matrixBlock_Type ( map ) );
487 BtMat->setBlockStructure ( blockNumRows, blockNumColumns );
488 MatrixEpetraStructuredUtility::copyBlock ( Bt, * ( BtMat->block ( 0, 1 ) ) );
489 BtMat->globalAssemble();
490 std::shared_ptr<matrixBlock_Type> BBtMat (
new matrixBlock_Type ( map ) );
491 BBtMat->setBlockStructure ( blockNumRows, blockNumColumns );
492 BinvDMat->multiply (
false,
499 MatrixEpetraStructuredUtility::copyBlock ( * ( BBtMat->block ( 1, 1 ) ), B22 );
507 M_adrPressureAssembler.addDiffusion ( PAp, M_divergenceCoeff, B22.firstRowIndex(), B22.firstColumnIndex() );
509 std::shared_ptr<matrix_Type> pAp = PAp;
512 std::cout <<
"done in " << timer.diff() <<
" s." << std::endl;
518 std::cout <<
" >Building Mp";
521 std::shared_ptr<matrixBlock_Type> PMp;
522 if ( M_pressureMassPrec ==
"LinearSolver" && M_pressureMassOperator ==
"standard" )
524 PMp.reset (
new matrixBlock_Type ( pressureMap ) );
526 PMp->blockView ( 0, 0, B22 );
531 PMp.reset (
new matrixBlock_Type ( map ) );
532 PMp->setBlockStructure ( blockNumRows, blockNumColumns );
534 PMp->blockView ( 0, 0, B11 );
535 PMp->blockView ( 1, 1, B22 );
536 MatrixEpetraStructuredUtility::createScalarBlock ( B11, 1.0 );
537 MpOffset = B22.firstRowIndex();
539 if ( M_pressureMassOperator ==
"lumped" )
543 std::cout <<
" (Lumped version)... ";
545 std::shared_ptr<matrixBlock_Type> tmpMass (
new matrixBlock_Type ( map ) );
546 M_adrPressureAssembler.addMass ( tmpMass, -1.0, B22.firstRowIndex(), B22.firstColumnIndex() );
547 tmpMass->globalAssemble();
548 tmpMass->setBlockStructure ( blockNumRows, blockNumColumns );
549 tmpMass->blockView ( 1, 1, B11 );
550 MatrixEpetraStructuredUtility::createInvLumpedBlock ( B11, B22 );
553 if ( M_pressureMassOperator ==
"diagonal" )
557 std::cout <<
" (diagonal version)... ";
559 std::shared_ptr<matrixBlock_Type> tmpMass (
new matrixBlock_Type ( map ) );
560 M_adrPressureAssembler.addMass ( tmpMass, -1.0, B22.firstRowIndex(), B22.firstColumnIndex() );
561 tmpMass->globalAssemble();
562 tmpMass->setBlockStructure ( blockNumRows, blockNumColumns );
563 tmpMass->blockView ( 1, 1, B11 );
564 MatrixEpetraStructuredUtility::createInvDiagBlock ( B11, B22 );
573 M_adrPressureAssembler.addMass ( PMp, -1.0, B22.firstRowIndex(), B22.firstColumnIndex() );
575 std::shared_ptr<matrix_Type> pMp = PMp;
578 std::cout <<
"done in " << timer.diff() <<
" s." << std::endl;
590 this->setBCByBoundaryType ( pAp, ApOffset,
598 std::cout <<
" >BC imposed on Ap" << std::endl;
602 std::cout <<
" >BC imposed on Fp" << std::endl;
606 std::cout <<
" >BC imposed on Mp" << std::endl;
613 std::cout <<
" >Use reverse order for the Schur approximation" << std::endl;
618 std::cout <<
" >Schur block (a)... ";
621 if ( M_pressureMassOperator !=
"standard" )
623 this->pushBack ( pMp, inversed, notTransposed );
627 superPtr_Type precForBlock2 ( PRECFactory::instance().createObject ( M_pressureMassPrec ) );
628 precForBlock2->setDataFromGetPot ( M_dataFile, M_pressureMassPrecDataSection );
629 if ( M_pressureMassPrec ==
"LinearSolver" )
631 this->pushBack ( pMp, precForBlock2, vectorStructure, 1, oper->map(), notInversed, notTransposed );
635 this->pushBack ( pMp, precForBlock2, notInversed, notTransposed );
640 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
645 std::cout <<
" >Schur block (b)... ";
648 std::shared_ptr<matrix_Type> p1b = PFp;
649 this->pushBack ( p1b, inversed, notTransposed );
652 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
657 std::cout <<
" >Schur block (c)... ";
660 superPtr_Type precForBlock1 ( PRECFactory::instance().createObject ( M_pressureLaplacianPrec ) );
661 precForBlock1->setDataFromGetPot ( M_dataFile, M_pressureLaplacianPrecDataSection );
662 if ( M_pressureLaplacianPrec ==
"LinearSolver" )
664 this->pushBack ( pAp, precForBlock1, vectorStructure, 1, oper->map(), notInversed, notTransposed );
668 this->pushBack ( pAp, precForBlock1, notInversed, notTransposed );
672 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
679 std::cout <<
" >Schur block (a)... ";
682 superPtr_Type precForBlock1 ( PRECFactory::instance().createObject ( M_pressureLaplacianPrec ) );
683 precForBlock1->setDataFromGetPot ( M_dataFile, M_pressureLaplacianPrecDataSection );
684 if ( M_pressureLaplacianPrec ==
"LinearSolver" )
686 this->pushBack ( pAp, precForBlock1, vectorStructure, 1, oper->map(), notInversed, notTransposed );
690 this->pushBack ( pAp, precForBlock1, notInversed, notTransposed );
694 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
699 std::cout <<
" >Schur block (b)... ";
702 std::shared_ptr<matrix_Type> p1b = PFp;
703 this->pushBack ( p1b, inversed, notTransposed );
706 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
711 std::cout <<
" >Schur block (c)... ";
714 if ( M_pressureMassOperator !=
"standard" )
716 this->pushBack ( pMp, inversed, notTransposed );
720 superPtr_Type precForBlock2 ( PRECFactory::instance().createObject ( M_pressureMassPrec ) );
721 precForBlock2->setDataFromGetPot ( M_dataFile, M_pressureMassPrecDataSection );
722 if ( M_pressureMassPrec ==
"LinearSolver" )
724 this->pushBack ( pMp, precForBlock2, vectorStructure, 1, oper->map(), notInversed, notTransposed );
728 this->pushBack ( pMp, precForBlock2, notInversed, notTransposed );
733 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
744 std::cout <<
" >Gradient block... ";
747 std::shared_ptr<matrixBlock_Type> P2 (
new matrixBlock_Type ( map ) );
748 P2->setBlockStructure ( blockNumRows, blockNumColumns );
749 P2->blockView ( 0, 0, B11 );
750 P2->blockView ( 0, 1, B12 );
751 P2->blockView ( 1, 1, B22 );
752 MatrixEpetraStructuredUtility::copyBlock ( Bt, B12 );
754 MatrixEpetraStructuredUtility::createIdentityBlock ( B11 );
755 MatrixEpetraStructuredUtility::createIdentityBlock ( B22 );
756 P2->globalAssemble();
757 std::shared_ptr<matrix_Type> p2 = P2;
758 this->pushBack ( p2, inversed, notTransposed );
761 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
771 if ( M_fluidPrec ==
"LinearSolver" )
773 this->pushBack ( p3, precForBlock3, vectorStructure, 0, oper->map(), notInversed, notTransposed );
777 this->pushBack ( p3, precForBlock3, notInversed, notTransposed );
781 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
788 std::cout <<
" >Fluid block... ";
791 precForBlock3.reset ( PRECFactory::instance().createObject ( M_fluidPrec ) );
792 precForBlock3->setDataFromGetPot ( M_dataFile, M_fluidPrecDataSection );
798 if ( M_fluidPrec ==
"LinearSolver" )
800 this->pushBack ( p3, precForBlock3, vectorStructure, 0, oper->map(), notInversed, notTransposed );
804 this->pushBack ( p3, precForBlock3, notInversed, notTransposed );
808 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
814 if ( verbose ) std::cout <<
" >All the blocks are built" << std::endl
816 return ( EXIT_SUCCESS );
833 const std::string& section )
835 M_dataFile = dataFile;
836 this->createParametersList ( M_list, dataFile, section,
"PCD" );
837 this->setParameters ( M_list );
843 M_precType = list.get (
"prectype",
"PCD" );
845 M_fluidPrec = list.get (
"subprecs: fluid prec",
"ML" );
846 M_fluidPrecDataSection = list.get (
"subprecs: fluid prec data section",
"" );
848 M_pressureLaplacianPrec = list.get (
"subprecs: pressure laplacian prec",
"ML");
849 M_pressureLaplacianPrecDataSection = list.get (
"subprecs: pressure laplacian prec data section",
"" );
851 M_pressureMassPrec = list.get (
"subprecs: pressure mass prec",
"ML" );
852 M_pressureMassPrecDataSection = list.get (
"subprecs: pressure mass prec data section",
"" );
854 M_pressureLaplacianOperator = list.get (
"pressure laplacian operator",
"standard" );
856 M_pressureMassOperator = list.get (
"pressure mass operator",
"lumped" );
857 M_setApBoundaryConditions = list.get (
"set Ap boundary conditions",
false );
858 M_setFpBoundaryConditions = list.get (
"set Fp boundary conditions",
false );
859 M_setMpBoundaryConditions = list.get (
"set Mp boundary conditions",
false );
860 M_fullFactorization = list.get (
"full factorization",
false );
861 M_useStiffStrain = list.get (
"use stiff strain",
false );
862 M_enableTransient = list.get (
"enable transient",
true );
863 bool useMinusDivergence = list.get (
"use minus divergence",
false );
865 M_recomputeNormalVectors = list.get (
"recompute normal vectors",
true );
866 M_schurOperatorReverseOrder = list.get (
"Schur operator reverse order",
false );
867 M_inflowBoundaryType = list.get (
"inflow boundary type",
"Robin" );
868 M_outflowBoundaryType = list.get (
"outflow boundary type",
"Neumann" );
869 M_characteristicBoundaryType = list.get (
"characteristic boundary type",
"Neumann" );
877 M_adrPressureAssembler.setup ( pFESpace, uFESpace );
878 M_adrVelocityAssembler.setup ( uFESpace, uFESpace );
879 M_beta.reset (
new vector_Type ( M_uFESpace->map() + M_pFESpace->map() ) );
883 M_velocityBlockSize = M_uFESpace->fieldDim() * M_uFESpace->dof().numTotalDof();
884 M_pressureBlockSize = M_pFESpace->dof().numTotalDof();
914 if ( useMinusDivergence )
927 bool verbose (
false );
928 if ( M_comm->MyPID() == 0 )
937 std::cout <<
" >Computing the normal vectors on the boundary... ";
945 vector_Type repNormals ( M_pFESpace->map() + M_pFESpace->map() + M_pFESpace->map(), Repeated );
946 UInt numTotalDofs ( M_pFESpace->dof().numTotalDof() );
949 UInt numBoundaryFacets ( M_pFESpace->mesh()->numBoundaryFacets() );
950 for (
UInt iFace = 0; iFace < numBoundaryFacets; ++iFace )
953 M_pFESpace->feBd().update ( M_pFESpace->mesh()->boundaryFacet ( iFace ), UPDATE_NORMALS | UPDATE_W_ROOT_DET_METRIC );
954 UInt nDofF = M_pFESpace->feBd().nbFEDof();
957 for (
UInt icheck = 0; icheck < nDofF; ++icheck )
959 ID idf = M_pFESpace->dof().localToGlobalMapByBdFacet ( iFace, icheck );
973 Real nx ( M_pFESpace->feBd().normal ( 0, 0 ) );
974 Real ny ( M_pFESpace->feBd().normal ( 1, 0 ) );
975 Real nz ( M_pFESpace->feBd().normal ( 2, 0 ) );
978 Real area ( M_pFESpace->feBd().measure() );
981 ( repNormals )
[idf] += nx * area;
993 M_normalVectors.reset (
new vector_Type ( repNormals, Unique ) );
1000 Int NumMyElements = M_normalVectors->map().map ( Unique )->NumMyElements();
1001 std::vector<Int> MyGlobalElements ( NumMyElements );
1002 M_normalVectors->map().map ( Unique )->MyGlobalElements ( & ( MyGlobalElements[0] ) );
1012 id = MyGlobalElements[i];
1013 Real nx ( ( *M_normalVectors ) [id] );
1014 Real ny ( ( *M_normalVectors ) [id + numTotalDofs] );
1015 Real nz ( ( *M_normalVectors ) [id + 2 * numTotalDofs] );
1016 norm = sqrt ( nx * nx + ny * ny + nz * nz );
1021 ( *M_normalVectors ) [id] /= norm;
1022 ( *M_normalVectors ) [id + numTotalDofs] /= norm;
1023 ( *M_normalVectors ) [id + 2 * numTotalDofs] /= norm;
1029 std::cout <<
" done in " << timer.diff() <<
" s." << std::endl;
1036 if ( M_normalVectors.get() == 0 || M_recomputeNormalVectors )
1041 vectorPtr_Type robinCoeffVector (
new vector_Type ( M_pFESpace->map(), Unique ) );
1044 Int numVelocityTotalDofs ( M_uFESpace->dof().numTotalDof() );
1045 Int numPressureTotalDofs ( M_pFESpace->dof().numTotalDof() );
1046 Int NumMyElements = robinCoeffVector->map().map ( Unique )->NumMyElements();
1047 std::vector<Int> MyGlobalElements ( NumMyElements );
1048 robinCoeffVector->map().map ( Unique )->MyGlobalElements ( & ( MyGlobalElements[0] ) );
1056 for (
Int i ( 0 ); i < NumMyElements; ++i )
1058 id = MyGlobalElements[i];
1059 Real x ( ( *M_normalVectors ) [id] * ( *M_beta ) [id] );
1060 Real y ( ( *M_normalVectors ) [id + numPressureTotalDofs] * ( *M_beta ) [id + numVelocityTotalDofs] );
1061 Real z ( ( *M_normalVectors ) [id + 2 * numPressureTotalDofs] * ( *M_beta ) [id + 2 * numVelocityTotalDofs] );
1062 ( *robinCoeffVector ) [id] = ( x + y + z ) * invNu;
1065 return robinCoeffVector;
1073 std::string boundaryType (
"none" );
1074 Real indicator ( 0.0 );
1076 vector_Type robinCoeffVector ( *computeRobinCoefficient(), Repeated );
1077 vector_Type robinRHS ( M_pFESpace->map(), Repeated );
1078 BCVector uRobin ( robinRHS, M_pFESpace->dof().numTotalDof(), 0 );
1149 BCBase* inflowBoundary, *outflowBoundary, *characteristicBoundary;
1152 if ( M_inflowBoundaryType ==
"Dirichlet" )
1154 bcHandler.addBC ( BCBase (
"inflow",
1162 else if ( M_inflowBoundaryType ==
"Neumann" )
1164 bcHandler.addBC ( BCBase (
"inflow",
1171 else if ( M_inflowBoundaryType ==
"Robin" )
1173 bcHandler.addBC ( BCBase (
"inflow",
1182 if ( M_outflowBoundaryType ==
"Dirichlet" )
1184 bcHandler.addBC ( BCBase (
"outflow",
1191 else if ( M_outflowBoundaryType ==
"Neumann" )
1193 bcHandler.addBC ( BCBase (
"outflow",
1200 else if ( M_outflowBoundaryType ==
"Robin" )
1202 bcHandler.addBC ( BCBase (
"outflow",
1211 if ( M_characteristicBoundaryType ==
"Dirichlet" )
1213 bcHandler.addBC ( BCBase (
"characteristic",
1220 else if ( M_characteristicBoundaryType ==
"Neumann" )
1222 bcHandler.addBC ( BCBase (
"characteristic",
1229 else if ( M_characteristicBoundaryType ==
"Robin" )
1231 bcHandler.addBC ( BCBase (
"characteristic",
1246 for ( ID iBoundaryElement = 0 ; iBoundaryElement < M_pFESpace->mesh()->numBoundaryFacets(); ++iBoundaryElement )
1249 M_pFESpace->feBd().update ( M_pFESpace->mesh()->boundaryFacet ( iBoundaryElement ), UPDATE_W_ROOT_DET_METRIC );
1254 std::vector<ID> localToGlobalMapOnBElem = M_pFESpace->dof().localToGlobalMapOnBdFacet ( iBoundaryElement );
1261 for (ID lDof = 0; lDof < localToGlobalMapOnBElem.size(); lDof++)
1263 ID gDof = localToGlobalMapOnBElem[lDof];
1264 indicator += robinCoeffVector[gDof];
1266 if ( indicator > 0.0 )
1268 boundaryType = M_inflowBoundaryType;
1269 currentBoundary = inflowBoundary;
1271 else if ( indicator < 0.0 )
1273 boundaryType = M_outflowBoundaryType;
1274 currentBoundary = outflowBoundary;
1276 else if ( indicator == 0.0 )
1278 boundaryType = M_characteristicBoundaryType;
1279 currentBoundary = characteristicBoundary;
1283 if ( boundaryType ==
"Dirichlet" )
1285 for (ID lDof = 0; lDof < localToGlobalMapOnBElem.size(); lDof++)
1287 ID gDof = localToGlobalMapOnBElem[lDof];
1290 currentBoundary->addBCIdentifier (
new BCIdentifierEssential ( gDof, 0.0, 0.0, 0.0 ) );
1293 else if ( boundaryType ==
"Robin" )
1296 currentBoundary->addBCIdentifier (
new BCIdentifierNatural ( iBoundaryElement, localToGlobalMapOnBElem ) );
1298 else if ( boundaryType ==
"Neumann" )
1314 bcManageMatrix ( *Ap, *M_pFESpace->mesh(), M_pFESpace->dof(), bcHandler, M_pFESpace->feBd(), 1.0, 0.0 );
1319 bcManageMatrix ( *Fp, *M_pFESpace->mesh(), M_pFESpace->dof(), bcHandler, M_pFESpace->feBd(), 1.0, 0.0 );
1324 bcManageMatrix ( *Mp, *M_pFESpace->mesh(), M_pFESpace->dof(), bcHandler, M_pFESpace->feBd(), 1.0, 0.0 );
1326 Ap->globalAssemble();
1327 Fp->globalAssemble();
1328 Mp->globalAssemble();
bool M_recomputeNormalVectors
bool M_setApBoundaryConditions
bool isGlobalIDPresent(const UInt row) const
Access operators.
BCBase & findBCWithFlag(const bcFlag_Type &aFlag)
Extract a BC in the list according to its flag.
int numBlocksRows() const
PreconditionerPCD(std::shared_ptr< Epetra_Comm > comm=std::shared_ptr< Epetra_Comm >(new Epetra_MpiComm(MPI_COMM_WORLD)))
default constructor
void start()
Start the timer.
std::shared_ptr< vector_Type > vectorPtr_Type
virtual void setParameters(Teuchos::ParameterList &list)
Method to setup the solver using Teuchos::ParameterList.
std::shared_ptr< BCHandler > BCHandlerPtr_Type
bool M_preconditionerCreated
double condest()
Return an estimation of the conditionement number of the preconditioner.
BCHandler - class for handling boundary conditions.
VectorBlockStructure - class representing the structure of a vector.
void setFESpace(FESpacePtr_Type uFESpace, FESpacePtr_Type pFESpace)
Setter for the FESpace.
FESpacePtr_Type M_pFESpace
int32_type Int
Generic integer data.
void updateInverseJacobian(const UInt &iQuadPt)
void setDataFromGetPot(const GetPot &dataFile, const std::string §ion)
Setter using GetPot.
BCHandlerPtr_Type M_bcHandlerPtr
int buildPreconditioner(matrixPtr_type &A)
Build the preconditioner.
FESpacePtr_Type M_uFESpace
void setBetaCoeff(const Real &betaCoeff)
set the Beta coefficient FE vector
BCFunctionBase - class that holds the function used for prescribing boundary conditions.
void setUseMinusDivergence(const bool &useMinusDivergence)
Setter to know if we used B or -B in the discretization of the Navier-Stokes equations.
void setOffset(const UInt &offset)
Set offset in all boundary conditions.
std::shared_ptr< matrix_Type > matrixPtr_type
bool M_setMpBoundaryConditions
void setTimestep(const Real ×tep)
Setter for the timestep.
bool M_schurOperatorReverseOrder
int numBlocksColumns() const
virtual ~PreconditionerPCD()
constructor from matrix A.
void setBCByBoundaryType(matrixPtr_type Ap, UInt ApOffset, matrixPtr_type Fp, UInt FpOffset, matrixPtr_type Mp, UInt MpOffset)
void setBCHandler(BCHandlerPtr_Type bchPtr)
Setter for the BCHandler.
std::shared_ptr< FESpace< mesh_Type, map_Type > > FESpacePtr_Type
vectorPtr_Type computeRobinCoefficient()
void setRobinCoeffVector(const vector_Type &robinBoundaryMassCoeffVector)
set the boundary mass coefficient FE vector for Robin boundary conditions
double Real
Generic real data.
void createParametersList(list_Type &list, const GetPot &dataFile, const std::string §ion, const std::string &subsection="PCD")
Create the list of parameters of the preconditioner.
void setViscosity(const Real &viscosity)
Setter for the viscosity.
const UInt nDimensions(NDIM)
void setDensity(const Real &density)
Setter for the density.
BCVector - class that holds the FE vectors used for prescribing boundary conditions.
Teuchos::ParameterList list_Type
void copyIdSetIntoIdVector()
std::vector< std::shared_ptr< BCIdentifierBase > > M_idVector
container for id's when the list is finalized
std::shared_ptr< super_Type > superPtr_Type
void updateBeta(const vector_Type &beta)
Update the vector beta of the convective term in Fp.
void computeNormalVectors()
uint32_type UInt
generic unsigned integer (used mainly for addressing)
data_type & operator[](const UInt row)
Access operators.
bool M_setFpBoundaryConditions
MatrixEpetraStructuredView< Real > matrixBlockView_Type