6. Learning NGSolve#

how good is AI with Netgen/NGSolve?

6.1. NGSolve in class#

6.1.1. Student’s homeworks#

  • looks very prefessional

  • well documented

6.1.2. Experiment: Let students learn Navier-Stokes solvers from AI#

Newbies to CFD and FEM: Various teams succeeded, with

  • a running FEniCS code with 80000 lines

  • a running NGSolve code with 20000 lines

  • code was running about 50 times slower than NGSolve tutorials

using Claude Sonnet 4.6

6.2. Netgen documentation created by AI:#

Link to Chrisopher’s occ-docu

6.3. How can we support AI generating good NGSolve code?#

6.4. My personal experience with Claude:#

6.4.1. How can we simplify onboarding with NGSolve?#

  • You need simple and catchy tutorials at the homepage

  • You need Colab or Binder support

6.4.2. Can you help me meshing a Möbius strip?#

  • Here is the formula for a Möbius surface

  • Depending on the version of Netgen, there is different syntax for Netgen.occ Spline surfaces

from netgen.occ import *
from ngsolve import *
from ngsolve.webgui import Draw
import numpy as np
import math

def mobius_point(u, v, R=10.0):
    x = (R + v * math.cos(u / 2.0)) * math.cos(u)
    y = (R + v * math.cos(u / 2.0)) * math.sin(u)
    z = v * math.sin(u / 2.0)
    return gp_Pnt(x, y, z)


nu, nv = 10, 10

pts = np.zeros((nu+1, nv+1, 3), dtype=np.float64)

for i in range(nu+1):
    u = math.pi * i / nu
    for j in range(nv+1):
        v = j / nv - 0.5
        p = mobius_point (u,v,3)
        pts[i, j, 0] = p[0]
        pts[i, j, 1] = p[1]
        pts[i, j, 2] = p[2]

face1 = SplineSurfaceApproximation(pts)

for i in range(nu+1):
    u = math.pi + math.pi * i / nu
    for j in range(nv+1):
        v = j / nv -0.5
        p = mobius_point (u,v,3)
        pts[i, j, 0] = p[0]
        pts[i, j, 1] = p[1]
        pts[i, j, 2] = p[2]

face2 = SplineSurfaceApproximation(pts)

face = Glue ([face1, face2])

mesh = face.GenerateMesh(maxh=0.2)
Draw(mesh);
fes = H1(mesh, order=2)
u, v = fes.TnT()
bfa = BilinearForm(grad(u).Trace()*grad(v).Trace()*ds).Assemble()
bfm = BilinearForm(u*v*ds).Assemble()
from ngsolve.solvers import *
pre = (bfa.mat+bfm.mat).CreateSparseMatrix().Inverse()
vals, vecs = LOBPCG(mata=bfa.mat, matm=bfm.mat, pre=pre, num=30, printrates=False)
gfu = GridFunction(fes)

gfu.vec.data = vecs[29]
Draw (gfu);

Very useful applications: https://www.youtube.com/watch?v=EC9nZFzMFZA

Question: Which surface function spaces actually need an oriented surface?