Including C++ code in python

Asked by Chris Richardson on 2010-03-10

I have a mesh generator, written in C++, which I have now linked with dolfin, using the MeshEditor class to construct
a mesh. This works, but I would like to be able to use it from python.
I have tried to use SWIG to create a module, but I don't know how to tell it that my new class inherits Mesh.

Here is a summary of my code... but maybe there is a better way to do this?

Chris

mymesh.i
========

 %module mymesh
 %{
 /* Put header files here or function declarations like below */
#include "mymesh.h"
 %}

/* mymesh.h */
namespace dolfin{

  class Mymesh : public Mesh
  {
  public:
    Mymesh();
  };
}

mymesh.cpp
==========

#include "mymesh.h"

#include <dolfin/mesh/MeshPartitioning.h>
#include <dolfin/mesh/MeshEditor.h>
#include <dolfin.h>

using namespace dolfin;
.....
Mymesh::Mymesh() {
 Mesheditor editor;
....
}

# swig -c++ -python mymesh.i
mymesh.i:11: Warning(401): Nothing known about base class 'Mesh'. Ignored.

Question information

Language:
English Edit question
Status:
Solved
For:
DOLFIN Edit question
Assignee:
No assignee Edit question
Solved by:
Chris Richardson
Solved:
2010-03-10
Last query:
2010-03-10
Last reply:
2010-03-10
Johan Hake (johan-hake) said : #1

On Wednesday 10 March 2010 05:39:21 Chris Richardson wrote:
> New question #103867 on DOLFIN:
> https://answers.launchpad.net/dolfin/+question/103867
>
> I have a mesh generator, written in C++, which I have now linked with
> dolfin, using the MeshEditor class to construct a mesh. This works, but I
> would like to be able to use it from python.

Cool! Do you link your generator to any particular
triangulation/tetrahedarlization library? I have written one TriTetMesh which
wrap Triangle and Tetgen. It is a bit sharp in the edges, but perfectly usable
both from C++ and Python. Have a look at:

   <https://launchpad.net/tritetmesh>

You should also be able to get some clues of how you can do the linking to
PyDOLFIN using TriTetMesh, as I also use SWIG. I do not return a mesh during
runtime, I just saves it to file. It spare me for some nasty SWIG related
stuff, which I eventually could fix.

> I have tried to use SWIG to
> create a module, but I don't know how to tell it that my new class
> inherits Mesh.

You need to %import the types. PyDOLFIN comes with some handy SWIG import
files, if you just want to import the types related to Mesh. You should for
example be able to put:

  %include "dolfin/swig/import/mesh.i"

before your SWIG declarations.

This file %import's all the types from the dolfin/mesh kernel modules, which
is probably what you want.

If you want to return a mesh at runtime you might experience some nasty
surprises as Mesh is a shared_ptr stored type in PyDOLFIN. This means you need
to explicitly tell SWIG this. Please ask for more help if you want to do this.

We also have a JIT compiler of DOLFIN code in PyDOLFIN, which (should)
automagicaly take care of the shared_ptr declarations.

  compile_extension_module(code, module_name="",
                           recompile=False,
                           dolfin_module_import=None,
                           additional_declarations="",
                           additional_system_headers=None,
                           use_numpy_typemaps=True)

This function is unfortunately wrapped by a Python decorator (due to some
parallel fixes), so the interactive documentation is None.

Here comes a summary:
  code is a 'str' with your C++ code.
  module_name is an optional name for your module,
  dolfin_module_import is a list of 'str' with name of the kernel module,
      in you case 'mesh',
  the other arguments can be used to fine tune typemaps.

Take a look in

   site-packages/dolfin/compile_modules/__init__.py

where the function is defined and in

  site-packages/dolfin/compile_modules/{subdomains.py, expression.py}

where the function is used.

The answer might be more than you asked for, but I would really like to have
users of the compile_extension_module function ;)

Best regards,

Johan

> Here is a summary of my code... but maybe there is a better way to do this?
>
> Chris
>
> mymesh.i
> ========
>
> %module mymesh
> %{
> /* Put header files here or function declarations like below */
> #include "mymesh.h"
> %}

Put %import/%include statement here.

> /* mymesh.h */
> namespace dolfin{
>
> class Mymesh : public Mesh
> {
> public:
> Mymesh();
> };
> }
>
> mymesh.cpp
> ==========
>
> #include "mymesh.h"
>
> #include <dolfin/mesh/MeshPartitioning.h>
> #include <dolfin/mesh/MeshEditor.h>
> #include <dolfin.h>
>
> using namespace dolfin;
> .....
> Mymesh::Mymesh() {
> Mesheditor editor;
> ....
> }
>
>
> # swig -c++ -python mymesh.i
> mymesh.i:11: Warning(401): Nothing known about base class 'Mesh'. Ignored.
>

Kent-Andre Mardal (kent-and) said : #2

> New question #103867 on DOLFIN:
> https://answers.launchpad.net/dolfin/+question/103867
>
> I have a mesh generator, written in C++, which I have now linked with
> dolfin, using the MeshEditor class to construct
> a mesh. This works, but I would like to be able to use it from python.
> I have tried to use SWIG to create a module, but I don't know how to tell
> it that my new class inherits Mesh.
>
> Here is a summary of my code... but maybe there is a better way to do
> this?
>
> Chris
>
> mymesh.i
> ========
>
> %module mymesh
> %{
> /* Put header files here or function declarations like below */
> #include "mymesh.h"
> %}
>
> /* mymesh.h */
> namespace dolfin{
>
> class Mymesh : public Mesh
> {
> public:
> Mymesh();
> };
> }
>
> mymesh.cpp
> ==========
>
> #include "mymesh.h"
>
> #include <dolfin/mesh/MeshPartitioning.h>
> #include <dolfin/mesh/MeshEditor.h>
> #include <dolfin.h>
>
> using namespace dolfin;
> .....
> Mymesh::Mymesh() {
> Mesheditor editor;
> ....
> }
>
>
> # swig -c++ -python mymesh.i
> mymesh.i:11: Warning(401): Nothing known about base class 'Mesh'. Ignored.
>
>

Hake gave a more comprehensive answer, but here is a short one, to
fix only this problem you need to include the path to Mesh on the command
line, i.e.,

swig -c++ -python -I/path/to/Mesh mymesh.i

You will also need to include dolfin during linking.

Kent

>
> --
> You received this question notification because you are a member of
> DOLFIN Team, which is an answer contact for DOLFIN.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~dolfin
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~dolfin
> More help : https://help.launchpad.net/ListHelp
>

Johan Hake (johan-hake) said : #3

On Wednesday 10 March 2010 09:49:42 <email address hidden> wrote:
> > New question #103867 on DOLFIN:
> > https://answers.launchpad.net/dolfin/+question/103867
> >
> > I have a mesh generator, written in C++, which I have now linked with
> > dolfin, using the MeshEditor class to construct
> > a mesh. This works, but I would like to be able to use it from python.
> > I have tried to use SWIG to create a module, but I don't know how to tell
> > it that my new class inherits Mesh.
> >
> > Here is a summary of my code... but maybe there is a better way to do
> > this?
> >
> > Chris
> >
> > mymesh.i
> > ========
> >
> > %module mymesh
> > %{
> > /* Put header files here or function declarations like below */
> > #include "mymesh.h"
> > %}
> >
> > /* mymesh.h */
> > namespace dolfin{
> >
> > class Mymesh : public Mesh
> > {
> > public:
> > Mymesh();
> > };
> > }
> >
> > mymesh.cpp
> > ==========
> >
> > #include "mymesh.h"
> >
> > #include <dolfin/mesh/MeshPartitioning.h>
> > #include <dolfin/mesh/MeshEditor.h>
> > #include <dolfin.h>
> >
> > using namespace dolfin;
> > .....
> > Mymesh::Mymesh() {
> > Mesheditor editor;
> > ....
> > }
> >
> >
> > # swig -c++ -python mymesh.i
> > mymesh.i:11: Warning(401): Nothing known about base class 'Mesh'.
> > Ignored.
>
> Hake gave a more comprehensive answer, but here is a short one, to
> fix only this problem you need to include the path to Mesh on the command
> line, i.e.,
>
> swig -c++ -python -I/path/to/Mesh mymesh.i
>
> You will also need to include dolfin during linking.

Yes this is of course also true.

If you use:

  %include "dolfin/swig/import/mesh.i"

you only need to pass the include path to where dolfin is installed. Which
also should be fine for the other include statements you have done above.

Johan

> Kent
>
> > --
> > You received this question notification because you are a member of
> > DOLFIN Team, which is an answer contact for DOLFIN.
> >
> > _______________________________________________
> > Mailing list: https://launchpad.net/~dolfin
> > Post to : <email address hidden>
> > Unsubscribe : https://launchpad.net/~dolfin
> > More help : https://help.launchpad.net/ListHelp
>
> _______________________________________________
> Mailing list: https://launchpad.net/~dolfin
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~dolfin
> More help : https://help.launchpad.net/ListHelp
>

Chris Richardson (chris-bpi) said : #4

Many thanks...
 I have used triangle before, and I think that will be fine for me, so I'll check out tritetmesh.
Anyway, its good to know how to do these things, so I'll try my code too.

luckas (eis-cream) said : #5

I have a problem, I would like four circles in a rectangle
draw, but the circle must be networked ........ I've done
to sign a networked circuits, and for that I used smoothing code.