コード例 #1
0
//=============================================================================
int Epetra_MsrMatrix::InvRowSums(Epetra_Vector& x) const {
//
// Put inverse of the sum of absolute values of the ith row of A in x[i].
//

  if (!OperatorRangeMap().SameAs(x.Map())) EPETRA_CHK_ERR(-2); // x must have the same distribution as the range of A

  int ierr = 0;
  int i, j;
  for (i=0; i < NumMyRows_; i++) {
    int NumEntries = GetRow(i); // Copies ith row of matrix into Values_ and Indices_
    double scale = 0.0;
    for (j=0; j < NumEntries; j++) scale += fabs(Values_[j]);
    if (scale<Epetra_MinDouble) {
      if (scale==0.0) ierr = 1; // Set error to 1 to signal that zero rowsum found (supercedes ierr = 2)
      else if (ierr!=1) ierr = 2;
      x[i] = Epetra_MaxDouble;
    }
    else
      x[i] = 1.0/scale;
  }
  UpdateFlops(NumGlobalNonzeros());
  EPETRA_CHK_ERR(ierr);
  return(0);
}
コード例 #2
0
//=============================================================================
int Epetra_MsrMatrix::LeftScale(const Epetra_Vector& x) {
//
// This function scales the ith row of A by x[i].
//
  // For this method, we have no choice but to work with the UGLY MSR data structures.

  if (!Filled()) EPETRA_CHK_ERR(-1); // Matrix must be filled.
  if (!OperatorRangeMap().SameAs(x.Map())) EPETRA_CHK_ERR(-2); // x must have the same distribution as the range of A

  int i, j;
  int * bindx = Amat_->bindx;
  double * val = Amat_->val;


  for (i=0; i < NumMyRows_; i++) {
    
    int NumEntries = bindx[i+1] - bindx[i];
    double scale = x[i];
    val[i] *= scale;
    double * Values = val + bindx[i];
    for (j=0; j < NumEntries; j++)  Values[j] *= scale;
  }
  NormOne_ = -1.0; // Reset Norm so it will be recomputed.
  NormInf_ = -1.0; // Reset Norm so it will be recomputed.
  UpdateFlops(NumGlobalNonzeros());
  return(0);
}
コード例 #3
0
//==============================================================================
int Poisson2dOperator::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const {


    // This is a very brain-dead implementation of a 5-point finite difference stencil, but
    // it should illustrate the basic process for implementing the Epetra_Operator interface.

    if (!X.Map().SameAs(OperatorDomainMap())) abort();  // These aborts should be handled as int return codes.
    if (!Y.Map().SameAs(OperatorRangeMap())) abort();
    if (Y.NumVectors()!=X.NumVectors()) abort();

    if (comm_.NumProc()>1) {
        if (importX_==0)
            importX_ = new Epetra_MultiVector(*importMap_, X.NumVectors());
        else if (importX_->NumVectors()!=X.NumVectors()) {
            delete importX_;
            importX_ = new Epetra_MultiVector(*importMap_, X.NumVectors());
        }
        importX_->Import(X, *importer_, Insert); // Get x values we need
    }

    double * importx1 = 0;
    double * importx2 = 0;
    int nx = nx_;
    //int ny = ny_;

    for (int j=0; j < X.NumVectors(); j++) {

        const double * x = X[j];
        if (comm_.NumProc()>1) {
            importx1 = (*importX_)[j];
            importx2 = importx1+nx;
            if (comm_.MyPID()==0) importx2=importx1;
        }
        double * y = Y[j];
        if (comm_.MyPID()==0) {
            y[0] = 4.0*x[0]-x[nx]-x[1];
            y[nx-1] = 4.0*x[nx-1]-x[nx-2]-x[nx+nx-1];
            for (int ix=1; ix< nx-1; ix++)
                y[ix] = 4.0*x[ix]-x[ix-1]-x[ix+1]-x[ix+nx];
        }
        else {
            y[0] = 4.0*x[0]-x[nx]-x[1]-importx1[0];
            y[nx-1] = 4.0*x[nx-1]-x[nx-2]-x[nx+nx-1]-importx1[nx-1];
            for (int ix=1; ix< nx-1; ix++)
                y[ix] = 4.0*x[ix]-x[ix-1]-x[ix+1]-x[ix+nx]-importx1[ix];
        }
        if (comm_.MyPID()+1==comm_.NumProc()) {
            int curxy = nx*myny_-1;
            y[curxy] = 4.0*x[curxy]-x[curxy-nx]-x[curxy-1];
            curxy -= (nx-1);
            y[curxy] = 4.0*x[curxy]-x[curxy-nx]-x[curxy+1];
            for (int ix=1; ix< nx-1; ix++) {
                curxy++;
                y[curxy] = 4.0*x[curxy]-x[curxy-1]-x[curxy+1]-x[curxy-nx];
            }
        }
        else {
            int curxy = nx*myny_-1;
            y[curxy] = 4.0*x[curxy]-x[curxy-nx]-x[curxy-1]-importx2[nx-1];
            curxy -= (nx-1);
            y[curxy] = 4.0*x[curxy]-x[curxy-nx]-x[curxy+1]-importx2[0];
            for (int ix=1; ix< nx-1; ix++) {
                curxy++;
                y[curxy] = 4.0*x[curxy]-x[curxy-1]-x[curxy+1]-x[curxy-nx]-importx2[ix];
            }
        }
        for (int iy=1; iy< myny_-1; iy++) {
            int curxy = nx*(iy+1)-1;
            y[curxy] = 4.0*x[curxy]-x[curxy-nx]-x[curxy-1]-x[curxy+nx];
            curxy -= (nx-1);
            y[curxy] = 4.0*x[curxy]-x[curxy-nx]-x[curxy+1]-x[curxy+nx];
            for (int ix=1; ix< nx-1; ix++) {
                curxy++;
                y[curxy] = 4.0*x[curxy]-x[curxy-1]-x[curxy+1]-x[curxy-nx]-x[curxy+nx];
            }
        }
    }
    return(0);
}
コード例 #4
0
// ================================================ ====== ==== ==== == =
// Computes the preconditioner
int ML_Epetra::FaceMatrixFreePreconditioner::ComputePreconditioner(const bool CheckFiltering)
{
  Teuchos::ParameterList & ListCoarse=List_.sublist("face matrix free: coarse");

  /* ML Communicator */
  ML_Comm_Create(&ml_comm_);

  /* Parameter List Options */
  int SmootherSweeps = List_.get("smoother: sweeps", 0);
  MaxLevels = List_.get("max levels",10);
  print_hierarchy= List_.get("print hierarchy",false);
  num_cycles  = List_.get("cycle applications",1);

  /* Sanity Checking*/
  int OperatorDomainPoints =  OperatorDomainMap().NumGlobalPoints();
  int OperatorRangePoints =  OperatorRangeMap().NumGlobalPoints();
  if (OperatorDomainPoints != OperatorRangePoints)
    ML_CHK_ERR(-1); // only square matrices

 /* Output Header */
  if(verbose_ && !Comm_->MyPID()) {
    printf("------------------------------------------------------------------------------\n");
    printf("***\n");
    printf("*** ML_Epetra::FaceMatrixFreePreconditioner [%s]\n",Label());
    printf("***\n");
  }

  /* Invert non-zeros on the diagonal */
  if(SmootherSweeps){
    for (int i = 0; i < InvDiagonal_->MyLength(); ++i)
      if ((*InvDiagonal_)[i] != 0.0)
        (*InvDiagonal_)[i] = 1.0 / (*InvDiagonal_)[i];
    double nrm;
    InvDiagonal_->Norm2(&nrm);
    if(verbose_ && !Comm_->MyPID()) printf("Inverse Diagonal Norm = %6.4e\n",nrm);
  }/*end if*/

  /* Do the eigenvalue estimation for Chebyshev */
  if(SmootherSweeps)
    ML_CHK_ERR(SetupSmoother());


  if(MaxLevels > 0) {
    /* Build the prolongator */
    ML_CHK_ERR(BuildProlongator());

    /* DEBUG: Output matrices */
    if(print_hierarchy) EpetraExt::RowMatrixToMatlabFile("prolongator.dat",*Prolongator_);

    /* Form the coarse matrix */
    ML_CHK_ERR(FormCoarseMatrix());

    /* DEBUG: Output matrices */
    if(print_hierarchy) EpetraExt::RowMatrixToMatlabFile("coarsemat.dat",*CoarseMatrix);

    /* Setup Preconditioner on Coarse Matrix */
    CoarsePC = new MultiLevelPreconditioner(*CoarseMatrix,ListCoarse);
    if(!CoarsePC) ML_CHK_ERR(-2);

    /* Clean Up */
    //delete nullspace;
  }/*end if*/

  return 0;
}/*end ComputePreconditioner*/