/*!\file: solutionsequence_nonlinear.cpp * \brief: core of a non-linear solution, using fixed-point method */ #include "../toolkits/toolkits.h" #include "../classes/classes.h" #include "../shared/shared.h" #include "../modules/modules.h" #include "../analyses/analyses.h" void solutionsequence_nonlinear(FemModel* femmodel,bool conserve_loads){ /*intermediary: */ Matrix* Kff = NULL; Matrix* Kfs = NULL; Vector* ug = NULL; Vector* old_ug = NULL; Vector* uf = NULL; Vector* old_uf = NULL; Vector* pf = NULL; Vector* df = NULL; Vector* ys = NULL; Loads* savedloads=NULL; bool converged; int constraints_converged; int num_unstable_constraints; int count; /*parameters:*/ int min_mechanical_constraints; int max_nonlinear_iterations; int configuration_type; /*Recover parameters: */ femmodel->parameters->FindParam(&min_mechanical_constraints,DiagnosticRiftPenaltyThresholdEnum); femmodel->parameters->FindParam(&max_nonlinear_iterations,DiagnosticMaxiterEnum); femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); femmodel->UpdateConstraintsx(); /*Were loads requested as output? : */ if(conserve_loads){ savedloads = static_cast(femmodel->loads->Copy()); } count=1; converged=false; /*Start non-linear iteration using input velocity: */ GetSolutionFromInputsx(&ug, femmodel->elements, femmodel->nodes, femmodel->vertices,femmodel->loads, femmodel->materials, femmodel->parameters); Reducevectorgtofx(&uf, ug, femmodel->nodes,femmodel->parameters); //Update once again the solution to make sure that vx and vxold are similar (for next step in transient or steadystate) InputUpdateFromConstantx( femmodel->elements,femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,converged,ConvergedEnum); InputUpdateFromSolutionx(femmodel->elements,femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,ug); for(;;){ //save pointer to old velocity delete old_ug;old_ug=ug; delete old_uf;old_uf=uf; femmodel->SystemMatricesx(&Kff, &Kfs, &pf, &df, NULL); CreateNodalConstraintsx(&ys,femmodel->nodes,configuration_type); Reduceloadx(pf, Kfs, ys); delete Kfs; Solverx(&uf, Kff, pf, old_uf, df, femmodel->parameters); Mergesolutionfromftogx(&ug, uf,ys,femmodel->nodes,femmodel->parameters);delete ys; convergence(&converged,Kff,pf,uf,old_uf,femmodel->parameters); delete Kff; delete pf; delete df; InputUpdateFromConstantx( femmodel->elements,femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,converged,ConvergedEnum); InputUpdateFromSolutionx( femmodel->elements,femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,ug); ConstraintsStatex(&constraints_converged, &num_unstable_constraints, femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters); if(VerboseConvergence()) _pprintLine_(" number of unstable constraints: " << num_unstable_constraints); //rift convergence if (!constraints_converged) { if (converged){ if (num_unstable_constraints <= min_mechanical_constraints) converged=true; else converged=false; } } /*Increase count: */ count++; if(converged==true){ bool max_iteration_state=false; int tempStep=1; IssmDouble tempTime=1.0; femmodel->results->AddObject(new GenericExternalResult(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, tempStep, tempTime)); break; } if(count>=max_nonlinear_iterations){ _pprintLine_(" maximum number of nonlinear iterations (" << max_nonlinear_iterations << ") exceeded"); converged=true; InputUpdateFromConstantx( femmodel->elements,femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,converged,ConvergedEnum); InputUpdateFromSolutionx( femmodel->elements,femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,ug); bool max_iteration_state=true; int tempStep=1; IssmDouble tempTime=1.0; femmodel->results->AddObject(new GenericExternalResult(femmodel->results->Size()+1, MaxIterationConvergenceFlagEnum, max_iteration_state, tempStep, tempTime)); break; } } if(VerboseConvergence()) _pprintLine_("\n total number of iterations: " << count-1); /*clean-up*/ if(conserve_loads){ delete femmodel->loads; femmodel->loads=savedloads; } delete uf; delete ug; delete old_ug; delete old_uf; }