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