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.

FESpace.Element(BND) returns empty list for L^2 spaces

More
3 years 11 months ago #2635 by arieder
Hi,

@schruste:

using (a slighlty modified version) of your code produces a segfault
"malloc(): invalid size (unsorted)".

File Attachment:

File Name: test_2020-04-30.py
File Size:1 KB


@christopher:
BoundaryFromVolumeCF seems to roughly do what I want, except that I don't have just a single GridFunction I have to transfer but I would really like to build the whole transfer matrix. (As doing the whole projection thing either for every dof or for every iteration in a solver seems overkill).
Maybe I can steal enough code from BoundaryFromVolumeCF to hack together a small C++-part that does what I want.



thanks for your help,
Alex
More
3 years 11 months ago - 3 years 11 months ago #2636 by lkogler
Do you only need the operator L2 -> surface L2, or also surface L2 -> L2?

The first is easy to do, the second is more difficult. I think for the second some C++ code is needed.
Code:
from ngsolve import * import netgen.geom2d as geom2d mesh = Mesh(geom2d.unit_square.GenerateMesh(maxh=0.5)) L = L2(mesh, order=0) F = FacetFESpace(mesh, order=0, dirichlet=".*") S = SurfaceL2(mesh, order=0) E1 = comp.ConvertOperator(spacea=L, spaceb=F) E2 = comp.ConvertOperator(spacea=F, spaceb=S, vb=BND) E = E2 @ E1 print(E)

This will give you the desired operator L2->surface L2 as a sparse matrix.

The operator "E1" will average on the interior facets, but we do not care about that as we are only interested in the boundary.

(I did have to add a single line of C++ code in one place to make this work, I will put up a merge request for this).


I do have an idea for the other direction, but it is a bit ugly and needs some C++ code.
Last edit: 3 years 11 months ago by lkogler.
More
3 years 11 months ago - 3 years 11 months ago #2637 by lkogler
You can check out the "set_dualshapes" branch from NGSolve and try the attached script.

For the Volume->Surface operator I did have to fix something in some code I wrote a while ago. That fix should come to the master soon.


For the Surface->Volume operator I did have to make one change to the "Discontinuous" spaces that Is kind of hacky, so I am not convinced it will come to the master branch. Also, it only works if you choose the volume L2 space to be at least of order 1.

Also, you will only get an exact extension of the surface space for functions that have an exact extension.
For example, if you have a triangle in a corner, and your surface function is 1 on one edge connected to it and 0 on the other, you can not have any volume l2 function with this trace, so you will get some interpolation of this (it will average the value in the corner).


If your surface functions are continuous, you could simply use an H1 space for the surface and then map the H1 function you get to an L2 function. No hacks needed for that.


Best,
Lukas
Attachments:
Last edit: 3 years 11 months ago by lkogler.
More
3 years 11 months ago #2639 by arieder
Hi Lukas,

thanks that solution looks interesting. I think the direction L^2->surface L^2 is sufficient.
The one other thing I would need for my method is the same map L^2->surface L^2 but evaluating the normal derivative. Is this possible in any way?
More
3 years 11 months ago #2640 by lkogler
Currently not quite, but it should be easy. Something like this is on my list of things to implement anyways, give me like an hour.

Best,
Lukas
More
3 years 11 months ago - 3 years 11 months ago #2641 by lkogler
Okay, that was easy. Should work with the "set_dualshapes" branch. This needs another small change I am putting up a merge request for

As before, we convert to a FacetFESpace, "F", but this time instead of the L2 function itself, we use it's normal derivative:
Code:
V2S_1 = comp.ConvertOperator(spacea=L, spaceb=F, trial_cf=InnerProduct(L.TrialFunction().Deriv(), specialcf.normal(mesh.dim)))

Then we go to the boundary as before:
Code:
V2S_2 = comp.ConvertOperator(spacea=F, spaceb=S, vb=BND)

Best, Lukas
Attachments:
Last edit: 3 years 11 months ago by lkogler.
Time to create page: 0.157 seconds