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
00029
00036 #include "SimplePetscNonlinearSolver.hpp"
00037 #include "Exception.hpp"
00038 #include "petscsnes.h"
00039 #include "PetscTools.hpp"
00040 #include <sstream>
00041
00042
00072 Vec SimplePetscNonlinearSolver::Solve(PetscErrorCode (*pComputeResidual)(SNES,Vec,Vec,void*),
00073 PetscErrorCode (*pComputeJacobian)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),
00074 Vec initialGuess,
00075 void* pContext)
00076 {
00077 SNES snes;
00078
00079
00080 Vec residual;
00081 VecDuplicate(initialGuess, &residual);
00082
00083 Mat jacobian;
00084
00085 PetscInt N;
00086
00087 VecGetSize(initialGuess,&N);
00088
00089 PetscTools::SetupMat(jacobian, N, N);
00090
00091 SNESCreate(PETSC_COMM_WORLD, &snes);
00092 SNESSetFunction(snes, residual, pComputeResidual, pContext);
00093 SNESSetJacobian(snes, jacobian, jacobian, pComputeJacobian, pContext);
00094 SNESSetType(snes,SNESLS);
00095 SNESSetTolerances(snes,1.0e-5,1.0e-5,1.0e-5,PETSC_DEFAULT,PETSC_DEFAULT);
00096
00097
00098 Vec x;
00099 VecDuplicate(initialGuess, &x);
00100 VecCopy(initialGuess, x);
00101
00102
00103 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00104 SNESSolve(snes, x);
00105 #else
00106 SNESSolve(snes, PETSC_NULL, x);
00107 #endif
00108
00109 VecDestroy(residual);
00110 MatDestroy(jacobian);
00111
00112 SNESConvergedReason reason;
00113 SNESGetConvergedReason(snes,&reason);
00114 #define COVERAGE_IGNORE
00115 if (reason<0)
00116 {
00117 std::stringstream reason_stream;
00118 reason_stream << reason;
00119 VecDestroy(x);
00120 SNESDestroy(snes);
00121 EXCEPTION("Nonlinear Solver did not converge. Petsc reason code:"
00122 +reason_stream.str()+" .");
00123 }
00124 #undef COVERAGE_IGNORE
00125 SNESDestroy(snes);
00126
00127 return x;
00128 }