8 #include <lifev/fsi_blocks/solver/FSIApplyOperator.hpp> 15 M_name(
"FSIApplyOperator"),
25 M_nBlockRows = map->nBlocks();
28 M_rangeMap = M_domainMap;
29 M_oper.resize(M_nBlockRows, M_nBlockCols);
35 const std::shared_ptr<BlockEpetra_Map> & rangeMap,
36 const commPtr_Type & comm)
40 M_nBlockRows = rangeMap->nBlocks();
41 M_nBlockCols = domainMap->nBlocks();
43 M_domainMap = domainMap;
44 M_rangeMap = rangeMap;
46 M_oper.resize(M_nBlockRows, M_nBlockCols);
54 M_nBlockRows = blockOper.size1();
55 M_nBlockCols = blockOper.size2();
63 if(blockOper(iblock,jblock) != 0 && rangeBlockMaps[iblock]==0)
65 rangeBlockMaps[iblock].reset(
new Epetra_Map(blockOper(iblock,jblock)->OperatorRangeMap() ));
73 if(blockOper(iblock,jblock) != 0 && domainBlockMaps[jblock]==0)
75 domainBlockMaps[jblock].reset(
new Epetra_Map(blockOper(iblock,jblock)->OperatorDomainMap() ));
80 M_domainMap.reset(
new BlockEpetra_Map(domainBlockMaps));
81 M_rangeMap.reset(
new BlockEpetra_Map(rangeBlockMaps));
91 ASSERT_PRE(M_rangeMap->blockMap(iblock)->PointSameAs(operBlock->OperatorRangeMap()),
"Wrong range map");
92 ASSERT_PRE(M_domainMap->blockMap(jblock)->PointSameAs(operBlock->OperatorDomainMap()),
"Wrong domain map");
94 M_oper(iblock, jblock) = operBlock;
104 if(M_oper(iblock,jblock).get() == 0)
107 nullOp->setUp(M_domainMap->blockMap(jblock), M_rangeMap->blockMap(iblock) );
108 M_oper(iblock,jblock).reset(nullOp);
110 ASSERT(M_rangeMap->blockMap(iblock)->PointSameAs(M_oper(iblock,jblock)->OperatorRangeMap()),
"Wrong range map");
111 ASSERT(M_domainMap->blockMap(jblock)->PointSameAs(M_oper(iblock,jblock)->OperatorDomainMap()),
"Wrong domain map");
118 #ifdef HAVE_LIFEV_DEBUG 120 for (UInt i(0); i<M_nBlockRows; ++i)
121 for (UInt j(0); j<M_nBlockCols; ++j)
123 EPETRA_CHK_ERR(M_oper(i,j)->SetUseTranspose(
true));
124 EPETRA_CHK_ERR(M_oper(i,j)->SetUseTranspose(
false));
160 ASSERT (iblock<M_nBlockRows,
"Error! Index out of bounds.\n");
161 ASSERT (jblock<M_nBlockCols,
"Error! Index out of bounds.\n");
162 return M_oper(iblock,jblock);
173 ASSERT_PRE(X.Map().SameAs(*(M_domainMap->monolithicMap())),
"The map of X is not conforming with domain map.");
174 ASSERT_PRE(Y.Map().SameAs(*(M_rangeMap->monolithicMap())),
"The map of Y is not conforming with range map.");
175 ASSERT_PRE(X.NumVectors() == Y.NumVectors(),
"The number of vectors in X and Y is different" );
177 const std::unique_ptr<BlockEpetra_MultiVector> Xview( createBlockView(X, *M_domainMap) );
178 const std::unique_ptr<BlockEpetra_MultiVector> Yview( createBlockView(Y, *M_rangeMap) );
181 Yview->PutScalar(0.0);
188 EPETRA_CHK_ERR(M_oper(iblock, jblock)->Apply(Xview->block(jblock), tmpY.block(iblock) ));
189 EPETRA_CHK_ERR(Yview->block(iblock).Update(1.0, tmpY.block(iblock), 1.0));
197 ASSERT_PRE(X.Map().SameAs(*(M_rangeMap->monolithicMap())),
"The map of X is not conforming with domain map.");
198 ASSERT_PRE(Y.Map().SameAs(*(M_domainMap->monolithicMap())),
"The map of Y is not conforming with range map.");
199 ASSERT_PRE(X.NumVectors() == Y.NumVectors(),
"The number of vectors in X and Y is different" );
201 const std::unique_ptr<BlockEpetra_MultiVector> Xview( createBlockView(X, *M_rangeMap) );
202 const std::unique_ptr<BlockEpetra_MultiVector> Yview( createBlockView(Y, *M_domainMap) );
205 Yview->PutScalar(0.0);
211 EPETRA_CHK_ERR(M_oper(iblock,jblock)->SetUseTranspose(
true));
212 EPETRA_CHK_ERR(M_oper(iblock, jblock)->Apply(Xview->block(jblock), tmpY.block(iblock) ));
213 EPETRA_CHK_ERR(Yview->block(iblock).Update(1.0, tmpY.block(iblock), 1.0));
214 EPETRA_CHK_ERR(M_oper(iblock,jblock)->SetUseTranspose(
false));
virtual int ApplyInverse(const vector_Type &X, vector_Type &Y) const
Compute Y = Op;.
This class handles block access to parallel monolithic Vectors with an underling block structure...
bool M_useTranspose
whenever transpose should be used
const operatorPtr_Type & block(UInt iblock, UInt jblock) const
Returns a const pointer to the (i,j) block.
commPtr_Type M_comm
Communicator.
void updateInverseJacobian(const UInt &iQuadPt)
int applyNoTranspose(const vector_Type &X, vector_Type &Y) const
Compute Y = Op*X;.
boost::numeric::ublas::matrix< operatorPtr_Type > operatorPtrContainer_Type
std::vector< mapPtr_Type > mapPtrContainer_Type
UInt M_nBlockCols
Number of blocks in each column.
int applyTranspose(const vector_Type &X, vector_Type &Y) const
Compute Y = Op'*X;.
operatorPtrContainer_Type M_oper
block operator represented like a dense matrix of pointers to Operators
A abstract class for handling n-by-m block operators This class inherits from LifeV::LinearOperator.
void setUp(const operatorPtrContainer_Type &blockOper, const commPtr_Type &comm)
SetUp when the operator is given like a boost::matrix.
VectorEpetra VectorEpetra_Type
void setUp(const std::shared_ptr< BlockEpetra_Map > &domainMap, const std::shared_ptr< BlockEpetra_Map > &rangeMap, const commPtr_Type &comm)
SetUp for a "rectangular operator".
A derived class from Epetra_MultiVector specialized to handle parallel block structured Vectors...
FSIApplyOperator()
Empty Constructor.
void setBlock(UInt iblock, UInt jblock, const operatorPtr_Type &operBlock)
set a component of the block operator
int SetUseTranspose(bool useTranspose)
If true the transpose of the operator will be computed.
UInt M_nBlockRows
Number of blocks in each row.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
void fillComplete()
Complete the block matrix with null operators.
virtual int Apply(const vector_Type &X, vector_Type &Y) const
Compute Y = Op*X;.