From 98fb0537f7c089b0184015696cf58e24c16e2f41 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@uliege.be> Date: Mon, 14 Sep 2020 12:53:33 +0200 Subject: [PATCH] basic python implementation of the global mesh size callback --- api/GenApi.py | 10 ++++++++-- api/gen.py | 6 +++--- api/gmsh.h | 6 ++++-- api/gmsh.h_cwrap | 6 ++++-- api/gmsh.jl | 2 +- api/gmsh.py | 22 +++++++++++++++++++++- api/gmshc.h | 6 ++++-- doc/texinfo/api.texi | 18 +++++++++++------- tutorial/c++/t10.cpp | 5 ++--- tutorial/python/t10.py | 5 ++--- 10 files changed, 60 insertions(+), 26 deletions(-) diff --git a/api/GenApi.py b/api/GenApi.py index 8553639582..5c9b1cbbfb 100644 --- a/api/GenApi.py +++ b/api/GenApi.py @@ -738,9 +738,13 @@ def isizefun(name): a.cpp = "double (*" + name + ")(int dim, int tag, double x, double y, double z)" a.c_arg = name a.c = a.cpp - a.c_pre = "" - a.c_post = "" a.cwrap_arg = a.c_arg + a.python_pre = ("global api_" + name + "_type_\n" + + " api_" + name + "_type_ = " + + "CFUNCTYPE(c_double, c_int, c_int, c_double, c_double, c_double)\n" + + " global api_" + name + "_\n" + + " api_" + name + "_ = api_" + name + "_type_(" + name + ")") + a.python_arg = "api_" + name + "_" return a @@ -1382,6 +1386,7 @@ class API: def write_function(f, fun, c_mpath, py_mpath, indent): (rtype, name, args, doc, special) = fun if "onlycc++" in special: return + if "nopython" in special: return iargs = list(a for a in args if not a.out) oargs = list(a for a in args if a.out) f.write("\n") @@ -1463,6 +1468,7 @@ class API: def write_function(f, fun, c_mpath, jl_mpath): (rtype, name, args, doc, special) = fun if "onlycc++" in special: return + if "nojulia" in special: return iargs = list(a for a in args if not a.out) oargs = list(a for a in args if a.out) f.write('\n"""\n ') diff --git a/api/gen.py b/api/gen.py index f42c862606..6457a98eab 100644 --- a/api/gen.py +++ b/api/gen.py @@ -377,10 +377,10 @@ mesh.add('setSize', doc, None, ivectorpair('dimTags'), idouble('size')) doc = '''Set mesh size constraints at the given parametric points `parametricCoord' on the model entity of dimension `dim' and tag `tag'. Currently only entities of dimension 1 (lines) are handled.''' mesh.add('setSizeAtParametricPoints', doc, None, iint('dim'), iint('tag'), ivectordouble('parametricCoord'), ivectordouble('sizes')) -doc = '''Set global mesh size callback. For C and C++ only.''' -mesh.add_special('setSizeCallback', doc, ['onlycc++'], None, isizefun('callback')) +doc = '''Set a global mesh size callback. The callback should take 5 arguments (`dim', `tag', `x', `y' and `z') and return the value of the mesh size at coordinates (`x', `y', `z').''' +mesh.add_special('setSizeCallback', doc, ['nojulia'], None, isizefun('callback')) -doc = '''Remove global mesh size callback. For C and C++ only.''' +doc = '''Remove the global mesh size callback.''' mesh.add('removeSizeCallback', doc, None) doc = '''Set a transfinite meshing constraint on the curve `tag', with `numNodes' nodes distributed according to `meshType' and `coef'. Currently supported types are "Progression" (geometrical progression with power `coef') and "Bump" (refinement toward both extremities of the curve).''' diff --git a/api/gmsh.h b/api/gmsh.h index b88666ea7a..5530e7c58a 100644 --- a/api/gmsh.h +++ b/api/gmsh.h @@ -1171,12 +1171,14 @@ namespace gmsh { // Top-level functions // gmsh::model::mesh::setSizeCallback // - // Set global mesh size callback. For C and C++ only. + // Set a global mesh size callback. The callback should take 5 arguments + // (`dim', `tag', `x', `y' and `z') and return the value of the mesh size at + // coordinates (`x', `y', `z'). GMSH_API void setSizeCallback(double (*callback)(int dim, int tag, double x, double y, double z)); // gmsh::model::mesh::removeSizeCallback // - // Remove global mesh size callback. For C and C++ only. + // Remove the global mesh size callback. GMSH_API void removeSizeCallback(); // gmsh::model::mesh::setTransfiniteCurve diff --git a/api/gmsh.h_cwrap b/api/gmsh.h_cwrap index ed864d4843..8963f0e0f0 100644 --- a/api/gmsh.h_cwrap +++ b/api/gmsh.h_cwrap @@ -1785,7 +1785,9 @@ namespace gmsh { // Top-level functions gmshFree(api_sizes_); } - // Set global mesh size callback. For C and C++ only. + // Set a global mesh size callback. The callback should take 5 arguments + // (`dim', `tag', `x', `y' and `z') and return the value of the mesh size at + // coordinates (`x', `y', `z'). inline void setSizeCallback(double (*callback)(int dim, int tag, double x, double y, double z)) { int ierr = 0; @@ -1793,7 +1795,7 @@ namespace gmsh { // Top-level functions if(ierr) throwLastError(); } - // Remove global mesh size callback. For C and C++ only. + // Remove the global mesh size callback. inline void removeSizeCallback() { int ierr = 0; diff --git a/api/gmsh.jl b/api/gmsh.jl index cebd116ae1..7277bef96f 100644 --- a/api/gmsh.jl +++ b/api/gmsh.jl @@ -2200,7 +2200,7 @@ end """ gmsh.model.mesh.removeSizeCallback() -Remove global mesh size callback. For C and C++ only. +Remove the global mesh size callback. """ function removeSizeCallback() ierr = Ref{Cint}() diff --git a/api/gmsh.py b/api/gmsh.py index daa213274e..d2666a771a 100644 --- a/api/gmsh.py +++ b/api/gmsh.py @@ -2602,12 +2602,32 @@ class model: if ierr.value != 0: raise Exception(logger.getLastError()) + @staticmethod + def setSizeCallback(callback): + """ + gmsh.model.mesh.setSizeCallback(callback) + + Set a global mesh size callback. The callback should take 5 arguments + (`dim', `tag', `x', `y' and `z') and return the value of the mesh size at + coordinates (`x', `y', `z'). + """ + global api_callback_type_ + api_callback_type_ = CFUNCTYPE(c_double, c_int, c_int, c_double, c_double, c_double) + global api_callback_ + api_callback_ = api_callback_type_(callback) + ierr = c_int() + lib.gmshModelMeshSetSizeCallback( + api_callback_, + byref(ierr)) + if ierr.value != 0: + raise Exception(logger.getLastError()) + @staticmethod def removeSizeCallback(): """ gmsh.model.mesh.removeSizeCallback() - Remove global mesh size callback. For C and C++ only. + Remove the global mesh size callback. """ ierr = c_int() lib.gmshModelMeshRemoveSizeCallback( diff --git a/api/gmshc.h b/api/gmshc.h index 2513e032cb..c2830ee620 100644 --- a/api/gmshc.h +++ b/api/gmshc.h @@ -1030,11 +1030,13 @@ GMSH_API void gmshModelMeshSetSizeAtParametricPoints(const int dim, double * sizes, size_t sizes_n, int * ierr); -/* Set global mesh size callback. For C and C++ only. */ +/* Set a global mesh size callback. The callback should take 5 arguments + * (`dim', `tag', `x', `y' and `z') and return the value of the mesh size at + * coordinates (`x', `y', `z'). */ GMSH_API void gmshModelMeshSetSizeCallback(double (*callback)(int dim, int tag, double x, double y, double z), int * ierr); -/* Remove global mesh size callback. For C and C++ only. */ +/* Remove the global mesh size callback. */ GMSH_API void gmshModelMeshRemoveSizeCallback(int * ierr); /* Set a transfinite meshing constraint on the curve `tag', with `numNodes' diff --git a/doc/texinfo/api.texi b/doc/texinfo/api.texi index 019eadb5cd..e4502e2c0f 100644 --- a/doc/texinfo/api.texi +++ b/doc/texinfo/api.texi @@ -1774,7 +1774,9 @@ entities of dimension 1 (lines) are handled. @end table @item gmsh/model/mesh/setSizeCallback -Set global mesh size callback. For C and C++ only. +Set a global mesh size callback. The callback should take 5 arguments +(@code{dim}, @code{tag}, @code{x}, @code{y} and @code{z}) and return the value +of the mesh size at coordinates (@code{x}, @code{y}, @code{z}). @table @asis @item Input: @@ -1783,10 +1785,12 @@ Set global mesh size callback. For C and C++ only. - @item Return: - +@item Examples: +C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L117,t10.cpp}), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L108,t10.py}) @end table @item gmsh/model/mesh/removeSizeCallback -Remove global mesh size callback. For C and C++ only. +Remove the global mesh size callback. @table @asis @item Input: @@ -2243,7 +2247,7 @@ the field tag. @item Return: integer value @item Examples: -C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t7.cpp#L49,t7.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L46,t10.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t11.cpp#L38,t11.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t13.cpp#L68,t13.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t17.cpp#L41,t17.cpp}, ...), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t7.py#L44,t7.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L44,t10.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t13.py#L57,t13.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t17.py#L35,t17.py}, @url{@value{GITLAB-PREFIX}/demos/api/adapt_mesh.py#L113,adapt_mesh.py}) +C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t7.cpp#L49,t7.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L51,t10.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t11.cpp#L38,t11.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t13.cpp#L68,t13.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t17.cpp#L41,t17.cpp}, ...), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t7.py#L44,t7.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L44,t10.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t13.py#L57,t13.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t17.py#L35,t17.py}, @url{@value{GITLAB-PREFIX}/demos/api/adapt_mesh.py#L113,adapt_mesh.py}) @end table @item gmsh/model/mesh/field/remove @@ -2270,7 +2274,7 @@ Set the numerical option @code{option} to value @code{value} for field @item Return: - @item Examples: -C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L48,t10.cpp}, @url{@value{GITLAB-PREFIX}/demos/api/adapt_mesh.cpp#L271,adapt_mesh.cpp}), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L46,t10.py}, @url{@value{GITLAB-PREFIX}/demos/api/adapt_mesh.py#L114,adapt_mesh.py}) +C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L53,t10.cpp}, @url{@value{GITLAB-PREFIX}/demos/api/adapt_mesh.cpp#L271,adapt_mesh.cpp}), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L46,t10.py}, @url{@value{GITLAB-PREFIX}/demos/api/adapt_mesh.py#L114,adapt_mesh.py}) @end table @item gmsh/model/mesh/field/setString @@ -2284,7 +2288,7 @@ Set the string option @code{option} to value @code{value} for field @code{tag}. @item Return: - @item Examples: -C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L73,t10.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t11.cpp#L39,t11.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t13.cpp#L70,t13.cpp}), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L70,t10.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t13.py#L59,t13.py}) +C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L78,t10.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t11.cpp#L39,t11.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t13.cpp#L70,t13.cpp}), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L70,t10.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t13.py#L59,t13.py}) @end table @item gmsh/model/mesh/field/setNumbers @@ -2299,7 +2303,7 @@ Set the numerical list option @code{option} to value @code{value} for field @item Return: - @item Examples: -C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L47,t10.cpp}), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L45,t10.py}) +C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L52,t10.cpp}), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L45,t10.py}) @end table @item gmsh/model/mesh/field/setAsBackgroundMesh @@ -2313,7 +2317,7 @@ Set the field @code{tag} as the background mesh size field. @item Return: - @item Examples: -C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t7.cpp#L52,t7.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L108,t10.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t11.cpp#L41,t11.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t13.cpp#L73,t13.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t17.cpp#L42,t17.cpp}, ...), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t7.py#L47,t7.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L102,t10.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t13.py#L62,t13.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t17.py#L36,t17.py}, @url{@value{GITLAB-PREFIX}/demos/api/adapt_mesh.py#L115,adapt_mesh.py}) +C++ (@url{@value{GITLAB-PREFIX}/tutorial/c++/t7.cpp#L52,t7.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t10.cpp#L113,t10.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t11.cpp#L41,t11.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t13.cpp#L73,t13.cpp}, @url{@value{GITLAB-PREFIX}/tutorial/c++/t17.cpp#L42,t17.cpp}, ...), Python (@url{@value{GITLAB-PREFIX}/tutorial/python/t7.py#L47,t7.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t10.py#L102,t10.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t13.py#L62,t13.py}, @url{@value{GITLAB-PREFIX}/tutorial/python/t17.py#L36,t17.py}, @url{@value{GITLAB-PREFIX}/demos/api/adapt_mesh.py#L115,adapt_mesh.py}) @end table @item gmsh/model/mesh/field/setAsBoundaryLayer diff --git a/tutorial/c++/t10.cpp b/tutorial/c++/t10.cpp index 86c1148c2a..59fcc2619d 100644 --- a/tutorial/c++/t10.cpp +++ b/tutorial/c++/t10.cpp @@ -15,8 +15,7 @@ double meshSizeCallback(int dim, int tag, double x, double y, double z) { - double val = 0.02 * x + 0.01; - return val; + return 0.02 * x + 0.01; } int main(int argc, char **argv) @@ -113,7 +112,7 @@ int main(int argc, char **argv) gmsh::model::mesh::field::setAsBackgroundMesh(7); - // In the API we can also set a global mesh size callback, which is called + // The API also allows to set a global mesh size callback, which is called // each time the mesh size is queried gmsh::model::mesh::setSizeCallback(meshSizeCallback); diff --git a/tutorial/python/t10.py b/tutorial/python/t10.py index 38924eb679..e542747ea3 100644 --- a/tutorial/python/t10.py +++ b/tutorial/python/t10.py @@ -101,11 +101,10 @@ gmsh.model.mesh.field.setNumbers(7, "FieldsList", [2, 3, 5, 6]) gmsh.model.mesh.field.setAsBackgroundMesh(7) -# In the API we can also set a global mesh size callback, which is called each +# The API also allows to set a global mesh size callback, which is called each # time the mesh size is queried def meshSizeCallback(dim, tag, x, y, z): - val = 0.02 * x + 0.01 - return val + return 0.02 * x + 0.01 gmsh.model.mesh.setSizeCallback(meshSizeCallback) # To determine the size of mesh elements, Gmsh locally computes the minimum of -- GitLab