17 #include <gsStructuralAnalysis/src/gsALMSolvers/gsALMHelper.h>
25 Base::defaultOptions();
26 m_options.addReal(
"Scaling",
"Set Scaling factor Phi",-1);
27 m_options.addInt (
"AngleMethod",
"Angle determination method: 0 = Previous step; 1 = Previous iteration",angmethod::Step);
34 m_phi = m_options.getReal(
"Scaling");
35 m_phi_user = m_phi == -1 ?
false :
true;
37 m_angleDetermine = m_options.getInt (
"AngleMethod");
43 m_numDof = m_forcing.size();
58 m_jacMat = computeJacobian();
59 this->factorizeMatrix(m_jacMat);
68 m_jacMat = computeJacobian();
69 this->factorizeMatrix(m_jacMat);
85 if (( (lamold*m_deltaL < 0) && (
abs(m_deltaL) <=
abs(lamold) ) ) && m_relax != 1.0 )
87 m_note +=
"\t relaxated solution!";
88 m_deltaU = m_relax * (m_deltaL*m_deltaUt + m_eta*m_deltaUbar);
89 m_deltaL = m_relax * m_deltaL;
95 if (m_angleDetermine == angmethod::Iteration)
97 m_DeltaUold = m_DeltaU;
98 m_DeltaLold = m_DeltaL;
106 m_DeltaL = m_deltaL = 0.0;
113 m_jacMat = computeJacobian();
114 this->factorizeMatrix(m_jacMat);
115 m_deltaUt = this->solveSystem(m_forcing);
118 if (m_DeltaUold.dot(m_DeltaUold) == 0 && m_DeltaLold*m_DeltaLold == 0)
121 m_note+=
"predictor\t";
122 m_deltaL = m_arcLength / math::pow(2*( m_deltaUt.dot(m_deltaUt) ) , 0.5);
123 m_deltaU = m_deltaUbar + m_deltaL*m_deltaUt;
125 m_phi = math::pow( m_deltaUt.dot(m_deltaUt) / m_forcing.dot(m_forcing),0.5);
150 m_phi = math::pow(m_U.dot(m_U)/( math::pow(m_L,2) * m_forcing.dot(m_forcing) ),0.5);
156 m_DeltaU += m_deltaU;
157 m_DeltaL += m_deltaL;
159 if (m_angleDetermine == angmethod::Iteration || m_angleDetermine == angmethod::Predictor)
161 m_DeltaUold = m_DeltaU;
162 m_DeltaLold = m_DeltaL;
169 GISMO_ASSERT(m_Uguess.rows()!=0 && m_Uguess.cols()!=0,
"Guess is empty");
171 m_jacMat = computeJacobian();
172 this->factorizeMatrix(m_jacMat);
173 m_deltaUt = this->solveSystem(m_forcing);
175 m_phi = math::pow( m_deltaUt.dot(m_deltaUt) / m_forcing.dot(m_forcing),0.5);
179 m_DeltaUold = -(m_Uguess - m_U);
180 m_DeltaLold = -(m_Lguess - m_L);
201 if (m_angleDetermine == angmethod::Step)
203 m_DeltaUold = m_DeltaU;
204 m_DeltaLold = m_DeltaL;
215 T A0 = math::pow(m_phi,2)* m_forcing.dot(m_forcing);
217 m_a0 = m_deltaUt.dot(m_deltaUt) + A0;
218 m_b0 = 2*( m_deltaUt.dot(m_DeltaU) + m_DeltaL * A0 );
219 m_b1 = 2*( m_deltaUbar.dot(m_deltaUt) );
220 m_c0 = m_DeltaU.dot(m_DeltaU) + m_DeltaL*m_DeltaL * A0 - math::pow(m_arcLength,2);
221 m_c1 = 2*( m_DeltaU.dot(m_deltaUbar) );
222 m_c2 = m_deltaUbar.dot(m_deltaUbar);
226 m_alpha2 = m_b0 + m_eta*m_b1;
227 m_alpha3 = m_c0 + m_eta*m_c1 + m_eta*m_eta*m_c2;
229 m_discriminant = math::pow(m_alpha2 ,2) - 4 * m_alpha1 * m_alpha3;
237 m_alpha2 = m_b0 + m_eta*m_b1;
238 m_alpha3 = m_c0 + m_eta*m_c1 + m_eta*m_eta*m_c2;
246 m_deltaLs[0] = (-m_alpha2 )/(2*m_alpha1);
247 m_deltaLs[1] = (-m_alpha2 )/(2*m_alpha1);
253 m_alpha1 = m_b1*m_b1 - 4.0*m_a0*m_c2;
254 m_alpha2 = 2.0*m_b0*m_b1 - 4.0*m_a0*m_c1;
255 m_alpha3 = m_b0*m_b0 - 4.0*m_a0*m_c0;
257 m_discriminant = math::pow(m_alpha2 ,2.0) - 4.0 * m_alpha1 * m_alpha3;
261 if (m_discriminant >= 0)
263 etas[0] = (-m_alpha2 + math::pow(m_discriminant,0.5))/(2.0*m_alpha1);
264 etas[1] = (-m_alpha2 - math::pow(m_discriminant,0.5))/(2.0*m_alpha1);
266 T eta1 = std::min(etas[0],etas[1]);
267 T eta2 = std::max(etas[0],etas[1]);
268 if (m_verbose) {
gsInfo<<
"eta 1 = "<<eta1<<
"\t eta2 = "<<eta2<<
"\n";}
281 T xi = 0.05*
abs(eta2-eta1);
284 else if ( (eta2 > 1.0) && (-m_alpha2/m_alpha1 < 1.0) )
286 else if ( (eta1 < 1.0) && (-m_alpha2/m_alpha1 > 1.0) )
288 else if ( eta1 > 1.0 )
292 m_note = m_note +
" option 1";
293 else if ( (eta2 > 1.0) && (-m_alpha2/m_alpha1 < 1.0) )
294 m_note = m_note +
" option 2";
295 else if ( (eta1 < 1.0) && (-m_alpha2/m_alpha1 > 1.0) )
296 m_note = m_note +
" option 3";
297 else if ( eta1 > 1.0 )
298 m_note = m_note +
" option 4";
304 gsInfo<<
"Discriminant was negative in modified method\n";
310 T A0 = math::pow(m_phi,2)* m_forcing.dot(m_forcing);
317 T Lcr = Fint.dot(m_forcing)/m_forcing.dot(m_forcing);
318 T DeltaLcr = Lcr - m_L;
320 T arcLength_cr = math::pow( DeltaUcr.dot(DeltaUcr) + A0 * math::pow(DeltaLcr, 2.0) ,0.5);
321 T mu = m_arcLength/arcLength_cr;
323 m_deltaL = mu*DeltaLcr - m_DeltaL;
324 m_deltaU = mu*DeltaUcr - m_DeltaU;
330 m_deltaLs.setZero(2);
331 computeLambdasSimple();
332 if (m_discriminant >= 0)
335 m_deltaLs[0] = (-m_alpha2 + math::pow(m_discriminant,0.5))/(2*m_alpha1);
336 m_deltaLs[1] = (-m_alpha2 - math::pow(m_discriminant,0.5))/(2*m_alpha1);
343 computeLambdasModified();
344 gsDebugVar(m_discriminant);
345 if ((m_discriminant >= 0) && m_eta > 0.05)
352 if (m_verbose) {
gsInfo<<
"Modified Complex Root Solve\n";}
358 computeLambdasComplex();
360 if (m_verbose) {
gsInfo<<
"Simplified Complex Root Solve\n";}
371 if (sign(m_DeltaL + m_deltaLs[0]) == sign(m_detKT))
372 m_deltaL = m_deltaLs[0];
374 m_deltaL = m_deltaLs[1];
377 m_deltaU = m_deltaUbar + m_deltaL*m_deltaUt;
387 T A0 = math::pow(m_phi,2)* m_forcing.dot(m_forcing);
388 index_t dir = sign(m_DeltaUold.dot(m_deltaUt) + A0*m_DeltaLold);
389 T denum = ( math::pow( m_deltaUt.dot(m_deltaUt) + A0 ,0.5) );
395 mu = m_arcLength / denum;
398 m_deltaU = m_deltaL*m_deltaUt;
405 deltaU1 = m_eta*m_deltaUbar + m_deltaUt*m_deltaLs[0];
406 deltaU2 = m_eta*m_deltaUbar + m_deltaUt*m_deltaLs[1];
411 DOT1 = m_deltaLs[0]*(m_DeltaUold.dot(m_deltaUt) + math::pow(m_phi,2)*m_DeltaLold);
412 DOT2 = m_deltaLs[1]*(m_DeltaUold.dot(m_deltaUt) + math::pow(m_phi,2)*m_DeltaLold);
416 m_deltaL = m_deltaLs[0];
419 else if (DOT1 < DOT2)
421 m_deltaL = m_deltaLs[1];
426 m_deltaL = m_deltaLs[0];
483 gsInfo<<std::setw(4)<<std::left<<
"It.";
484 gsInfo<<std::setw(17)<<std::left<<
"Res. F";
485 gsInfo<<std::setw(17)<<std::left<<
"|dU|/|Du|";
486 gsInfo<<std::setw(17)<<std::left<<
"dL/DL";
487 gsInfo<<std::setw(17)<<std::left<<
"|U|";
488 gsInfo<<std::setw(17)<<std::left<<
"L";
489 gsInfo<<std::setw(17)<<std::left<<
"|DU|";
490 gsInfo<<std::setw(17)<<std::left<<
"DL";
491 gsInfo<<std::setw(17)<<std::left<<
"|dU|";
492 gsInfo<<std::setw(17)<<std::left<<
"dL";
493 gsInfo<<std::setw(17)<<std::left<<
"ds²";
494 gsInfo<<std::setw(17)<<std::left<<
"|dU|²";
495 gsInfo<<std::setw(17)<<std::left<<
"dL²";
496 gsInfo<<std::setw(17)<<std::left<<
"Dmin";
497 gsInfo<<std::setw(17)<<std::left<<
"note";
508 computeStability(
false);
513 T A0 = math::pow(m_phi,2)*m_forcing.dot(m_forcing);
516 gsInfo<<std::setw(4)<<std::left<<m_numIterations;
517 gsInfo<<std::setw(17)<<std::left<<m_residueF;
518 gsInfo<<std::setw(17)<<std::left<<m_residueU;
519 gsInfo<<std::setw(17)<<std::left<<m_residueL;
520 gsInfo<<std::setw(17)<<std::left<<(m_U+m_DeltaU).norm();
521 gsInfo<<std::setw(17)<<std::left<<(m_L + m_DeltaL);
522 gsInfo<<std::setw(17)<<std::left<<m_DeltaU.norm();
523 gsInfo<<std::setw(17)<<std::left<<m_DeltaL;
524 gsInfo<<std::setw(17)<<std::left<<m_deltaU.norm();
525 gsInfo<<std::setw(17)<<std::left<<m_deltaL;
526 gsInfo<<std::setw(17)<<std::left<<this->
distance(m_DeltaU,m_DeltaL);
527 gsInfo<<std::setw(17)<<std::left<<math::pow(m_DeltaU.norm(),2.0);
528 gsInfo<<std::setw(17)<<std::left<<A0*math::pow(m_DeltaL,2.0);
529 gsInfo<<std::setw(17)<<std::left<<m_indicator <<std::left <<
" (" <<std::left<< m_negatives<<std::left <<
")";
530 gsInfo<<std::setw(17)<<std::left<<m_note;
void computeLambdaDET()
Compute the load factors.
Definition: gsALMCrisfield.hpp:367
void iterationFinish()
See gsALMBase.
Definition: gsALMCrisfield.hpp:194
void predictor()
See gsALMBase.
Definition: gsALMCrisfield.hpp:111
void computeLambdas()
Compute the load factors.
Definition: gsALMCrisfield.hpp:328
T distance(gsMatrix< T > const &A, gsMatrix< T > const &B, index_t i=0, index_t j=0, bool cols=false)
compute a distance between the point number in the set and the point number <j> in the set ; by def...
void iteration()
See gsALMBase.
Definition: gsALMCrisfield.hpp:74
void getOptions()
See gsALMBase.
Definition: gsALMCrisfield.hpp:31
#define index_t
Definition: gsConfig.h:32
void computeLambdasEta()
Compute the load factors.
Definition: gsALMCrisfield.hpp:234
void quasiNewtonPredictor()
See gsALMBase.
Definition: gsALMCrisfield.hpp:56
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void initOutput()
See gsALMBase.
Definition: gsALMCrisfield.hpp:480
void computeLambdaMU()
Compute the load factors.
Definition: gsALMCrisfield.hpp:385
void defaultOptions()
See gsALMBase.
Definition: gsALMCrisfield.hpp:23
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition: gsXml.cpp:74
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition: gsVector.h:35
void quasiNewtonIteration()
See gsALMBase.
Definition: gsALMCrisfield.hpp:66
#define gsInfo
Definition: gsDebug.h:43
void computeLambdasModified()
Compute the load factors.
Definition: gsALMCrisfield.hpp:251
Performs the Crisfield arc length method to solve a nonlinear equation system.
Definition: gsALMCrisfield.h:29
void stepOutput()
See gsALMBase.
Definition: gsALMCrisfield.hpp:504
void computeLambdasComplex()
Compute the load factors.
Definition: gsALMCrisfield.hpp:308
void initiateStep()
See gsALMBase.
Definition: gsALMCrisfield.hpp:103
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4488
void computeLambdasSimple()
Compute the load factors.
Definition: gsALMCrisfield.hpp:213
void initMethods()
See gsALMBase.
Definition: gsALMCrisfield.hpp:41
void computeLambdaDOT()
Compute the load factors.
Definition: gsALMCrisfield.hpp:402