Forum Message

 

 

We have moved the forum to https://forum.ngsolve.org . This is an archived version of the topics until 05/05/23. All the topics were moved to the new forum and conversations can be continued there. This forum is just kept as legacy to not invalidate old links. If you want to continue a conversation just look for the topic in the new forum.

Notice

The forum is in read only mode.

Singular matrix for non-linear conductivity in heat equation

More
2 years 3 weeks ago - 2 years 3 weeks ago #4290 by sindresb
Hello,

I am looking to solve the steady heat equation for various systems with various temperature-dependent thermal conductivity functions. For certain conductivity functions, I encounter a warning from UMFPACK stating that my assembled matrix is singular. Subsequently, the iterative solver crashes and the program exits. Unfortunately, my theoretical understanding of FEM is rather limited, so I do not understand why some of the functions I have explored yield a singular matrix while others do not.

For example, it appears to be problematic to have float exponents. E.g. k(T) = 1 + T^1.1 (T=temperature, k=conductivity). k(T) = 1 + T^2 does not yield the same problem. k(T) = 1 + 0.9*sin(pi*T) also works. However, k(T) = 1 + ln(T) does not, even if the boundary conditions ensure k>0 throughout.

If anyone could shed some light on why I sometimes get singular matrices, that would be greatly apprectiated. I have attached an example code below. If it can be modified in a simple way to provide non-singular matrices for e.g. k(T) = 1 + T^1.1 or k(T) = 1 + ln(T), I would love to know how.

Best regards,
Sindre

import ngsolve as ng
from ngsolve.webgui import Draw
from netgen.geom2d import unit_square
from ngsolve.solvers import Newton

mesh = ng.Mesh(unit_square.GenerateMesh(maxh=0.1))

V = ng.H1(mesh, order=1, dirichlet="left|right")
u = V.TrialFunction()
v = V.TestFunction()
uh = ng.GridFunction(V)

dirichletBCs = mesh.BoundaryCF({'left':2, 'right':1})
uh.Set(dirichletBCs, ng.BND)

k = lambda T: 1 + T**1.1
a = ng.BilinearForm(V)
a += k(u) * ng.grad(u) * ng.grad(v) * ng.dx
Newton(a, uh)
Last edit: 2 years 3 weeks ago by sindresb.
More
2 years 3 weeks ago - 2 years 3 weeks ago #4294 by mneunteufel
Hi Sindre,
by setting only the Dirichlet data of the temperature on the boundaries the initial guess uh for the Newton is zero in the interior. Evaluating (the first variation of) e.g. ln(uh) leads to NaNs in the matrix such that the matrix is not regular (functions like uh**2 work also for uh=0).Setting a non-zero function as initial guess including the appropriate boundary conditions solves the problem, in your example
#uh.Set(dirichletBCs, ng.BND)
cf = 2-ng.x
uh.Set(cf)
Another possibility is to first extend the boundary data to the domain by solving e.g. an auxiliary Poisson problem. 

Best,
Michael
Last edit: 2 years 3 weeks ago by mneunteufel.
More
2 years 3 weeks ago #4295 by sindresb
Hi, Michael

Thank you for the clear and concise explanation!

For beginners like myself, I would like to add that writing
uh.Set(1)
uh.Set(dirichletBCs, ng.BND)
does not solve the problem because the second call to .Set somehow overwrites the first call.

Best,
Sindre
More
2 years 2 weeks ago #4307 by joachim
Time to create page: 0.116 seconds