예제 #1
0
int main( int argc, char **argv )
{

// check for parallel computation
#ifdef HAVE_MPI
  MPI_Init(&argc, &argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif


// define main parameters

  double c = 0.25;             // continuation parameter
  int N = 50;                  // number of grid points
  int maxNewtonIters = 20;     // max number of Newton iterations
  int maxSteps = 75;           // max number of continuation steps taken

// Set flag for whether the computations will be Matrix-free (true) or will use a computed
//   Jacobian (false)
  bool doMatFree = false;      
      
// Create output file to save solutions
  ofstream outFile("Heq4.dat");
  outFile.setf(ios::scientific, ios::floatfield);
  outFile.precision(10);

// Define the problem class
  HeqProblem Problem(N,&Comm,outFile);
  
// Create the initial guess vector and set it to all ones
  Epetra_Vector InitialGuess(Problem.GetMap());
  InitialGuess.PutScalar(1.0);     

// Create the top level parameter list
  Teuchos::RCP<Teuchos::ParameterList> ParamList = Teuchos::rcp(new Teuchos::ParameterList);

  // Create LOCA sublist
  Teuchos::ParameterList& locaParamsList = ParamList->sublist("LOCA");

  // Create the sublist for continuation and set the stepper parameters
  Teuchos::ParameterList& stepperList = locaParamsList.sublist("Stepper");
  stepperList.set("Continuation Method", "Arc Length");// Default
  // stepperList.set("Continuation Method", "Natural");
  stepperList.set("Continuation Parameter", "c");  // Must set
  stepperList.set("Initial Value", c);             // Must set
  stepperList.set("Max Value", 100.0);             // Must set
  stepperList.set("Min Value", 0.0);             // Must set
  stepperList.set("Max Steps", maxSteps);                    // Should set
  stepperList.set("Max Nonlinear Iterations", maxNewtonIters); // Should set

// Set up parameters to compute Eigenvalues
#ifdef HAVE_LOCA_ANASAZI
  // Create Anasazi Eigensolver sublist (needs --with-loca-anasazi)
  stepperList.set("Compute Eigenvalues",true);
  Teuchos::ParameterList& aList = stepperList.sublist("Eigensolver");
  aList.set("Method", "Anasazi");
  aList.set("Block Size", 1);        // Size of blocks
  aList.set("Num Blocks", 20);       // Size of Arnoldi factorization
  aList.set("Num Eigenvalues", 5);   // Number of eigenvalues
  //  aList.set("Sorting Order", "SR");
  aList.set("Convergence Tolerance", 2.0e-7);          // Tolerance
  aList.set("Step Size", 1);         // How often to check convergence
  aList.set("Maximum Restarts",2);   // Maximum number of restarts
  aList.set("Verbosity",  
	    Anasazi::Errors + 
	    Anasazi::Warnings +
	    Anasazi::FinalSummary);        // Verbosity
#else
    stepperList.set("Compute Eigenvalues",false);
#endif
 
    stepperList.set("Bordered Solver Method", "Householder");
//    stepperList.set("Bordered Solver Method", "Bordering");

  //  Teuchos::ParameterList& nestedList = 
  //    stepperList.sublist("Nested Bordered Solver");
  //  nestedList.set("Bordered Solver Method", "Householder");
  //  nestedList.set("Include UV In Preconditioner", true);
  //  //nestedList.set("Use P For Preconditioner", true);
  //  nestedList.set("Preconditioner Method", "SMW");

 
// Create bifurcation sublist -- use if not doing turning point
  Teuchos::ParameterList& bifurcationList = locaParamsList.sublist("Bifurcation");
  bifurcationList.set("Type", "None");                 // Default

  // Create predictor sublist
  Teuchos::ParameterList& predictorList = locaParamsList.sublist("Predictor");
  predictorList.set("Method", "Secant");               // Default
  // predictorList.set("Method", "Constant");     // Other options
  // predictorList.set("Method", "Tangent");      // Other options

  // Create step size sublist
  Teuchos::ParameterList& stepSizeList = locaParamsList.sublist("Step Size");
  stepSizeList.set("Method", "Adaptive");             // Default
  stepSizeList.set("Initial Step Size", 0.1);   // Should set
  stepSizeList.set("Min Step Size", 1.0e-4);    // Should set
  stepSizeList.set("Max Step Size", 1.0);      // Should set
  stepSizeList.set("Aggressiveness", 0.1);

  // Set up NOX info
  Teuchos::ParameterList& nlParams = ParamList->sublist("NOX");

  // Set the nonlinear solver method
  nlParams.set("Nonlinear Solver", "Line Search Based");

  // Set the printing parameters in the "Printing" sublist
  Teuchos::ParameterList& printParams = nlParams.sublist("Printing");
  printParams.set("MyPID", Comm.MyPID()); 
  printParams.set("Output Precision", 5);
  printParams.set("Output Processor", 0);
  printParams.set("Output Information", 
			NOX::Utils::OuterIteration + 
			NOX::Utils::OuterIterationStatusTest + 
			NOX::Utils::InnerIteration +
			NOX::Utils::LinearSolverDetails +
			NOX::Utils::Parameters + 
			NOX::Utils::Details + 
			NOX::Utils::Warning +
         NOX::Utils::StepperIteration +
         NOX::Utils::StepperDetails +
         NOX::Utils::StepperParameters);


  // NOX parameters - Sublist for line search 
  Teuchos::ParameterList& searchParams = nlParams.sublist("Line Search");
  searchParams.set("Method", "Full Step");
//  searchParams.set("Method", "Backtrack");

  // Sublist for direction
  Teuchos::ParameterList& dirParams = nlParams.sublist("Direction");
  dirParams.set("Method", "Newton");

  Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
  newtonParams.set("Forcing Term Method", "Constant");

  // Sublist for linear solver for the Newton method
  Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
  lsParams.set("Aztec Solver", "GMRES");  
  lsParams.set("Max Iterations", 800);  
  lsParams.set("Tolerance", 1e-8);
  lsParams.set("Output Frequency", 1);    
  lsParams.set("Preconditioner", "None");
//  lsParams.set("Preconditioner", "AztecOO");
//  lsParams.set("Aztec Preconditioner", "ilu"); 
//  lsParams.set("Preconditioner", "Ifpack");
//  lsParams.set("Ifpack Preconditioner", "ILU");
//  lsParams.set("Preconditioner", "New Ifpack");
//  Teuchos::ParameterList& ifpackParams = lsParams.sublist("Ifpack");
//    ifpackParams.set("fact: level-of-fill", 1);


  // set up the continuation parameter vector
  LOCA::ParameterVector p;
  p.addParameter("c",c);  

  // Set up the problem interface
  Teuchos::RCP<SimpleProblemInterface> interface = 
    Teuchos::rcp(new SimpleProblemInterface(&Problem,c) );

  Teuchos::RCP<LOCA::Epetra::Interface::Required> iReq = interface;

// Create the operator to hold either the Jacobian matrix or the Matrix-free operator
  Teuchos::RCP<Epetra_Operator> A;
  Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac;

  // Need a NOX::Epetra::Vector for constructor
  // This becomes the initial guess vector that is used for the nonlinear solves
  NOX::Epetra::Vector noxInitGuess(InitialGuess, NOX::DeepCopy);   

  if (doMatFree) {
    // Matrix Free application (Epetra Operator):
    Teuchos::RCP<NOX::Epetra::MatrixFree> MF = 
      Teuchos::rcp(new NOX::Epetra::MatrixFree(printParams, interface, noxInitGuess)); 
    A = MF;
    iJac = MF;
  }
  else  {  // Computed Jacobian application
    A = Teuchos::rcp( Problem.GetMatrix(), false );
    iJac = interface;
  }
 
// Build the linear system solver
  Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys = 
    Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
						      iReq,
						      iJac, A, 
						      noxInitGuess));

// Create the Loca (continuation) vector
  NOX::Epetra::Vector locaSoln(noxInitGuess);
  
  // Create Epetra Factory
  Teuchos::RCP<LOCA::Abstract::Factory> epetraFactory = Teuchos::rcp(new LOCA::Epetra::Factory);

  // Create global data object
  Teuchos::RCP<LOCA::GlobalData> globalData = LOCA::createGlobalData(ParamList, epetraFactory);
 
  // Create the Group - must be LOCA group
  Teuchos::RCP<LOCA::Epetra::Group> grpPtr = 
    Teuchos::rcp(new LOCA::Epetra::Group(globalData, printParams, 
					iReq, locaSoln, 
					linSys, p)); 

  // Calculate the first F(x0) as a starting point.  This is only needed for
  // certain status tests, to ensure that an initial residual (|r0|) is calculated
  grpPtr->computeF();

// Set up the status tests to check for convergence
  // Determines the error tolerance for the Newton solves 
  Teuchos::RCP<NOX::StatusTest::NormF> testNormF = 
    Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-4));
  // Sets the max number of nonlinear (Newton) iterations that will be taken.  If this is not
  //   already set, it will default to the '20' given 
  Teuchos::RCP<NOX::StatusTest::MaxIters> testMaxIters = 
    Teuchos::rcp(new NOX::StatusTest::MaxIters(stepperList.get("Max Nonlinear Iterations", 20)));
// This combination of tests will be used by NOX to determine whether the step converged
  Teuchos::RCP<NOX::StatusTest::Combo> combo = 
    Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR, 
					    testNormF, testMaxIters));

// This is sample code to write and read parameters to/from a file.  Currently not activated! 
// To use, change the 'XXXHAVE_TEUCHOS_EXTENDED' TO 'HAVE_TEUCHOS_EXTENDED'
#ifdef XXXHAVE_TEUCHOS_EXTENDED
  // Write the parameter list to a file
  cout << "Writing parameter list to \"input.xml\"" << endl;
  Teuchos::writeParameterListToXmlFile(*ParamList, "input.xml");

  // Read in the parameter list from a file
  cout << "Reading parameter list from \"input.xml\"" << endl;
  Teuchos::RCP<Teuchos::ParameterList> paramList2 = 
    Teuchos::rcp(new Teuchos::ParameterList);
  Teuchos::updateParametersFromXmlFile("input.xml", paramList2.get());
  ParamList = paramList2;
#endif


// Create the stepper
  LOCA::Stepper stepper(globalData, grpPtr, combo, ParamList);
  LOCA::Abstract::Iterator::IteratorStatus status = stepper.run();

  // Check if the stepper completed  
  if  (status == LOCA::Abstract::Iterator::Finished)
    globalData->locaUtils->out() << "\nAll tests passed!" << endl;
  else 
    if (globalData->locaUtils->isPrintType(NOX::Utils::Error))
      globalData->locaUtils->out() << "\nStepper failed to converge!"  << endl;

// Output the stepper parameter list info
  if (globalData->locaUtils->isPrintType(NOX::Utils::StepperParameters)) {
    globalData->locaUtils->out() << endl << "Final Parameters" << endl
    << "*******************" << endl;
    stepper.getList()->print(globalData->locaUtils->out());
    globalData->locaUtils->out() << endl;
  }

// Make sure all processors are done and close the output file
Comm.Barrier();
outFile.close();

// Deallocate memory
LOCA::destroyGlobalData(globalData);

#ifdef HAVE_MPI
  MPI_Finalize();
#endif
  return(EXIT_SUCCESS);
}  // DONE!!
예제 #2
0
파일: test.C 프로젝트: gitter-badger/quinoa
int main(int argc, char *argv[]) 
{
  // Initialize MPI
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
#endif

  // Create a communicator for Epetra objects
#ifdef HAVE_MPI
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif
 
  bool verbose = false;

  if (argc > 1)
    if (argv[1][0]=='-' && argv[1][1]=='v')
      verbose = true;

  // Get the process ID and the total number of processors
  int MyPID = Comm.MyPID();
#ifdef HAVE_MPI
  int NumProc = Comm.NumProc();
#endif

  // define the parameters of the nonlinear PDE problem
  int nx = 5;
  int ny = 6;  
  double lambda = 1.0;

  PDEProblem Problem(nx,ny,lambda,&Comm);
 
  // starting solution, here a zero vector
  Epetra_Vector InitialGuess(Problem.GetMatrix()->Map());
  InitialGuess.PutScalar(0.0);

  // random vector upon which to apply each operator being tested
  Epetra_Vector directionVec(Problem.GetMatrix()->Map());
  directionVec.Random();

  // Set up the problem interface
  Teuchos::RCP<SimpleProblemInterface> interface = 
    Teuchos::rcp(new SimpleProblemInterface(&Problem) );
  
  // Set up theolver options parameter list
  Teuchos::RCP<Teuchos::ParameterList> noxParamsPtr = Teuchos::rcp(new Teuchos::ParameterList);
  Teuchos::ParameterList & noxParams = *(noxParamsPtr.get());

  // Set the nonlinear solver method
  noxParams.set("Nonlinear Solver", "Line Search Based");

  // Set up the printing utilities
  // Only print output if the "-v" flag is set on the command line
  Teuchos::ParameterList& printParams = noxParams.sublist("Printing");
  printParams.set("MyPID", MyPID); 
  printParams.set("Output Precision", 5);
  printParams.set("Output Processor", 0);
  if( verbose )
    printParams.set("Output Information", 
		NOX::Utils::OuterIteration + 
		NOX::Utils::OuterIterationStatusTest + 
		NOX::Utils::InnerIteration +
		NOX::Utils::Parameters + 
		NOX::Utils::Details + 
		NOX::Utils::Warning +
		NOX::Utils::TestDetails);
  else
    printParams.set("Output Information", NOX::Utils::Error +
		NOX::Utils::TestDetails);

  NOX::Utils printing(printParams);


  // Identify the test problem
  if (printing.isPrintType(NOX::Utils::TestDetails))
    printing.out() << "Starting epetra/NOX_Operators/NOX_Operators.exe" << std::endl;

  // Identify processor information
#ifdef HAVE_MPI
  if (printing.isPrintType(NOX::Utils::TestDetails)) {
    printing.out() << "Parallel Run" << std::endl;
    printing.out() << "Number of processors = " << NumProc << std::endl;
    printing.out() << "Print Process = " << MyPID << std::endl;
  }
  Comm.Barrier();
  if (printing.isPrintType(NOX::Utils::TestDetails))
    printing.out() << "Process " << MyPID << " is alive!" << std::endl;
  Comm.Barrier();
#else
  if (printing.isPrintType(NOX::Utils::TestDetails))
    printing.out() << "Serial Run" << std::endl;
#endif

  int status = 0;

  Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = interface;

  // Need a NOX::Epetra::Vector for constructor
  NOX::Epetra::Vector noxInitGuess(InitialGuess, NOX::DeepCopy);

  // Analytic matrix
  Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( Problem.GetMatrix(), false );

  Epetra_Vector A_resultVec(Problem.GetMatrix()->Map());
  interface->computeJacobian( InitialGuess, *A );
  A->Apply( directionVec, A_resultVec );

  // FD operator
  Teuchos::RCP<Epetra_CrsGraph> graph = Teuchos::rcp( const_cast<Epetra_CrsGraph*>(&A->Graph()), false );
  Teuchos::RCP<NOX::Epetra::FiniteDifference> FD = Teuchos::rcp(
    new NOX::Epetra::FiniteDifference(printParams, iReq, noxInitGuess, graph) );
  
  Epetra_Vector FD_resultVec(Problem.GetMatrix()->Map());
  FD->computeJacobian(InitialGuess, *FD);
  FD->Apply( directionVec, FD_resultVec );

  // Matrix-Free operator
  Teuchos::RCP<NOX::Epetra::MatrixFree> MF = Teuchos::rcp(
    new NOX::Epetra::MatrixFree(printParams, iReq, noxInitGuess) );

  Epetra_Vector MF_resultVec(Problem.GetMatrix()->Map());
  MF->computeJacobian(InitialGuess, *MF);
  MF->Apply( directionVec, MF_resultVec );

  // Need NOX::Epetra::Vectors for tests
  NOX::Epetra::Vector noxAvec ( A_resultVec , NOX::DeepCopy );
  NOX::Epetra::Vector noxFDvec( FD_resultVec, NOX::DeepCopy );
  NOX::Epetra::Vector noxMFvec( MF_resultVec, NOX::DeepCopy );

  // Create a TestCompare class
  NOX::Epetra::TestCompare tester( printing.out(), printing);
  double abstol = 1.e-4;
  double reltol = 1.e-4 ;
  //NOX::TestCompare::CompareType aComp = NOX::TestCompare::Absolute;

  status += tester.testVector( noxFDvec, noxAvec, reltol, abstol,
                              "Finite-Difference Operator Apply Test" );
  status += tester.testVector( noxMFvec, noxAvec, reltol, abstol,
                              "Matrix-Free Operator Apply Test" );

  // Summarize test results  
  if( status == 0 )
    printing.out() << "Test passed!" << std::endl;
  else 
    printing.out() << "Test failed!" << std::endl;

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  // Final return value (0 = successfull, non-zero = failure)
  return status;

}
예제 #3
0
int main( int argc, char **argv )
{

// check for parallel computation
#ifdef HAVE_MPI
  MPI_Init(&argc, &argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif


// define main parameters

  double c = 0.9999;           // continuation parameter
  int N = 50;                  // number of grid points
  int maxNewtonIters = 20;     // max number of Newton iterations
  int maxSteps = 50;           // max number of continuation steps taken
  int ilocal, iglobal;         // counter variables used for loops:
                               //   ilocal = counter for local elements on this processor;
                               //   iglobal = counter to signify global position across all procs 
  int Myele;                   // holds the number of elements on the processor

// Set flag for whether the computations will be Matrix-free (true) or will use a computed
//   Jacobian (false)
  bool doMatFree = false;      
   
// Create output file to save solutions
  ofstream outFile("Heq5.dat");
  outFile.setf(ios::scientific, ios::floatfield);
  outFile.precision(10);

// Define the problem class
  HeqProblem Problem(N,&Comm,outFile);
  
// Build initial guess.  The initial guess should be a solution vector x close to the 
//   bifurcation point.

  // Create the initial guess vector
  Epetra_Vector InitialGuess(Problem.GetMap());

  // Get the number of elements on this processor  
  Myele = Problem.GetMap().NumMyElements();

  // Compute the initial guess.  For this example, it is a line from (0,1) to (1,8/3)
  for (ilocal=0; ilocal<Myele; ilocal++) {
     iglobal=Problem.GetMap().GID(ilocal);
     InitialGuess[ilocal]= 1.0 + (5.0*iglobal)/(3.0*(N-1));
  }

// Create the null vector for the Jacobian (ie, J*v=0, used to solve the system of equations
//   f(x,p)=0; J*v=0; v0*v=1.  The solution of the system is [x*,v*,p*]. )
  Teuchos::RCP<NOX::Abstract::Vector> nullVec =
    Teuchos::rcp(new NOX::Epetra::Vector(InitialGuess));

  // Initialize to all ones
  nullVec->init(1.0);  
    // NOTE:  init is a function within the NOX::Abstract:Vector class which initializes every
    // value of the vector to the value within the parentheses (must be in 'double' format) 

// Create the top level parameter list
  Teuchos::RCP<Teuchos::ParameterList> ParamList = Teuchos::rcp(new Teuchos::ParameterList);

  // Create LOCA sublist
  Teuchos::ParameterList& locaParamsList = ParamList->sublist("LOCA");

  // Create the sublist for continuation and set the stepper parameters
  Teuchos::ParameterList& stepperList = locaParamsList.sublist("Stepper");
    //stepperList.set("Continuation Method", "Arc Length");// Default
    stepperList.set("Continuation Method", "Natural");
    stepperList.set("Continuation Parameter", "dummy");  // Must set
    stepperList.set("Initial Value", 999.0);             // Must set
    stepperList.set("Max Value", 50.0e4);             // Must set
    stepperList.set("Min Value", 0.0);             // Must set
    stepperList.set("Max Steps", maxSteps);                    // Should set
    stepperList.set("Max Nonlinear Iterations", maxNewtonIters); // Should set
    stepperList.set("Bordered Solver Method", "Bordering");

  //  Teuchos::ParameterList& nestedList = 
  //    stepperList.sublist("Nested Bordered Solver");
  //  nestedList.set("Bordered Solver Method", "Householder");
  //  nestedList.set("Include UV In Preconditioner", true);
  //  //nestedList.set("Use P For Preconditioner", true);
  //  nestedList.set("Preconditioner Method", "SMW");

// Set up parameters to compute Eigenvalues
#ifdef HAVE_LOCA_ANASAZI
  // Create Anasazi Eigensolver sublist (needs --with-loca-anasazi)
  stepperList.set("Compute Eigenvalues",true);
  Teuchos::ParameterList& aList = stepperList.sublist("Eigensolver");
  aList.set("Method", "Anasazi");
  aList.set("Block Size", 1);        // Size of blocks
  aList.set("Num Blocks", 20);       // Size of Arnoldi factorization
  aList.set("Num Eigenvalues", 5);   // Number of eigenvalues
  //  aList.set("Sorting Order", "SR");
  aList.set("Convergence Tolerance", 2.0e-7);          // Tolerance
  aList.set("Step Size", 1);         // How often to check convergence
  aList.set("Maximum Restarts",2);   // Maximum number of restarts
  aList.set("Verbosity",  
	    Anasazi::Errors + 
	    Anasazi::Warnings +
	    Anasazi::FinalSummary);        // Verbosity
#else
    stepperList.set("Compute Eigenvalues",false);
#endif
  
  // Create bifurcation sublist.  Note that for turning point continuation, the "type"
  //   is set to "Turning Point".  If not doing TP, type should be "None".
  Teuchos::ParameterList& bifurcationList = locaParamsList.sublist("Bifurcation");
  bifurcationList.set("Type", "Turning Point");
  bifurcationList.set("Bifurcation Parameter", "c");
  //  bifurcationList.set("Formulation", "Minimally Augmented");
  bifurcationList.set("Symmetric Jacobian", false); 
  bifurcationList.set("Update Null Vectors Every Continuation Step", true);
  bifurcationList.set("Update Null Vectors Every Nonlinear Iteration", false);
  bifurcationList.set("Transpose Solver Method","Explicit Transpose");
  //  bifurcationList.set("Transpose Solver Method","Transpose Preconditioner");
  //  bifurcationList.set("Transpose Solver Method","Left Preconditioning");
  bifurcationList.set("Initial Null Vector Computation", "Solve df/dp");
  //  bifurcationList.set("Initial A Vector", nullVec);      // minimally augmented
  //  bifurcationList.set("Initial B Vector", nullVec);      //minimally augmented
  
  //  bifurcationList.set("Bordered Solver Method", "Householder");
  //  bifurcationList.set("Include UV In Preconditioner", true);
  //  //bifurcationList.set("Use P For Preconditioner", true);
  //  bifurcationList.set("Preconditioner Method", "SMW");

  bifurcationList.set("Formulation", "Moore-Spence");
  bifurcationList.set("Solver Method", "Phipps Bordering"); // better for nearly singular matrices
  //  bifurcationList.set("Solver Method", "Salinger Bordering");   
  bifurcationList.set("Initial Null Vector", nullVec);
  bifurcationList.set("Length Normalization Vector", nullVec);

    // Create the sublist for the predictor
    Teuchos::ParameterList& predictorList = locaParamsList.sublist("Predictor");
    predictorList.set("Method", "Secant");         // Default
    // predictorList.set("Method", "Constant");     // Other options
    // predictorList.set("Method", "Tangent");      // Other options

    // Create step size sublist
    Teuchos::ParameterList& stepSizeList = locaParamsList.sublist("Step Size");
    stepSizeList.set("Method", "Adaptive");             // Default
    stepSizeList.set("Initial Step Size", 0.1);   // Should set
    stepSizeList.set("Min Step Size", 1.0e-6);    // Should set
    stepSizeList.set("Max Step Size", 1.0);      // Should set
    stepSizeList.set("Aggressiveness", 0.1);

// Set up NOX info
  Teuchos::ParameterList& nlParams = ParamList->sublist("NOX");

// Set the nonlinear solver method
  nlParams.set("Nonlinear Solver", "Line Search Based");

// Set the printing parameters in the "Printing" sublist.  This list determines how much
//   of the NOX information is output
  Teuchos::ParameterList& printParams = nlParams.sublist("Printing");
  printParams.set("MyPID", Comm.MyPID()); 
  printParams.set("Output Precision", 5);
  printParams.set("Output Processor", 0);
  printParams.set("Output Information", 
			NOX::Utils::OuterIteration + 
			NOX::Utils::OuterIterationStatusTest + 
			NOX::Utils::InnerIteration +
			NOX::Utils::LinearSolverDetails +
			NOX::Utils::Parameters + 
			NOX::Utils::Details + 
			NOX::Utils::Warning +
         NOX::Utils::StepperIteration +
         NOX::Utils::StepperDetails +
         NOX::Utils::StepperParameters);

  // NOX parameters - Sublist for line search 
  Teuchos::ParameterList& searchParams = nlParams.sublist("Line Search");
  searchParams.set("Method", "Backtrack");
  //  searchParams.set("Method", "Full Step");

  // Sublist for direction
  Teuchos::ParameterList& dirParams = nlParams.sublist("Direction");
  dirParams.set("Method", "Newton");

  Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
  newtonParams.set("Forcing Term Method", "Constant");

  // Sublist for linear solver for the Newton method
  Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
  lsParams.set("Aztec Solver", "GMRES");  
  lsParams.set("Max Iterations", 800);  
  lsParams.set("Tolerance", 1e-8);
  lsParams.set("Output Frequency", 1);    
  lsParams.set("Preconditioner", "None");
  //  lsParams.set("Preconditioner", "AztecOO");
  //  lsParams.set("Aztec Preconditioner", "ilu"); 
  //  lsParams.set("Scaling", "None");
  //  lsParams.set("Scaling", "Row Sum");  
  lsParams.set("Compute Scaling Manually", false);
  //  lsParams.set("Preconditioner", "Ifpack");
  //  lsParams.set("Ifpack Preconditioner", "ILU");
  //  lsParams.set("Preconditioner", "New Ifpack");
  //  Teuchos::ParameterList& ifpackParams = lsParams.sublist("Ifpack");
  //  ifpackParams.set("fact: level-of-fill", 1);

// Set up the continuation parameter vector
  LOCA::ParameterVector p;
  p.addParameter("c",c);  
  p.addParameter("dummy",999.0);  

// Create the problem interface
  Teuchos::RCP<SimpleProblemInterface> interface = 
    Teuchos::rcp(new SimpleProblemInterface(&Problem,c) );

  Teuchos::RCP<LOCA::Epetra::Interface::Required> iReq = interface;

// Create the operator to hold either the Jacobian matrix or the Matrix-free operator
  Teuchos::RCP<Epetra_Operator> A;
  //  Teuchos::RCP<Epetra_RowMatrix> A;
  Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac;

  // Need a NOX::Epetra::Vector for constructor
  // This becomes the initial guess vector that is used for the nonlinear solves
  NOX::Epetra::Vector noxInitGuess(InitialGuess, NOX::DeepCopy);   

  if (doMatFree) {
    // Matrix Free application (Epetra Operator):
    Teuchos::RCP<NOX::Epetra::MatrixFree> MF = 
      Teuchos::rcp(new NOX::Epetra::MatrixFree(printParams, interface, noxInitGuess)); 
    A = MF;
    iJac = MF;
  }
  else  {  // Computed Jacobian application
    A = Teuchos::rcp( Problem.GetMatrix(), false );
    iJac = interface;
  }
 
  // Create scaling object
  Teuchos::RCP<NOX::Epetra::Scaling> scaling = Teuchos::null;
  //   scaling = Teuchos::rcp(new NOX::Epetra::Scaling);
  //   Teuchos::RCP<Epetra_Vector> scalingVector = 
  //     Teuchos::rcp(new Epetra_Vector(soln.Map()));
  //   //scaling->addRowSumScaling(NOX::Epetra::Scaling::Left, scalingVector);
  //   scaling->addColSumScaling(NOX::Epetra::Scaling::Right, scalingVector);

  // Create transpose scaling object
  Teuchos::RCP<NOX::Epetra::Scaling> trans_scaling = Teuchos::null;
  //   trans_scaling = Teuchos::rcp(new NOX::Epetra::Scaling);
  //   Teuchos::RCP<Epetra_Vector> transScalingVector = 
  //     Teuchos::rcp(new Epetra_Vector(soln.Map()));
  //   trans_scaling->addRowSumScaling(NOX::Epetra::Scaling::Right, 
  // 				  transScalingVector);
  //   trans_scaling->addColSumScaling(NOX::Epetra::Scaling::Left, 
  // 				  transScalingVector);
    //bifurcationList.set("Transpose Scaling", trans_scaling);

// Build the linear system solver
  Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys = 
    Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
						      iReq,
						      iJac, A, 
                        noxInitGuess, scaling));            // use if scaling
//                        noxInitGuess));                     // use if no scaling

// Create the Loca (continuation) vector
  NOX::Epetra::Vector locaSoln(noxInitGuess);
  
  // Create Epetra Factory
  Teuchos::RCP<LOCA::Abstract::Factory> epetraFactory = Teuchos::rcp(new LOCA::Epetra::Factory);

  // Create global data object
  Teuchos::RCP<LOCA::GlobalData> globalData = LOCA::createGlobalData(ParamList, epetraFactory);
 
  // Create the Group - must be LOCA group
  Teuchos::RCP<LOCA::Epetra::Group> grpPtr = 
    Teuchos::rcp(new LOCA::Epetra::Group(globalData, printParams, 
					iReq, locaSoln, 
					linSys, p)); 

  // Calculate the first F(x0) as a starting point.  This is only needed for
  // certain status tests, to ensure that an initial residual (|r0|) is calculated
  grpPtr->computeF();

// Set up the status tests to check for convergence
  // Determines the error tolerance for the Newton solves 
  Teuchos::RCP<NOX::StatusTest::NormF> testNormF = 
    Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-4));
  // Sets the max number of nonlinear (Newton) iterations that will be taken.  If this is not
  //   already set, it will default to the '20' given 
  Teuchos::RCP<NOX::StatusTest::MaxIters> testMaxIters = 
    Teuchos::rcp(new NOX::StatusTest::MaxIters(stepperList.get("Max Nonlinear Iterations", 20)));
// This combination of tests will be used by NOX to determine whether the step converged
  Teuchos::RCP<NOX::StatusTest::Combo> combo = 
    Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR, 
					    testNormF, testMaxIters));

// This is sample code to write and read parameters to/from a file.  Currently not activated! 
// To use, change the 'XXXHAVE_TEUCHOS_EXTENDED' TO 'HAVE_TEUCHOS_EXTENDED'
#ifdef XXXHAVE_TEUCHOS_EXTENDED
  // Write the parameter list to a file
  cout << "Writing parameter list to \"input.xml\"" << endl;
  Teuchos::writeParameterListToXmlFile(*ParamList, "input.xml");

  // Read in the parameter list from a file
  cout << "Reading parameter list from \"input.xml\"" << endl;
  Teuchos::RCP<Teuchos::ParameterList> paramList2 = 
    Teuchos::rcp(new Teuchos::ParameterList);
  Teuchos::updateParametersFromXmlFile("input.xml", paramList2.get());
  ParamList = paramList2;
#endif


// Create the stepper
  LOCA::Stepper stepper(globalData, grpPtr, combo, ParamList);
  LOCA::Abstract::Iterator::IteratorStatus status = stepper.run();
  
  // Check if the stepper completed
  if  (status == LOCA::Abstract::Iterator::Finished)
    globalData->locaUtils->out() << "\nAll tests passed!" << endl;
  else 
    if (globalData->locaUtils->isPrintType(NOX::Utils::Error))
      globalData->locaUtils->out() << "\nStepper failed to converge!"  << endl;

// Output the stepper parameter list info
  if (globalData->locaUtils->isPrintType(NOX::Utils::StepperParameters)) {
    globalData->locaUtils->out() << endl << "Final Parameters" << endl
    << "*******************" << endl;
    stepper.getList()->print(globalData->locaUtils->out());
    globalData->locaUtils->out() << endl;
  }

// Make sure all processors are done and close the output file
Comm.Barrier();
outFile.close();

// Deallocate memory
LOCA::destroyGlobalData(globalData);

#ifdef HAVE_MPI
  MPI_Finalize();
#endif
  return(EXIT_SUCCESS);
}  // DONE!!
예제 #4
0
std::pair<int, typename SolverNonLinearTrilinos<T>::real_type>
SolverNonLinearTrilinos<T>::solve ( sparse_matrix_ptrtype&  jac_in,  // System Jacobian Matrix
                                    vector_ptrtype& x_in,    // Solution vector
                                    vector_ptrtype& r_in,    // Residual vector
                                    const double,              // Stopping tolerance
                                    const unsigned int )
{
    //printf("Entering solve...\n");
    MatrixEpetra* jac = dynamic_cast<MatrixEpetra *>( jac_in.get() );
    VectorEpetra<T>* x  = dynamic_cast<VectorEpetra<T>*>( x_in.get() );

    // We cast to pointers so we can be sure that they succeeded
    // by comparing the result against NULL.
    //    assert(jac != NULL); assert(jac->mat() != NULL);
    //    assert(x   != NULL); assert(x->vec()   != NULL);
    //    assert(r   != NULL); assert(r->vec()   != NULL);

    // Create the top level parameter list
    Teuchos::RCP<Teuchos::ParameterList> nlParamsPtr =
        Teuchos::rcp( new Teuchos::ParameterList );
    Teuchos::ParameterList& nlParams = *( nlParamsPtr.get() );

    // Set the nonlinear solver method
    nlParams.set( "Nonlinear Solver", "Line Search Based" );

    // Set the printing parameters in the "Printing" sublist
    Teuchos::ParameterList& printParams = nlParams.sublist( "Printing" );
    printParams.set( "Output Precision", 10 );
    printParams.set( "Output Processor", 0 );
    printParams.set( "Output Information",
                     NOX::Utils::OuterIteration +
                     NOX::Utils::OuterIterationStatusTest +
                     NOX::Utils::InnerIteration +
                     NOX::Utils::Parameters +
                     NOX::Utils::Details +
                     NOX::Utils::Warning );

    // start definition of nonlinear solver parameters
    // Sublist for line search
    Teuchos::ParameterList& searchParams = nlParams.sublist( "Line Search" );
    searchParams.set( "Method", "Polynomial" );

    // Sublist for direction
    Teuchos::ParameterList& dirParams = nlParams.sublist( "Direction" );
    dirParams.set( "Method", "Newton" );

    Teuchos::ParameterList& newtonParams = dirParams.sublist( "Newton" );
    newtonParams.set( "Forcing Term Method", "Constant" );

    // Sublist for linear solver for the Newton method
    Teuchos::ParameterList& lsParams = newtonParams.sublist( "Linear Solver" );
    lsParams.set( "Aztec Solver", "GMRES" );
    lsParams.set( "Max Iterations", 800 );
    lsParams.set( "Tolerance", 1e-7 );
    lsParams.set( "Output Frequency", 50 );
    lsParams.set( "Aztec Preconditioner", "ilu" );

    // -> A : Jacobian for the first iteration
    // -> InitialGuess : first value x0
    //printf("convert vectors...\n");
    boost::shared_ptr<Epetra_Vector> InitialGuess = x->epetraVector();

    // has_ownership=false in order to let the matrix jac be destroyed by boost
    // and not by Teuchos::RCP
    Teuchos::RCP<Epetra_CrsMatrix> A =
        Teuchos::rcp( ( ( boost::shared_ptr<Epetra_CrsMatrix> )( jac->matrix() ) ).get(),false );

    //std::cout << "A.has_ownership()=" << A.has_ownership() << std::endl;

    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq =
        Teuchos::rcp( new SolverNonLinearTrilinosInterface( this ) );
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac =
        Teuchos::rcp( new SolverNonLinearTrilinosInterface( this ) );
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys =
        Teuchos::rcp( new NOX::Epetra::LinearSystemAztecOO( printParams,
                      lsParams,
                      iReq,
                      iJac,
                      A,
                      *InitialGuess ) );

    // Need a NOX::Epetra::Vector for constructor
    NOX::Epetra::Vector noxInitGuess( *InitialGuess, NOX::DeepCopy );
    Teuchos::RCP<NOX::Epetra::Group> grpPtr =
        Teuchos::rcp( new NOX::Epetra::Group( printParams,
                      iReq,
                      noxInitGuess,
                      linSys ) );

    // Set up the status tests
    Teuchos::RCP<NOX::StatusTest::NormF> testNormF =
        Teuchos::rcp( new NOX::StatusTest::NormF( 1.0e-7 ) );
    Teuchos::RCP<NOX::StatusTest::MaxIters> testMaxIters =
        Teuchos::rcp( new NOX::StatusTest::MaxIters( 20 ) );

    // this will be the convergence test to be used
    Teuchos::RCP<NOX::StatusTest::Combo> combo =
        Teuchos::rcp( new NOX::StatusTest::Combo( NOX::StatusTest::Combo::OR,
                      testNormF, testMaxIters ) );

    // Create the solver
    Teuchos::RCP<NOX::Solver::Generic> solver =
        NOX::Solver::buildSolver( grpPtr, combo, nlParamsPtr );

    // Solve the nonlinesar system
    NOX::StatusTest::StatusType status = solver->solve();

    if ( NOX::StatusTest::Converged  != status )
        std::cout << "\n" << "-- NOX solver did not converged --" << "\n";

    else
        std::cout << "\n" << "-- NOX solver converged --" << "\n";

    // Print the answer
    std::cout << "\n" << "-- Parameter List From Solver --" << "\n";
    solver->getList().print( cout );

    // Get the Epetra_Vector with the final solution from the solver
    const NOX::Epetra::Group & finalGroup =
        dynamic_cast<const NOX::Epetra::Group&>( solver->getSolutionGroup() );
    const Epetra_Vector & finalSolution =
        ( dynamic_cast<const NOX::Epetra::Vector&>( finalGroup.getX() ) ).getEpetraVector();

    //cout << "Computed solution : " << endl;
    //cout << finalSolution;
    x_in = boost::shared_ptr<VectorEpetra<T> > ( new VectorEpetra<T>( &finalSolution ) );

    //std::cout << "InitialGuess.use_count()=" << InitialGuess.use_count() << std::endl;
    //std::cout << "jac.use_count()=" << jac->matrix().use_count() << std::endl;
    //std::cout << "x_in.use_count()=" << x_in.use_count() << std::endl;

    return std::make_pair( 1,finalGroup.getNormF() );
}