// -------------------------------------------------------------
// PETScConfigurable::p_unprocessOptions
// -------------------------------------------------------------
void
PETScConfigurable::p_unprocessOptions(void)
{
  boost::char_separator<char> sep(" \t\f\n\r\v", "");
  boost::tokenizer<boost::char_separator<char> > 
    opttok(p_loadedOptions, sep);
  boost::tokenizer<boost::char_separator<char> >::iterator o;
  for (o = opttok.begin(); o != opttok.end(); ++o) {
    if ((*o)[0] == '-' && islower((*o)[1])) {
      PetscErrorCode ierr(0);
      try {
        if (verbose) {
          std::cout << "p_unprocessOptions: removing \"" 
                    << *o << "\"" << std::endl;
        }
        ierr = PetscOptionsClearValue(
#if PETSC_VERSION_GE(3,7,0)
                                    NULL,
#endif
                                    o->c_str());
      } catch (const PETSC_EXCEPTION_TYPE& e) {
        throw PETScException(ierr, e);
      }
    }
  } 
  p_loadedOptions.clear();
}
// -------------------------------------------------------------
// PetscNonlinearSolverImplementation::p_solve
// -------------------------------------------------------------
void
PetscNonlinearSolverImplementation::p_solve(void)
{
  PetscErrorCode ierr(0);
  p_petsc_X = PETScVector(*p_X);
  int me(this->processor_rank());

  try {
    ierr = SNESSolve(p_snes, NULL, *p_petsc_X); CHKERRXX(ierr);
    SNESConvergedReason reason;
    PetscInt iter;
    ierr = SNESGetConvergedReason(p_snes, &reason); CHKERRXX(ierr);
    ierr = SNESGetIterationNumber(p_snes, &iter); CHKERRXX(ierr);

    std::string msg;
    if (reason < 0) {
      msg = 
        boost::str(boost::format("%d: PETSc SNES diverged after %d iterations, reason: %d") % 
                   me % iter % reason);
      throw Exception(msg);
    } else if (me == 0) {
      msg = 
        boost::str(boost::format("%d: PETSc SNES converged after %d iterations, reason: %d") % 
                   me % iter % reason);
      std::cerr << msg << std::endl;
    }
  } catch (const PETSC_EXCEPTION_TYPE& e) {
    throw PETScException(ierr, e);
  } catch (const Exception& e) {
    throw e;
  }
}
  /// Do what is necessary to build this instance
  void p_build(const std::string& option_prefix)
  {
    PetscErrorCode ierr;
    try  {
      parallel::Communicator comm(this->communicator());
      if (this->p_doSerial) {
        comm = this->communicator().self();
      }
      ierr = KSPCreate(comm, &p_KSP); CHKERRXX(ierr);
      if (!this->p_guessZero) {
        ierr = KSPSetInitialGuessNonzero(p_KSP,PETSC_TRUE); CHKERRXX(ierr); 
      } else {
        ierr = KSPSetInitialGuessNonzero(p_KSP,PETSC_FALSE); CHKERRXX(ierr); 
      }
      ierr = KSPSetOptionsPrefix(p_KSP, option_prefix.c_str()); CHKERRXX(ierr);
      PC pc;
      ierr = KSPGetPC(p_KSP, &pc); CHKERRXX(ierr);
      ierr = PCSetOptionsPrefix(pc, option_prefix.c_str()); CHKERRXX(ierr);

      ierr = KSPSetTolerances(p_KSP, 
                              LinearSolverImplementation<T, I>::p_relativeTolerance, 
                              LinearSolverImplementation<T, I>::p_solutionTolerance, 
                              PETSC_DEFAULT,
                              LinearSolverImplementation<T, I>::p_maxIterations); CHKERRXX(ierr);

      ierr = KSPSetFromOptions(p_KSP);CHKERRXX(ierr);
    } catch (const PETSC_EXCEPTION_TYPE& e) {
      throw PETScException(ierr, e);
    }
  }  
  /// Solve again w/ the specified RHS, put result in specified vector (specialized)
  void p_resolveImpl(const VectorType& b, VectorType& x) const
  {
    PetscErrorCode ierr(0);
    int me(this->processor_rank());
    try {
      const Vec *bvec(PETScVector(b));
      Vec *xvec(PETScVector(x));

      ierr = KSPSolve(p_KSP, *bvec, *xvec); CHKERRXX(ierr);
      int its;
      KSPConvergedReason reason;
      PetscReal rnorm;
      ierr = KSPGetIterationNumber(p_KSP, &its); CHKERRXX(ierr);
      ierr = KSPGetConvergedReason(p_KSP, &reason); CHKERRXX(ierr);
      ierr = KSPGetResidualNorm(p_KSP, &rnorm); CHKERRXX(ierr);
      std::string msg;
      if (reason < 0) {
        msg = 
          boost::str(boost::format("%d: PETSc KSP diverged after %d iterations, reason: %d") % 
                     me % its % reason);
        throw Exception(msg);
      } else if (me == 0) {
        msg = 
          boost::str(boost::format("%d: PETSc KSP converged after %d iterations, reason: %d") % 
                     me % its % reason);
        std::cerr << msg << std::endl;
      }
    } catch (const PETSC_EXCEPTION_TYPE& e) {
      throw PETScException(ierr, e);
    } catch (const Exception& e) {
      throw e;
    }
  }    
  /// Solve w/ the specified RHS and estimate (result in x)
  void p_solveImpl(MatrixType& A, const VectorType& b, VectorType& x) const
  {
    PetscErrorCode ierr(0);
    try {
      Mat *Amat(PETScMatrix(A));

      if (p_matrixSet && this->p_constSerialMatrix) {
        // KSPSetOperators can be skipped
      } else {
#if PETSC_VERSION_LT(3,5,0)
        ierr = KSPSetOperators(p_KSP, *Amat, *Amat, SAME_NONZERO_PATTERN); CHKERRXX(ierr);
#else
        ierr = KSPSetOperators(p_KSP, *Amat, *Amat); CHKERRXX(ierr);
#endif
        p_matrixSet = true;
      }

      this->p_resolveImpl(b, x);
          
    } catch (const PETSC_EXCEPTION_TYPE& e) {
      throw PETScException(ierr, e);
    } catch (const Exception& e) {
      throw e;
    }
  }
Exemple #6
0
// -------------------------------------------------------------
// Finalize
// -------------------------------------------------------------
/// Does whatever is necessary to shut down the PETSc library
void
Finalize(void)
{
  if (!Initialized()) return;
  PetscErrorCode ierr(0);
  try {
    ierr = PetscFinalize(); CHKERRXX(ierr);
  } catch (const PETSC_EXCEPTION_TYPE& e) {
    throw PETScException(ierr, e);
  }
}
Exemple #7
0
// -------------------------------------------------------------
// Initialized
// -------------------------------------------------------------
bool
Initialized(void)
{
  PetscErrorCode ierr(0);
  PetscBool result;
  try {
    ierr = PetscInitialized(&result); CHKERRXX(ierr);
  } catch (const PETSC_EXCEPTION_TYPE& e) {
    throw PETScException(ierr, e);
  }
  return result;
}
Exemple #8
0
// -------------------------------------------------------------
// Initialize
// -------------------------------------------------------------
/// Does whatever is necessary to start up the PETSc library
void
Initialize(void)
{
  if (Initialized()) return;
  PetscErrorCode ierr(0);
  PetscBool flg;
#if USE_PROGRESS_RANKS
  gridpack::parallel::Communicator comm;
  MPI_Comm world = GA_MPI_Comm();
  PETSC_COMM_WORLD = world;
#endif
  try {
// Turn this on to enable PETSc logging.
#if 0
    int argc = 2;
    char **args;
    args = new char*[2];
    args[0] = new char[32];
    args[1] = new char[32];
    sprintf(args[0],"powerflow.x");
    sprintf(args[1],"-log_summary");
    ierr = PetscInitialize(&argc,&args,NULL,NULL); CHKERRXX(ierr);
    delete [] args[1];
    delete [] args[0];
    delete [] args;
#else
    ierr = PetscInitializeNoArguments(); CHKERRXX(ierr);
#endif
    PetscOptionsHasName(
#if PETSC_VERSION_GE(3,7,0)
                                    NULL,
#endif
                                    NULL, "-log_summary", &flg);
    ierr = PetscOptionsInsertFile(PETSC_COMM_WORLD,
#if PETSC_VERSION_GE(3,7,0)
                                    NULL,
#endif
                                  "gridpack.petscrc",
                                  PETSC_FALSE); CHKERRXX(ierr);
  } catch (const PETSC_EXCEPTION_TYPE& e) {
    throw PETScException(ierr, e);
  }
  // Print out some information on processor configuration
  int mpi_err, me, nproc;
  mpi_err = MPI_Comm_rank(PETSC_COMM_WORLD, &me);
  mpi_err = MPI_Comm_size(PETSC_COMM_WORLD, &nproc);
  if (mpi_err > 0) {
    throw gridpack::Exception("MPI initialization failed");
  }
  if (me == 0) {
    printf("\nGridPACK math module configured on %d processors\n",nproc);
  }
}
// -------------------------------------------------------------
// PetscNonlinearSolverImplementation::p_build
// -------------------------------------------------------------
void
PetscNonlinearSolverImplementation::p_build(const std::string& option_prefix)
{
  PetscErrorCode ierr(0);
  try {
    ierr  = SNESCreate(this->communicator(), &p_snes); CHKERRXX(ierr);
    p_petsc_F = PETScVector(*p_F);

    if (!p_function.empty()) {
      ierr = SNESSetFunction(p_snes, *p_petsc_F, FormFunction, 
                             static_cast<void *>(this)); CHKERRXX(ierr);
    }

    p_petsc_J = PETScMatrix(*p_J);
    
    if (!p_jacobian.empty()) {
      ierr = SNESSetJacobian(p_snes, *p_petsc_J, *p_petsc_J, FormJacobian, 
                             static_cast<void *>(this)); CHKERRXX(ierr);
    }

    // set the 
    ierr = SNESSetOptionsPrefix(p_snes, option_prefix.c_str()); CHKERRXX(ierr);
    KSP ksp;
    ierr = SNESGetKSP(p_snes, &ksp); CHKERRXX(ierr);
    ierr = KSPSetOptionsPrefix(ksp, option_prefix.c_str()); CHKERRXX(ierr);
    
    PC pc;
    ierr = KSPGetPC(ksp, &pc); CHKERRXX(ierr);
    ierr = PCSetOptionsPrefix(pc, option_prefix.c_str()); CHKERRXX(ierr);

    ierr = SNESMonitorSet(p_snes, MonitorNorms, PETSC_NULL, PETSC_NULL); CHKERRXX(ierr);

    ierr = SNESSetTolerances(p_snes, 
                             p_functionTolerance, 
                             PETSC_DEFAULT,
                             p_solutionTolerance,
                             p_maxIterations, 
                             PETSC_DEFAULT);
                             
    ierr = SNESSetFromOptions(p_snes); CHKERRXX(ierr);
    
  } catch (const PETSC_EXCEPTION_TYPE& e) {
    throw PETScException(ierr, e);
  }
}
/** 
 * 
 * 
 * @param comm 
 * @param props 
 * 
 * @return PETSc options prefix to use
 */
void
PETScConfigurable::p_processOptions(utility::Configuration::CursorPtr props)
{
  if (!props) return;

  p_prefix = props->get(p_prefixKey, p_generatePrefix(p_comm));
  if (*p_prefix.rbegin() != '_') {
    p_prefix.append("_");
  }

  std::string optsorig, optsmod, optsfmt;
  optsorig = props->get(p_optionsKey, "");

  boost::char_separator<char> sep(" \t\f\n\r\v", "");
  boost::tokenizer<boost::char_separator<char> > 
    opttok(optsorig, sep);
  boost::tokenizer<boost::char_separator<char> >::iterator o;
  for (o = opttok.begin(); o != opttok.end(); ++o) {
    optsfmt.append(*o);
    optsfmt.append(" ");
    optsmod.append(prefixOptionMaybe(p_prefix, *o));
    optsmod.append(" ");
  }

  if (verbose) {
    std::cout << "p_processOptions:  in: " << optsorig << std::endl;
    std::cout << "p_processOptions: fmt: " << optsfmt << std::endl;
    std::cout << "p_processOptions: out: " << optsmod << std::endl;
  }
  p_loadedOptions = optsmod;

  PetscErrorCode ierr(0);
  try {
    ierr = PetscOptionsInsertString(
#if PETSC_VERSION_GE(3,7,0)
                                    NULL,
#endif
                                    p_loadedOptions.c_str()); CHKERRXX(ierr);
  } catch (const PETSC_EXCEPTION_TYPE& e) {
    throw PETScException(ierr, e);
  }
  return;
}