13
13
14
14
#include "QuasiStaticSIM.h"
15
15
#include "HermiteInterpolator.h"
16
+ #include "FractureElasticityVoigt.h"
16
17
#include "SIMoutput.h"
17
18
#include "TimeStep.h"
18
19
#include "Utilities.h"
30
31
QuasiStaticSIM ::QuasiStaticSIM (SIMbase & sim ) : NonLinSIM (sim )
31
32
{
32
33
numPt = numPtPos = nDump = 0 ;
34
+ version = 1 ;
33
35
}
34
36
35
37
@@ -66,6 +68,7 @@ bool QuasiStaticSIM::parse (const TiXmlElement* elem)
66
68
numPt = params .size ();
67
69
}
68
70
utl ::getAttribute (child ,"nDump" ,nDump );
71
+ utl ::getAttribute (child ,"version" ,version );
69
72
}
70
73
71
74
return this -> NonLinSIM ::parse (elem );
@@ -84,6 +87,10 @@ void QuasiStaticSIM::printProblem () const
84
87
IFEM ::cout << (i %10 ? " " : "\n\t " ) << params [i ];
85
88
if (nDump > 0 )
86
89
IFEM ::cout <<"\n\tDumping f(alpha) at " << nDump <<" sampling points." ;
90
+ if (version == 1 )
91
+ IFEM ::cout <<"\n\tEvaluating f'(alpha) as {F}_int * {u}_corr." ;
92
+ else if (version == 2 )
93
+ IFEM ::cout <<"\n\tEvaluating f'(alpha) by direct integration." ;
87
94
}
88
95
IFEM ::cout << std ::endl ;
89
96
}
@@ -93,8 +100,10 @@ bool QuasiStaticSIM::evalEnergyFunctional (const TimeDomain& time,
93
100
const Vectors & pSol ,
94
101
double * fVal , double * fDer )
95
102
{
96
- if (fDer )
103
+ if (fDer && version == 1 )
97
104
{
105
+ // Integrate f'(alpha) as the dot-product between internal force vector
106
+ // and the solution correction vector
98
107
if (!model .setMode (SIM ::INT_FORCES ))
99
108
return false;
100
109
@@ -107,16 +116,23 @@ bool QuasiStaticSIM::evalEnergyFunctional (const TimeDomain& time,
107
116
* fDer = - residual .dot (linsol );
108
117
}
109
118
110
- if (fVal )
119
+ if (fVal || version == 2 )
111
120
{
121
+ FractureElasticNorm ::dirDer = version == 2 ;
122
+
112
123
if (!model .setMode (SIM ::RECOVERY ))
113
124
return false;
114
125
115
126
Vectors gNorm ;
116
127
if (!model .solutionNorms (time ,pSol ,gNorm ))
117
128
return false;
118
129
119
- * fVal = gNorm .front ()(1 ) + gNorm .front ()(6 );
130
+ if (fVal )
131
+ * fVal = gNorm .front ()(1 ) + gNorm .front ()(6 );
132
+ if (fDer && version == 2 )
133
+ * fDer = gNorm .front ()(5 ); // f'(alpha) is integrated by the norm class
134
+
135
+ FractureElasticNorm ::dirDer = false;
120
136
}
121
137
122
138
return true;
@@ -129,8 +145,11 @@ bool QuasiStaticSIM::lineSearch (TimeStep& param)
129
145
if (numPtPos < 2 )
130
146
return true; // No line search
131
147
148
+ FractureElasticNorm ::extEnr = false; // Disable external energy calculation,
149
+ // since it uses a path integral valid at the converged configuration only
150
+
132
151
// Make a temporary copy of the primary solution
133
- Vectors tmpSol (1 , solution .front ());
152
+ Vectors tmpSol (version == 2 ? 2 : 1 , solution .front ());
134
153
Vector & solVec = tmpSol .front ();
135
154
double curr , prev ;
136
155
@@ -148,7 +167,13 @@ bool QuasiStaticSIM::lineSearch (TimeStep& param)
148
167
std ::cout <<"\tLine search? curr: " << curr <<" prev: " << prev << std ::endl ;
149
168
#endif
150
169
if (curr < prev )
170
+ {
171
+ FractureElasticNorm ::extEnr = true; // Enable external energy calculation
151
172
return true; // No line search needed in this iteration
173
+ }
174
+
175
+ if (version == 2 ) // Store the solution correction in tmpSol
176
+ tmpSol .back () = linsol ;
152
177
153
178
// Evaluate f'(alpha) at alpha=0.0
154
179
if (!this -> evalEnergyFunctional (param .time ,tmpSol ,nullptr ,& curr ))
@@ -171,6 +196,7 @@ bool QuasiStaticSIM::lineSearch (TimeStep& param)
171
196
if (!this -> evalEnergyFunctional (param .time ,tmpSol ,& values [i ],& derivs [i ]))
172
197
return false;
173
198
}
199
+ FractureElasticNorm ::extEnr = true; // Enable external energy calculation
174
200
175
201
#if SP_DEBUG > 1
176
202
std ::cout <<"\nParameters:\n" ;
0 commit comments