本文整理汇总了C++中Epetra_MultiVector::Update方法的典型用法代码示例。如果您正苦于以下问题:C++ Epetra_MultiVector::Update方法的具体用法?C++ Epetra_MultiVector::Update怎么用?C++ Epetra_MultiVector::Update使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Epetra_MultiVector
的用法示例。
在下文中一共展示了Epetra_MultiVector::Update方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Resid
// ================================================ ====== ==== ==== == =
//! Implicitly applies in the inverse in an 1-2-1 format
int ML_Epetra::RefMaxwellPreconditioner::ApplyInverse_Implicit_121(const Epetra_MultiVector& B, Epetra_MultiVector& X) const
{
#ifdef ML_TIMING
double t_time,t_diff;
StartTimer(&t_time);
#endif
int NumVectors=B.NumVectors();
Epetra_MultiVector TempE1(X.Map(),NumVectors,false);
Epetra_MultiVector TempE2(X.Map(),NumVectors,true);
Epetra_MultiVector TempN1(*NodeMap_,NumVectors,false);
Epetra_MultiVector TempN2(*NodeMap_,NumVectors,true);
Epetra_MultiVector Resid(B);
/* Pre-Smoothing */
ML_CHK_ERR(PreEdgeSmoother->ApplyInverse(B,X));
/* Precondition (1,1) Block */
ML_CHK_ERR(EdgePC->ApplyInverse(Resid,TempE2));
ML_CHK_ERR(X.Update(1.0,TempE2,1.0));;
/* Build Residual */
ML_CHK_ERR(SM_Matrix_->Multiply(false,X,TempE1));
ML_CHK_ERR(Resid.Update(-1.0,TempE1,1.0,B,0.0));
if(!HasOnlyDirichletNodes){
ML_CHK_ERR(D0_Matrix_->Multiply(true,Resid,TempN1));
}
/* Precondition (2,2) Block */
if(!HasOnlyDirichletNodes){
ML_CHK_ERR(NodePC->ApplyInverse(TempN1,TempN2));
D0_Matrix_->Multiply(false,TempN2,TempE1);
}/*end if*/
if(!HasOnlyDirichletNodes) X.Update(1.0,TempE1,1.0);
/* Build Residual */
ML_CHK_ERR(SM_Matrix_->Multiply(false,X,TempE1));
ML_CHK_ERR(Resid.Update(-1.0,TempE1,1.0,B,0.0));
/* Precondition (1,1) Block */
TempE2.PutScalar(0.0);
ML_CHK_ERR(EdgePC->ApplyInverse(Resid,TempE2));
ML_CHK_ERR(X.Update(1.0,TempE2,1.0));;
/* Post-Smoothing */
ML_CHK_ERR(PostEdgeSmoother->ApplyInverse(B,X));
#ifdef ML_TIMING
StopTimer(&t_time,&t_diff);
/* Output */
ML_Comm *comm_;
ML_Comm_Create(&comm_);
this->ApplicationTime_+= t_diff;
ML_Comm_Destroy(&comm_);
#endif
return 0;
}
示例2: ComputeFullSolution
//==============================================================================
int LinearProblem_CrsSingletonFilter::ComputeFullSolution() {
int jj, k;
Epetra_MultiVector * FullLHS = FullProblem()->GetLHS();
Epetra_MultiVector * FullRHS = FullProblem()->GetRHS();
tempX_->PutScalar(0.0); tempExportX_->PutScalar(0.0);
// Inject values that the user computed for the reduced problem into the full solution vector
EPETRA_CHK_ERR(tempX_->Export(*ReducedLHS_, *Full2ReducedLHSImporter_, Add));
FullLHS->Update(1.0, *tempX_, 1.0);
// Next we will use our full solution vector which is populated with pre-filter solution
// values and reduced system solution values to compute the sum of the row contributions
// that must be subtracted to get the post-filter solution values
EPETRA_CHK_ERR(FullMatrix()->Multiply(false, *FullLHS, *tempB_));
// Finally we loop through the local rows that were associated with column singletons and compute the
// solution for these equations.
int NumVectors = tempB_->NumVectors();
for (k=0; k<NumMyColSingletons_; k++) {
int i = ColSingletonRowLIDs_[k];
int j = ColSingletonColLIDs_[k];
double pivot = ColSingletonPivots_[k];
for (jj=0; jj<NumVectors; jj++)
(*tempExportX_)[jj][j]= ((*FullRHS)[jj][i] - (*tempB_)[jj][i])/pivot;
}
// Finally, insert values from post-solve step and we are done!!!!
if (FullMatrix()->RowMatrixImporter()!=0) {
EPETRA_CHK_ERR(tempX_->Export(*tempExportX_, *FullMatrix()->RowMatrixImporter(), Add));
}
else {
tempX_->Update(1.0, *tempExportX_, 0.0);
}
FullLHS->Update(1.0, *tempX_, 1.0);
return(0);
}
示例3: node_rhs
// ================================================ ====== ==== ==== == =
//! Implicitly applies in the inverse in a 2-1-2 format
int ML_Epetra::RefMaxwellPreconditioner::ApplyInverse_Implicit_212(const Epetra_MultiVector& B, Epetra_MultiVector& X) const
{
#ifdef ML_TIMING
double t_time,t_diff;
StartTimer(&t_time);
#endif
int NumVectors=B.NumVectors();
/* Setup Temps */
Epetra_MultiVector node_sol1(*NodeMap_,NumVectors,true);
Epetra_MultiVector node_sol2(*NodeMap_,NumVectors,false);
Epetra_MultiVector node_rhs(*NodeMap_,NumVectors,false);
Epetra_MultiVector edge_temp1(*DomainMap_,NumVectors,false);
Epetra_MultiVector edge_rhs(*DomainMap_,NumVectors,false);
Epetra_MultiVector edge_sol(*DomainMap_,NumVectors,true);
/* Build Nodal RHS */
ML_CHK_ERR(D0_Matrix_->Multiply(true,B,node_rhs));
/* Precondition (2,2) Block */
ML_CHK_ERR(NodePC->ApplyInverse(node_rhs,node_sol1));
/* Build Residual */
ML_CHK_ERR(D0_Matrix_->Multiply(false,node_sol1,edge_temp1));
ML_CHK_ERR(edge_rhs.Update(1.0,B,-1.0));
/* Precondition (1,1) Block */
// _CHK_ERR(PreEdgeSmoother->ApplyInverse(B,X));
ML_CHK_ERR(EdgePC->ApplyInverse(edge_rhs,edge_sol));
/* Build Nodal RHS */
ML_CHK_ERR(edge_temp1.Update(1.0,edge_rhs,-1.0));
ML_CHK_ERR(D0_Matrix_->Multiply(true,edge_temp1,node_rhs));
/* Precondition (2,2) Block */
ML_CHK_ERR(NodePC->ApplyInverse(node_rhs,node_sol2));
/* Assemble solution (x = xe + T*(xn1 + xn2)) */
ML_CHK_ERR(node_sol1.Update(1.0,node_sol2,1.0));
ML_CHK_ERR(D0_Matrix_->Multiply(false,node_sol1,X));
ML_CHK_ERR(X.Update(1.0,edge_sol,1.0));
#ifdef ML_TIMING
StopTimer(&t_time,&t_diff);
/* Output */
ML_Comm *comm_;
ML_Comm_Create(&comm_);
this->ApplicationTime_+= t_diff;
ML_Comm_Destroy(&comm_);
#endif
return 0;
}/*end ApplyInverse_Implicit_212*/
示例4: Xcopy
//==============================================================================
int Ifpack_Polynomial::
ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
{
if (!IsComputed())
IFPACK_CHK_ERR(-3);
if (PolyDegree_ == 0)
return 0;
int nVec = X.NumVectors();
if (nVec != Y.NumVectors())
IFPACK_CHK_ERR(-2);
Time_->ResetStartTime();
Epetra_MultiVector Xcopy(X);
if(ZeroStartingSolution_==true) {
Y.PutScalar(0.0);
}
// mfh 20 Mar 2014: IBD never gets used, so I'm commenting out the
// following lines of code in order to forestall build warnings.
// #ifdef HAVE_IFPACK_EPETRAEXT
// EpetraExt_PointToBlockDiagPermute* IBD=0;
// if (UseBlockMode_) IBD=&*InvBlockDiagonal_;
// #endif
Y.Update(-coeff_[1], Xcopy, 1.0);
for (int ii = 2; ii < static_cast<int> (coeff_.size ()); ++ii) {
const Epetra_MultiVector V(Xcopy);
Operator_->Apply(V,Xcopy);
Xcopy.Multiply(1.0, *InvDiagonal_, Xcopy, 0.0);
// Update Y
Y.Update(-coeff_[ii], Xcopy, 1.0);
}
// Flops are updated in each of the following.
++NumApplyInverse_;
ApplyInverseTime_ += Time_->ElapsedTime();
return(0);
}
示例5: return
// ============================================================================
int ML_Epetra::MatrixFreePreconditioner::
ApplyJacobi(Epetra_MultiVector& X, const Epetra_MultiVector& B,
const double omega, Epetra_MultiVector& tmp) const
{
Operator_.Apply(X, tmp);
tmp.Update(1.0, B, -1.0);
ML_CHK_ERR(X.Multiply((double)omega, *InvPointDiagonal_, tmp, 1.0));
///ML_CHK_ERR(X.Multiply('T', 'N', (double)omega, *InvPointDiagonal_, tmp, 1.0));
return(0);
}
示例6: removeConstField
void MxGeoMultigridPrec::removeConstField(Epetra_MultiVector & x) const {
//x.Comm().Barrier();
Epetra_MultiVector ones(x);
double dotProd, norm;
ones.PutScalar(1);
ones.Norm2(&norm);
x.Dot(ones, &dotProd);
//std::cout << "norm = " << norm << ", dotProd = " << dotProd << "\n";
x.Update(-dotProd / norm / norm, ones, 1.);
x.Dot(ones, &dotProd);
//std::cout << "const vec part: " << dotProd << "\n";
}
示例7: temp
// ================================================ ====== ==== ==== == =
// Computes Y= <me> * X
int ML_Epetra::ML_RefMaxwell_11_Operator::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
{
Epetra_MultiVector temp(X);
/* Do the SM part */
SM_Matrix_->Apply(X,Y);
/* Do the Addon part */
Addon_->Apply(X,temp);
/* Sum things together*/
Y.Update(1,temp,1);
return 0;
}/*end Apply*/
示例8: smoothInterpolation
// return x = (I - op/rhomax)*x in x
void MxGeoMultigridPrec::smoothInterpolation(int level, Epetra_MultiVector & x) const {
Epetra_MultiVector xtmp(x);
// get matrix diagonal
Epetra_Vector diag(ops[level]->RangeMap());
ops[level]->ExtractDiagonalCopy(diag);
//diag.Reciprocal(diag);
ops[level]->Apply(x, xtmp); // xtmp = op*x
xtmp.ReciprocalMultiply(1.0, diag, xtmp, 0.0);
//xtmp.Scale(1.3333 / maxEigs[level]); // xtmp = (op/rhomax)*x
xtmp.Scale(0.5 * 1.3333); // xtmp = (op/rhomax)*x (rhomax is usually 2)
x.Update(-1.0, xtmp, 1.0); // x = x - xtmp
}
示例9: block_v
void
Stokhos::EpetraMultiVectorOrthogPoly::
assignToBlockMultiVector(Epetra_MultiVector& v) const
{
if (this->size() > 0) {
if (bv != Teuchos::null)
v.Update(1.0, *bv, 0.0);
else {
EpetraExt::BlockMultiVector block_v(View, this->coeff_[0]->Map(), v);
for (int i=0; i<this->size(); i++)
*(block_v.GetBlock(i)) = *(coeff_[i]);
}
}
}
示例10: sg_input
int
Stokhos::ProductEpetraOperator::
Apply(const Epetra_MultiVector& Input, Epetra_MultiVector& Result) const
{
if (useTranspose) {
EpetraExt::BlockMultiVector sg_input(View, *range_base_map, Input);
Epetra_MultiVector tmp(Result.Map(), Result.NumVectors());
Result.PutScalar(0.0);
for (int i=0; i<coeff_.size(); i++) {
coeff_[i]->Apply(*(sg_input.GetBlock(i)), tmp);
Result.Update(1.0, tmp, 1.0);
}
}
else {
EpetraExt::BlockMultiVector sg_result(View, *range_base_map, Result);
for (int i=0; i<coeff_.size(); i++)
coeff_[i]->Apply(Input, *(sg_result.GetBlock(i)));
}
return 0;
}
示例11: dz
//.........这里部分代码省略.........
}
if ( xnorm == 0.0 )
{
Y.Scale (0.);
dz.Scale (0.);
}
else
{
vector_Type const z (X, M_ej->solidInterfaceMap(), Unique);
M_ej->displayer().leaderPrint ( "NormInf res " , z.normInf(), "\n" );
//M_ej->solid().residual() *= 0.;
//M_ej->transferInterfaceOnSolid(z, M_ej->solid().residual());
//std::cout << "NormInf res_d " << M_ej->solid().residual().NormInf() << std::endl;
//if (M_ej->isSolid())
// M_ej->solid().postProcess();
M_ej->setLambdaFluid (z);
//M_ej->transferInterfaceOnSolid(z, M_ej->solid().disp());
chronoInterface.start();
vector_Type sigmaFluidUnique (M_ej->sigmaFluid(), Unique);
chronoInterface.stop();
M_comm->Barrier();
chronoFluid.start();
if (M_ej->isFluid() )
{
//to be used when we correct the other lines
if (true || ( !this->M_ej->dataFluid()->isSemiImplicit() /*|| this->M_ej->dataFluid().semiImplicit()==-1*/) )
{
M_ej->meshMotion().iterate (*M_ej->BCh_harmonicExtension() );
//std::cout<<" mesh motion iterated!!!"<<std::endl;
}
M_ej->displayer().leaderPrint ( " norm inf dx = " , M_ej->meshMotion().disp().normInf(), "\n" );
M_ej->solveLinearFluid();
M_ej->transferFluidOnInterface (M_ej->fluid().residual(), sigmaFluidUnique);
//M_ej->fluidPostProcess();
}
M_comm->Barrier();
chronoFluid.stop();
M_ej->displayer().leaderPrintMax ( "Fluid linear solution: total time : ", chronoFluid.diff() );
chronoInterface.start();
// M_ej->setSigmaFluid(sigmaFluidUnique);
M_ej->setSigmaSolid (sigmaFluidUnique);
vector_Type lambdaSolidUnique (M_ej->lambdaSolid(), Unique);
chronoInterface.stop();
M_comm->Barrier();
chronoFluid.start();
if (M_ej->isSolid() )
{
M_ej->solveLinearSolid();
M_ej->transferSolidOnInterface (M_ej->solid().displacement(), lambdaSolidUnique);
}
M_comm->Barrier();
chronoSolid.stop();
M_ej->displayer().leaderPrintMax ( "Solid linear solution: total time : " , chronoSolid.diff() );
chronoInterface.start();
M_ej->setLambdaSolid (lambdaSolidUnique);
chronoInterface.stop();
M_ej->displayer().leaderPrintMax ( "Interface linear transfer: total time : " , chronoInterface.diffCumul() );
dz = lambdaSolidUnique.epetraVector();
}
Y = X;
Y.Update (1., dz, -1.);
double ynorm;
Y.NormInf (&ynorm);
if (M_ej->isSolid() )
std::cout << "\n\n ***** norm (Jz)= " << ynorm
<< std::endl << std::endl;
return 0;
}
示例12: main
int main(int argc, char *argv[])
{
#ifdef HAVE_MPI
Teuchos::GlobalMPISession mpiSession(&argc, &argv, 0);
Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
Epetra_SerialComm Comm;
#endif
int nProcs, myPID ;
Teuchos::ParameterList pLUList ; // ParaLU parameters
Teuchos::ParameterList isoList ; // Isorropia parameters
string ipFileName = "ShyLU.xml"; // TODO : Accept as i/p
nProcs = mpiSession.getNProc();
myPID = Comm.MyPID();
if (myPID == 0)
{
cout <<"Parallel execution: nProcs="<< nProcs << endl;
}
// =================== Read input xml file =============================
Teuchos::updateParametersFromXmlFile(ipFileName, &pLUList);
isoList = pLUList.sublist("Isorropia Input");
// Get matrix market file name
string MMFileName = Teuchos::getParameter<string>(pLUList, "mm_file");
string prec_type = Teuchos::getParameter<string>(pLUList, "preconditioner");
if (myPID == 0)
{
cout << "Input :" << endl;
cout << "ParaLU params " << endl;
pLUList.print(std::cout, 2, true, true);
cout << "Matrix market file name: " << MMFileName << endl;
}
// ==================== Read input Matrix ==============================
Epetra_CrsMatrix *A;
int err = EpetraExt::MatrixMarketFileToCrsMatrix(MMFileName.c_str(), Comm, A);
//EpetraExt::MatlabFileToCrsMatrix(MMFileName.c_str(), Comm, A);
//assert(err != 0);
cout <<"Done reading the matrix"<< endl;
int n = A->NumGlobalRows();
cout <<"n="<< n << endl;
// Create input vectors
Epetra_Map vecMap(n, 0, Comm);
Epetra_MultiVector x(vecMap, 1);
Epetra_MultiVector b(vecMap, 1, false);
b.PutScalar(1.0); // TODO : Accept it as input
// Partition the matrix with hypergraph partitioning and redisstribute
Isorropia::Epetra::Partitioner *partitioner = new
Isorropia::Epetra::Partitioner(A, isoList, false);
partitioner->partition();
Isorropia::Epetra::Redistributor rd(partitioner);
Epetra_CrsMatrix *newA;
Epetra_MultiVector *newX, *newB;
rd.redistribute(*A, newA);
delete A;
A = newA;
rd.redistribute(x, newX);
rd.redistribute(b, newB);
Epetra_LinearProblem problem(A, newX, newB);
Amesos Factory;
char* SolverType = "Amesos_Klu";
bool IsAvailable = Factory.Query(SolverType);
Epetra_LinearProblem *LP = new Epetra_LinearProblem();
LP->SetOperator(A);
LP->SetLHS(newX);
LP->SetRHS(newB);
Amesos_BaseSolver *Solver = Factory.Create(SolverType, *LP);
Solver->SymbolicFactorization();
Teuchos::Time ftime("setup time");
ftime.start();
Solver->NumericFactorization();
cout << "Numeric Factorization" << endl;
Solver->Solve();
cout << "Solve done" << endl;
ftime.stop();
cout << "Time to setup" << ftime.totalElapsedTime() << endl;
// compute ||Ax - b||
double Norm;
Epetra_MultiVector Ax(vecMap, 1);
Epetra_MultiVector *newAx;
rd.redistribute(Ax, newAx);
A->Multiply(false, *newX, *newAx);
newAx->Update(1.0, *newB, -1.0);
newAx->Norm2(&Norm);
//.........这里部分代码省略.........
示例13: UpdateReducedProblem
//==============================================================================
int LinearProblem_CrsSingletonFilter::UpdateReducedProblem(Epetra_LinearProblem * Problem) {
int i, j;
if (Problem==0) EPETRA_CHK_ERR(-1); // Null problem pointer
FullProblem_ = Problem;
FullMatrix_ = dynamic_cast<Epetra_RowMatrix *>(Problem->GetMatrix());
if (FullMatrix_==0) EPETRA_CHK_ERR(-2); // Need a RowMatrix
if (Problem->GetRHS()==0) EPETRA_CHK_ERR(-3); // Need a RHS
if (Problem->GetLHS()==0) EPETRA_CHK_ERR(-4); // Need a LHS
if (!HaveReducedProblem_) EPETRA_CHK_ERR(-5); // Must have set up reduced problem
// Create pointer to Full RHS, LHS
Epetra_MultiVector * FullRHS = FullProblem()->GetRHS();
Epetra_MultiVector * FullLHS = FullProblem()->GetLHS();
int NumVectors = FullLHS->NumVectors();
int NumEntries;
int * Indices;
double * Values;
int NumMyRows = FullMatrix()->NumMyRows();
int ColSingletonCounter = 0;
for (i=0; i<NumMyRows; i++) {
int curGRID = FullMatrixRowMap().GID(i);
if (ReducedMatrixRowMap()->MyGID(curGRID)) { // Check if this row should go into reduced matrix
EPETRA_CHK_ERR(GetRowGCIDs(i, NumEntries, Values, Indices)); // Get current row (indices global)
int ierr = ReducedMatrix()->ReplaceGlobalValues(curGRID, NumEntries,
Values, Indices);
// Positive errors will occur because we are submitting col entries that are not part of
// reduced system. However, because we specified a column map to the ReducedMatrix constructor
// these extra column entries will be ignored and we will be politely reminded by a positive
// error code
if (ierr<0) EPETRA_CHK_ERR(ierr);
}
// Otherwise if singleton row we explicitly eliminate this row and solve for corresponding X value
else {
EPETRA_CHK_ERR(GetRow(i, NumEntries, Values, Indices)); // Get current row
if (NumEntries==1) {
double pivot = Values[0];
if (pivot==0.0) EPETRA_CHK_ERR(-1); // Encountered zero row, unable to continue
int indX = Indices[0];
for (j=0; j<NumVectors; j++)
(*tempExportX_)[j][indX] = (*FullRHS)[j][i]/pivot;
}
// Otherwise, this is a singleton column and we will scan for the pivot element needed
// for post-solve equations
else {
j = ColSingletonPivotLIDs_[ColSingletonCounter];
double pivot = Values[j];
if (pivot==0.0) EPETRA_CHK_ERR(-2); // Encountered zero column, unable to continue
ColSingletonPivots_[ColSingletonCounter] = pivot;
ColSingletonCounter++;
}
}
}
assert(ColSingletonCounter==NumMyColSingletons_); // Sanity test
// Update Reduced LHS (Puts any initial guess values into reduced system)
ReducedLHS_->PutScalar(0.0); // zero out Reduced LHS
EPETRA_CHK_ERR(ReducedLHS_->Import(*FullLHS, *Full2ReducedLHSImporter_, Insert));
FullLHS->PutScalar(0.0); // zero out Full LHS since we will inject values as we get them
// Construct Reduced RHS
// Zero out temp space
tempX_->PutScalar(0.0);
tempB_->PutScalar(0.0);
//Inject known X values into tempX for purpose of computing tempB = FullMatrix*tempX
// Also inject into full X since we already know the solution
if (FullMatrix()->RowMatrixImporter()!=0) {
EPETRA_CHK_ERR(tempX_->Export(*tempExportX_, *FullMatrix()->RowMatrixImporter(), Add));
EPETRA_CHK_ERR(FullLHS->Export(*tempExportX_, *FullMatrix()->RowMatrixImporter(), Add));
}
else {
tempX_->Update(1.0, *tempExportX_, 0.0);
FullLHS->Update(1.0, *tempExportX_, 0.0);
}
EPETRA_CHK_ERR(FullMatrix()->Multiply(false, *tempX_, *tempB_));
EPETRA_CHK_ERR(tempB_->Update(1.0, *FullRHS, -1.0)); // tempB now has influence of already-known X values
ReducedRHS_->PutScalar(0.0);
EPETRA_CHK_ERR(ReducedRHS_->Import(*tempB_, *Full2ReducedRHSImporter_, Insert));
return(0);
}
示例14: ConstructReducedProblem
//.........这里部分代码省略.........
// Create storage for temporary X values due to explicit elimination of rows
tempExportX_ = new Epetra_MultiVector(FullMatrixColMap(), NumVectors);
int NumEntries;
int * Indices;
double * Values;
int NumMyRows = FullMatrix()->NumMyRows();
int ColSingletonCounter = 0;
for (i=0; i<NumMyRows; i++) {
int curGRID = FullMatrixRowMap().GID(i);
if (ReducedMatrixRowMap()->MyGID(curGRID)) { // Check if this row should go into reduced matrix
EPETRA_CHK_ERR(GetRowGCIDs(i, NumEntries, Values, Indices)); // Get current row (Indices are global)
int ierr = ReducedMatrix()->InsertGlobalValues(curGRID, NumEntries,
Values, Indices); // Insert into reduce matrix
// Positive errors will occur because we are submitting col entries that are not part of
// reduced system. However, because we specified a column map to the ReducedMatrix constructor
// these extra column entries will be ignored and we will be politely reminded by a positive
// error code
if (ierr<0) EPETRA_CHK_ERR(ierr);
}
else {
EPETRA_CHK_ERR(GetRow(i, NumEntries, Values, Indices)); // Get current row
if (NumEntries==1) {
double pivot = Values[0];
if (pivot==0.0) EPETRA_CHK_ERR(-1); // Encountered zero row, unable to continue
int indX = Indices[0];
for (j=0; j<NumVectors; j++)
(*tempExportX_)[j][indX] = (*FullRHS)[j][i]/pivot;
}
// Otherwise, this is a singleton column and we will scan for the pivot element needed
// for post-solve equations
else {
int targetCol = ColSingletonColLIDs_[ColSingletonCounter];
for (j=0; j<NumEntries; j++) {
if (Indices[j]==targetCol) {
double pivot = Values[j];
if (pivot==0.0) EPETRA_CHK_ERR(-2); // Encountered zero column, unable to continue
ColSingletonPivotLIDs_[ColSingletonCounter] = j; // Save for later use
ColSingletonPivots_[ColSingletonCounter] = pivot;
ColSingletonCounter++;
break;
}
}
}
}
}
// Now convert to local indexing. We have constructed things so that the domain and range of the
// matrix will have the same map. If the reduced matrix domain and range maps were not the same, the
// differences were addressed in the ConstructRedistributeExporter() method
EPETRA_CHK_ERR(ReducedMatrix()->FillComplete(*ReducedMatrixDomainMap(), *ReducedMatrixRangeMap()));
// Construct Reduced LHS (Puts any initial guess values into reduced system)
ReducedLHS_ = new Epetra_MultiVector(*ReducedMatrixDomainMap(), NumVectors);
EPETRA_CHK_ERR(ReducedLHS_->Import(*FullLHS, *Full2ReducedLHSImporter_, Insert));
FullLHS->PutScalar(0.0); // zero out Full LHS since we will inject values as we get them
// Construct Reduced RHS
// First compute influence of already-known values of X on RHS
tempX_ = new Epetra_MultiVector(FullMatrixDomainMap(), NumVectors);
tempB_ = new Epetra_MultiVector(FullRHS->Map(), NumVectors);
//Inject known X values into tempX for purpose of computing tempB = FullMatrix*tempX
// Also inject into full X since we already know the solution
if (FullMatrix()->RowMatrixImporter()!=0) {
EPETRA_CHK_ERR(tempX_->Export(*tempExportX_, *FullMatrix()->RowMatrixImporter(), Add));
EPETRA_CHK_ERR(FullLHS->Export(*tempExportX_, *FullMatrix()->RowMatrixImporter(), Add));
}
else {
tempX_->Update(1.0, *tempExportX_, 0.0);
FullLHS->Update(1.0, *tempExportX_, 0.0);
}
EPETRA_CHK_ERR(FullMatrix()->Multiply(false, *tempX_, *tempB_));
EPETRA_CHK_ERR(tempB_->Update(1.0, *FullRHS, -1.0)); // tempB now has influence of already-known X values
ReducedRHS_ = new Epetra_MultiVector(*ReducedMatrixRowMap(), FullRHS->NumVectors());
EPETRA_CHK_ERR(ReducedRHS_->Import(*tempB_, *Full2ReducedRHSImporter_, Insert));
// Finally construct Reduced Linear Problem
ReducedProblem_ = new Epetra_LinearProblem(ReducedMatrix_, ReducedLHS_, ReducedRHS_);
double fn = FullMatrix()->NumGlobalRows();
double fnnz = FullMatrix()->NumGlobalNonzeros();
double rn = ReducedMatrix()->NumGlobalRows();
double rnnz = ReducedMatrix()->NumGlobalNonzeros();
RatioOfDimensions_ = rn/fn;
RatioOfNonzeros_ = rnnz/fnnz;
HaveReducedProblem_ = true;
return(0);
}
示例15: r_edge
// ================================================ ====== ==== ==== == =
//! Apply the preconditioner to an Epetra_MultiVector X, puts the result in Y
int ML_Epetra::FaceMatrixFreePreconditioner::ApplyInverse(const Epetra_MultiVector& B_, Epetra_MultiVector& X) const{
const Epetra_MultiVector *B;
Epetra_MultiVector *Bcopy=0;
/* Sanity Checks */
int NumVectors=B_.NumVectors();
if (!B_.Map().SameAs(*FaceDomainMap_)) ML_CHK_ERR(-1);
if (NumVectors != X.NumVectors()) ML_CHK_ERR(-1);
Epetra_MultiVector r_edge(*FaceDomainMap_,NumVectors,false);
Epetra_MultiVector e_edge(*FaceDomainMap_,NumVectors,false);
Epetra_MultiVector e_node(*CoarseMap_,NumVectors,false);
Epetra_MultiVector r_node(*CoarseMap_,NumVectors,false);
/* Deal with the B==X case */
if (B_.Pointers()[0] == X.Pointers()[0]){
Bcopy=new Epetra_MultiVector(B_);
B=Bcopy;
X.PutScalar(0.0);
}
else B=&B_;
for(int i=0;i<num_cycles;i++){
/* Pre-smoothing */
#ifdef HAVE_ML_IFPACK
if(Smoother_) ML_CHK_ERR(Smoother_->ApplyInverse(*B,X));
#endif
if(MaxLevels > 0){
if(i != 0
#ifdef HAVE_ML_IFPACK
|| Smoother_
#endif
){
/* Calculate Residual (r_e = b - (S+M+Addon) * x) */
ML_CHK_ERR(Operator_->Apply(X,r_edge));
ML_CHK_ERR(r_edge.Update(1.0,*B,-1.0));
/* Xfer to coarse grid (r_n = P' * r_e) */
ML_CHK_ERR(Prolongator_->Multiply(true,r_edge,r_node));
}
else{
/* Xfer to coarse grid (r_n = P' * r_e) */
ML_CHK_ERR(Prolongator_->Multiply(true,*B,r_node));
}
/* AMG on coarse grid (e_n = (CoarseMatrix)^{-1} r_n) */
ML_CHK_ERR(CoarsePC->ApplyInverse(r_node,e_node));
/* Xfer back to fine grid (e_e = P * e_n) */
ML_CHK_ERR(Prolongator_->Multiply(false,e_node,e_edge));
/* Add in correction (x = x + e_e) */
ML_CHK_ERR(X.Update(1.0,e_edge,1.0));
}/*end if*/
/* Post-Smoothing */
#ifdef HAVE_ML_IFPACK
if(Smoother_) ML_CHK_ERR(Smoother_->ApplyInverse(*B,X));
#endif
}/*end for*/
/* Cleanup */
if(Bcopy) delete Bcopy;
return 0;
}/*end ApplyInverse*/