Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question on VectorFEBoundaryTangentLFIntegrator #4114

Closed
AlejandroMunozManterola opened this issue Feb 5, 2024 · 3 comments
Closed

Question on VectorFEBoundaryTangentLFIntegrator #4114

AlejandroMunozManterola opened this issue Feb 5, 2024 · 3 comments
Assignees

Comments

@AlejandroMunozManterola
Copy link

AlejandroMunozManterola commented Feb 5, 2024

Good day, MFEM community,

I have a question on the use of the VectorFEBoundaryTangentLFIntegrator for Linear Forms, and indirectly, in the L2 -> ND/H1 FES transformation/conversion.

I have a solver based on MFEM that is capable of solving basic fullwave EM problems and export data for later postprocessing through the MFEM DataCollection class, specifically for RCS analysis. The data exported are L2 GridFunctions based on a vdim 1 FiniteElementSpace, the time at which the system was evolved and the minimal mesh consisting on only elements with a specific interior boundary attribute to minimise future dof and memory usage (in this case, we have a 'spiky 1-element-wide crown')

From the global problem...
fullsystem
To this...
crown

Based on a specific step through the simulation, I export the same data, so I have multiple folders with six GridFunctions, a time .txt file and the mesh file at said specific time.

In order to perform the postprocessing, we need to perform a surface integral on the marked faces where we compute the vectorial product of the normal and a function, along with the basis functions... which makes the natural choice to use the previously mentioned VectorFEBoundaryTangentLFIntegrator. (If the integral already exists, it felt unneccessary to implement a L2 integrator that did the same. In retrospect, maybe that would have saved me a couple headaches, hehe).

imagen

After some playing around with Projection methods for GridFunctions and some Coefficients, I've been able to project my vdim 1 L2 GridFunctions onto a Nedelec vdim 2 fes, which I use to create a LinearForm, to which then I AddBoundaryIntegrator the VectorFEBoundaryTangentLFIntegrator, with a bdr_marker containing the marker information for my desired faces.

The issue I find is, during the assembly of said LinearForm, I seem to be triggering a MFEM_VERIFY line on the vdim:

mfem/fem/lininteg.cpp

Lines 654 to 665 in 33617ce

void VectorFEBoundaryTangentLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
int dof = el.GetDof();
int dim = el.GetDim();
int vdim = el.GetRangeDim();
DenseMatrix vshape(dof, vdim);
Vector f_loc(3);
Vector f_hat(2);
MFEM_VERIFY(vdim == 2, "VectorFEBoundaryTangentLFIntegrator "
"must be called with vector basis functions of dimension 2.");

I have assured the used FES is vdim 2, along with the vdim in the VectorFunctionCoefficient I have passed as argument, but it seems the element vdim retrieved on line 659 returns 1, so I am a bit at a loss on what to do at this point.

Due to how extense the question and process is, I haven't posted any specific code, but if anyone requires it please feel free to ask about it and I'll go ahead and post it.

I really appreciate any input here, hope to hear from you.

Have a great day :)

@najlkin
Copy link
Contributor

najlkin commented Feb 16, 2024

I am not sure if it is it, but you are maybe mistaking the dimensions here 😮 😵 . There are two types of elements: scalar and vector. Scalar elements (like L2), as the name suggests, represent scalar values. When you want to represent a vector by them, you need to use the vector dimension of the FE space, which stacks them on top of each other. In contrast, vector finite elements (like ND) represent certain components of vector fields of the dimension given by the mesh. Unless you want to represent something multi-valued like complex amplitude or something like that, you should use vector dimension equal to 1 for them 😉

@mlstowell
Copy link
Member

Hi, @AlejandroMunozManterola,

I believe the problem is that this is a boundary integral on a 2D mesh where the boundary is 1D. Nedelec basis functions on 1D domains are scalar valued so vdim=1. This integrator was obviously (now that we notice this issue) designed to function on 2D boundaries of 3D domains. We should correct the documentation that you quote above (sorry for the confusion).

A custom integrator may be necessary in this case although I cannot be certain. There are two complications you should be aware of; the direction normal to an interior surface may not be consistent everywhere on the surface also the orientation of the Nedelec basis functions on this surface may also appear inconsistent. The issue of the normal direction can be circumvented if you can provide a vector function which pierces the surface in a consistent manner so that you can check the sign of the normal with this vector function. The second issue should be easily avoided if you evaluate the Nedelec grid function at each interpolation point as you almost certainly will if you're using a accessing that through a VectorGridFunctionCoefficient.

Best wishes,
Mark

@AlejandroMunozManterola
Copy link
Author

AlejandroMunozManterola commented Feb 19, 2024

Thank you both.

@najlkin, yes, I do understand the differences between L2 and Nedelec fields. The main issue came mainly with where Nedelec GridFunctions were storing the direction information for the values we'd assign to them, which prompted me to go ahead and experiment a bit with the vdim. This one's on me, just some learning process.

@mlstowell, thank you, it was slightly confusing to me as in the (https://mfem.org/lininteg/) page, even if it's in the boundary section, it did say the VectorFEBoundaryTangentLFIntegrator worked on 2D and 3D, and considering one cannot have a 3D boundary face (it'd be fairly amusing, isn't it?), I considered this could be applied to 2D meshes too. It was just a small slip up and I'm happy we caught that small mistake in the documentation, so no worries about it.

Considering that I wasn't able to make that Integrator work (the only reason we'd travelled from L2 to ND), I returned to L2 and implemented my own custom integrator.

Thanks again for checking this up, glad we discovered a sneaky thing.

Have a great day everyone,
Alejandro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants