Including C++ code in python

Asked by Chris Richardson

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:
Last query:
Last reply:
Revision history for this message
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.
>

Revision history for this message
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
>

Revision history for this message
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
>

Revision history for this message
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.

Revision history for this message
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.