//EpetraVector_To_TpetraVectorNonConst: copies Epetra_Vector to non-const Tpetra_Vector
Teuchos::RCP<Tpetra_Vector> Petra::EpetraVector_To_TpetraVectorNonConst(const Epetra_Vector& epetraVector_,
                                                               const Teuchos::RCP<const Teuchos::Comm<int> >& commT_)
{
  //get map from epetraVector_ and convert to Tpetra::Map
  auto mapT = EpetraMap_To_TpetraMap(epetraVector_.Map(), commT_);
  ST *values;
  epetraVector_.ExtractView(&values);
  Teuchos::ArrayView<ST> valuesAV = Teuchos::arrayView(values, mapT->getNodeNumElements());
  Teuchos::RCP<Tpetra_Vector> tpetraVector_ = Teuchos::rcp(new Tpetra_Vector(mapT, valuesAV));
  return tpetraVector_;
}
//=============================================================================
int Epetra_PETScAIJMatrix::RightScale(const Epetra_Vector& X) {
//
// This function scales the jth row of A by x[j].
//
  double *xptr;
  X.ExtractView(&xptr);
  Vec petscX;
# ifdef HAVE_MPI
  int ierr=VecCreateMPIWithArray(Comm_->Comm(),X.MyLength(),X.GlobalLength(),xptr,&petscX); CHKERRQ(ierr);
# else //FIXME  untested
  int ierr=VecCreateSeqWithArray(Comm_->Comm(),X.MyLength(),X.GlobalLength(),xptr,&petscX); CHKERRQ(ierr);
# endif

  MatDiagonalScale(Amat_, PETSC_NULL, petscX);

  ierr=VecDestroy(petscX); CHKERRQ(ierr);
  return(0);
} //RightScale()
Beispiel #3
0
int test_azoo_scaling(Epetra_CrsMatrix& A,
                      Epetra_Vector& x,
                      Epetra_Vector& b,
                      bool verbose)
{
  Epetra_Vector vec1(x);
  Epetra_Vector vec2(x);
  Epetra_Vector diag(x);
  Epetra_Vector vec3(x);
  Epetra_Vector vec4(x);
  Epetra_Vector rhs(x);
  Epetra_Vector soln_none(x);
  Epetra_Vector soln_jacobi(x);
  Epetra_Vector soln_rowsum(x);
  Epetra_Vector soln_symdiag(x);

  vec1.PutScalar(1.0);

  A.Multiply(false, vec1, vec2);

  A.ExtractDiagonalCopy(diag);

  double* diag_vals = NULL;
  diag.ExtractView(&diag_vals);

  int* options = new int[AZ_OPTIONS_SIZE];
  double* params = new double[AZ_PARAMS_SIZE];
  AZ_defaults(options, params);

  options[AZ_output] = verbose ? 1 : AZ_none;

  options[AZ_scaling] = AZ_Jacobi;
  AztecOO::MatrixData mdata(&A);
  AZ_MATRIX* Amat = AZ_matrix_create(vec1.Map().NumMyElements());
  AZ_set_MATFREE(Amat, (void*)(&mdata), Epetra_Aztec_matvec);

  AZ_SCALING* scaling = AZ_scaling_create();

  double* xvals = NULL, *bvals = NULL;
  x.ExtractView(&xvals);
  b.ExtractView(&bvals);

  int err = AztecOO_scale_epetra(AZ_SCALE_MAT_RHS_SOL, Amat,
                                 options, bvals, xvals, NULL, scaling);
  if (err != 0) {
    if (verbose) {
      cout << "AztecOO_scale_epetra returned err="<<err<<endl;
    }
    return(err);
  }

  A.Multiply(false, vec1, vec3);

  vec4.Multiply(1.0, diag, vec3, 0.0);

  double vec2nrm, vec4nrm;

  vec2.Norm2(&vec2nrm);
  vec4.Norm2(&vec4nrm);

  if (fabs(vec2nrm - vec4nrm) > 1.e-6) {
    return(-1);
  }

  //now call the scaling function again, just to allow for
  //testing memory-leak issues.
  err = AztecOO_scale_epetra(AZ_SCALE_MAT_RHS_SOL, Amat,
                             options, bvals, xvals, NULL, scaling);
  if (err != 0) {
    if (verbose) {
      cout << "AztecOO_scale_epetra returned err="<<err<<endl;
    }
    return(err);
  }

  AztecOO_scale_epetra(AZ_DESTROY_SCALING_DATA, Amat, options,
                       bvals, xvals, NULL, scaling);

  x.PutScalar(1.0);

  Epetra_CrsMatrix* Atmp = create_and_fill_crs_matrix(A.RowMap());
  Atmp->Multiply(false, x, rhs);

  x.PutScalar(0.0);

  AztecOO azoo(&A, &x, &b);

  azoo.SetAztecOption(AZ_scaling, AZ_Jacobi);
  if (verbose) {
    azoo.SetAztecOption(AZ_output, 1);
  }
  else {
    azoo.SetAztecOption(AZ_output, AZ_none);
  }

  azoo.Iterate(100, 1.e-6);

  delete Atmp;

  Epetra_CrsMatrix* Atmp1 = create_and_fill_crs_matrix(A.RowMap());

  x.PutScalar(1.0);

  Atmp1->Multiply(false, x, rhs);

  soln_rowsum.PutScalar(0.0);

  AztecOO azoo1(Atmp1, &soln_rowsum, &rhs);

  azoo1.SetAztecOption(AZ_scaling, AZ_row_sum);

  azoo1.Iterate(100, 1.e-8);

  delete Atmp1;

  Epetra_CrsMatrix* Atmp2 = create_and_fill_crs_matrix(A.RowMap());

  x.PutScalar(1.0);

  Atmp2->Multiply(false, x, rhs);

  soln_symdiag.PutScalar(0.0);

  AztecOO azoo2(Atmp2, &soln_symdiag, &rhs);

  azoo2.SetAztecOption(AZ_scaling, AZ_sym_diag);

  azoo2.Iterate(100, 1.e-8);

  delete Atmp2;

  Epetra_CrsMatrix* Atmp3 = create_and_fill_crs_matrix(A.RowMap());

  x.PutScalar(1.0);

  Atmp3->Multiply(false, x, rhs);

  soln_none.PutScalar(0.0);

  AztecOO azoo3(Atmp3, &soln_none, &rhs);

  azoo3.SetAztecOption(AZ_scaling, AZ_none);

  azoo3.Iterate(100, 1.e-8);

  delete Atmp3;


  Epetra_CrsMatrix* Atmp4 = create_and_fill_crs_matrix(A.RowMap());

  x.PutScalar(1.0);

  Atmp4->Multiply(false, x, rhs);

  soln_jacobi.PutScalar(0.0);

  AztecOO azoo4(Atmp4, &soln_jacobi, &rhs);

  azoo4.SetAztecOption(AZ_scaling, AZ_Jacobi);

  azoo4.Iterate(100, 1.e-8);

  delete Atmp4;

  //at this point, soln_none, soln_jacobi, soln_rowsum and soln_symdiag
  //should be the same or at least close to the same, since the
  //matrix used in the solution has well-behaved coefficients.
  
  //form vec1 = soln_none - soln_rowsum
  vec1.PutScalar(0.0);
  vec1.Update(1.0, soln_none, 0.0);
  vec1.Update(-1.0, soln_rowsum, 1.0);

  double norm_check1= 0.0;
  vec1.Norm2(&norm_check1);

  //form vec2 = soln_none - soln_symdiag
  vec2.PutScalar(0.0);
  vec2.Update(1.0, soln_none, 0.0);
  vec2.Update(-1.0, soln_symdiag, 1.0);

  double norm_check2= 0.0;
  vec2.Norm2(&norm_check2);

  //form vec3 = soln_none - soln_jacobi
  vec3.PutScalar(0.0);
  vec3.Update(1.0, soln_none, 0.0);
  vec3.Update(-1.0, soln_jacobi, 1.0);

  double norm_check3= 0.0;
  vec3.Norm2(&norm_check3);


  if (std::abs(norm_check1) > 1.e-6) {
    if (verbose) {
      cerr << "AZ_row_sum scaling produced bad soln"
      << endl;
    }
    return(-1);
  }

  if (std::abs(norm_check2) > 1.e-6) {
    if (verbose) {
      cerr << "AZ_sym_diag scaling produced bad soln"
      << endl;
    }
    return(-1);
  }

  if (std::abs(norm_check3) > 1.e-6) {
    if (verbose) {
      cerr << "AZ_Jacobi scaling produced bad soln"
      << endl;
    }
    return(-1);
  }

  options[AZ_pre_calc] = AZ_reuse;

  err = AztecOO_scale_epetra(AZ_SCALE_MAT_RHS_SOL, Amat,
                             options, bvals, xvals, NULL, scaling);
  if (err == 0) {
    if (verbose) {
      cerr << "AztecOO_scale_epetra failed to return err when"
        << " asked to reuse non-existent scaling data."<<endl;
    }
    return(-1);
  }

  options[AZ_keep_info] = 1;
  options[AZ_pre_calc] = AZ_calc;
  err = AztecOO_scale_epetra(AZ_SCALE_MAT_RHS_SOL, Amat,
                             options, bvals, xvals, NULL, scaling);
  if (err != 0) {
    if (verbose) {
      cerr << "AztecOO_scale_epetra returned err=="<<err<<endl;
    }
    return(err);
  }

  options[AZ_keep_info] = 0;
  options[AZ_pre_calc] = AZ_reuse;
  err = AztecOO_scale_epetra(AZ_SCALE_MAT_RHS_SOL, Amat,
                             options, bvals, xvals, NULL, scaling);
  if (err != 0) {
    if (verbose) {
      cerr << "AztecOO_scale_epetra returned err=="<<err
          <<" when asked to reuse scaling data"<<endl;
    }
    return(err);
  }

  options[AZ_pre_calc] = AZ_calc;
  err = AztecOO_scale_epetra(AZ_DESTROY_SCALING_DATA, Amat,
                             options, bvals, xvals, NULL, scaling);
  if (err != 0) {
    if (verbose) {
      std::cerr << "AztecOO_scale_epetra returned err=="<<err
      << " when asked to destroy scaling data."<<std::endl;
    }
    return(err);
  }

  AZ_matrix_destroy(&Amat);
  delete [] options; 
  delete [] params;
  AZ_scaling_destroy(&scaling);

  AZ_manage_memory(0, AZ_CLEAR_ALL, 0, 0, 0);

  return(0);
}