Efficient Formulation and Acceleration Techniques for Nonlinear Problems

Hello community,

I am currently working on a non linear magnetic problem where I need to define a BH curves that are different on each elements of a specific region.

This is a the simplified logic of my code. I create B and H list for each element. Then, for each element a BSpline is created along with the analytical formulation depending on this Bspline.

fes_tau = L2(mesh, order = 0)
for el in mesh.Elements() :
B_data[el.nr] = …
# logic to compute B list depending on the element. H list doesnt change

for el in elements :
gf_indice_mesh = GridFunction(fes_tau) # grid function created to define formulation on 1 element
gf_indice_mesh.vec.data[el.nr] = 1 # grid function = 1 on current element, 0 elswere
hb_curve = BSpline(2, [0]+[0]+list(B_data[el.nr]), [0]+list(H))
energy_dens = hb_curve.Integrate() # BSpline created for each elemeent
aEnergy += SymbolicEnergy(gf_indice_mesh*energy_dens(sqrt(1e-12+grad(u)*grad(u)))*ng_fea.gf_scale, definedon=mesh.Materials(material_name_to_study)) # formulation defined on 1 element

This method is functionnal, however very time consuming. I have thus two questions :

1 - Defining stuff on elements
Is there a more convinient way to define CoefficientFunctions or SumOfIntegrals objects on elements.

2 - Solving Time
Secondly, the computation time to solve such problem is very high. By this I mean the computation time of the solver nonlinear iteration. Is there any way to improve it ?

Thanks in advance,

Best Regards,

Hello, I’m having trouble with a similar problem, the newton itration is waay too slow, did you manage to find a good way to accelerate the solver?

the bspline doesn’t need data from all elements, but should only contain the bh curve.
Not sure why you put element wise data in.

Could you explain in more detail what you want to do exactly so we can help you? As for me, I applied the BH to the entire region with some adjustments specific to my problem.

My problem is in the amount of time that NR takes to solve the nonlinear problem, with a rough mesh is not that bad but it gets VERY SLOW as soon as i refine the mesh, i know NR has cuadratic order of convergence so something as Anderson acceleration wont work, but as I need to do many times the experiment i want to accelerate the non linear solver part. I know NR is slow because it need to assemble the lienarization which takes say 20% of the iteration time, and then invert (or solve) a linear problem which takes roguhly 75% of the iteration time, so im looking for other ways to accelerate the computation. I’ve thought of changing to julia, approximating the inversion problem with something as GMRES, preconditioning at each step or even change the nonlinear solver completely, so im open to any recomendations that you could give me.

Many thanks for your time :slight_smile:

why you think julia would be faster? :wink:

can you post some minimal example showcasing what you mean?

if problems get big solving linear system iteratively is helping

if you compute many cases taking good starting values from previous case should give good speedup

best Christopher

c = Preconditioner(BF, "bddc")
        for iter in range(maxiter):
            # Prints before the iteration: number of it, residual, energy
            print("Energy: ", BF.Energy(gfu.vec), "Residual: ", sqrt(abs(InnerProduct(res,res))), "Iteration: ", iter)
            t1 = time()
            BF.Apply(gfu.vec, res)
            t2 = time()
            with TaskManager():
                BF.AssembleLinearization(gfu.vec)
                t3 = time() 
                w.data = damp * GMRes(BF.mat, res, pre=c.mat, printrates = False, maxsteps = 100, tol = 1e-8)
                t5 = time()
                gfu.vec.data -= w
            print("Time to apply: ", t2-t1, "Time to assemble: ", t3-t2, "Time to inverse: ", t5-t3)
            history.AddMultiDimComponent(gfu.vec)
            if sqrt(abs(InnerProduct(w,res))) < tol:
                print("Converged")
                break

here im trying to minimize a nonlinear energy term, i dont think its important to show its structure. So i tried (as you suggested in another post hehe) to use bddc because meshgrid was crashing for this problem. In this example now it takes more time to assemble the preconditioner but the solving part is very fast, but the sum of these times still doesnt beat just using BF.mat.inv().

About Julia, it was just an idea that got to me while google ways to speed up this process.

if the problem size is “small” direct inverse is faster. but it should scale differently. from this code part I do not see issues.

You can look at vite-traces to see where you spend most of your time and how well the code works parallel: Parallel computing with TaskManager — NGS-Py 6.2.2403 documentation

Next week is usermeeting in Vienna, we will also try to live stream it on youtube. There will be some talks about solving techniques and also coupling to external solvers (petsc, hypre). There might be interesting things there for you.

that would be awesome, what’s the name of the youtube channel?

https://www.youtube.com/ngsolve

You can also use PETSc SNES which allows you to play with different linear and non–linear solver, simply changing the solver parameters dictionary: Non-linear simulation of a Hyperelastic beam — ngsPETSc 0.0.5 documentation.