Imposing two different boundary conditions on some sides of a square


In order to impose two different boundary conditions on some sides of a square I would like to set two different functions on two different boundaries. However, when trying to call GridFunction.Set twice, I find that the second call overwrites values computed by the first one. Is there a way to have GridFunction.Set only change the degrees of freedom associated to the boundary passed as definedon kwarg?

Other related thoughts:
a) I am aware that on a square I could probably come up with a simple myfunc12 that is a combination of myfunc1 and myfunc2 and features the correct expression on both boundaries. However, I would not like to do so because the square is just the first step towards more complex domains where finding the correct combination would be cumbersome.
b) I had also thought of defining two different functions and summing them, but that would give a boundary value of 2 on the top-right corner, wouldn’t it? Please find a simple example in the code below:

[code]from time import sleep
from ngsolve import *
from netgen.geom2d import SplineGeometry
ngsglobals.msg_level = 0

geo = SplineGeometry()
geo.AddRectangle((0., 0.), (1, 1), leftdomain=1, rightdomain=0, bcs=[“Bottom”, “Right”, “Top”, “Left”])
mesh = Mesh(geo.GenerateMesh(maxh=0.1))

V = H1(mesh, order=1)
u = GridFunction(V)

myfunc1 = y
u.Set(myfunc1, definedon=mesh.Boundaries(“Right”))

myfunc2 = x
u.Set(myfunc2, definedon=mesh.Boundaries(“Top”))

Best Wishes

The way to go here is to define a coefficient function depending on the boundary condition and then setting the Gridfunction to this function:

cf = CoefficientFunction([y if bc=="Right" else x if bc=="Top" else 0 for bc in mesh.GetBoundaries()])
u.Set(cf, definedon=mesh.Boundaries("Right|Top"))


Is there a way maybe to set that coefficient function without resetting to zero the degrees of freedom in the interior of the domain? Thanks M.

You can store the function in a temporary vector and then add them together:

tmp = u.vec.CreateVector() = u.vec
u.Set(x,definedon=mesh.Boundaries("Bottom")) += tmp

If they have both values on the same boundaries then you only want to set these values:

setdofs = BitArray(V.ndof)
for el in V.Elements(BND):
    if el.mat in ("Top","Right"):
        for dof in el.dofs:

tmp = u.vec.CreateVector() = u.vec
for dnr in range(V.ndof):
    if setdofs[dnr]:
        u.vec[dnr] = tmp[dnr]