How to access CreateSmoothingBlocks from python for fes?

More
3 years 10 months ago #3442 by Guosheng Fu
Hello,

I am trying to use the "many" default smoothing blocks implemented for finite element spaces for preconditioning.
So I tried to export CreateSmoothingBlocks for a finite element space (EdgeFESpace is "exactly" your NedelecFESpace), with
Code:
ExportFESpace<EdgeFESpace> (m, "EdgeFESpace") .def("CreateSmoothingBlocks", [](shared_ptr<EdgeFESpace> self, int type) { return self->CreateSmoothingBlocks(type); }, py::arg("type"), "create smoothing block for this type") ;

But when I call
Code:
fes.CreateSmoothingBlocks(0)
python complains:
Code:
TypeError: Unable to convert function return value to a Python type! The signature was (self: xfem.ngsxfem_py.EdgeFESpace, type: int) -> ngcore::Table<int, unsigned long>

I didn't find a solution to this in the source files. Can you help with this?

Best,
Guosheng
More
3 years 10 months ago #3453 by christopher
This means that the class Table<int, unsigned long> doesn't have a Python equivalent (=export). You can either export the table or convert the table first to some Python object (for example a list of lists).
Best
Christopher
More
3 years 10 months ago #3456 by Guosheng Fu
Yes. I noticed that the python list will then be converted back to Table <int, unsigned long> in the CreateBlockSmoother class.
But, I haven't found a way to convert the Table<int, ...> class back to python list back. I don't know how to create a python list in C++.
More
3 years 10 months ago - 3 years 10 months ago #3458 by christopher
Something like
Code:
py::list pytable; for(const auto& row : table) pytable.append(MakePyList(row));
should work.

But you could as well just export the Table and write another python constructor for the smoother to be constructed with a table, then you don't have to copy

Best
Last edit: 3 years 10 months ago by christopher.
More
3 years 10 months ago #3460 by Guosheng Fu
Thanks, Christopher. This works.
I need to change the loop to
Code:
for(const auto& row : *table)
as table is a smart pointer from CreateSmoothingBlocks.

The code works much faster now.
So, there is basically no difference from the python end whether the block is a list of lists or a list of sets (which we use to generate the blocks in the python script) because they will simply be converted to the Table<int> type in CreateBlockSmoother, right?
More
3 years 10 months ago #3461 by Guosheng Fu
To create a new python BlockSmoother constructor that takes the table as input seems the fastest approach, but then I need to modify the source file in linalg/python_linalg.cpp, which is a bit of a headache for me. (if you could include this in later ngsolve versions, that would be great ;)

Currently I am simply adding "new" fespaces/classes in a separate project, which I feel a little bit safer as I don't need to directly touch the git source files.
Time to create page: 0.114 seconds