SimplePetscNonlinearSolver.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00033 #include "SimplePetscNonlinearSolver.hpp"
00034 #include "Exception.hpp"
00035 #include "petscsnes.h"
00036 #include "PetscTools.hpp"
00037 #include <sstream>
00038
00039 Vec SimplePetscNonlinearSolver::Solve(PetscErrorCode (*pComputeResidual)(SNES,Vec,Vec,void*),
00040 PetscErrorCode (*pComputeJacobian)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),
00041 Vec initialGuess,
00042 unsigned fill,
00043 void* pContext)
00044 {
00045 SNES snes;
00046
00047
00048 Vec residual;
00049 VecDuplicate(initialGuess, &residual);
00050
00051 Mat jacobian;
00052
00053 PetscInt N;
00054
00055
00056 VecGetSize(initialGuess,&N);
00057
00058 PetscTools::SetupMat(jacobian, N, N, fill);
00059
00060 SNESCreate(PETSC_COMM_WORLD, &snes);
00061 SNESSetFunction(snes, residual, pComputeResidual, pContext);
00062 SNESSetJacobian(snes, jacobian, jacobian, pComputeJacobian, pContext);
00063 SNESSetType(snes,SNESLS);
00064 SNESSetTolerances(snes,1.0e-5,1.0e-5,1.0e-5,PETSC_DEFAULT,PETSC_DEFAULT);
00065
00066
00067 Vec x;
00068 VecDuplicate(initialGuess, &x);
00069 VecCopy(initialGuess, x);
00070
00071 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00072 SNESSolve(snes, x);
00073 #else
00074 SNESSolve(snes, PETSC_NULL, x);
00075 #endif
00076
00077 VecDestroy(residual);
00078 MatDestroy(jacobian);
00079
00080 SNESConvergedReason reason;
00081 SNESGetConvergedReason(snes,&reason);
00082 #define COVERAGE_IGNORE
00083 if (reason < 0)
00084 {
00085 std::stringstream reason_stream;
00086 reason_stream << reason;
00087 VecDestroy(x);
00088 SNESDestroy(snes);
00089 EXCEPTION("Nonlinear Solver did not converge. PETSc reason code:"
00090 +reason_stream.str()+" .");
00091 }
00092 #undef COVERAGE_IGNORE
00093 SNESDestroy(snes);
00094
00095 return x;
00096 }