gimli-org / gimli

Geophysical Inversion and Modeling Library :earth_africa:
https://www.pygimli.org
Other
344 stars 131 forks source link

How to implement inhomogeneous Dirichlet boundary conditions? #675

Closed ruboerner closed 2 months ago

ruboerner commented 2 months ago

Problem description

I'm trying to solve the Laplace equation on a unit square.

It is unclear how to project the exact solution as Dirichlet boundary condition onto the FE space.

Your environment

--------------------------------------------------------------------------------
  Date: Fri Mar 15 13:25:18 2024 CET

                OS : Darwin
            CPU(s) : 8
           Machine : arm64
      Architecture : 64bit
               RAM : 16.0 GiB
       Environment : Jupyter
       File system : apfs

  Python 3.11.8 | packaged by conda-forge | (main, Feb 16 2024, 20:49:36)
  [Clang 16.0.6 ]

           pygimli : 1.5.0
            pgcore : 1.5.0
             numpy : 1.26.4
        matplotlib : 3.8.3
             scipy : 1.12.0
           IPython : 8.20.0
           pyvista : 0.43.3
--------------------------------------------------------------------------------

Steps to reproduce

import numpy as np
import pygimli as pg
from pygimli import meshtools as mt # import a module 
from pygimli.viewer import showMesh # import a function

geometry = mt.createWorld(start=[0, 0], end=[1, 1], worldMarker=False)

mesh = mt.createMesh(geometry, area=0.005, quality=33, smooth=True)
mesh = mesh.createP2()

X = 1
Y = 1

def BC(boundary):
    return (-X * boundary.nodes()[0][0] -Y * boundary.nodes()[0][1])

bc={'Dirichlet': {1: BC,
                  2: BC,
                  3: BC,
                  4: BC}}

u = pg.solve(mesh, a=[[1, 1]], bc=bc, verbose=True)

showMesh(mesh, data=u, showMesh=True, 
         contourLines=False, nCols=41, cMap='RdBu_r');

Expected behavior

As the solution of the considered Laplace problem we assume a simple linear function $u: \mathbb R^2 \mapsto \mathbb R$ with exact values given at the boundaries, we expect to obtain the exact solution in the interior of the computational domain.

In our case the function is

u(x,y) = -x - y.

Actual behavior

It can be observed from the MWE that (probably) not all DOFs at the boundaries have been assigned the desired boundary values.

If possible, please add one or more labels to your issue, e.g. if you expect that your issue is rather a question than a problem with the code, please add the label "question".

ruboerner commented 2 months ago
Bildschirmfoto 2024-03-15 um 14 00 29
carsten-forty2 commented 2 months ago

I can confirm the issue.

A quick test with the new fea implementation (yet unpublished) shows the resulting field need to be exact and mesh independend due to the bilinear field characteristics:

image

Its a little unclear where this comes from and when I will have time to fix it. In the meantime you can set the Dirichlet values to the nodes directly which seems to work as expected.

def BCN(node):
    return (-X * node.x() -Y * node.y())
bc={'Node': [[b.node(0).id(), BCN(b.node(0))] for b in mesh.findBoundaryByMarker(1,5)]}
uh = pg.solve(mesh, a=[[1, 1]], bc=bc, verbose=True)
u = (-pg.x(mesh) - pg.y(mesh))
print('normL2(u-uh):', pg.solver.normL2(u-uh, mesh))

image

Also there seems an issue with the showMesh keyword argument in the current release which I need to fix.

Many thanks for reporting, Carsten

Edit: Added the code for normL2 calculation Edit 2: The workarround only works for p=1 meshes, for p=2 also the middle node (b.node(2)) need to be considered.

carsten-forty2 commented 2 months ago

The problem comes from the numbering directions of the boundary nodes. Not every node(0) is connected to node(1) from its neighbour, some are screwed due to triangle. So if you assign the value for one boundary to its node(0) might lead to wrong assigments. This is unfortunately broken be 'very old design' and I'm unsure if this can be fixed with moderate afford. Until the new implementation comes online, the little bit unconveniant direct node assignment will work.

ruboerner commented 2 months ago

Hi @carsten-forty2,

thanks for the quick and insightful response!

The news about a re-implementation of the FE code basis is great!

Cheers, Ralph