Package: contique
Numerical continuation of nonlinear equilibrium equations.Contique is a Python 3.7+ package that provides methods for numeric continuation. It depends onnumpy(for arrays) andscipy(check if matrix is sparse and sparse solver).NoteThe original motivation was to create a generalized standalone package with the built-in numeric continuation methods taken from the nonlinear truss analysis packagetrusspy.Theory ofcontique's numeric continuationA solution curve for(n)equilibrium equationsfunin terms of(n)unknownsxand a load-proportionality-factorlpfshould be found by numeric continuation from an initial equilibrium statefun(x0, lpf0) = 0. Contique's numeric continuation method is best classified as acomponent-based continuationwith an adaptivemagnitude-based control-component switching.Fig. 1Archimedean spiralequation solved withcontiqueExtended equilibrium equationsThelpfvalue is appended to the unknowsxwhich gives the so-called extended unknownsy = [x, lpf]. One additional control equation is added to the equilibrium equations to ensure(n+1)equations in terms of(n+1)extended unknowns (see next section). This reduces the solution to a point on the initial solution curve.Control EquationThe control equation is defined as follows: First, a needle-vector with dimension(n+1)is created and filled with zerosneedle = 0. For a given initial signed control componentjthe needle is positioned atneedle[|j|] = 1. The maximum allowed values per component are calculated asymax = y0 + np.sign(j) dymax. The control equation is finally formulated asf(y) = needle.T (y - ymax).Solution techniqueThe numeric solution process is divided into three main parts:StepCycleIteration(...of a Newton-Rhapson root method)As the name implies, aSteptries to find the extended unknowns for the next step forward of the equilibrium state. For each Cycle, the initial control component has to be evaluated first (see comment below). The additional control equation is evaluated with this initial control component. The generated extended equilibrium equations in terms of the extended unknows are now solved with the help of a root method (Newton-RhapsonIterations). The solution of the root methoddyis further normalized asdy/dymaxand the final control component is evaluated asj = |j| sign((dy/dymax)[|j|])with|j| = argmax(|dy/dymax|). If the control component changed, another Cycle is performed with the initial control component being now the final control component of the last cycle. This Cycle-loop is repeated until the control component does not change anymore.A note on the pre-evaluation of the initial control component of aStep: This is performed by the linear solution of the extended equilibrium equations. It is equal to the result of the firstIterationof the Newton-Rhapson root method.ExampleA given set of equilibrium equations in terms ofxandlpf(a.k.a. load-proportionality-factor) should be solved by numeric continuation of a given initial solution.Function definitiondeffun(x,lpf,a,b):returnnp.array([-a*np.sin(x[0])+x[1]**2+lpf,-b*np.cos(x[1])*x[1]+lpf])with its initial solutionx0=np.zeros(2)lpf0=0.0and function parametersa=1b=1Runcontique.solveand plot equilibrium statesRes=contique.solve(fun=fun,x0=x0,args=(a,b),lpf0=lpf0,dxmax=0.1,dlpfmax=0.1,maxsteps=75,maxcycles=4,maxiter=20,tol=1e-8,overshoot=1.05,)For eachstepa summary is printed out percycle. This contains an information about the control component at the beginning and the end of a cycle as well as the norm of the residuals along with needed Newton-Rhapsoniterationspercycle. As an example the ouput of some interestingsteps31-33 and 38-40 are shown below. The last column contains messages about the solution. On the one hand, instep32,cycle1 the control component changed from+1to-2, but the relative overshoot on the final control component-2was inside the tolerated range ofovershoot=1.05. Therefore the solver proceeds withstep33 without re-cyclingstep32. On the other hand, instep39,cycle1 the control component changed from-2to-1and this time the overshoot on the final control component-1was outside the tolerated range. A newcycle2 is performed forstep39 with the new control component-1.|Step,C.| Control Comp. | Norm (Iter.#) | Message     |
|-------|---------------|---------------|-------------|

(...)

|  31,1 |   +1  =>   +1 | 7.6e-10 ( 3#) |             |
|  32,1 |   +1  =>   -2 | 1.7e-14 ( 4#) |tol.Overshoot|
|  33,1 |   -2  =>   -2 | 4.8e-12 ( 3#) |             |

 (...)
 
|  38,1 |   -2  =>   -2 | 9.2e-12 ( 3#) |             |
|  39,1 |   -2  =>   -1 | 1.9e-13 ( 3#) | => re-Cycle |
|     2 |   -1  =>   -1 | 2.3e-13 ( 4#) |             |
|  40,1 |   -1  =>   -1 | 7.9e-09 ( 3#) |             |

(...)Next, we have to assemble the resultsX=np.array([res.xforresinRes])and plot the solution curve.importmatplotlib.pyplotaspltplt.plot(X[:,0],X[:,1],"C0.-")plt.xlabel("$x_1$")plt.ylabel("$x_2$")plt.plot([0],[0],"C0o",lw=3)plt.arrow(X[-2,0],X[-2,1],X[-1,0]-X[-2,0],X[-1,1]-X[-2,1],head_width=0.075,head_length=0.15,fc="C0",ec="C0",)plt.gca().set_aspect("equal")Fig. 2 Solution states ofequilibrium equationssolved with contiqueChangelogAll notable changes to this project will be documented inthis file. The format is based onKeep a Changelog, and this project adheres toSemantic Versioning.