Element weighting

Hello everyone!

I’m working on a hyper-reduction method where each element in the mesh has a unique weight.

The weights must be applied to the local element stiffness matrices during the assembly to the bilinear form.
Is there a way of doing that given a vector of element weights?

Or else is there a way to get single element stiffness matrices in global coordinates?

Thank you
Nils

You can do this quite easily with a c++ extension. Basically you need to follow the first two steps of the c++ tutorial here: NGSolve Basics — NGS-Py 6.2.2302 documentation

You can for example parse the elementwise coefficients as a list or a numpy array and store them in a c++ array. Then in the evaluate function of your coefficient you query the element number by

int elnr = mip.GetTransformation().GetElementNr();

Then return the corresponding value from the array.

You can then use this CoefficientFunction in your stiffness bilinearform.

I hope this helps, if you run into problems write again. This part of the documentation is not often used yet.

Best
Christopher

Hello Christopher,

thank you for the help.
I got as far as making a CoefficientFunction that gives the element number.

But I need the CoefficientFunction to know the element weights. You said to store the weights in an array. At what point can I do that?

I tried to initialize with the array.
The idea was to initialize my custom CoefficientFunction like this:

cf = ElementWeightCF(weights)

But that didn’t work:

TypeError: __init__(): incompatible constructor arguments. The following argument types are supported:
    1. CppExtension.cppextension.ElementWeightCF()

It seems like the issue is to initialize the ngsolve CoefficientFunction with to many arguments.
You can find my .hpp file in the attachments.

How can I fix that issue or is there a better way of passing the element weights to my c++ CoefficientFunction?

Thanks in advance
Nils

https://ngsolve.org/media/kunena/attachments/1180/ElementWeightCF.hpp

Attachment: ElementWeightCF.hpp

Hi Nils,
the code in your hpp seems ok, I expect the problem is in the binding code. Can you send the cpp file as well?
Best

You can find the remaining code in the attachments.

https://ngsolve.org/media/kunena/attachments/1180/ElementWeightCF.cpp

https://ngsolve.org/media/kunena/attachments/1180/cppextension.cpp

Attachment: ElementWeightCF.cpp

Attachment: cppextension.cpp

The export of the constructor is wrong, the template arguments for the py::init must be the arguments for the constructor:

.def(py::init<py::array_t<double>>())

best

Hello Christopher,

thank you! Now the weighting CoefficientFunction works.

For linear problems the everything works as expected but I want to apply the element weights to nonlinear problems as well.
When calling AssembleLinearization of the BilinearForm I get the following error:

    K_weighted.AssembleLinearization(u_full.vec)

Evaluate AutoDiff<double> not overloaded, type = class ngfem::MyElementWeightCFin Assemble Element Mat, bfi = Symbolic BFI in AssembleLinearization

Is there a way to make AssembleLinearization work with the custom CoefficientFunction?

Best regards
Nils

Hi
for this derive your function from CoefficientFunctionNoDerivative instead of CoefficientFunction

Best
Christopher