00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __itkFEMSolverCrankNicolson_h
00019 #define __itkFEMSolverCrankNicolson_h
00020
00021 #include "itkFEMSolver.h"
00022 #include "itkFEMElementBase.h"
00023 #include "itkFEMMaterialBase.h"
00024 #include "itkFEMLoadBase.h"
00025 #include "itkFEMLinearSystemWrapperVNL.h"
00026
00027 #include "vnl/vnl_sparse_matrix.h"
00028 #include "vnl/vnl_matrix.h"
00029 #include "vnl/vnl_vector.h"
00030 #include "vnl/algo/vnl_svd.h"
00031 #include "vnl/algo/vnl_cholesky.h"
00032 #include <vnl/vnl_sparse_matrix_linear_system.h>
00033 #include <vnl/algo/vnl_lsqr.h>
00034 #include <math.h>
00035
00036
00037 namespace itk {
00038 namespace fem {
00039
00040
00063 class SolverCrankNicolson : public Solver
00064 {
00065 public:
00066
00067
00068
00069
00070 void InitializeForSolution();
00075 void AssembleKandM();
00076
00084 void AssembleFforTimeStep(int dim=0);
00085
00089 void Solve();
00090
00095 void AddToDisplacements(Float optimum=1.0);
00096 void AverageLastTwoDisplacements(Float t=0.5);
00097 void ZeroVector(int which=0);
00098 void PrintDisplacements();
00099 void PrintForce();
00100
00102 inline void SetAlpha(Float a = 0.5) { m_alpha=a; }
00103
00105 inline void SetDeltatT(Float T) { m_deltaT=T; }
00106
00108 inline void SetRho(Float rho) { m_rho=rho; }
00109
00113 void RecomputeForceVector(unsigned int index);
00114
00115
00116 void FindBracketingTriplet(Float* a,Float* b,Float* c);
00120 Float GoldenSection(Float tol=0.01,unsigned int MaxIters=25);
00121
00122 Float BrentsMethod(Float tol=0.01,unsigned int MaxIters=25);
00123 Float EvaluateResidual(Float t=1.0);
00124 Float GetDeformationEnergy(Float t=1.0);
00125 inline Float GSSign(Float a,Float b) { return (b > 0.0 ? fabs(a) : -1.*fabs(a)); }
00126 inline Float GSMax(Float a,Float b) { return (a > b ? a : b); }
00127
00128 void SetEnergyToMin(Float xmin);
00129 inline LinearSystemWrapper* GetLS(){ return m_ls;}
00130
00131 Float GetCurrentMaxSolution() { return m_CurrentMaxSolution; }
00132
00134 void PrintMinMaxOfSolution();
00139 SolverCrankNicolson()
00140 {
00141 m_deltaT=0.5;
00142 m_rho=1.;
00143 m_alpha=0.5;
00144
00145 ForceTIndex=0;
00146 ForceTMinus1Index=2;
00147 SolutionVectorTMinus1Index=3;
00148 DiffMatrixBySolutionTMinus1Index=4;
00149 ForceTotalIndex=5;
00150 SolutionTIndex=0;
00151 TotalSolutionIndex=1;
00152 SolutionTMinus1Index=2;
00153 SumMatrixIndex=0;
00154 DifferenceMatrixIndex=1;
00155 m_CurrentMaxSolution=1.0;
00156 }
00157
00158
00159 ~SolverCrankNicolson() { }
00160
00161 Float m_deltaT;
00162 Float m_rho;
00163 Float m_alpha;
00164 Float m_CurrentMaxSolution;
00165
00166 unsigned int ForceTIndex;
00167 unsigned int ForceTotalIndex;
00168 unsigned int ForceTMinus1Index;
00169 unsigned int SolutionTIndex;
00170 unsigned int SolutionTMinus1Index;
00171 unsigned int SolutionVectorTMinus1Index;
00172 unsigned int TotalSolutionIndex;
00173 unsigned int DifferenceMatrixIndex;
00174 unsigned int SumMatrixIndex;
00175 unsigned int DiffMatrixBySolutionTMinus1Index;
00176
00177 };
00178
00179
00180
00181
00182 }}
00183
00184 #endif // #ifndef __itkFEMSolverCrankNicolson_h