nschloe / pygmsh

:spider_web: Gmsh for Python
GNU General Public License v3.0
857 stars 162 forks source link

Is 'get_code' not available anymore? #405

Closed KeunwooPark closed 3 years ago

KeunwooPark commented 3 years ago

Hi. pygmsh document says that Geometry has get_code method. However, pygmsh version 7.1.4 says that AttributeError: 'Geometry' object has no attribute 'get_code'.

Python 3.6.9 (default, Oct  8 2020, 12:12:24)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygmsh
>>> pygmsh.__version__
'7.1.4'
>>> geom = pygmsh.occ.Geometry()
>>> geom.get_code()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Geometry' object has no attribute 'get_code'

If I remember correctly, this method was available a few months ago. Any reason why get_code is not available anymore? Then, how is it possible to get Gmsh code?

gdmcbain commented 3 years ago

I don't know whether the readthedocs is maintained, but no, get_code went out with pygmsh 7, which is very different from earlier versions. pygmsh<7 generated GEO code which was then fed to Gmsh; pygmsh 7 works directly with Gmsh's Python API. If you want a GEO code generator, I'm afraid you'll have to pip install pygmsh<7. So far as I know, it's not possible to get GEO code from any of the gmsh Python objects, as wrapped by the new pygmsh Geometry classes. There are many advantages to the new approach though; are you sure you need the GEO? See #380 for more discussion of rationale and motivation.

KeunwooPark commented 3 years ago

Thank you for your reply. Then I guess I have to use pygmsh 6.

I share my problem here for anyone who might have a similar problem. What I want to do is creating a mesh for fipy Gmsh.

The input should be either

I did not want to create .msh file and load it again, because of IO overhead. However, I guess there is no other way except using pygsmh 6.

nschloe commented 3 years ago

I did not want to create .msh file and load it again, because of IO overhead.

What do you think happens when passing a geo file? There has to be a reader in there somewhere.

Personally, I wouldn't worry too much about overhead because it's usually small.

KeunwooPark commented 3 years ago

@nschloe Thank you for your comment. As you suggested, I'm trying to use a .geo file. However, it is hard for me to figure out how to export geo file with pygmsh.

As I understand, geo file is a script for Gmsh. Therefore, I think it could be possible to save geo file without calling Geometry.generate_mesh. Please correct me if I'm wrong.

I'm aware of this issue, but pygmsh.helpers.generate_mesh does not exist anymore. Moreover, it seems that CommonGeometry does not have related features.

Could you explain how to export geo file?

gdmcbain commented 3 years ago

Yep, #349 was pygmsh<7.

So far as I know, it's not possible to get GEO code from any of the gmsh Python objects

(and hence not from pygmsh>=7, which relies on them). I think I read this somewhere, but don't have a link, sorry. The reply to a query to ‘Save .geo file from python API’ wasn't explicitly negative but suggested saving BRep instead.

I did actually come across another use for GEO codes yesterday—hitherto I'd believed that the only possible purpose of generating GEO code was for processing by Gmsh.

Nektar++'s NekMesh reads a two-dimensional subset of GEO code as CAD-backing for generating higher-order meshes, for defining the curvature. See §4.5.2.1 ‘GEO format’ in §4.5.2 of Nektar++'s User Guide. I don't know whether that'll catch on; it's an interesting idea. But NekMesh does also accept STEP which can be generated from a Gmsh Python object in the same way as BRep, I think.

gdmcbain commented 3 years ago

O. K., here we go. Christophe Geuzaine (2019-09-27) answered ‘python API save geo file’ with:

Use gmsh.write("foo.geo_unrolled")

KeunwooPark commented 3 years ago

@gdmcbain Thank you for your kind answer. However, I think I'm still not fully understanding the relationship between .mesh and .geo files.

I tried gmsh.write, but it does not write anything to the file unless I actually generate a mesh with generate_mesh.

import pygmsh
import gmsh
import meshio

geo_fn = "tmp.geo_unrolled"

with pygmsh.occ.Geometry() as geom:

    geom.characteristic_length_max = 1

    outer = geom.add_ball([0,0,0], 10)
    inner = geom.add_ball([0,0,0], 3)
    geom.boolean_difference([outer], [inner])

    mesh = geom.generate_mesh(verbose=True) # file is empty without this line
    gmsh.write(geo_fn)

pygmsh.occ.Geometry.add_ball just calls gmsh API gmsh.model.occ.addSphere internally. So I guess it is not supported at the gmsh side, which ‘Save .geo file from python API’ query implies.

Similar to the above query, I wanted to save .geo without running the actual meshing algorithm for efficiency. However, it seems to be not possible with gmsh python API.

nschloe commented 3 years ago

Okay, we now have

geom.save_geometry(filename)

to which you can supply a geo_unrolled or a brep file.

@ keunwoo You'll need to gmsh.synchronize() first. I know it's weird, and save_geometry does it for you.

KeunwooPark commented 3 years ago

@nschloe Thank you very much. It works perfectly.

nschloe commented 3 years ago

@uttamcadambi07 There's a difference between the geometry and the mesh. If you want to store the mesh, just use mesh.write("out.vtk"), for example.

uttamcadambi07 commented 3 years ago

@uttamcadambi07 There's a difference between the geometry and the mesh. If you want to store the mesh, just use mesh.write("out.vtk"), for example.

Dear Nico, Thank you! I had made a rookie mistake and just after posting the comment did I realise what I had done. True, I can use the mesh.write("out.vtk") but I wanted something like, creating a mesh with gmsh python API upto a certain level and picking it up from gmsh later on. What I did was used gmsh.write("out.geo_unrolled") and then could use edit script feature in gmsh to make whatever changes I needed. Thanks for your help!