Imposing two different boundary conditions on some sides of a square

More
6 years 11 months ago #296 by Karatza
Hi,

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
Code:
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")) Draw(u) sleep(1) myfunc2 = x u.Set(myfunc2, definedon=mesh.Boundaries("Top")) Draw(u)

Best Wishes
M.
More
6 years 11 months ago #300 by christopher
The way to go here is to define a coefficient function depending on the boundary condition and then setting the Gridfunction to this function:
Code:
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"))

Best
Christopher
The following user(s) said Thank You: Karatza
More
6 years 11 months ago #301 by Karatza
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.
More
6 years 11 months ago #304 by christopher
You can store the function in a temporary vector and then add them together:
Code:
tmp = u.vec.CreateVector() tmp.data = u.vec u.Set(x,definedon=mesh.Boundaries("Bottom")) u.vec.data += tmp
If they have both values on the same boundaries then you only want to set these values:
Code:
setdofs = BitArray(V.ndof) setdofs.Clear() for el in V.Elements(BND): if el.mat in ("Top","Right"): for dof in el.dofs: setdofs.Set(dof) tmp = u.vec.CreateVector() tmp.data = u.vec u.Set(x,definedon=mesh.Boundaries("Bottom")) for dnr in range(V.ndof): if setdofs[dnr]: u.vec[dnr] = tmp[dnr]

Best
Christopher
The following user(s) said Thank You: Karatza
Time to create page: 0.101 seconds