Пример #1
0
/*!
 * \brief Solve.
 */
void JacobiSolver::iterate( const int max_iters, const double tolerance )
{
    // Extract the linear problem.
    Epetra_CrsMatrix *A = 
	dynamic_cast<Epetra_CrsMatrix*>( d_linear_problem->GetMatrix() );
    Epetra_Vector *x = 
	dynamic_cast<Epetra_Vector*>( d_linear_problem->GetLHS() );
    const Epetra_Vector *b = 
	dynamic_cast<Epetra_Vector*>( d_linear_problem->GetRHS() );

    // Setup the residual.
    Epetra_Map row_map = A->RowMap();
    Epetra_Vector residual( row_map );

    // Iterate.
    Epetra_CrsMatrix H = buildH( A );
    Epetra_Vector temp_vec( row_map );
    d_num_iters = 0;
    double residual_norm = 1.0;
    double b_norm;
    b->NormInf( &b_norm );
    double conv_crit = b_norm*tolerance;
    while ( residual_norm > conv_crit && d_num_iters < max_iters )
    {
	H.Apply( *x, temp_vec );
	x->Update( 1.0, temp_vec, 1.0, *b, 0.0 );

	A->Apply( *x, temp_vec );
	residual.Update( 1.0, *b, -1.0, temp_vec, 0.0 );

	residual.NormInf( &residual_norm );
	++d_num_iters;
    }
}
Пример #2
0
// B here is the "reduced" matrix.  Square matrices w/ Row=Domain=Range only.
double test_with_matvec_reduced_maps(const Epetra_CrsMatrix &A, const Epetra_CrsMatrix &B, const Epetra_Map & Bfullmap){
  const Epetra_Map & Amap  = A.DomainMap();
  Epetra_Vector Xa(Amap), Ya(Amap), Diff(Amap);
  const Epetra_Map *Bmap  = Bfullmap.NumMyElements() > 0 ? &B.DomainMap() : 0;
  Epetra_Vector *Xb = Bmap ? new Epetra_Vector(*Bmap) : 0;
  Epetra_Vector *Yb = Bmap ? new Epetra_Vector(*Bmap) : 0;

  Epetra_Vector Xb_alias(View,Bfullmap, Bmap ? Xb->Values(): 0);
  Epetra_Vector Yb_alias(View,Bfullmap, Bmap ? Yb->Values(): 0);

  Epetra_Import Ximport(Bfullmap,Amap);

  // Set the input vector
  Xa.SetSeed(24601);
  Xa.Random();
  Xb_alias.Import(Xa,Ximport,Insert);

  // Do the multiplies
  A.Apply(Xa,Ya);
  if(Bmap) B.Apply(*Xb,*Yb);

  // Check solution
  Epetra_Import Yimport(Amap,Bfullmap);
  Diff.Import(Yb_alias,Yimport,Insert);


  Diff.Update(-1.0,Ya,1.0);
  double norm;
  Diff.Norm2(&norm);

  delete Xb; delete Yb;
  return norm;
}
Пример #3
0
void PhcGeoMGPrec::GetBoundaryBulkResiduals (const Epetra_CrsMatrix & op, 
                                             const Epetra_MultiVector & x, 
                                             const Epetra_MultiVector & b,
                                             double & bndryRes,
                                             double & bulkRes,
                                             double & totalRes,
                                             int level) const {
  Epetra_MultiVector work(x);
  op.Apply(x, work);
  work.Update(-1., b, 1.);
  bndryRes=0.; bulkRes=0.; totalRes=0.;

  int numInds = x.Map().getNodeNumElements();
  double * vals = work[0];
  for (int i=0; i<numInds; i++) {
    double val = vals[i];
    double afrac = (*dmAreas_[level])[i];
    if ((afrac==0.) || (afrac==1.))
      bulkRes += val*val;
    else {
      //std::cout << "afrac: " << afrac << std::endl;
      bndryRes += val*val;
    }
    totalRes += val*val;
  }
  bulkRes = sqrt(bulkRes);
  bndryRes = sqrt(bndryRes);
  totalRes = sqrt(totalRes);
}
Пример #4
0
double MxGeoMultigridPrec::getResidual(const Epetra_CrsMatrix & op, const Epetra_MultiVector & x, 
const Epetra_MultiVector & b) const {
  Epetra_MultiVector work(x);
  op.Apply(x, work);
  work.Update(-1., b, 1.);
  double res;
  work.Norm2(&res);
  return res;
}
Пример #5
0
double test_with_matvec(const Epetra_CrsMatrix &A, const Epetra_CrsMatrix &B){
  const Epetra_Map & Xamap  = A.DomainMap();
  const Epetra_Map & Yamap  = A.RangeMap();
  const Epetra_Map & Xbmap  = B.DomainMap();
  const Epetra_Map & Ybmap  = B.RangeMap();

  Epetra_Vector Xa(Xamap), Xb(Xbmap), Ya(Yamap), Yb(Ybmap), Diff(Yamap);

  Xa.SetSeed(24601);
  Xa.Random();

  // Handle domain map change
  if(!Xamap.SameAs(Xbmap)) {
    Epetra_Import Ximport(Xbmap,Xamap);
    Xb.Import(Xa,Ximport,Insert);
  }
  else {
    Xb=Xa;
  }

  // Do the multiplies
  A.Apply(Xa,Ya);
  B.Apply(Xb,Yb);

  // Handle Rangemap change
  if(!Yamap.SameAs(Ybmap)) {
    Epetra_Import Yimport(Yamap,Ybmap);
    Diff.Import(Yb,Yimport,Insert);
  }
  else {
    Diff=Yb;
  }

  // Check solution
  Diff.Update(-1.0,Ya,1.0);
  double norm;
  Diff.Norm2(&norm);

  return norm;
}
Пример #6
0
int main(int argc, char *argv[]) {

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm comm (MPI_COMM_WORLD);
#else
  Epetra_SerialComm comm;
#endif

  int MyPID = comm.MyPID();

  bool verbose = false;
  bool verbose1 = false; 
  // Check if we should print results to standard out
  if (argc > 1) {
    if ((argv[1][0] == '-') && (argv[1][1] == 'v')) {
      verbose1 = true;
      if (MyPID==0) verbose = true;
    }
  }

  if (verbose1) cout << comm << endl;


  // Uncomment the next three lines to debug in mpi mode
  //int tmp;
  //if (MyPID==0) cin >> tmp;
  //comm.Barrier();

  Epetra_CrsMatrix * A; 
  EPETRA_CHK_ERR(EpetraExt::MatlabFileToCrsMatrix("A.dat", comm, A));

  Epetra_Vector  x(A->OperatorDomainMap()); 
  Epetra_Vector  b(A->OperatorRangeMap());
  x.Random();
  A->Apply(x,b); // Generate RHS from x
  Epetra_Vector xx(x); // Copy x to xx for later use

  Epetra_LinearProblem problem(A, &x, &b);
  // Construct a solver object for this problem

  AztecOO solver(problem);
  solver.SetAztecOption(AZ_precond, AZ_none);
  if (!verbose1) solver.SetAztecOption(AZ_output, AZ_none);
  solver.SetAztecOption(AZ_kspace, A->NumGlobalRows());
  AztecOO_Operator AOpInv(&solver, A->NumGlobalRows());
  Epetra_InvOperator AInvOp(&AOpInv);

  EPETRA_CHK_ERR(EpetraExt::OperatorToMatlabFile("Ainv.dat", AInvOp));

  comm.Barrier();

  Epetra_CrsMatrix * AInv; 
  EPETRA_CHK_ERR(EpetraExt::MatlabFileToCrsMatrix("Ainv.dat", comm, AInv));

  EPETRA_CHK_ERR(AInv->Apply(b,x));

  EPETRA_CHK_ERR(x.Update(1.0, xx, -1.0));
  double residual = 0.0;
  EPETRA_CHK_ERR(x.Norm2(&residual));
  if (verbose) cout << "Norm of difference between computed x and exact x = " << residual << endl;
  int ierr = checkValues(residual,0.0,"Norm of difference between computed A1x1 and A1x1 from file", verbose);

  
  delete A;
  delete AInv;


  #ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

  return(ierr);
}