| 1 | /*!\file: solutionsequence_nonlinear.cpp | 
|---|
| 2 | * \brief: core of a non-linear solution, using fixed-point method | 
|---|
| 3 | */ | 
|---|
| 4 |  | 
|---|
| 5 | #include "./solutionsequences.h" | 
|---|
| 6 | #include "../toolkits/toolkits.h" | 
|---|
| 7 | #include "../classes/classes.h" | 
|---|
| 8 | #include "../shared/shared.h" | 
|---|
| 9 | #include "../modules/modules.h" | 
|---|
| 10 |  | 
|---|
| 11 | void solutionsequence_nonlinear(FemModel* femmodel,bool conserve_loads){ | 
|---|
| 12 |  | 
|---|
| 13 | /*intermediary: */ | 
|---|
| 14 | Matrix<IssmDouble>* Kff = NULL; | 
|---|
| 15 | Matrix<IssmDouble>* Kfs = NULL; | 
|---|
| 16 | Vector<IssmDouble>* ug  = NULL; | 
|---|
| 17 | Vector<IssmDouble>* uf  = NULL; | 
|---|
| 18 | Vector<IssmDouble>* old_uf = NULL; | 
|---|
| 19 | Vector<IssmDouble>* pf  = NULL; | 
|---|
| 20 | Vector<IssmDouble>* df  = NULL; | 
|---|
| 21 | Vector<IssmDouble>* ys  = NULL; | 
|---|
| 22 |  | 
|---|
| 23 | Loads* savedloads=NULL; | 
|---|
| 24 | bool converged; | 
|---|
| 25 | int constraints_converged; | 
|---|
| 26 | int num_unstable_constraints; | 
|---|
| 27 | int count; | 
|---|
| 28 |  | 
|---|
| 29 | /*parameters:*/ | 
|---|
| 30 | int min_mechanical_constraints; | 
|---|
| 31 | int max_nonlinear_iterations; | 
|---|
| 32 | int configuration_type; | 
|---|
| 33 | IssmDouble eps_res,eps_rel,eps_abs; | 
|---|
| 34 |  | 
|---|
| 35 | /*Recover parameters: */ | 
|---|
| 36 | femmodel->parameters->FindParam(&min_mechanical_constraints,StressbalanceRiftPenaltyThresholdEnum); | 
|---|
| 37 | femmodel->parameters->FindParam(&max_nonlinear_iterations,StressbalanceMaxiterEnum); | 
|---|
| 38 | femmodel->parameters->FindParam(&eps_res,StressbalanceRestolEnum); | 
|---|
| 39 | femmodel->parameters->FindParam(&eps_rel,StressbalanceReltolEnum); | 
|---|
| 40 | femmodel->parameters->FindParam(&eps_abs,StressbalanceAbstolEnum); | 
|---|
| 41 | femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); | 
|---|
| 42 | femmodel->UpdateConstraintsx(); | 
|---|
| 43 |  | 
|---|
| 44 | /*Were loads requested as output? : */ | 
|---|
| 45 | if(conserve_loads){ | 
|---|
| 46 | savedloads = static_cast<Loads*>(femmodel->loads->Copy()); | 
|---|
| 47 | } | 
|---|
| 48 |  | 
|---|
| 49 | count=0; | 
|---|
| 50 | converged=false; | 
|---|
| 51 |  | 
|---|
| 52 | /*Start non-linear iteration using input velocity: */ | 
|---|
| 53 | GetSolutionFromInputsx(&ug,femmodel); | 
|---|
| 54 | Reducevectorgtofx(&uf, ug, femmodel->nodes,femmodel->parameters); | 
|---|
| 55 |  | 
|---|
| 56 | //Update once again the solution to make sure that vx and vxold are similar (for next step in transient or steadystate) | 
|---|
| 57 | InputUpdateFromConstantx(femmodel,converged,ConvergedEnum); | 
|---|
| 58 | InputUpdateFromSolutionx(femmodel,ug); | 
|---|
| 59 |  | 
|---|
| 60 | for(;;){ | 
|---|
| 61 |  | 
|---|
| 62 | //save pointer to old velocity | 
|---|
| 63 | delete old_uf;old_uf=uf; | 
|---|
| 64 | delete ug; | 
|---|
| 65 |  | 
|---|
| 66 | SystemMatricesx(&Kff,&Kfs,&pf,&df,NULL,femmodel); | 
|---|
| 67 | CreateNodalConstraintsx(&ys,femmodel->nodes); | 
|---|
| 68 | Reduceloadx(pf, Kfs, ys); delete Kfs; | 
|---|
| 69 | femmodel->profiler->Start(SOLVER); | 
|---|
| 70 | Solverx(&uf, Kff, pf, old_uf, df, femmodel->parameters); | 
|---|
| 71 | femmodel->profiler->Stop(SOLVER); | 
|---|
| 72 |  | 
|---|
| 73 | Mergesolutionfromftogx(&ug, uf,ys,femmodel->nodes,femmodel->parameters);delete ys; | 
|---|
| 74 |  | 
|---|
| 75 | convergence(&converged,Kff,pf,uf,old_uf,eps_res,eps_rel,eps_abs); delete Kff; delete pf; delete df; | 
|---|
| 76 | InputUpdateFromConstantx(femmodel,converged,ConvergedEnum); | 
|---|
| 77 | InputUpdateFromSolutionx(femmodel,ug); | 
|---|
| 78 |  | 
|---|
| 79 | ConstraintsStatex(&constraints_converged,&num_unstable_constraints,femmodel); | 
|---|
| 80 | if(VerboseConvergence()) _printf0_("   number of unstable constraints: " << num_unstable_constraints << "\n"); | 
|---|
| 81 |  | 
|---|
| 82 | //rift convergence | 
|---|
| 83 | if (!constraints_converged) { | 
|---|
| 84 | if (converged){ | 
|---|
| 85 | if (num_unstable_constraints <= min_mechanical_constraints) converged=true; | 
|---|
| 86 | else converged=false; | 
|---|
| 87 | } | 
|---|
| 88 | } | 
|---|
| 89 |  | 
|---|
| 90 | /*Increase count: */ | 
|---|
| 91 | count++; | 
|---|
| 92 | if(converged==true){ | 
|---|
| 93 | femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,StressbalanceConvergenceNumStepsEnum,count)); | 
|---|
| 94 | break; | 
|---|
| 95 | } | 
|---|
| 96 | if(count>=max_nonlinear_iterations){ | 
|---|
| 97 | _printf0_("   maximum number of nonlinear iterations (" << max_nonlinear_iterations << ") exceeded\n"); | 
|---|
| 98 | converged=true; | 
|---|
| 99 | femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,StressbalanceConvergenceNumStepsEnum,max_nonlinear_iterations)); | 
|---|
| 100 | InputUpdateFromConstantx(femmodel,converged,ConvergedEnum); | 
|---|
| 101 | InputUpdateFromSolutionx(femmodel,ug); | 
|---|
| 102 | break; | 
|---|
| 103 | } | 
|---|
| 104 | } | 
|---|
| 105 |  | 
|---|
| 106 | if(VerboseConvergence()) _printf0_("\n   total number of iterations: " << count << "\n"); | 
|---|
| 107 |  | 
|---|
| 108 | /*clean-up*/ | 
|---|
| 109 | if(conserve_loads){ | 
|---|
| 110 | delete femmodel->loads; | 
|---|
| 111 | int index=femmodel->AnalysisIndex(configuration_type); | 
|---|
| 112 | femmodel->loads_list[index]=savedloads; | 
|---|
| 113 | femmodel->loads=savedloads; | 
|---|
| 114 | } | 
|---|
| 115 | delete uf; | 
|---|
| 116 | delete ug; | 
|---|
| 117 | delete old_uf; | 
|---|
| 118 | } | 
|---|