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!!
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; }
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!!
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() ); }