int testTransposeSolve( int NumGlobalElements, int nRHS, double reltol, double abstol, Epetra_Comm& Comm, const Teuchos::RCP<LOCA::GlobalData>& globalData, const Teuchos::RCP<Teuchos::ParameterList>& paramList) { int ierr = 0; double left_bc = 0.0; double right_bc = 1.0; double nonlinear_factor = 1.0; // Create the FiniteElementProblem class. This creates all required // Epetra objects for the problem and allows calls to the // function (RHS) and Jacobian evaluation routines. Tcubed_FiniteElementProblem Problem(NumGlobalElements, Comm); // Get the vector from the Problem Epetra_Vector& soln = Problem.getSolution(); // Initialize Solution soln.PutScalar(0.0); // Create and initialize the parameter vector LOCA::ParameterVector pVector; pVector.addParameter("Nonlinear Factor",nonlinear_factor); pVector.addParameter("Left BC", left_bc); pVector.addParameter("Right BC", right_bc); // Create the interface between the test problem and the nonlinear solver // This is created by the user using inheritance of the abstract base // class: Teuchos::RCP<Problem_Interface> interface = Teuchos::rcp(new Problem_Interface(Problem)); Teuchos::RCP<LOCA::Epetra::Interface::Required> iReq = interface; Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = interface; // Create the Epetra_RowMatrixfor the Jacobian/Preconditioner Teuchos::RCP<Epetra_RowMatrix> Amat = Teuchos::rcp(&Problem.getJacobian(),false); // Get sublists Teuchos::ParameterList& nlParams = paramList->sublist("NOX"); Teuchos::ParameterList& nlPrintParams = nlParams.sublist("Printing"); Teuchos::ParameterList& dirParams = nlParams.sublist("Direction"); Teuchos::ParameterList& newParams = dirParams.sublist("Newton"); Teuchos::ParameterList& lsParams = newParams.sublist("Linear Solver"); // Create the linear systems Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linsys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(nlPrintParams, lsParams, iReq, iJac, Amat, soln)); // Create the loca vector NOX::Epetra::Vector locaSoln(soln); // Create the Group Teuchos::RCP<LOCA::Epetra::Group> grp_tp = Teuchos::rcp(new LOCA::Epetra::Group(globalData, nlPrintParams, iReq, locaSoln, linsys, pVector)); // Create the Group Teuchos::RCP<LOCA::Epetra::Group> grp_lp = Teuchos::rcp(new LOCA::Epetra::Group(globalData, nlPrintParams, iReq, locaSoln, linsys, pVector)); // Create the Group Teuchos::RCP<LOCA::Epetra::Group> grp_ep = Teuchos::rcp(new LOCA::Epetra::Group(globalData, nlPrintParams, iReq, locaSoln, linsys, pVector)); // Change initial guess to a random vector Teuchos::RCP<NOX::Abstract::Vector> xnew = grp_tp->getX().clone(); xnew->random(); grp_tp->setX(*xnew); grp_lp->setX(*xnew); grp_ep->setX(*xnew); // Check some statistics on the solution Teuchos::RCP<NOX::TestCompare> testCompare = Teuchos::rcp(new NOX::TestCompare(globalData->locaUtils->out(), *(globalData->locaUtils))); // Evaluate blocks grp_tp->computeF(); grp_lp->computeF(); grp_ep->computeF(); grp_tp->computeJacobian(); grp_lp->computeJacobian(); grp_ep->computeJacobian(); // Set up left- and right-hand sides Teuchos::RCP<NOX::Abstract::MultiVector> F = grp_tp->getX().createMultiVector(nRHS); F->random(); Teuchos::RCP<NOX::Abstract::MultiVector> X_tp = F->clone(NOX::ShapeCopy); X_tp->init(0.0); Teuchos::RCP<NOX::Abstract::MultiVector> X_lp = F->clone(NOX::ShapeCopy); X_lp->init(0.0); Teuchos::RCP<NOX::Abstract::MultiVector> X_ep = F->clone(NOX::ShapeCopy); X_ep->init(0.0); // Set up residuals Teuchos::RCP<NOX::Abstract::MultiVector> R_tp = F->clone(NOX::ShapeCopy); Teuchos::RCP<NOX::Abstract::MultiVector> R_lp = F->clone(NOX::ShapeCopy); Teuchos::RCP<NOX::Abstract::MultiVector> R_ep = F->clone(NOX::ShapeCopy); // Set up linear solver lists Teuchos::ParameterList lsParams_tp = lsParams; Teuchos::ParameterList lsParams_lp = lsParams; Teuchos::ParameterList lsParams_ep = lsParams; lsParams_tp.set("Transpose Solver Method", "Transpose Preconditioner"); lsParams_lp.set("Transpose Solver Method", "Left Preconditioning"); lsParams_ep.set("Transpose Solver Method", "Explicit Transpose"); NOX::Abstract::Group::ReturnType status; // Test transpose solve with transposed preconditioner if (globalData->locaUtils->isPrintType(NOX::Utils::TestDetails)) globalData->locaUtils->out() << std::endl << "\t***** " << "Testing Transposed Preconditioner Residual" << " *****" << std::endl; status = grp_tp->applyJacobianTransposeInverseMultiVector(lsParams_tp, *F, *X_tp); if (status == NOX::Abstract::Group::Failed) ++ierr; status = grp_tp->applyJacobianTransposeMultiVector(*X_tp, *R_tp); ierr += testCompare->testMultiVector(*R_tp, *F, reltol, abstol, "Residual"); // Test transpose solve with transposed left-preconditioner if (lsParams.get("Preconditioner", "None") != "None") { if (globalData->locaUtils->isPrintType(NOX::Utils::TestDetails)) globalData->locaUtils->out() << std::endl << "\t***** " << "Testing Transposed Left Preconditioner Residual" << " *****" << std::endl; status = grp_lp->applyJacobianTransposeInverseMultiVector(lsParams_lp, *F, *X_lp); if (status == NOX::Abstract::Group::Failed) ++ierr; status = grp_lp->applyJacobianTransposeMultiVector(*X_lp, *R_lp); ierr += testCompare->testMultiVector(*R_lp, *F, reltol, abstol, "Residual"); } #ifdef HAVE_NOX_EPETRAEXT // Test transpose solve with explicit preconditioner if (globalData->locaUtils->isPrintType(NOX::Utils::TestDetails)) globalData->locaUtils->out() << std::endl << "\t***** " << "Testing Explicit Preconditioner Residual" << " *****" << std::endl; status = grp_ep->applyJacobianTransposeInverseMultiVector(lsParams_ep, *F, *X_ep); if (status == NOX::Abstract::Group::Failed) ++ierr; status = grp_ep->applyJacobianTransposeMultiVector(*X_ep, *R_ep); ierr += testCompare->testMultiVector(*R_ep, *F, reltol, abstol, "Residual"); #endif // Compare solutions if (lsParams.get("Preconditioner", "None") != "None") { if (globalData->locaUtils->isPrintType(NOX::Utils::TestDetails)) globalData->locaUtils->out() << std::endl << "\t***** " << "Comparing Transposed Preconditioner and Left Preconditioner Solutions" << " *****" << std::endl; ierr += testCompare->testMultiVector(*X_lp, *X_tp, reltol, abstol, "Solution"); } #ifdef HAVE_NOX_EPETRAEXT if (globalData->locaUtils->isPrintType(NOX::Utils::TestDetails)) globalData->locaUtils->out() << std::endl << "\t***** " << "Comparing Transposed Preconditioner and Explicit Preconditioner Solutions" << " *****" << std::endl; ierr += testCompare->testMultiVector(*X_ep, *X_tp, reltol, abstol, "Solution"); #endif return ierr; }
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!!
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[]) { int nConstraints = 10; int nRHS = 7; double left_bc = 0.0; double right_bc = 1.0; double nonlinear_factor = 1.0; int ierr = 0; double reltol = 1.0e-8; double abstol = 1.0e-8; double lstol = 1.0e-11; int MyPID = 0; try { // 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 // Get the total number of processors MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); bool verbose = false; // Check for verbose output if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; // Get the number of elements from the command line int NumGlobalElements = 0; if ((argc > 2) && (verbose)) NumGlobalElements = atoi(argv[2]) + 1; else if ((argc > 1) && (!verbose)) NumGlobalElements = atoi(argv[1]) + 1; else NumGlobalElements = 101; // The number of unknowns must be at least equal to the // number of processors. if (NumGlobalElements < NumProc) { std::cout << "numGlobalBlocks = " << NumGlobalElements << " cannot be < number of processors = " << NumProc << std::endl; exit(1); } // Seed the random number generator in Teuchos. We create random // bordering matrices and it is possible different processors might generate // different matrices. By setting the seed, this shouldn't happen. Teuchos::ScalarTraits<double>::seedrandom(12345); // Create parameter list Teuchos::RCP<Teuchos::ParameterList> paramList = Teuchos::rcp(new Teuchos::ParameterList); // Create LOCA sublist Teuchos::ParameterList& locaParamsList = paramList->sublist("LOCA"); // Create the constraints list Teuchos::ParameterList& constraintsList = locaParamsList.sublist("Constraints"); constraintsList.set("Bordered Solver Method", "Bordering"); // Create the "Solver" parameters sublist to be used with NOX Solvers Teuchos::ParameterList& nlParams = paramList->sublist("NOX"); Teuchos::ParameterList& nlPrintParams = nlParams.sublist("Printing"); nlPrintParams.set("MyPID", MyPID); if (verbose) nlPrintParams.set("Output Information", NOX::Utils::Error + NOX::Utils::Details + NOX::Utils::LinearSolverDetails + NOX::Utils::OuterIteration + NOX::Utils::InnerIteration + NOX::Utils::Warning + NOX::Utils::TestDetails + NOX::Utils::StepperIteration + NOX::Utils::StepperDetails); else nlPrintParams.set("Output Information", NOX::Utils::Error); // Create the "Direction" sublist for the "Line Search Based" solver Teuchos::ParameterList& dirParams = nlParams.sublist("Direction"); Teuchos::ParameterList& newParams = dirParams.sublist("Newton"); Teuchos::ParameterList& lsParams = newParams.sublist("Linear Solver"); lsParams.set("Aztec Solver", "GMRES"); lsParams.set("Max Iterations", 100); lsParams.set("Tolerance", lstol); if (verbose) lsParams.set("Output Frequency", 1); else lsParams.set("Output Frequency", 0); lsParams.set("Scaling", "None"); lsParams.set("Preconditioner", "Ifpack"); //lsParams.set("Preconditioner", "AztecOO"); //lsParams.set("Jacobian Operator", "Matrix-Free"); //lsParams.set("Preconditioner Operator", "Finite Difference"); lsParams.set("Aztec Preconditioner", "ilut"); //lsParams.set("Overlap", 2); //lsParams.set("Fill Factor", 2.0); //lsParams.set("Drop Tolerance", 1.0e-12); lsParams.set("Max Age Of Prec", -2); // Create the FiniteElementProblem class. This creates all required // Epetra objects for the problem and allows calls to the // function (RHS) and Jacobian evaluation routines. Tcubed_FiniteElementProblem Problem(NumGlobalElements, Comm); // Get the vector from the Problem Epetra_Vector& soln = Problem.getSolution(); // Initialize Solution soln.PutScalar(0.0); // Create and initialize the parameter vector LOCA::ParameterVector pVector; pVector.addParameter("Nonlinear Factor",nonlinear_factor); pVector.addParameter("Left BC", left_bc); pVector.addParameter("Right BC", right_bc); // Create the interface between the test problem and the nonlinear solver // This is created by the user using inheritance of the abstract base // class: Teuchos::RCP<Problem_Interface> interface = Teuchos::rcp(new Problem_Interface(Problem)); Teuchos::RCP<LOCA::Epetra::Interface::Required> iReq = interface; Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = interface; // Create the Epetra_RowMatrixfor the Jacobian/Preconditioner Teuchos::RCP<Epetra_RowMatrix> Amat = Teuchos::rcp(&Problem.getJacobian(),false); // Create the linear systems Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linsys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(nlPrintParams, lsParams, iReq, iJac, Amat, soln)); // Create the loca vector NOX::Epetra::Vector locaSoln(soln); // Create Epetra factory Teuchos::RCP<LOCA::Abstract::Factory> epetraFactory = Teuchos::rcp(new LOCA::Epetra::Factory); // Create global data object globalData = LOCA::createGlobalData(paramList, epetraFactory); // Create parsed parameter list parsedParams = Teuchos::rcp(new LOCA::Parameter::SublistParser(globalData)); parsedParams->parseSublists(paramList); // Create the Group grp = Teuchos::rcp(new LOCA::Epetra::Group(globalData, nlPrintParams, iReq, locaSoln, linsys, pVector)); // Create Jacobian operator op = Teuchos::rcp(new LOCA::BorderedSolver::JacobianOperator(grp)); // Change initial guess to a random vector Teuchos::RCP<NOX::Abstract::Vector> xnew = grp->getX().clone(); xnew->random(); grp->setX(*xnew); // Create the constraints object & constraint param IDs list constraints = Teuchos::rcp(new LinearConstraint(nConstraints, LOCA::ParameterVector(), locaSoln)); // Create bordering solver bordering = globalData->locaFactory->createBorderedSolverStrategy( parsedParams, parsedParams->getSublist("Constraints")); // Change strategy to Householder constraintsList.set("Bordered Solver Method", "Householder"); // Create householder solver householder = globalData->locaFactory->createBorderedSolverStrategy( parsedParams, parsedParams->getSublist("Constraints")); // Check some statistics on the solution testCompare = Teuchos::rcp(new NOX::TestCompare( globalData->locaUtils->out(), *(globalData->locaUtils))); // Evaluate blocks grp->computeF(); grp->computeJacobian(); // A A = grp->getX().createMultiVector(nConstraints); A->random(); // B constraints->setX(grp->getX()); B = grp->getX().createMultiVector(nConstraints); B->random(); constraints->setDgDx(*B); constraints->computeConstraints(); constraints->computeDX(); // C C = Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(nConstraints, nConstraints)); C->random(); // Set up left- and right-hand sides F = grp->getX().createMultiVector(nRHS); F->random(); G = Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(nConstraints, nRHS)); G->random(); X_bordering = F->clone(NOX::ShapeCopy); Y_bordering = Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(nConstraints, nRHS)); X_householder = F->clone(NOX::ShapeCopy); Y_householder = Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(nConstraints, nRHS)); std::string testName; // Test all nonzero testName = "Testing all nonzero"; ierr += testSolve(false, false, false, false, false, reltol, abstol, testName); // Test A = 0 testName = "Testing A=0"; ierr += testSolve(true, false, false, false, false, reltol, abstol, testName); // Test B = 0 testName = "Testing B=0"; ierr += testSolve(false, true, false, false, false, reltol, abstol, testName); // Test C = 0 testName = "Testing C=0"; ierr += testSolve(false, false, true, false, false, reltol, abstol, testName); // Test F = 0 testName = "Testing F=0"; ierr += testSolve(false, false, false, true, false, reltol, abstol, testName); // Test G = 0 testName = "Testing G=0"; ierr += testSolve(false, false, false, false, true, reltol, abstol, testName); // Test A,B = 0 testName = "Testing A,B=0"; ierr += testSolve(true, true, false, false, false, reltol, abstol, testName); // Test A,F = 0 testName = "Testing A,F=0"; ierr += testSolve(true, false, false, true, false, reltol, abstol, testName); // Test A,G = 0 testName = "Testing A,G=0"; ierr += testSolve(true, false, false, false, true, reltol, abstol, testName); // Test B,F = 0 testName = "Testing B,F=0"; ierr += testSolve(false, true, false, true, false, reltol, abstol, testName); // Test B,G = 0 testName = "Testing B,G=0"; ierr += testSolve(false, true, false, false, true, reltol, abstol, testName); // Test C,F = 0 testName = "Testing C,F=0"; ierr += testSolve(false, false, true, true, false, reltol, abstol, testName); // Test C,G = 0 testName = "Testing C,G=0"; ierr += testSolve(false, false, true, false, true, reltol, abstol, testName); // Test F,G = 0 testName = "Testing F,G=0"; ierr += testSolve(false, false, false, true, true, reltol, abstol, testName); // Test A,B,F = 0 testName = "Testing A,B,F=0"; ierr += testSolve(true, true, false, true, false, reltol, abstol, testName); // Test A,B,G = 0 testName = "Testing A,B,G=0"; ierr += testSolve(true, true, false, false, true, reltol, abstol, testName); // Test A,F,G = 0 testName = "Testing A,F,G=0"; ierr += testSolve(true, false, false, true, true, reltol, abstol, testName); // Test B,F,G = 0 testName = "Testing B,F,G=0"; ierr += testSolve(false, true, false, true, true, reltol, abstol, testName); // Test C,F,G = 0 testName = "Testing C,F,G=0"; ierr += testSolve(false, false, true, true, true, reltol, abstol, testName); // Test A,B,F,G = 0 testName = "Testing A,B,F,G=0"; ierr += testSolve(true, true, false, true, true, reltol, abstol, testName); LOCA::destroyGlobalData(globalData); } catch (std::exception& e) { std::cout << e.what() << std::endl; ierr = 1; } catch (const char *s) { std::cout << s << std::endl; ierr = 1; } catch (...) { std::cout << "Caught unknown exception!" << std::endl; ierr = 1; } if (MyPID == 0) { if (ierr == 0) std::cout << "All tests passed!" << std::endl; else std::cout << ierr << " test(s) failed!" << std::endl; } #ifdef HAVE_MPI MPI_Finalize() ; #endif return ierr; }