Skip to content
Snippets Groups Projects
Select Git revision
  • d007c2fa04aa9e6bbf02e7e7e663a79d859c3ea5
  • master default
  • cgnsUnstructured
  • partitioning
  • poppler
  • HighOrderBLCurving
  • gmsh_3_0_4
  • gmsh_3_0_3
  • gmsh_3_0_2
  • gmsh_3_0_1
  • gmsh_3_0_0
  • gmsh_2_16_0
  • gmsh_2_15_0
  • gmsh_2_14_1
  • gmsh_2_14_0
  • gmsh_2_13_2
  • gmsh_2_13_1
  • gmsh_2_12_0
  • gmsh_2_11_0
  • gmsh_2_10_1
  • gmsh_2_10_0
  • gmsh_2_9_3
  • gmsh_2_9_2
  • gmsh_2_9_1
  • gmsh_2_9_0
  • gmsh_2_8_6
26 results

graphicWindow.cpp

Blame
  • Forked from gmsh / gmsh
    Source project has a limited visibility.
    gmsh.f90 659.86 KiB
    !
    ! Gmsh - Copyright (C) 1997-2024 C. Geuzaine, J.-F. Remacle
    !
    ! See the LICENSE.txt file in the Gmsh root directory for license information.
    ! Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
    
    ! Gmsh is an automatic three-dimensional finite element mesh generator with a
    ! built-in CAD engine and post-processor. Its design goal is to provide a fast,
    ! light and user-friendly meshing tool with parametric input and flexible
    ! visualization capabilities. Gmsh is built around four modules (geometry, mesh,
    ! solver and post-processing), which can be controlled with the graphical user
    ! interface, from the command line, using text files written in Gmsh's own
    ! scripting language (.geo files), or through the C++, C, Python, Julia and
    ! Fortran application programming interface (API).
    !
    ! This file defines the Gmsh Fortran API (v4.13.1).
    !
    ! Do not edit this file directly: it is automatically generated by `api/gen.py'.
    !
    ! By design, the Gmsh Fortran API is purely functional, and only uses elementary
    ! Fortran types. See `tutorials/fortran' and `examples/api' for tutorials and
    ! examples.
    
    module gmsh
    
      use, intrinsic :: iso_c_binding
    
      implicit none
    
      private
    
      integer, parameter, public :: GMSH_API_VERSION_MAJOR = 4
      integer, parameter, public :: GMSH_API_VERSION_MINOR = 13
      integer, parameter, public :: GMSH_API_VERSION_PATCH = 1
      integer, parameter, public :: GMSH_API_MAX_STR_LEN = 512
      real(c_double), parameter, public :: M_PI = 3.14159265358979323846_c_double
      character(len=100), parameter, public :: GMSH_API_VERSION = "4.13.1"
    
      public :: gmshFree
    
      type cstr_t
        character(len=:), allocatable :: s
      end type cstr_t
    
      type, private :: c_array_t
        type(c_ptr) :: s
      end type c_array_t
    
      interface optval_c_int
        module procedure optval_c_int_1
      end interface optval_c_int
    
      interface optval_c_size_t
        module procedure optval_c_size_t_1, optval_c_size_t_2
      end interface optval_c_size_t
    
      interface optval_c_double
        module procedure optval_c_double_1, optval_c_double_2
      end interface optval_c_double
    
      type, public :: gmsh_logger_t
        contains
        procedure, nopass :: write => &
            gmshLoggerWrite
        procedure, nopass :: start => &
            gmshLoggerStart
        procedure, nopass :: get => &
            gmshLoggerGet
        procedure, nopass :: stop => &
            gmshLoggerStop
        procedure, nopass :: getWallTime => &
            gmshLoggerGetWallTime
        procedure, nopass :: getCpuTime => &
            gmshLoggerGetCpuTime
        procedure, nopass :: getMemory => &
            gmshLoggerGetMemory
        procedure, nopass :: getTotalMemory => &
            gmshLoggerGetTotalMemory
        procedure, nopass :: getLastError => &
            gmshLoggerGetLastError
      end type gmsh_logger_t
    
      type, public :: gmsh_onelab_t
        contains
        procedure, nopass :: set => &
            gmshOnelabSet
        procedure, nopass :: get => &
            gmshOnelabGet
        procedure, nopass :: getNames => &
            gmshOnelabGetNames
        procedure, nopass :: setNumber => &
            gmshOnelabSetNumber
        procedure, nopass :: setString => &
            gmshOnelabSetString
        procedure, nopass :: getNumber => &
            gmshOnelabGetNumber
        procedure, nopass :: getString => &
            gmshOnelabGetString
        procedure, nopass :: getChanged => &
            gmshOnelabGetChanged
        procedure, nopass :: setChanged => &
            gmshOnelabSetChanged
        procedure, nopass :: clear => &
            gmshOnelabClear
        procedure, nopass :: run => &
            gmshOnelabRun
      end type gmsh_onelab_t
    
      type, public :: gmsh_parser_t
        contains
        procedure, nopass :: getNames => &
            gmshParserGetNames
        procedure, nopass :: setNumber => &
            gmshParserSetNumber
        procedure, nopass :: setString => &
            gmshParserSetString
        procedure, nopass :: getNumber => &
            gmshParserGetNumber
        procedure, nopass :: getString => &
            gmshParserGetString
        procedure, nopass :: clear => &
            gmshParserClear
        procedure, nopass :: parse => &
            gmshParserParse
      end type gmsh_parser_t
    
      type, public :: gmsh_fltk_t
        contains
        procedure, nopass :: initialize => &
            gmshFltkInitialize
        procedure, nopass :: finalize => &
            gmshFltkFinalize
        procedure, nopass :: wait => &
            gmshFltkWait
        procedure, nopass :: update => &
            gmshFltkUpdate
        procedure, nopass :: awake => &
            gmshFltkAwake
        procedure, nopass :: lock => &
            gmshFltkLock
        procedure, nopass :: unlock => &
            gmshFltkUnlock
        procedure, nopass :: run => &
            gmshFltkRun
        procedure, nopass :: isAvailable => &
            gmshFltkIsAvailable
        procedure, nopass :: selectEntities => &
            gmshFltkSelectEntities
        procedure, nopass :: selectElements => &
            gmshFltkSelectElements
        procedure, nopass :: selectViews => &
            gmshFltkSelectViews
        procedure, nopass :: splitCurrentWindow => &
            gmshFltkSplitCurrentWindow
        procedure, nopass :: setCurrentWindow => &
            gmshFltkSetCurrentWindow
        procedure, nopass :: setStatusMessage => &
            gmshFltkSetStatusMessage
        procedure, nopass :: showContextWindow => &
            gmshFltkShowContextWindow
        procedure, nopass :: openTreeItem => &
            gmshFltkOpenTreeItem
        procedure, nopass :: closeTreeItem => &
            gmshFltkCloseTreeItem
      end type gmsh_fltk_t
    
      type, public :: gmsh_graphics_t
        contains
        procedure, nopass :: draw => &
            gmshGraphicsDraw
      end type gmsh_graphics_t
    
      type, public :: gmsh_plugin_t
        contains
        procedure, nopass :: setNumber => &
            gmshPluginSetNumber
        procedure, nopass :: setString => &
            gmshPluginSetString
        procedure, nopass :: run => &
            gmshPluginRun
      end type gmsh_plugin_t
    
      type, public :: gmsh_view_option_t
        contains
        procedure, nopass :: setNumber => &
            gmshViewOptionSetNumber
        procedure, nopass :: getNumber => &
            gmshViewOptionGetNumber
        procedure, nopass :: setString => &
            gmshViewOptionSetString
        procedure, nopass :: getString => &
            gmshViewOptionGetString
        procedure, nopass :: setColor => &
            gmshViewOptionSetColor
        procedure, nopass :: getColor => &
            gmshViewOptionGetColor
        procedure, nopass :: copy => &
            gmshViewOptionCopy
      end type gmsh_view_option_t
    
      type, public :: gmsh_view_t
        type(gmsh_view_option_t) :: option
        contains
        procedure, nopass :: add => &
            gmshViewAdd
        procedure, nopass :: remove => &
            gmshViewRemove
        procedure, nopass :: getIndex => &
            gmshViewGetIndex
        procedure, nopass :: getTags => &
            gmshViewGetTags
        procedure, nopass :: addModelData => &
            gmshViewAddModelData
        procedure, nopass :: addHomogeneousModelData => &
            gmshViewAddHomogeneousModelData
        procedure, nopass :: getModelData => &
            gmshViewGetModelData
        procedure, nopass :: getHomogeneousModelData => &
            gmshViewGetHomogeneousModelData
        procedure, nopass :: addListData => &
            gmshViewAddListData
        procedure, nopass :: getListData => &
            gmshViewGetListData
        procedure, nopass :: addListDataString => &
            gmshViewAddListDataString
        procedure, nopass :: getListDataStrings => &
            gmshViewGetListDataStrings
        procedure, nopass :: setInterpolationMatrices => &
            gmshViewSetInterpolationMatrices
        procedure, nopass :: addAlias => &
            gmshViewAddAlias
        procedure, nopass :: combine => &
            gmshViewCombine
        procedure, nopass :: probe => &
            gmshViewProbe
        procedure, nopass :: write => &
            gmshViewWrite
        procedure, nopass :: setVisibilityPerWindow => &
            gmshViewSetVisibilityPerWindow
      end type gmsh_view_t
    
      type, public :: gmsh_model_occ_mesh_t
        contains
        procedure, nopass :: setSize => &
            gmshModelOccMeshSetSize
      end type gmsh_model_occ_mesh_t
    
      type, public :: gmsh_model_occ_t
        type(gmsh_model_occ_mesh_t) :: mesh
        contains
        procedure, nopass :: addPoint => &
            gmshModelOccAddPoint
        procedure, nopass :: addLine => &
            gmshModelOccAddLine
        procedure, nopass :: addCircleArc => &
            gmshModelOccAddCircleArc
        procedure, nopass :: addCircle => &
            gmshModelOccAddCircle
        procedure, nopass :: addEllipseArc => &
            gmshModelOccAddEllipseArc
        procedure, nopass :: addEllipse => &
            gmshModelOccAddEllipse
        procedure, nopass :: addSpline => &
            gmshModelOccAddSpline
        procedure, nopass :: addBSpline => &
            gmshModelOccAddBSpline
        procedure, nopass :: addBezier => &
            gmshModelOccAddBezier
        procedure, nopass :: addWire => &
            gmshModelOccAddWire
        procedure, nopass :: addCurveLoop => &
            gmshModelOccAddCurveLoop
        procedure, nopass :: addRectangle => &
            gmshModelOccAddRectangle
        procedure, nopass :: addDisk => &
            gmshModelOccAddDisk
        procedure, nopass :: addPlaneSurface => &
            gmshModelOccAddPlaneSurface
        procedure, nopass :: addSurfaceFilling => &
            gmshModelOccAddSurfaceFilling
        procedure, nopass :: addBSplineFilling => &
            gmshModelOccAddBSplineFilling
        procedure, nopass :: addBezierFilling => &
            gmshModelOccAddBezierFilling
        procedure, nopass :: addBSplineSurface => &
            gmshModelOccAddBSplineSurface
        procedure, nopass :: addBezierSurface => &
            gmshModelOccAddBezierSurface
        procedure, nopass :: addTrimmedSurface => &
            gmshModelOccAddTrimmedSurface
        procedure, nopass :: addSurfaceLoop => &
            gmshModelOccAddSurfaceLoop
        procedure, nopass :: addVolume => &
            gmshModelOccAddVolume
        procedure, nopass :: addSphere => &
            gmshModelOccAddSphere
        procedure, nopass :: addBox => &
            gmshModelOccAddBox
        procedure, nopass :: addCylinder => &
            gmshModelOccAddCylinder
        procedure, nopass :: addCone => &
            gmshModelOccAddCone
        procedure, nopass :: addWedge => &
            gmshModelOccAddWedge
        procedure, nopass :: addTorus => &
            gmshModelOccAddTorus
        procedure, nopass :: addThruSections => &
            gmshModelOccAddThruSections
        procedure, nopass :: addThickSolid => &
            gmshModelOccAddThickSolid
        procedure, nopass :: extrude => &
            gmshModelOccExtrude
        procedure, nopass :: revolve => &
            gmshModelOccRevolve
        procedure, nopass :: addPipe => &
            gmshModelOccAddPipe
        procedure, nopass :: fillet => &
            gmshModelOccFillet
        procedure, nopass :: chamfer => &
            gmshModelOccChamfer
        procedure, nopass :: defeature => &
            gmshModelOccDefeature
        procedure, nopass :: fillet2D => &
            gmshModelOccFillet2D
        procedure, nopass :: chamfer2D => &
            gmshModelOccChamfer2D
        procedure, nopass :: offsetCurve => &
            gmshModelOccOffsetCurve
        procedure, nopass :: getDistance => &
            gmshModelOccGetDistance
        procedure, nopass :: fuse => &
            gmshModelOccFuse
        procedure, nopass :: intersect => &
            gmshModelOccIntersect
        procedure, nopass :: cut => &
            gmshModelOccCut
        procedure, nopass :: fragment => &
            gmshModelOccFragment
        procedure, nopass :: translate => &
            gmshModelOccTranslate
        procedure, nopass :: rotate => &
            gmshModelOccRotate
        procedure, nopass :: dilate => &
            gmshModelOccDilate
        procedure, nopass :: mirror => &
            gmshModelOccMirror
        procedure, nopass :: symmetrize => &
            gmshModelOccSymmetrize
        procedure, nopass :: affineTransform => &
            gmshModelOccAffineTransform
        procedure, nopass :: copy => &
            gmshModelOccCopy
        procedure, nopass :: remove => &
            gmshModelOccRemove
        procedure, nopass :: removeAllDuplicates => &
            gmshModelOccRemoveAllDuplicates
        procedure, nopass :: healShapes => &
            gmshModelOccHealShapes
        procedure, nopass :: convertToNURBS => &
            gmshModelOccConvertToNURBS
        procedure, nopass :: importShapes => &
            gmshModelOccImportShapes
        procedure, nopass :: importShapesNativePointer => &
            gmshModelOccImportShapesNativePointer
        procedure, nopass :: getEntities => &
            gmshModelOccGetEntities
        procedure, nopass :: getEntitiesInBoundingBox => &
            gmshModelOccGetEntitiesInBoundingBox
        procedure, nopass :: getBoundingBox => &
            gmshModelOccGetBoundingBox
        procedure, nopass :: getCurveLoops => &
            gmshModelOccGetCurveLoops
        procedure, nopass :: getSurfaceLoops => &
            gmshModelOccGetSurfaceLoops
        procedure, nopass :: getMass => &
            gmshModelOccGetMass
        procedure, nopass :: getCenterOfMass => &
            gmshModelOccGetCenterOfMass
        procedure, nopass :: getMatrixOfInertia => &
            gmshModelOccGetMatrixOfInertia
        procedure, nopass :: getMaxTag => &
            gmshModelOccGetMaxTag
        procedure, nopass :: setMaxTag => &
            gmshModelOccSetMaxTag
        procedure, nopass :: synchronize => &
            gmshModelOccSynchronize
      end type gmsh_model_occ_t
    
      type, public :: gmsh_model_geo_mesh_t
        contains
        procedure, nopass :: setSize => &
            gmshModelGeoMeshSetSize
        procedure, nopass :: setTransfiniteCurve => &
            gmshModelGeoMeshSetTransfiniteCurve
        procedure, nopass :: setTransfiniteSurface => &
            gmshModelGeoMeshSetTransfiniteSurface
        procedure, nopass :: setTransfiniteVolume => &
            gmshModelGeoMeshSetTransfiniteVolume
        procedure, nopass :: setRecombine => &
            gmshModelGeoMeshSetRecombine
        procedure, nopass :: setSmoothing => &
            gmshModelGeoMeshSetSmoothing
        procedure, nopass :: setReverse => &
            gmshModelGeoMeshSetReverse
        procedure, nopass :: setAlgorithm => &
            gmshModelGeoMeshSetAlgorithm
        procedure, nopass :: setSizeFromBoundary => &
            gmshModelGeoMeshSetSizeFromBoundary
      end type gmsh_model_geo_mesh_t
    
      type, public :: gmsh_model_geo_t
        type(gmsh_model_geo_mesh_t) :: mesh
        contains
        procedure, nopass :: addPoint => &
            gmshModelGeoAddPoint
        procedure, nopass :: addLine => &
            gmshModelGeoAddLine
        procedure, nopass :: addCircleArc => &
            gmshModelGeoAddCircleArc
        procedure, nopass :: addEllipseArc => &
            gmshModelGeoAddEllipseArc
        procedure, nopass :: addSpline => &
            gmshModelGeoAddSpline
        procedure, nopass :: addBSpline => &
            gmshModelGeoAddBSpline
        procedure, nopass :: addBezier => &
            gmshModelGeoAddBezier
        procedure, nopass :: addPolyline => &
            gmshModelGeoAddPolyline
        procedure, nopass :: addCompoundSpline => &
            gmshModelGeoAddCompoundSpline
        procedure, nopass :: addCompoundBSpline => &
            gmshModelGeoAddCompoundBSpline
        procedure, nopass :: addCurveLoop => &
            gmshModelGeoAddCurveLoop
        procedure, nopass :: addCurveLoops => &
            gmshModelGeoAddCurveLoops
        procedure, nopass :: addPlaneSurface => &
            gmshModelGeoAddPlaneSurface
        procedure, nopass :: addSurfaceFilling => &
            gmshModelGeoAddSurfaceFilling
        procedure, nopass :: addSurfaceLoop => &
            gmshModelGeoAddSurfaceLoop
        procedure, nopass :: addVolume => &
            gmshModelGeoAddVolume
        procedure, nopass :: addGeometry => &
            gmshModelGeoAddGeometry
        procedure, nopass :: addPointOnGeometry => &
            gmshModelGeoAddPointOnGeometry
        procedure, nopass :: extrude => &
            gmshModelGeoExtrude
        procedure, nopass :: revolve => &
            gmshModelGeoRevolve
        procedure, nopass :: twist => &
            gmshModelGeoTwist
        procedure, nopass :: extrudeBoundaryLayer => &
            gmshModelGeoExtrudeBoundaryLayer
        procedure, nopass :: translate => &
            gmshModelGeoTranslate
        procedure, nopass :: rotate => &
            gmshModelGeoRotate
        procedure, nopass :: dilate => &
            gmshModelGeoDilate
        procedure, nopass :: mirror => &
            gmshModelGeoMirror
        procedure, nopass :: symmetrize => &
            gmshModelGeoSymmetrize
        procedure, nopass :: copy => &
            gmshModelGeoCopy
        procedure, nopass :: remove => &
            gmshModelGeoRemove
        procedure, nopass :: removeAllDuplicates => &
            gmshModelGeoRemoveAllDuplicates
        procedure, nopass :: splitCurve => &
            gmshModelGeoSplitCurve
        procedure, nopass :: getMaxTag => &
            gmshModelGeoGetMaxTag
        procedure, nopass :: setMaxTag => &
            gmshModelGeoSetMaxTag
        procedure, nopass :: addPhysicalGroup => &
            gmshModelGeoAddPhysicalGroup
        procedure, nopass :: removePhysicalGroups => &
            gmshModelGeoRemovePhysicalGroups
        procedure, nopass :: synchronize => &
            gmshModelGeoSynchronize
      end type gmsh_model_geo_t
    
      type, public :: gmsh_model_mesh_field_t
        contains
        procedure, nopass :: add => &
            gmshModelMeshFieldAdd
        procedure, nopass :: remove => &
            gmshModelMeshFieldRemove
        procedure, nopass :: list => &
            gmshModelMeshFieldList
        procedure, nopass :: getType => &
            gmshModelMeshFieldGetType
        procedure, nopass :: setNumber => &
            gmshModelMeshFieldSetNumber
        procedure, nopass :: getNumber => &
            gmshModelMeshFieldGetNumber
        procedure, nopass :: setString => &
            gmshModelMeshFieldSetString
        procedure, nopass :: getString => &
            gmshModelMeshFieldGetString
        procedure, nopass :: setNumbers => &
            gmshModelMeshFieldSetNumbers
        procedure, nopass :: getNumbers => &
            gmshModelMeshFieldGetNumbers
        procedure, nopass :: setAsBackgroundMesh => &
            gmshModelMeshFieldSetAsBackgroundMesh
        procedure, nopass :: setAsBoundaryLayer => &
            gmshModelMeshFieldSetAsBoundaryLayer
      end type gmsh_model_mesh_field_t
    
      type, public :: gmsh_model_mesh_t
        type(gmsh_model_mesh_field_t) :: field
        contains
        procedure, nopass :: generate => &
            gmshModelMeshGenerate
        procedure, nopass :: partition => &
            gmshModelMeshPartition
        procedure, nopass :: unpartition => &
            gmshModelMeshUnpartition
        procedure, nopass :: optimize => &
            gmshModelMeshOptimize
        procedure, nopass :: recombine => &
            gmshModelMeshRecombine
        procedure, nopass :: refine => &
            gmshModelMeshRefine
        procedure, nopass :: setOrder => &
            gmshModelMeshSetOrder
        procedure, nopass :: getLastEntityError => &
            gmshModelMeshGetLastEntityError
        procedure, nopass :: getLastNodeError => &
            gmshModelMeshGetLastNodeError
        procedure, nopass :: clear => &
            gmshModelMeshClear
        procedure, nopass :: removeElements => &
            gmshModelMeshRemoveElements
        procedure, nopass :: reverse => &
            gmshModelMeshReverse
        procedure, nopass :: reverseElements => &
            gmshModelMeshReverseElements
        procedure, nopass :: affineTransform => &
            gmshModelMeshAffineTransform
        procedure, nopass :: getNodes => &
            gmshModelMeshGetNodes
        procedure, nopass :: getNodesByElementType => &
            gmshModelMeshGetNodesByElementType
        procedure, nopass :: getNode => &
            gmshModelMeshGetNode
        procedure, nopass :: setNode => &
            gmshModelMeshSetNode
        procedure, nopass :: rebuildNodeCache => &
            gmshModelMeshRebuildNodeCache
        procedure, nopass :: rebuildElementCache => &
            gmshModelMeshRebuildElementCache
        procedure, nopass :: getNodesForPhysicalGroup => &
            gmshModelMeshGetNodesForPhysicalGroup
        procedure, nopass :: getMaxNodeTag => &
            gmshModelMeshGetMaxNodeTag
        procedure, nopass :: addNodes => &
            gmshModelMeshAddNodes
        procedure, nopass :: reclassifyNodes => &
            gmshModelMeshReclassifyNodes
        procedure, nopass :: relocateNodes => &
            gmshModelMeshRelocateNodes
        procedure, nopass :: getElements => &
            gmshModelMeshGetElements
        procedure, nopass :: getElement => &
            gmshModelMeshGetElement
        procedure, nopass :: getElementByCoordinates => &
            gmshModelMeshGetElementByCoordinates
        procedure, nopass :: getElementsByCoordinates => &
            gmshModelMeshGetElementsByCoordinates
        procedure, nopass :: getLocalCoordinatesInElement => &
            gmshModelMeshGetLocalCoordinatesInElement
        procedure, nopass :: getElementTypes => &
            gmshModelMeshGetElementTypes
        procedure, nopass :: getElementType => &
            gmshModelMeshGetElementType
        procedure, nopass :: getElementProperties => &
            gmshModelMeshGetElementProperties
        procedure, nopass :: getElementsByType => &
            gmshModelMeshGetElementsByType
        procedure, nopass :: getMaxElementTag => &
            gmshModelMeshGetMaxElementTag
        procedure, nopass :: preallocateElementsByType => &
            gmshModelMeshPreallocateElementsByType
        procedure, nopass :: getElementQualities => &
            gmshModelMeshGetElementQualities
        procedure, nopass :: addElements => &
            gmshModelMeshAddElements
        procedure, nopass :: addElementsByType => &
            gmshModelMeshAddElementsByType
        procedure, nopass :: getIntegrationPoints => &
            gmshModelMeshGetIntegrationPoints
        procedure, nopass :: getJacobians => &
            gmshModelMeshGetJacobians
        procedure, nopass :: preallocateJacobians => &
            gmshModelMeshPreallocateJacobians
        procedure, nopass :: getJacobian => &
            gmshModelMeshGetJacobian
        procedure, nopass :: getBasisFunctions => &
            gmshModelMeshGetBasisFunctions
        procedure, nopass :: getBasisFunctionsOrientation => &
            gmshModelMeshGetBasisFunctionsOrientation
        procedure, nopass :: getBasisFunctionsOrientationForElement => &
            gmshModelMeshGetBasisFunctionsOrientationForElement
        procedure, nopass :: getNumberOfOrientations => &
            gmshModelMeshGetNumberOfOrientations
        procedure, nopass :: preallocateBasisFunctionsOrientation => &
            gmshModelMeshPreallocateBasisFunctionsOrientation
        procedure, nopass :: getEdges => &
            gmshModelMeshGetEdges
        procedure, nopass :: getFaces => &
            gmshModelMeshGetFaces
        procedure, nopass :: createEdges => &
            gmshModelMeshCreateEdges
        procedure, nopass :: createFaces => &
            gmshModelMeshCreateFaces
        procedure, nopass :: getAllEdges => &
            gmshModelMeshGetAllEdges
        procedure, nopass :: getAllFaces => &
            gmshModelMeshGetAllFaces
        procedure, nopass :: addEdges => &
            gmshModelMeshAddEdges
        procedure, nopass :: addFaces => &
            gmshModelMeshAddFaces
        procedure, nopass :: getKeys => &
            gmshModelMeshGetKeys
        procedure, nopass :: getKeysForElement => &
            gmshModelMeshGetKeysForElement
        procedure, nopass :: getNumberOfKeys => &
            gmshModelMeshGetNumberOfKeys
        procedure, nopass :: getKeysInformation => &
            gmshModelMeshGetKeysInformation
        procedure, nopass :: getBarycenters => &
            gmshModelMeshGetBarycenters
        procedure, nopass :: preallocateBarycenters => &
            gmshModelMeshPreallocateBarycenters
        procedure, nopass :: getElementEdgeNodes => &
            gmshModelMeshGetElementEdgeNodes
        procedure, nopass :: getElementFaceNodes => &
            gmshModelMeshGetElementFaceNodes
        procedure, nopass :: getGhostElements => &
            gmshModelMeshGetGhostElements
        procedure, nopass :: setSize => &
            gmshModelMeshSetSize
        procedure, nopass :: getSizes => &
            gmshModelMeshGetSizes
        procedure, nopass :: setSizeAtParametricPoints => &
            gmshModelMeshSetSizeAtParametricPoints
        procedure, nopass :: setSizeCallback => &
            gmshModelMeshSetSizeCallback
        procedure, nopass :: removeSizeCallback => &
            gmshModelMeshRemoveSizeCallback
        procedure, nopass :: setTransfiniteCurve => &
            gmshModelMeshSetTransfiniteCurve
        procedure, nopass :: setTransfiniteSurface => &
            gmshModelMeshSetTransfiniteSurface
        procedure, nopass :: setTransfiniteVolume => &
            gmshModelMeshSetTransfiniteVolume
        procedure, nopass :: setTransfiniteAutomatic => &
            gmshModelMeshSetTransfiniteAutomatic
        procedure, nopass :: setRecombine => &
            gmshModelMeshSetRecombine
        procedure, nopass :: setSmoothing => &
            gmshModelMeshSetSmoothing
        procedure, nopass :: setReverse => &
            gmshModelMeshSetReverse
        procedure, nopass :: setAlgorithm => &
            gmshModelMeshSetAlgorithm
        procedure, nopass :: setSizeFromBoundary => &
            gmshModelMeshSetSizeFromBoundary
        procedure, nopass :: setCompound => &
            gmshModelMeshSetCompound
        procedure, nopass :: setOutwardOrientation => &
            gmshModelMeshSetOutwardOrientation
        procedure, nopass :: removeConstraints => &
            gmshModelMeshRemoveConstraints
        procedure, nopass :: embed => &
            gmshModelMeshEmbed
        procedure, nopass :: removeEmbedded => &
            gmshModelMeshRemoveEmbedded
        procedure, nopass :: getEmbedded => &
            gmshModelMeshGetEmbedded
        procedure, nopass :: reorderElements => &
            gmshModelMeshReorderElements
        procedure, nopass :: computeRenumbering => &
            gmshModelMeshComputeRenumbering
        procedure, nopass :: renumberNodes => &
            gmshModelMeshRenumberNodes
        procedure, nopass :: renumberElements => &
            gmshModelMeshRenumberElements
        procedure, nopass :: setPeriodic => &
            gmshModelMeshSetPeriodic
        procedure, nopass :: getPeriodic => &
            gmshModelMeshGetPeriodic
        procedure, nopass :: getPeriodicNodes => &
            gmshModelMeshGetPeriodicNodes
        procedure, nopass :: getPeriodicKeys => &
            gmshModelMeshGetPeriodicKeys
        procedure, nopass :: importStl => &
            gmshModelMeshImportStl
        procedure, nopass :: getDuplicateNodes => &
            gmshModelMeshGetDuplicateNodes
        procedure, nopass :: removeDuplicateNodes => &
            gmshModelMeshRemoveDuplicateNodes
        procedure, nopass :: removeDuplicateElements => &
            gmshModelMeshRemoveDuplicateElements
        procedure, nopass :: splitQuadrangles => &
            gmshModelMeshSplitQuadrangles
        procedure, nopass :: setVisibility => &
            gmshModelMeshSetVisibility
        procedure, nopass :: getVisibility => &
            gmshModelMeshGetVisibility
        procedure, nopass :: classifySurfaces => &
            gmshModelMeshClassifySurfaces
        procedure, nopass :: createGeometry => &
            gmshModelMeshCreateGeometry
        procedure, nopass :: createTopology => &
            gmshModelMeshCreateTopology
        procedure, nopass :: addHomologyRequest => &
            gmshModelMeshAddHomologyRequest
        procedure, nopass :: clearHomologyRequests => &
            gmshModelMeshClearHomologyRequests
        procedure, nopass :: computeHomology => &
            gmshModelMeshComputeHomology
        procedure, nopass :: computeCrossField => &
            gmshModelMeshComputeCrossField
        procedure, nopass :: triangulate => &
            gmshModelMeshTriangulate
        procedure, nopass :: tetrahedralize => &
            gmshModelMeshTetrahedralize
      end type gmsh_model_mesh_t
    
      type, public :: gmsh_model_t
        type(gmsh_model_mesh_t) :: mesh
        type(gmsh_model_geo_t) :: geo
        type(gmsh_model_occ_t) :: occ
        contains
        procedure, nopass :: add => &
            gmshModelAdd
        procedure, nopass :: remove => &
            gmshModelRemove
        procedure, nopass :: list => &
            gmshModelList
        procedure, nopass :: getCurrent => &
            gmshModelGetCurrent
        procedure, nopass :: setCurrent => &
            gmshModelSetCurrent
        procedure, nopass :: getFileName => &
            gmshModelGetFileName
        procedure, nopass :: setFileName => &
            gmshModelSetFileName
        procedure, nopass :: getEntities => &
            gmshModelGetEntities
        procedure, nopass :: setEntityName => &
            gmshModelSetEntityName
        procedure, nopass :: getEntityName => &
            gmshModelGetEntityName
        procedure, nopass :: removeEntityName => &
            gmshModelRemoveEntityName
        procedure, nopass :: getPhysicalGroups => &
            gmshModelGetPhysicalGroups
        procedure, nopass :: getEntitiesForPhysicalGroup => &
            gmshModelGetEntitiesForPhysicalGroup
        procedure, nopass :: getEntitiesForPhysicalName => &
            gmshModelGetEntitiesForPhysicalName
        procedure, nopass :: getPhysicalGroupsForEntity => &
            gmshModelGetPhysicalGroupsForEntity
        procedure, nopass :: addPhysicalGroup => &
            gmshModelAddPhysicalGroup
        procedure, nopass :: removePhysicalGroups => &
            gmshModelRemovePhysicalGroups
        procedure, nopass :: setPhysicalName => &
            gmshModelSetPhysicalName
        procedure, nopass :: getPhysicalName => &
            gmshModelGetPhysicalName
        procedure, nopass :: removePhysicalName => &
            gmshModelRemovePhysicalName
        procedure, nopass :: setTag => &
            gmshModelSetTag
        procedure, nopass :: getBoundary => &
            gmshModelGetBoundary
        procedure, nopass :: getAdjacencies => &
            gmshModelGetAdjacencies
        procedure, nopass :: getEntitiesInBoundingBox => &
            gmshModelGetEntitiesInBoundingBox
        procedure, nopass :: getBoundingBox => &
            gmshModelGetBoundingBox
        procedure, nopass :: getDimension => &
            gmshModelGetDimension
        procedure, nopass :: addDiscreteEntity => &
            gmshModelAddDiscreteEntity
        procedure, nopass :: removeEntities => &
            gmshModelRemoveEntities
        procedure, nopass :: getType => &
            gmshModelGetType
        procedure, nopass :: getParent => &
            gmshModelGetParent
        procedure, nopass :: getNumberOfPartitions => &
            gmshModelGetNumberOfPartitions
        procedure, nopass :: getPartitions => &
            gmshModelGetPartitions
        procedure, nopass :: getValue => &
            gmshModelGetValue
        procedure, nopass :: getDerivative => &
            gmshModelGetDerivative
        procedure, nopass :: getSecondDerivative => &
            gmshModelGetSecondDerivative
        procedure, nopass :: getCurvature => &
            gmshModelGetCurvature
        procedure, nopass :: getPrincipalCurvatures => &
            gmshModelGetPrincipalCurvatures
        procedure, nopass :: getNormal => &
            gmshModelGetNormal
        procedure, nopass :: getParametrization => &
            gmshModelGetParametrization
        procedure, nopass :: getParametrizationBounds => &
            gmshModelGetParametrizationBounds
        procedure, nopass :: isInside => &
            gmshModelIsInside
        procedure, nopass :: getClosestPoint => &
            gmshModelGetClosestPoint
        procedure, nopass :: reparametrizeOnSurface => &
            gmshModelReparametrizeOnSurface
        procedure, nopass :: setVisibility => &
            gmshModelSetVisibility
        procedure, nopass :: getVisibility => &
            gmshModelGetVisibility
        procedure, nopass :: setVisibilityPerWindow => &
            gmshModelSetVisibilityPerWindow
        procedure, nopass :: setColor => &
            gmshModelSetColor
        procedure, nopass :: getColor => &
            gmshModelGetColor
        procedure, nopass :: setCoordinates => &
            gmshModelSetCoordinates
        procedure, nopass :: setAttribute => &
            gmshModelSetAttribute
        procedure, nopass :: getAttribute => &
            gmshModelGetAttribute
        procedure, nopass :: getAttributeNames => &
            gmshModelGetAttributeNames
        procedure, nopass :: removeAttribute => &
            gmshModelRemoveAttribute
      end type gmsh_model_t
    
      type, public :: gmsh_option_t
        contains
        procedure, nopass :: setNumber => &
            gmshOptionSetNumber
        procedure, nopass :: getNumber => &
            gmshOptionGetNumber
        procedure, nopass :: setString => &
            gmshOptionSetString
        procedure, nopass :: getString => &
            gmshOptionGetString
        procedure, nopass :: setColor => &
            gmshOptionSetColor
        procedure, nopass :: getColor => &
            gmshOptionGetColor
        procedure, nopass :: restoreDefaults => &
            gmshOptionRestoreDefaults
      end type gmsh_option_t
    
      type, public :: gmsh_t
        type(gmsh_option_t) :: option
        type(gmsh_model_t) :: model
        type(gmsh_view_t) :: view
        type(gmsh_plugin_t) :: plugin
        type(gmsh_graphics_t) :: graphics
        type(gmsh_fltk_t) :: fltk
        type(gmsh_parser_t) :: parser
        type(gmsh_onelab_t) :: onelab
        type(gmsh_logger_t) :: logger
        contains
        procedure, nopass :: initialize => &
            gmshInitialize
        procedure, nopass :: isInitialized => &
            gmshIsInitialized
        procedure, nopass :: finalize => &
            gmshFinalize
        procedure, nopass :: open => &
            gmshOpen
        procedure, nopass :: merge => &
            gmshMerge
        procedure, nopass :: write => &
            gmshWrite
        procedure, nopass :: clear => &
            gmshClear
      end type gmsh_t
    
      contains
    
      !> Initialize the Gmsh API. This must be called before any call to the other
      !! functions in the API. If `argc' and `argv' (or just `argv' in Python or
      !! Julia) are provided, they will be handled in the same way as the command
      !! line arguments in the Gmsh app. If `readConfigFiles' is set, read system
      !! Gmsh configuration files (gmshrc and gmsh-options). If `run' is set, run in
      !! the same way as the Gmsh app, either interactively or in batch mode
      !! depending on the command line arguments. If `run' is not set, initializing
      !! the API sets the options "General.AbortOnError" to 2 and "General.Terminal"
      !! to 1.
      subroutine gmshInitialize(argv, &
                                readConfigFiles, &
                                run, &
                                ierr)
        interface
        subroutine C_API(argc, &
                         argv, &
                         readConfigFiles, &
                         run, &
                         ierr_) &
          bind(C, name="gmshInitialize")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: argc
          type(c_ptr), dimension(*), intent(in) :: argv
          integer(c_int), value, intent(in) :: readConfigFiles
          integer(c_int), value, intent(in) :: run
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), dimension(:), intent(in), optional :: argv
        logical, intent(in), optional :: readConfigFiles
        logical, intent(in), optional :: run
        integer(c_int), intent(out), optional :: ierr
        character(len=GMSH_API_MAX_STR_LEN, kind=c_char), allocatable :: argv_strs(:)
        type(c_ptr), allocatable :: argv_cptr(:)
        call ivectorstring_(optval_str_array(def=[''], val=argv), argv_strs, argv_cptr)
        call C_API(argc=size_gmsh_str_array(argv), argv=argv_cptr, &
             readConfigFiles=optval_c_bool(.true., readConfigFiles), &
             run=optval_c_bool(.false., run), &
             ierr_=ierr)
      end subroutine gmshInitialize
    
      !> Return 1 if the Gmsh API is initialized, and 0 if not.
      function gmshIsInitialized(ierr)
        interface
        function C_API(ierr_) &
          bind(C, name="gmshIsInitialized")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshIsInitialized
        integer(c_int), intent(out), optional :: ierr
        gmshIsInitialized = C_API(ierr_=ierr)
      end function gmshIsInitialized
    
      !> Finalize the Gmsh API. This must be called when you are done using the Gmsh
      !! API.
      subroutine gmshFinalize(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshFinalize")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshFinalize
    
      !> Open a file. Equivalent to the `File->Open' menu in the Gmsh app. Handling
      !! of the file depends on its extension and/or its contents: opening a file
      !! with model data will create a new model.
      subroutine gmshOpen(fileName, &
                          ierr)
        interface
        subroutine C_API(fileName, &
                         ierr_) &
          bind(C, name="gmshOpen")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: fileName
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: fileName
        integer(c_int), intent(out), optional :: ierr
        call C_API(fileName=istring_(fileName), &
             ierr_=ierr)
      end subroutine gmshOpen
    
      !> Merge a file. Equivalent to the `File->Merge' menu in the Gmsh app.
      !! Handling of the file depends on its extension and/or its contents. Merging
      !! a file with model data will add the data to the current model.
      subroutine gmshMerge(fileName, &
                           ierr)
        interface
        subroutine C_API(fileName, &
                         ierr_) &
          bind(C, name="gmshMerge")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: fileName
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: fileName
        integer(c_int), intent(out), optional :: ierr
        call C_API(fileName=istring_(fileName), &
             ierr_=ierr)
      end subroutine gmshMerge
    
      !> Write a file. The export format is determined by the file extension.
      subroutine gmshWrite(fileName, &
                           ierr)
        interface
        subroutine C_API(fileName, &
                         ierr_) &
          bind(C, name="gmshWrite")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: fileName
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: fileName
        integer(c_int), intent(out), optional :: ierr
        call C_API(fileName=istring_(fileName), &
             ierr_=ierr)
      end subroutine gmshWrite
    
      !> Clear all loaded models and post-processing data, and add a new empty
      !! model.
      subroutine gmshClear(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshClear")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshClear
    
      !> Set a numerical option to `value'. `name' is of the form "Category.Option"
      !! or "Category[num].Option". Available categories and options are listed in
      !! the "Gmsh options" chapter of the Gmsh reference manual
      !! (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-options).
      subroutine gmshOptionSetNumber(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         value, &
                         ierr_) &
          bind(C, name="gmshOptionSetNumber")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          real(c_double), value, intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        real(c_double), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             value=real(value, c_double), &
             ierr_=ierr)
      end subroutine gmshOptionSetNumber
    
      !> Get the `value' of a numerical option. `name' is of the form
      !! "Category.Option" or "Category[num].Option". Available categories and
      !! options are listed in the "Gmsh options" chapter of the Gmsh reference
      !! manual (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-options).
      subroutine gmshOptionGetNumber(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         value, &
                         ierr_) &
          bind(C, name="gmshOptionGetNumber")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          real(c_double) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        real(c_double) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             value=value, &
             ierr_=ierr)
      end subroutine gmshOptionGetNumber
    
      !> Set a string option to `value'. `name' is of the form "Category.Option" or
      !! "Category[num].Option". Available categories and options are listed in the
      !! "Gmsh options" chapter of the Gmsh reference manual
      !! (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-options).
      subroutine gmshOptionSetString(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         value, &
                         ierr_) &
          bind(C, name="gmshOptionSetString")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          character(len=1, kind=c_char), dimension(*), intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=*), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             value=istring_(value), &
             ierr_=ierr)
      end subroutine gmshOptionSetString
    
      !> Get the `value' of a string option. `name' is of the form "Category.Option"
      !! or "Category[num].Option". Available categories and options are listed in
      !! the "Gmsh options" chapter of the Gmsh reference manual
      !! (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-options).
      subroutine gmshOptionGetString(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         ierr_) &
          bind(C, name="gmshOptionGetString")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), intent(out) :: api_value_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=:), allocatable, intent(out) :: value
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_value_
        call C_API(name=istring_(name), &
             api_value_=api_value_, &
             ierr_=ierr)
        value = ostring_(api_value_)
      end subroutine gmshOptionGetString
    
      !> Set a color option to the RGBA value (`r', `g', `b', `a'), where where `r',
      !! `g', `b' and `a' should be integers between 0 and 255. `name' is of the
      !! form "Category.Color.Option" or "Category[num].Color.Option". Available
      !! categories and options are listed in the "Gmsh options" chapter of the Gmsh
      !! reference manual (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-options).
      !! For conciseness "Color." can be ommitted in `name'.
      subroutine gmshOptionSetColor(name, &
                                    r, &
                                    g, &
                                    b, &
                                    a, &
                                    ierr)
        interface
        subroutine C_API(name, &
                         r, &
                         g, &
                         b, &
                         a, &
                         ierr_) &
          bind(C, name="gmshOptionSetColor")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), value, intent(in) :: r
          integer(c_int), value, intent(in) :: g
          integer(c_int), value, intent(in) :: b
          integer(c_int), value, intent(in) :: a
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer, intent(in) :: r
        integer, intent(in) :: g
        integer, intent(in) :: b
        integer, intent(in), optional :: a
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             r=int(r, c_int), &
             g=int(g, c_int), &
             b=int(b, c_int), &
             a=optval_c_int(255, a), &
             ierr_=ierr)
      end subroutine gmshOptionSetColor
    
      !> Get the `r', `g', `b', `a' value of a color option. `name' is of the form
      !! "Category.Color.Option" or "Category[num].Color.Option". Available
      !! categories and options are listed in the "Gmsh options" chapter of the Gmsh
      !! reference manual (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-options).
      !! For conciseness "Color." can be ommitted in `name'.
      subroutine gmshOptionGetColor(name, &
                                    r, &
                                    g, &
                                    b, &
                                    a, &
                                    ierr)
        interface
        subroutine C_API(name, &
                         r, &
                         g, &
                         b, &
                         a, &
                         ierr_) &
          bind(C, name="gmshOptionGetColor")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int) :: r
          integer(c_int) :: g
          integer(c_int) :: b
          integer(c_int) :: a
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int) :: r
        integer(c_int) :: g
        integer(c_int) :: b
        integer(c_int) :: a
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             r=r, &
             g=g, &
             b=b, &
             a=a, &
             ierr_=ierr)
      end subroutine gmshOptionGetColor
    
      !> Restore all options to default settings.
      subroutine gmshOptionRestoreDefaults(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshOptionRestoreDefaults")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshOptionRestoreDefaults
    
      !> Add a new model, with name `name', and set it as the current model.
      subroutine gmshModelAdd(name, &
                              ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshModelAdd")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshModelAdd
    
      !> Remove the current model.
      subroutine gmshModelRemove(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelRemove")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelRemove
    
      !> List the names of all models.
      subroutine gmshModelList(names, &
                               ierr)
        interface
        subroutine C_API(api_names_, &
                         api_names_n_, &
                         ierr_) &
          bind(C, name="gmshModelList")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_names_
          integer(c_size_t), intent(out) :: api_names_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: names
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_names_
        integer(c_size_t) :: api_names_n_
        call C_API(api_names_=api_names_, &
             api_names_n_=api_names_n_, &
             ierr_=ierr)
        names = ovectorstring_(api_names_, &
          api_names_n_)
      end subroutine gmshModelList
    
      !> Get the name of the current model.
      subroutine gmshModelGetCurrent(name, &
                                     ierr)
        interface
        subroutine C_API(api_name_, &
                         ierr_) &
          bind(C, name="gmshModelGetCurrent")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_name_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=:), allocatable, intent(out) :: name
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_name_
        call C_API(api_name_=api_name_, &
             ierr_=ierr)
        name = ostring_(api_name_)
      end subroutine gmshModelGetCurrent
    
      !> Set the current model to the model with name `name'. If several models have
      !! the same name, select the one that was added first.
      subroutine gmshModelSetCurrent(name, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshModelSetCurrent")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshModelSetCurrent
    
      !> Get the file name (if any) associated with the current model. A file name
      !! is associated when a model is read from a file on disk.
      subroutine gmshModelGetFileName(fileName, &
                                      ierr)
        interface
        subroutine C_API(api_fileName_, &
                         ierr_) &
          bind(C, name="gmshModelGetFileName")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_fileName_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=:), allocatable, intent(out) :: fileName
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_fileName_
        call C_API(api_fileName_=api_fileName_, &
             ierr_=ierr)
        fileName = ostring_(api_fileName_)
      end subroutine gmshModelGetFileName
    
      !> Set the file name associated with the current model.
      subroutine gmshModelSetFileName(fileName, &
                                      ierr)
        interface
        subroutine C_API(fileName, &
                         ierr_) &
          bind(C, name="gmshModelSetFileName")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: fileName
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: fileName
        integer(c_int), intent(out), optional :: ierr
        call C_API(fileName=istring_(fileName), &
             ierr_=ierr)
      end subroutine gmshModelSetFileName
    
      !> Get all the entities in the current model. A model entity is represented by
      !! two integers: its dimension (dim == 0, 1, 2 or 3) and its tag (its unique,
      !! strictly positive identifier). If `dim' is >= 0, return only the entities
      !! of the specified dimension (e.g. points if `dim' == 0). The entities are
      !! returned as a vector of (dim, tag) pairs.
      subroutine gmshModelGetEntities(dimTags, &
                                      dim, &
                                      ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         dim, &
                         ierr_) &
          bind(C, name="gmshModelGetEntities")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             dim=optval_c_int(-1, dim), &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelGetEntities
    
      !> Set the name of the entity of dimension `dim' and tag `tag'.
      subroutine gmshModelSetEntityName(dim, &
                                        tag, &
                                        name, &
                                        ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         name, &
                         ierr_) &
          bind(C, name="gmshModelSetEntityName")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshModelSetEntityName
    
      !> Get the name of the entity of dimension `dim' and tag `tag'.
      subroutine gmshModelGetEntityName(dim, &
                                        tag, &
                                        name, &
                                        ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_name_, &
                         ierr_) &
          bind(C, name="gmshModelGetEntityName")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_name_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        character(len=:), allocatable, intent(out) :: name
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_name_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_name_=api_name_, &
             ierr_=ierr)
        name = ostring_(api_name_)
      end subroutine gmshModelGetEntityName
    
      !> Remove the entity name `name' from the current model.
      subroutine gmshModelRemoveEntityName(name, &
                                           ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshModelRemoveEntityName")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshModelRemoveEntityName
    
      !> Get all the physical groups in the current model. If `dim' is >= 0, return
      !! only the entities of the specified dimension (e.g. physical points if `dim'
      !! == 0). The entities are returned as a vector of (dim, tag) pairs.
      subroutine gmshModelGetPhysicalGroups(dimTags, &
                                            dim, &
                                            ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         dim, &
                         ierr_) &
          bind(C, name="gmshModelGetPhysicalGroups")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             dim=optval_c_int(-1, dim), &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelGetPhysicalGroups
    
      !> Get the tags of the model entities making up the physical group of
      !! dimension `dim' and tag `tag'.
      subroutine gmshModelGetEntitiesForPhysicalGroup(dim, &
                                                      tag, &
                                                      tags, &
                                                      ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_tags_, &
                         api_tags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetEntitiesForPhysicalGroup")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_tags_
          integer(c_size_t), intent(out) :: api_tags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int), dimension(:), allocatable, intent(out) :: tags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_tags_
        integer(c_size_t) :: api_tags_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_tags_=api_tags_, &
             api_tags_n_=api_tags_n_, &
             ierr_=ierr)
        tags = ovectorint_(api_tags_, &
          api_tags_n_)
      end subroutine gmshModelGetEntitiesForPhysicalGroup
    
      !> Get the model entities (as a vector (dim, tag) pairs) making up the
      !! physical group with name `name'.
      subroutine gmshModelGetEntitiesForPhysicalName(name, &
                                                     dimTags, &
                                                     ierr)
        interface
        subroutine C_API(name, &
                         api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetEntitiesForPhysicalName")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(name=istring_(name), &
             api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelGetEntitiesForPhysicalName
    
      !> Get the tags of the physical groups (if any) to which the model entity of
      !! dimension `dim' and tag `tag' belongs.
      subroutine gmshModelGetPhysicalGroupsForEntity(dim, &
                                                     tag, &
                                                     physicalTags, &
                                                     ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_physicalTags_, &
                         api_physicalTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetPhysicalGroupsForEntity")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_physicalTags_
          integer(c_size_t), intent(out) :: api_physicalTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int), dimension(:), allocatable, intent(out) :: physicalTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_physicalTags_
        integer(c_size_t) :: api_physicalTags_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_physicalTags_=api_physicalTags_, &
             api_physicalTags_n_=api_physicalTags_n_, &
             ierr_=ierr)
        physicalTags = ovectorint_(api_physicalTags_, &
          api_physicalTags_n_)
      end subroutine gmshModelGetPhysicalGroupsForEntity
    
      !> Add a physical group of dimension `dim', grouping the model entities with
      !! tags `tags'. Return the tag of the physical group, equal to `tag' if `tag'
      !! is positive, or a new tag if `tag' < 0. Set the name of the physical group
      !! if `name' is not empty.
      function gmshModelAddPhysicalGroup(dim, &
                                         tags, &
                                         tag, &
                                         name, &
                                         ierr)
        interface
        function C_API(dim, &
                       api_tags_, &
                       api_tags_n_, &
                       tag, &
                       name, &
                       ierr_) &
          bind(C, name="gmshModelAddPhysicalGroup")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: dim
          integer(c_int), dimension(*) :: api_tags_
          integer(c_size_t), value, intent(in) :: api_tags_n_
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: name
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelAddPhysicalGroup
        integer, intent(in) :: dim
        integer(c_int), dimension(:), intent(in) :: tags
        integer, intent(in), optional :: tag
        character(len=*), intent(in), optional :: name
        integer(c_int), intent(out), optional :: ierr
        gmshModelAddPhysicalGroup = C_API(dim=int(dim, c_int), &
                                    api_tags_=tags, &
                                    api_tags_n_=size_gmsh_int(tags), &
                                    tag=optval_c_int(-1, tag), &
                                    name=istring_(optval_c_str("", name)), &
                                    ierr_=ierr)
      end function gmshModelAddPhysicalGroup
    
      !> Remove the physical groups `dimTags' (given as a vector of (dim, tag)
      !! pairs) from the current model. If `dimTags' is empty, remove all groups.
      subroutine gmshModelRemovePhysicalGroups(dimTags, &
                                               ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelRemovePhysicalGroups")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelRemovePhysicalGroups
    
      !> Set the name of the physical group of dimension `dim' and tag `tag'.
      subroutine gmshModelSetPhysicalName(dim, &
                                          tag, &
                                          name, &
                                          ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         name, &
                         ierr_) &
          bind(C, name="gmshModelSetPhysicalName")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshModelSetPhysicalName
    
      !> Get the name of the physical group of dimension `dim' and tag `tag'.
      subroutine gmshModelGetPhysicalName(dim, &
                                          tag, &
                                          name, &
                                          ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_name_, &
                         ierr_) &
          bind(C, name="gmshModelGetPhysicalName")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_name_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        character(len=:), allocatable, intent(out) :: name
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_name_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_name_=api_name_, &
             ierr_=ierr)
        name = ostring_(api_name_)
      end subroutine gmshModelGetPhysicalName
    
      !> Remove the physical name `name' from the current model.
      subroutine gmshModelRemovePhysicalName(name, &
                                             ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshModelRemovePhysicalName")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshModelRemovePhysicalName
    
      !> Set the tag of the entity of dimension `dim' and tag `tag' to the new value
      !! `newTag'.
      subroutine gmshModelSetTag(dim, &
                                 tag, &
                                 newTag, &
                                 ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         newTag, &
                         ierr_) &
          bind(C, name="gmshModelSetTag")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: newTag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer, intent(in) :: newTag
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             newTag=int(newTag, c_int), &
             ierr_=ierr)
      end subroutine gmshModelSetTag
    
      !> Get the boundary of the model entities `dimTags', given as a vector of
      !! (dim, tag) pairs. Return in `outDimTags' the boundary of the individual
      !! entities (if `combined' is false) or the boundary of the combined
      !! geometrical shape formed by all input entities (if `combined' is true).
      !! Return tags multiplied by the sign of the boundary entity if `oriented' is
      !! true. Apply the boundary operator recursively down to dimension 0 (i.e. to
      !! points) if `recursive' is true.
      subroutine gmshModelGetBoundary(dimTags, &
                                      outDimTags, &
                                      combined, &
                                      oriented, &
                                      recursive, &
                                      ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         combined, &
                         oriented, &
                         recursive, &
                         ierr_) &
          bind(C, name="gmshModelGetBoundary")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), value, intent(in) :: combined
          integer(c_int), value, intent(in) :: oriented
          integer(c_int), value, intent(in) :: recursive
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        logical, intent(in), optional :: combined
        logical, intent(in), optional :: oriented
        logical, intent(in), optional :: recursive
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             combined=optval_c_bool(.true., combined), &
             oriented=optval_c_bool(.true., oriented), &
             recursive=optval_c_bool(.false., recursive), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelGetBoundary
    
      !> Get the upward and downward adjacencies of the model entity of dimension
      !! `dim' and tag `tag'. The `upward' vector returns the tags of adjacent
      !! entities of dimension `dim' + 1; the `downward' vector returns the tags of
      !! adjacent entities of dimension `dim' - 1.
      subroutine gmshModelGetAdjacencies(dim, &
                                         tag, &
                                         upward, &
                                         downward, &
                                         ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_upward_, &
                         api_upward_n_, &
                         api_downward_, &
                         api_downward_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetAdjacencies")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_upward_
          integer(c_size_t), intent(out) :: api_upward_n_
          type(c_ptr), intent(out) :: api_downward_
          integer(c_size_t), intent(out) :: api_downward_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int), dimension(:), allocatable, intent(out) :: upward
        integer(c_int), dimension(:), allocatable, intent(out) :: downward
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_upward_
        integer(c_size_t) :: api_upward_n_
        type(c_ptr) :: api_downward_
        integer(c_size_t) :: api_downward_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_upward_=api_upward_, &
             api_upward_n_=api_upward_n_, &
             api_downward_=api_downward_, &
             api_downward_n_=api_downward_n_, &
             ierr_=ierr)
        upward = ovectorint_(api_upward_, &
          api_upward_n_)
        downward = ovectorint_(api_downward_, &
          api_downward_n_)
      end subroutine gmshModelGetAdjacencies
    
      !> Get the model entities in the bounding box defined by the two points
      !! (`xmin', `ymin', `zmin') and (`xmax', `ymax', `zmax'). If `dim' is >= 0,
      !! return only the entities of the specified dimension (e.g. points if `dim'
      !! == 0).
      subroutine gmshModelGetEntitiesInBoundingBox(xmin, &
                                                   ymin, &
                                                   zmin, &
                                                   xmax, &
                                                   ymax, &
                                                   zmax, &
                                                   dimTags, &
                                                   dim, &
                                                   ierr)
        interface
        subroutine C_API(xmin, &
                         ymin, &
                         zmin, &
                         xmax, &
                         ymax, &
                         zmax, &
                         api_dimTags_, &
                         api_dimTags_n_, &
                         dim, &
                         ierr_) &
          bind(C, name="gmshModelGetEntitiesInBoundingBox")
          use, intrinsic :: iso_c_binding
          real(c_double), value, intent(in) :: xmin
          real(c_double), value, intent(in) :: ymin
          real(c_double), value, intent(in) :: zmin
          real(c_double), value, intent(in) :: xmax
          real(c_double), value, intent(in) :: ymax
          real(c_double), value, intent(in) :: zmax
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), intent(in) :: xmin
        real(c_double), intent(in) :: ymin
        real(c_double), intent(in) :: zmin
        real(c_double), intent(in) :: xmax
        real(c_double), intent(in) :: ymax
        real(c_double), intent(in) :: zmax
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(xmin=real(xmin, c_double), &
             ymin=real(ymin, c_double), &
             zmin=real(zmin, c_double), &
             xmax=real(xmax, c_double), &
             ymax=real(ymax, c_double), &
             zmax=real(zmax, c_double), &
             api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             dim=optval_c_int(-1, dim), &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelGetEntitiesInBoundingBox
    
      !> Get the bounding box (`xmin', `ymin', `zmin'), (`xmax', `ymax', `zmax') of
      !! the model entity of dimension `dim' and tag `tag'. If `dim' and `tag' are
      !! negative, get the bounding box of the whole model.
      subroutine gmshModelGetBoundingBox(dim, &
                                         tag, &
                                         xmin, &
                                         ymin, &
                                         zmin, &
                                         xmax, &
                                         ymax, &
                                         zmax, &
                                         ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         xmin, &
                         ymin, &
                         zmin, &
                         xmax, &
                         ymax, &
                         zmax, &
                         ierr_) &
          bind(C, name="gmshModelGetBoundingBox")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double) :: xmin
          real(c_double) :: ymin
          real(c_double) :: zmin
          real(c_double) :: xmax
          real(c_double) :: ymax
          real(c_double) :: zmax
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double) :: xmin
        real(c_double) :: ymin
        real(c_double) :: zmin
        real(c_double) :: xmax
        real(c_double) :: ymax
        real(c_double) :: zmax
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             xmin=xmin, &
             ymin=ymin, &
             zmin=zmin, &
             xmax=xmax, &
             ymax=ymax, &
             zmax=zmax, &
             ierr_=ierr)
      end subroutine gmshModelGetBoundingBox
    
      !> Return the geometrical dimension of the current model.
      function gmshModelGetDimension(ierr)
        interface
        function C_API(ierr_) &
          bind(C, name="gmshModelGetDimension")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGetDimension
        integer(c_int), intent(out), optional :: ierr
        gmshModelGetDimension = C_API(ierr_=ierr)
      end function gmshModelGetDimension
    
      !> Add a discrete model entity (defined by a mesh) of dimension `dim' in the
      !! current model. Return the tag of the new discrete entity, equal to `tag' if
      !! `tag' is positive, or a new tag if `tag' < 0. `boundary' specifies the tags
      !! of the entities on the boundary of the discrete entity, if any. Specifying
      !! `boundary' allows Gmsh to construct the topology of the overall model.
      function gmshModelAddDiscreteEntity(dim, &
                                          tag, &
                                          boundary, &
                                          ierr)
        interface
        function C_API(dim, &
                       tag, &
                       api_boundary_, &
                       api_boundary_n_, &
                       ierr_) &
          bind(C, name="gmshModelAddDiscreteEntity")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), dimension(*), optional :: api_boundary_
          integer(c_size_t), value, intent(in) :: api_boundary_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelAddDiscreteEntity
        integer, intent(in) :: dim
        integer, intent(in), optional :: tag
        integer(c_int), dimension(:), intent(in), optional :: boundary
        integer(c_int), intent(out), optional :: ierr
        gmshModelAddDiscreteEntity = C_API(dim=int(dim, c_int), &
                                     tag=optval_c_int(-1, tag), &
                                     api_boundary_=boundary, &
                                     api_boundary_n_=size_gmsh_int(boundary), &
                                     ierr_=ierr)
      end function gmshModelAddDiscreteEntity
    
      !> Remove the entities `dimTags' (given as a vector of (dim, tag) pairs) of
      !! the current model, provided that they are not on the boundary of (or
      !! embedded in) higher-dimensional entities. If `recursive' is true, remove
      !! all the entities on their boundaries, down to dimension 0.
      subroutine gmshModelRemoveEntities(dimTags, &
                                         recursive, &
                                         ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         recursive, &
                         ierr_) &
          bind(C, name="gmshModelRemoveEntities")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: recursive
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        logical, intent(in), optional :: recursive
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             recursive=optval_c_bool(.false., recursive), &
             ierr_=ierr)
      end subroutine gmshModelRemoveEntities
    
      !> Get the type of the entity of dimension `dim' and tag `tag'.
      subroutine gmshModelGetType(dim, &
                                  tag, &
                                  entityType, &
                                  ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_entityType_, &
                         ierr_) &
          bind(C, name="gmshModelGetType")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_entityType_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        character(len=:), allocatable, intent(out) :: entityType
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_entityType_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_entityType_=api_entityType_, &
             ierr_=ierr)
        entityType = ostring_(api_entityType_)
      end subroutine gmshModelGetType
    
      !> In a partitioned model, get the parent of the entity of dimension `dim' and
      !! tag `tag', i.e. from which the entity is a part of, if any. `parentDim' and
      !! `parentTag' are set to -1 if the entity has no parent.
      subroutine gmshModelGetParent(dim, &
                                    tag, &
                                    parentDim, &
                                    parentTag, &
                                    ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         parentDim, &
                         parentTag, &
                         ierr_) &
          bind(C, name="gmshModelGetParent")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int) :: parentDim
          integer(c_int) :: parentTag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int) :: parentDim
        integer(c_int) :: parentTag
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             parentDim=parentDim, &
             parentTag=parentTag, &
             ierr_=ierr)
      end subroutine gmshModelGetParent
    
      !> Return the number of partitions in the model.
      function gmshModelGetNumberOfPartitions(ierr)
        interface
        function C_API(ierr_) &
          bind(C, name="gmshModelGetNumberOfPartitions")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGetNumberOfPartitions
        integer(c_int), intent(out), optional :: ierr
        gmshModelGetNumberOfPartitions = C_API(ierr_=ierr)
      end function gmshModelGetNumberOfPartitions
    
      !> In a partitioned model, return the tags of the partition(s) to which the
      !! entity belongs.
      subroutine gmshModelGetPartitions(dim, &
                                        tag, &
                                        partitions, &
                                        ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_partitions_, &
                         api_partitions_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetPartitions")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_partitions_
          integer(c_size_t), intent(out) :: api_partitions_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int), dimension(:), allocatable, intent(out) :: partitions
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_partitions_
        integer(c_size_t) :: api_partitions_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_partitions_=api_partitions_, &
             api_partitions_n_=api_partitions_n_, &
             ierr_=ierr)
        partitions = ovectorint_(api_partitions_, &
          api_partitions_n_)
      end subroutine gmshModelGetPartitions
    
      !> Evaluate the parametrization of the entity of dimension `dim' and tag `tag'
      !! at the parametric coordinates `parametricCoord'. Only valid for `dim' equal
      !! to 0 (with empty `parametricCoord'), 1 (with `parametricCoord' containing
      !! parametric coordinates on the curve) or 2 (with `parametricCoord'
      !! containing u, v parametric coordinates on the surface, concatenated: [p1u,
      !! p1v, p2u, ...]). Return x, y, z coordinates in `coord', concatenated: [p1x,
      !! p1y, p1z, p2x, ...].
      subroutine gmshModelGetValue(dim, &
                                   tag, &
                                   parametricCoord, &
                                   coord, &
                                   ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetValue")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: parametricCoord
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             ierr_=ierr)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
      end subroutine gmshModelGetValue
    
      !> Evaluate the derivative of the parametrization of the entity of dimension
      !! `dim' and tag `tag' at the parametric coordinates `parametricCoord'. Only
      !! valid for `dim' equal to 1 (with `parametricCoord' containing parametric
      !! coordinates on the curve) or 2 (with `parametricCoord' containing u, v
      !! parametric coordinates on the surface, concatenated: [p1u, p1v, p2u, ...]).
      !! For `dim' equal to 1 return the x, y, z components of the derivative with
      !! respect to u [d1ux, d1uy, d1uz, d2ux, ...]; for `dim' equal to 2 return the
      !! x, y, z components of the derivative with respect to u and v: [d1ux, d1uy,
      !! d1uz, d1vx, d1vy, d1vz, d2ux, ...].
      subroutine gmshModelGetDerivative(dim, &
                                        tag, &
                                        parametricCoord, &
                                        derivatives, &
                                        ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         api_derivatives_, &
                         api_derivatives_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetDerivative")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          type(c_ptr), intent(out) :: api_derivatives_
          integer(c_size_t) :: api_derivatives_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: parametricCoord
        real(c_double), dimension(:), allocatable, intent(out) :: derivatives
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_derivatives_
        integer(c_size_t) :: api_derivatives_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             api_derivatives_=api_derivatives_, &
             api_derivatives_n_=api_derivatives_n_, &
             ierr_=ierr)
        derivatives = ovectordouble_(api_derivatives_, &
          api_derivatives_n_)
      end subroutine gmshModelGetDerivative
    
      !> Evaluate the second derivative of the parametrization of the entity of
      !! dimension `dim' and tag `tag' at the parametric coordinates
      !! `parametricCoord'. Only valid for `dim' equal to 1 (with `parametricCoord'
      !! containing parametric coordinates on the curve) or 2 (with
      !! `parametricCoord' containing u, v parametric coordinates on the surface,
      !! concatenated: [p1u, p1v, p2u, ...]). For `dim' equal to 1 return the x, y,
      !! z components of the second derivative with respect to u [d1uux, d1uuy,
      !! d1uuz, d2uux, ...]; for `dim' equal to 2 return the x, y, z components of
      !! the second derivative with respect to u and v, and the mixed derivative
      !! with respect to u and v: [d1uux, d1uuy, d1uuz, d1vvx, d1vvy, d1vvz, d1uvx,
      !! d1uvy, d1uvz, d2uux, ...].
      subroutine gmshModelGetSecondDerivative(dim, &
                                              tag, &
                                              parametricCoord, &
                                              derivatives, &
                                              ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         api_derivatives_, &
                         api_derivatives_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetSecondDerivative")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          type(c_ptr), intent(out) :: api_derivatives_
          integer(c_size_t) :: api_derivatives_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: parametricCoord
        real(c_double), dimension(:), allocatable, intent(out) :: derivatives
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_derivatives_
        integer(c_size_t) :: api_derivatives_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             api_derivatives_=api_derivatives_, &
             api_derivatives_n_=api_derivatives_n_, &
             ierr_=ierr)
        derivatives = ovectordouble_(api_derivatives_, &
          api_derivatives_n_)
      end subroutine gmshModelGetSecondDerivative
    
      !> Evaluate the (maximum) curvature of the entity of dimension `dim' and tag
      !! `tag' at the parametric coordinates `parametricCoord'. Only valid for `dim'
      !! equal to 1 (with `parametricCoord' containing parametric coordinates on the
      !! curve) or 2 (with `parametricCoord' containing u, v parametric coordinates
      !! on the surface, concatenated: [p1u, p1v, p2u, ...]).
      subroutine gmshModelGetCurvature(dim, &
                                       tag, &
                                       parametricCoord, &
                                       curvatures, &
                                       ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         api_curvatures_, &
                         api_curvatures_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetCurvature")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          type(c_ptr), intent(out) :: api_curvatures_
          integer(c_size_t) :: api_curvatures_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: parametricCoord
        real(c_double), dimension(:), allocatable, intent(out) :: curvatures
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_curvatures_
        integer(c_size_t) :: api_curvatures_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             api_curvatures_=api_curvatures_, &
             api_curvatures_n_=api_curvatures_n_, &
             ierr_=ierr)
        curvatures = ovectordouble_(api_curvatures_, &
          api_curvatures_n_)
      end subroutine gmshModelGetCurvature
    
      !> Evaluate the principal curvatures of the surface with tag `tag' at the
      !! parametric coordinates `parametricCoord', as well as their respective
      !! directions. `parametricCoord' are given by pair of u and v coordinates,
      !! concatenated: [p1u, p1v, p2u, ...].
      subroutine gmshModelGetPrincipalCurvatures(tag, &
                                                 parametricCoord, &
                                                 curvatureMax, &
                                                 curvatureMin, &
                                                 directionMax, &
                                                 directionMin, &
                                                 ierr)
        interface
        subroutine C_API(tag, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         api_curvatureMax_, &
                         api_curvatureMax_n_, &
                         api_curvatureMin_, &
                         api_curvatureMin_n_, &
                         api_directionMax_, &
                         api_directionMax_n_, &
                         api_directionMin_, &
                         api_directionMin_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetPrincipalCurvatures")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          type(c_ptr), intent(out) :: api_curvatureMax_
          integer(c_size_t) :: api_curvatureMax_n_
          type(c_ptr), intent(out) :: api_curvatureMin_
          integer(c_size_t) :: api_curvatureMin_n_
          type(c_ptr), intent(out) :: api_directionMax_
          integer(c_size_t) :: api_directionMax_n_
          type(c_ptr), intent(out) :: api_directionMin_
          integer(c_size_t) :: api_directionMin_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: parametricCoord
        real(c_double), dimension(:), allocatable, intent(out) :: curvatureMax
        real(c_double), dimension(:), allocatable, intent(out) :: curvatureMin
        real(c_double), dimension(:), allocatable, intent(out) :: directionMax
        real(c_double), dimension(:), allocatable, intent(out) :: directionMin
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_curvatureMax_
        integer(c_size_t) :: api_curvatureMax_n_
        type(c_ptr) :: api_curvatureMin_
        integer(c_size_t) :: api_curvatureMin_n_
        type(c_ptr) :: api_directionMax_
        integer(c_size_t) :: api_directionMax_n_
        type(c_ptr) :: api_directionMin_
        integer(c_size_t) :: api_directionMin_n_
        call C_API(tag=int(tag, c_int), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             api_curvatureMax_=api_curvatureMax_, &
             api_curvatureMax_n_=api_curvatureMax_n_, &
             api_curvatureMin_=api_curvatureMin_, &
             api_curvatureMin_n_=api_curvatureMin_n_, &
             api_directionMax_=api_directionMax_, &
             api_directionMax_n_=api_directionMax_n_, &
             api_directionMin_=api_directionMin_, &
             api_directionMin_n_=api_directionMin_n_, &
             ierr_=ierr)
        curvatureMax = ovectordouble_(api_curvatureMax_, &
          api_curvatureMax_n_)
        curvatureMin = ovectordouble_(api_curvatureMin_, &
          api_curvatureMin_n_)
        directionMax = ovectordouble_(api_directionMax_, &
          api_directionMax_n_)
        directionMin = ovectordouble_(api_directionMin_, &
          api_directionMin_n_)
      end subroutine gmshModelGetPrincipalCurvatures
    
      !> Get the normal to the surface with tag `tag' at the parametric coordinates
      !! `parametricCoord'. The `parametricCoord' vector should contain u and v
      !! coordinates, concatenated: [p1u, p1v, p2u, ...]. `normals' are returned as
      !! a vector of x, y, z components, concatenated: [n1x, n1y, n1z, n2x, ...].
      subroutine gmshModelGetNormal(tag, &
                                    parametricCoord, &
                                    normals, &
                                    ierr)
        interface
        subroutine C_API(tag, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         api_normals_, &
                         api_normals_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetNormal")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          type(c_ptr), intent(out) :: api_normals_
          integer(c_size_t) :: api_normals_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: parametricCoord
        real(c_double), dimension(:), allocatable, intent(out) :: normals
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_normals_
        integer(c_size_t) :: api_normals_n_
        call C_API(tag=int(tag, c_int), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             api_normals_=api_normals_, &
             api_normals_n_=api_normals_n_, &
             ierr_=ierr)
        normals = ovectordouble_(api_normals_, &
          api_normals_n_)
      end subroutine gmshModelGetNormal
    
      !> Get the parametric coordinates `parametricCoord' for the points `coord' on
      !! the entity of dimension `dim' and tag `tag'. `coord' are given as x, y, z
      !! coordinates, concatenated: [p1x, p1y, p1z, p2x, ...]. `parametricCoord'
      !! returns the parametric coordinates t on the curve (if `dim' = 1) or u and v
      !! coordinates concatenated on the surface (if `dim' == 2), i.e. [p1t, p2t,
      !! ...] or [p1u, p1v, p2u, ...].
      subroutine gmshModelGetParametrization(dim, &
                                             tag, &
                                             coord, &
                                             parametricCoord, &
                                             ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_coord_, &
                         api_coord_n_, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetParametrization")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_coord_
          integer(c_size_t), value, intent(in) :: api_coord_n_
          type(c_ptr), intent(out) :: api_parametricCoord_
          integer(c_size_t) :: api_parametricCoord_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: coord
        real(c_double), dimension(:), allocatable, intent(out) :: parametricCoord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_parametricCoord_
        integer(c_size_t) :: api_parametricCoord_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_coord_=coord, &
             api_coord_n_=size_gmsh_double(coord), &
             api_parametricCoord_=api_parametricCoord_, &
             api_parametricCoord_n_=api_parametricCoord_n_, &
             ierr_=ierr)
        parametricCoord = ovectordouble_(api_parametricCoord_, &
          api_parametricCoord_n_)
      end subroutine gmshModelGetParametrization
    
      !> Get the `min' and `max' bounds of the parametric coordinates for the entity
      !! of dimension `dim' and tag `tag'.
      subroutine gmshModelGetParametrizationBounds(dim, &
                                                   tag, &
                                                   min, &
                                                   max, &
                                                   ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_min_, &
                         api_min_n_, &
                         api_max_, &
                         api_max_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetParametrizationBounds")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_min_
          integer(c_size_t) :: api_min_n_
          type(c_ptr), intent(out) :: api_max_
          integer(c_size_t) :: api_max_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), allocatable, intent(out) :: min
        real(c_double), dimension(:), allocatable, intent(out) :: max
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_min_
        integer(c_size_t) :: api_min_n_
        type(c_ptr) :: api_max_
        integer(c_size_t) :: api_max_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_min_=api_min_, &
             api_min_n_=api_min_n_, &
             api_max_=api_max_, &
             api_max_n_=api_max_n_, &
             ierr_=ierr)
        min = ovectordouble_(api_min_, &
          api_min_n_)
        max = ovectordouble_(api_max_, &
          api_max_n_)
      end subroutine gmshModelGetParametrizationBounds
    
      !> Check if the coordinates (or the parametric coordinates if `parametric' is
      !! set) provided in `coord' correspond to points inside the entity of
      !! dimension `dim' and tag `tag', and return the number of points inside. This
      !! feature is only available for a subset of entities, depending on the
      !! underlying geometrical representation.
      function gmshModelIsInside(dim, &
                                 tag, &
                                 coord, &
                                 parametric, &
                                 ierr)
        interface
        function C_API(dim, &
                       tag, &
                       api_coord_, &
                       api_coord_n_, &
                       parametric, &
                       ierr_) &
          bind(C, name="gmshModelIsInside")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_coord_
          integer(c_size_t), value, intent(in) :: api_coord_n_
          integer(c_int), value, intent(in) :: parametric
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelIsInside
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: coord
        logical, intent(in), optional :: parametric
        integer(c_int), intent(out), optional :: ierr
        gmshModelIsInside = C_API(dim=int(dim, c_int), &
                            tag=int(tag, c_int), &
                            api_coord_=coord, &
                            api_coord_n_=size_gmsh_double(coord), &
                            parametric=optval_c_bool(.false., parametric), &
                            ierr_=ierr)
      end function gmshModelIsInside
    
      !> Get the points `closestCoord' on the entity of dimension `dim' and tag
      !! `tag' to the points `coord', by orthogonal projection. `coord' and
      !! `closestCoord' are given as x, y, z coordinates, concatenated: [p1x, p1y,
      !! p1z, p2x, ...]. `parametricCoord' returns the parametric coordinates t on
      !! the curve (if `dim' == 1) or u and v coordinates concatenated on the
      !! surface (if `dim' = 2), i.e. [p1t, p2t, ...] or [p1u, p1v, p2u, ...].
      subroutine gmshModelGetClosestPoint(dim, &
                                          tag, &
                                          coord, &
                                          closestCoord, &
                                          parametricCoord, &
                                          ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_coord_, &
                         api_coord_n_, &
                         api_closestCoord_, &
                         api_closestCoord_n_, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetClosestPoint")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_coord_
          integer(c_size_t), value, intent(in) :: api_coord_n_
          type(c_ptr), intent(out) :: api_closestCoord_
          integer(c_size_t) :: api_closestCoord_n_
          type(c_ptr), intent(out) :: api_parametricCoord_
          integer(c_size_t) :: api_parametricCoord_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: coord
        real(c_double), dimension(:), allocatable, intent(out) :: closestCoord
        real(c_double), dimension(:), allocatable, intent(out) :: parametricCoord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_closestCoord_
        integer(c_size_t) :: api_closestCoord_n_
        type(c_ptr) :: api_parametricCoord_
        integer(c_size_t) :: api_parametricCoord_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_coord_=coord, &
             api_coord_n_=size_gmsh_double(coord), &
             api_closestCoord_=api_closestCoord_, &
             api_closestCoord_n_=api_closestCoord_n_, &
             api_parametricCoord_=api_parametricCoord_, &
             api_parametricCoord_n_=api_parametricCoord_n_, &
             ierr_=ierr)
        closestCoord = ovectordouble_(api_closestCoord_, &
          api_closestCoord_n_)
        parametricCoord = ovectordouble_(api_parametricCoord_, &
          api_parametricCoord_n_)
      end subroutine gmshModelGetClosestPoint
    
      !> Reparametrize the boundary entity (point or curve, i.e. with `dim' == 0 or
      !! `dim' == 1) of tag `tag' on the surface `surfaceTag'. If `dim' == 1,
      !! reparametrize all the points corresponding to the parametric coordinates
      !! `parametricCoord'. Multiple matches in case of periodic surfaces can be
      !! selected with `which'. This feature is only available for a subset of
      !! entities, depending on the underlying geometrical representation.
      subroutine gmshModelReparametrizeOnSurface(dim, &
                                                 tag, &
                                                 parametricCoord, &
                                                 surfaceTag, &
                                                 surfaceParametricCoord, &
                                                 which, &
                                                 ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         surfaceTag, &
                         api_surfaceParametricCoord_, &
                         api_surfaceParametricCoord_n_, &
                         which, &
                         ierr_) &
          bind(C, name="gmshModelReparametrizeOnSurface")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          integer(c_int), value, intent(in) :: surfaceTag
          type(c_ptr), intent(out) :: api_surfaceParametricCoord_
          integer(c_size_t) :: api_surfaceParametricCoord_n_
          integer(c_int), value, intent(in) :: which
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: parametricCoord
        integer, intent(in) :: surfaceTag
        real(c_double), dimension(:), allocatable, intent(out) :: surfaceParametricCoord
        integer, intent(in), optional :: which
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_surfaceParametricCoord_
        integer(c_size_t) :: api_surfaceParametricCoord_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             surfaceTag=int(surfaceTag, c_int), &
             api_surfaceParametricCoord_=api_surfaceParametricCoord_, &
             api_surfaceParametricCoord_n_=api_surfaceParametricCoord_n_, &
             which=optval_c_int(0, which), &
             ierr_=ierr)
        surfaceParametricCoord = ovectordouble_(api_surfaceParametricCoord_, &
          api_surfaceParametricCoord_n_)
      end subroutine gmshModelReparametrizeOnSurface
    
      !> Set the visibility of the model entities `dimTags' (given as a vector of
      !! (dim, tag) pairs) to `value'. Apply the visibility setting recursively if
      !! `recursive' is true.
      subroutine gmshModelSetVisibility(dimTags, &
                                        value, &
                                        recursive, &
                                        ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         value, &
                         recursive, &
                         ierr_) &
          bind(C, name="gmshModelSetVisibility")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: value
          integer(c_int), value, intent(in) :: recursive
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer, intent(in) :: value
        logical, intent(in), optional :: recursive
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             value=int(value, c_int), &
             recursive=optval_c_bool(.false., recursive), &
             ierr_=ierr)
      end subroutine gmshModelSetVisibility
    
      !> Get the visibility of the model entity of dimension `dim' and tag `tag'.
      subroutine gmshModelGetVisibility(dim, &
                                        tag, &
                                        value, &
                                        ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         value, &
                         ierr_) &
          bind(C, name="gmshModelGetVisibility")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             value=value, &
             ierr_=ierr)
      end subroutine gmshModelGetVisibility
    
      !> Set the global visibility of the model per window to `value', where
      !! `windowIndex' identifies the window in the window list.
      subroutine gmshModelSetVisibilityPerWindow(value, &
                                                 windowIndex, &
                                                 ierr)
        interface
        subroutine C_API(value, &
                         windowIndex, &
                         ierr_) &
          bind(C, name="gmshModelSetVisibilityPerWindow")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: value
          integer(c_int), value, intent(in) :: windowIndex
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: value
        integer, intent(in), optional :: windowIndex
        integer(c_int), intent(out), optional :: ierr
        call C_API(value=int(value, c_int), &
             windowIndex=optval_c_int(0, windowIndex), &
             ierr_=ierr)
      end subroutine gmshModelSetVisibilityPerWindow
    
      !> Set the color of the model entities `dimTags' (given as a vector of (dim,
      !! tag) pairs) to the RGBA value (`r', `g', `b', `a'), where `r', `g', `b' and
      !! `a' should be integers between 0 and 255. Apply the color setting
      !! recursively if `recursive' is true.
      subroutine gmshModelSetColor(dimTags, &
                                   r, &
                                   g, &
                                   b, &
                                   a, &
                                   recursive, &
                                   ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         r, &
                         g, &
                         b, &
                         a, &
                         recursive, &
                         ierr_) &
          bind(C, name="gmshModelSetColor")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: r
          integer(c_int), value, intent(in) :: g
          integer(c_int), value, intent(in) :: b
          integer(c_int), value, intent(in) :: a
          integer(c_int), value, intent(in) :: recursive
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer, intent(in) :: r
        integer, intent(in) :: g
        integer, intent(in) :: b
        integer, intent(in), optional :: a
        logical, intent(in), optional :: recursive
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             r=int(r, c_int), &
             g=int(g, c_int), &
             b=int(b, c_int), &
             a=optval_c_int(255, a), &
             recursive=optval_c_bool(.false., recursive), &
             ierr_=ierr)
      end subroutine gmshModelSetColor
    
      !> Get the color of the model entity of dimension `dim' and tag `tag'. If no
      !! color is specified for the entity, return fully transparent blue, i.e. (0,
      !! 0, 255, 0).
      subroutine gmshModelGetColor(dim, &
                                   tag, &
                                   r, &
                                   g, &
                                   b, &
                                   a, &
                                   ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         r, &
                         g, &
                         b, &
                         a, &
                         ierr_) &
          bind(C, name="gmshModelGetColor")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int) :: r
          integer(c_int) :: g
          integer(c_int) :: b
          integer(c_int) :: a
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int) :: r
        integer(c_int) :: g
        integer(c_int) :: b
        integer(c_int) :: a
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             r=r, &
             g=g, &
             b=b, &
             a=a, &
             ierr_=ierr)
      end subroutine gmshModelGetColor
    
      !> Set the `x', `y', `z' coordinates of a geometrical point.
      subroutine gmshModelSetCoordinates(tag, &
                                         x, &
                                         y, &
                                         z, &
                                         ierr)
        interface
        subroutine C_API(tag, &
                         x, &
                         y, &
                         z, &
                         ierr_) &
          bind(C, name="gmshModelSetCoordinates")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             ierr_=ierr)
      end subroutine gmshModelSetCoordinates
    
      !> Set the values of the attribute with name `name'.
      subroutine gmshModelSetAttribute(name, &
                                       values, &
                                       ierr)
        interface
        subroutine C_API(name, &
                         api_values_, &
                         api_values_n_, &
                         ierr_) &
          bind(C, name="gmshModelSetAttribute")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), dimension(*) :: api_values_
          integer(c_size_t), value, intent(in) :: api_values_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=*), dimension(:), intent(in) :: values
        integer(c_int), intent(out), optional :: ierr
        character(len=GMSH_API_MAX_STR_LEN, kind=c_char), allocatable :: api_values_strs(:)
        type(c_ptr), allocatable :: api_values_(:)
        call ivectorstring_(values, &
          api_values_strs, &
          api_values_)
        call C_API(name=istring_(name), &
             api_values_=api_values_, &
             api_values_n_=size_gmsh_str(values), &
             ierr_=ierr)
      end subroutine gmshModelSetAttribute
    
      !> Get the values of the attribute with name `name'.
      subroutine gmshModelGetAttribute(name, &
                                       values, &
                                       ierr)
        interface
        subroutine C_API(name, &
                         api_values_, &
                         api_values_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetAttribute")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), intent(out) :: api_values_
          integer(c_size_t), intent(out) :: api_values_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: values
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_values_
        integer(c_size_t) :: api_values_n_
        call C_API(name=istring_(name), &
             api_values_=api_values_, &
             api_values_n_=api_values_n_, &
             ierr_=ierr)
        values = ovectorstring_(api_values_, &
          api_values_n_)
      end subroutine gmshModelGetAttribute
    
      !> Get the names of any optional attributes stored in the model.
      subroutine gmshModelGetAttributeNames(names, &
                                            ierr)
        interface
        subroutine C_API(api_names_, &
                         api_names_n_, &
                         ierr_) &
          bind(C, name="gmshModelGetAttributeNames")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_names_
          integer(c_size_t), intent(out) :: api_names_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: names
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_names_
        integer(c_size_t) :: api_names_n_
        call C_API(api_names_=api_names_, &
             api_names_n_=api_names_n_, &
             ierr_=ierr)
        names = ovectorstring_(api_names_, &
          api_names_n_)
      end subroutine gmshModelGetAttributeNames
    
      !> Remove the attribute with name `name'.
      subroutine gmshModelRemoveAttribute(name, &
                                          ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshModelRemoveAttribute")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshModelRemoveAttribute
    
      !> Generate a mesh of the current model, up to dimension `dim' (0, 1, 2 or 3).
      subroutine gmshModelMeshGenerate(dim, &
                                       ierr)
        interface
        subroutine C_API(dim, &
                         ierr_) &
          bind(C, name="gmshModelMeshGenerate")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=optval_c_int(3, dim), &
             ierr_=ierr)
      end subroutine gmshModelMeshGenerate
    
      !> Partition the mesh of the current model into `numPart' partitions.
      !! Optionally, `elementTags' and `partitions' can be provided to specify the
      !! partition of each element explicitly.
      subroutine gmshModelMeshPartition(numPart, &
                                        elementTags, &
                                        partitions, &
                                        ierr)
        interface
        subroutine C_API(numPart, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         api_partitions_, &
                         api_partitions_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshPartition")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: numPart
          integer(c_size_t), dimension(*), optional :: api_elementTags_
          integer(c_size_t), value, intent(in) :: api_elementTags_n_
          integer(c_int), dimension(*), optional :: api_partitions_
          integer(c_size_t), value, intent(in) :: api_partitions_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: numPart
        integer(c_size_t), dimension(:), intent(in), optional :: elementTags
        integer(c_int), dimension(:), intent(in), optional :: partitions
        integer(c_int), intent(out), optional :: ierr
        call C_API(numPart=int(numPart, c_int), &
             api_elementTags_=elementTags, &
             api_elementTags_n_=size_gmsh_size(elementTags), &
             api_partitions_=partitions, &
             api_partitions_n_=size_gmsh_int(partitions), &
             ierr_=ierr)
      end subroutine gmshModelMeshPartition
    
      !> Unpartition the mesh of the current model.
      subroutine gmshModelMeshUnpartition(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelMeshUnpartition")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelMeshUnpartition
    
      !> Optimize the mesh of the current model using `method' (empty for default
      !! tetrahedral mesh optimizer, "Netgen" for Netgen optimizer, "HighOrder" for
      !! direct high-order mesh optimizer, "HighOrderElastic" for high-order elastic
      !! smoother, "HighOrderFastCurving" for fast curving algorithm, "Laplace2D"
      !! for Laplace smoothing, "Relocate2D" and "Relocate3D" for node relocation,
      !! "QuadQuasiStructured" for quad mesh optimization, "UntangleMeshGeometry"
      !! for untangling). If `force' is set apply the optimization also to discrete
      !! entities. If `dimTags' (given as a vector of (dim, tag) pairs) is given,
      !! only apply the optimizer to the given entities.
      subroutine gmshModelMeshOptimize(method, &
                                       force, &
                                       niter, &
                                       dimTags, &
                                       ierr)
        interface
        subroutine C_API(method, &
                         force, &
                         niter, &
                         api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshOptimize")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: method
          integer(c_int), value, intent(in) :: force
          integer(c_int), value, intent(in) :: niter
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in), optional :: method
        logical, intent(in), optional :: force
        integer, intent(in), optional :: niter
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(method=istring_(optval_c_str("", method)), &
             force=optval_c_bool(.false., force), &
             niter=optval_c_int(1, niter), &
             api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshOptimize
    
      !> Recombine the mesh of the current model.
      subroutine gmshModelMeshRecombine(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelMeshRecombine")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelMeshRecombine
    
      !> Refine the mesh of the current model by uniformly splitting the elements.
      subroutine gmshModelMeshRefine(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelMeshRefine")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelMeshRefine
    
      !> Change the order of the elements in the mesh of the current model to
      !! `order'.
      subroutine gmshModelMeshSetOrder(order, &
                                       ierr)
        interface
        subroutine C_API(order, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetOrder")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: order
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: order
        integer(c_int), intent(out), optional :: ierr
        call C_API(order=int(order, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetOrder
    
      !> Get the last entities `dimTags' (as a vector of (dim, tag) pairs) where a
      !! meshing error occurred. Currently only populated by the new 3D meshing
      !! algorithms.
      subroutine gmshModelMeshGetLastEntityError(dimTags, &
                                                 ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetLastEntityError")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelMeshGetLastEntityError
    
      !> Get the last node tags `nodeTags' where a meshing error occurred. Currently
      !! only populated by the new 3D meshing algorithms.
      subroutine gmshModelMeshGetLastNodeError(nodeTags, &
                                               ierr)
        interface
        subroutine C_API(api_nodeTags_, &
                         api_nodeTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetLastNodeError")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        call C_API(api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
      end subroutine gmshModelMeshGetLastNodeError
    
      !> Clear the mesh, i.e. delete all the nodes and elements, for the entities
      !! `dimTags', given as a vector of (dim, tag) pairs. If `dimTags' is empty,
      !! clear the whole mesh. Note that the mesh of an entity can only be cleared
      !! if this entity is not on the boundary of another entity with a non-empty
      !! mesh.
      subroutine gmshModelMeshClear(dimTags, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshClear")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshClear
    
      !> Remove the elements with tags `elementTags' from the entity of dimension
      !! `dim' and tag `tag'. If `elementTags' is empty, remove all the elements
      !! classified on the entity. To get consistent node classification on model
      !! entities, `reclassifyNodes()' should be called afterwards.
      subroutine gmshModelMeshRemoveElements(dim, &
                                             tag, &
                                             elementTags, &
                                             ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshRemoveElements")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_size_t), dimension(*), optional :: api_elementTags_
          integer(c_size_t), value, intent(in) :: api_elementTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_size_t), dimension(:), intent(in), optional :: elementTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_elementTags_=elementTags, &
             api_elementTags_n_=size_gmsh_size(elementTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshRemoveElements
    
      !> Reverse the orientation of the elements in the entities `dimTags', given as
      !! a vector of (dim, tag) pairs. If `dimTags' is empty, reverse the
      !! orientation of the elements in the whole mesh.
      subroutine gmshModelMeshReverse(dimTags, &
                                      ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshReverse")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshReverse
    
      !> Reverse the orientation of the elements with tags `elementTags'.
      subroutine gmshModelMeshReverseElements(elementTags, &
                                              ierr)
        interface
        subroutine C_API(api_elementTags_, &
                         api_elementTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshReverseElements")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), dimension(*) :: api_elementTags_
          integer(c_size_t), value, intent(in) :: api_elementTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), intent(in) :: elementTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_elementTags_=elementTags, &
             api_elementTags_n_=size_gmsh_size(elementTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshReverseElements
    
      !> Apply the affine transformation `affineTransform' (16 entries of a 4x4
      !! matrix, by row; only the 12 first can be provided for convenience) to the
      !! coordinates of the nodes classified on the entities `dimTags', given as a
      !! vector of (dim, tag) pairs. If `dimTags' is empty, transform all the nodes
      !! in the mesh.
      subroutine gmshModelMeshAffineTransform(affineTransform, &
                                              dimTags, &
                                              ierr)
        interface
        subroutine C_API(api_affineTransform_, &
                         api_affineTransform_n_, &
                         api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshAffineTransform")
          use, intrinsic :: iso_c_binding
          real(c_double), dimension(*) :: api_affineTransform_
          integer(c_size_t), value, intent(in) :: api_affineTransform_n_
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), dimension(:), intent(in) :: affineTransform
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_affineTransform_=affineTransform, &
             api_affineTransform_n_=size_gmsh_double(affineTransform), &
             api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshAffineTransform
    
      !> Get the nodes classified on the entity of dimension `dim' and tag `tag'. If
      !! `tag' < 0, get the nodes for all entities of dimension `dim'. If `dim' and
      !! `tag' are negative, get all the nodes in the mesh. `nodeTags' contains the
      !! node tags (their unique, strictly positive identification numbers). `coord'
      !! is a vector of length 3 times the length of `nodeTags' that contains the x,
      !! y, z coordinates of the nodes, concatenated: [n1x, n1y, n1z, n2x, ...]. If
      !! `dim' >= 0 and `returnParamtricCoord' is set, `parametricCoord' contains
      !! the parametric coordinates ([u1, u2, ...] or [u1, v1, u2, ...]) of the
      !! nodes, if available. The length of `parametricCoord' can be 0 or `dim'
      !! times the length of `nodeTags'. If `includeBoundary' is set, also return
      !! the nodes classified on the boundary of the entity (which will be
      !! reparametrized on the entity if `dim' >= 0 in order to compute their
      !! parametric coordinates).
      subroutine gmshModelMeshGetNodes(nodeTags, &
                                       coord, &
                                       parametricCoord, &
                                       dim, &
                                       tag, &
                                       includeBoundary, &
                                       returnParametricCoord, &
                                       ierr)
        interface
        subroutine C_API(api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         dim, &
                         tag, &
                         includeBoundary, &
                         returnParametricCoord, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetNodes")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          type(c_ptr), intent(out) :: api_parametricCoord_
          integer(c_size_t) :: api_parametricCoord_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: includeBoundary
          integer(c_int), value, intent(in) :: returnParametricCoord
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        real(c_double), dimension(:), allocatable, intent(out) :: parametricCoord
        integer, intent(in), optional :: dim
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: includeBoundary
        logical, intent(in), optional :: returnParametricCoord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        type(c_ptr) :: api_parametricCoord_
        integer(c_size_t) :: api_parametricCoord_n_
        call C_API(api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             api_parametricCoord_=api_parametricCoord_, &
             api_parametricCoord_n_=api_parametricCoord_n_, &
             dim=optval_c_int(-1, dim), &
             tag=optval_c_int(-1, tag), &
             includeBoundary=optval_c_bool(.false., includeBoundary), &
             returnParametricCoord=optval_c_bool(.true., returnParametricCoord), &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
        parametricCoord = ovectordouble_(api_parametricCoord_, &
          api_parametricCoord_n_)
      end subroutine gmshModelMeshGetNodes
    
      !> Get the nodes classified on the entity of tag `tag', for all the elements
      !! of type `elementType'. The other arguments are treated as in `getNodes'.
      subroutine gmshModelMeshGetNodesByElementType(elementType, &
                                                    nodeTags, &
                                                    coord, &
                                                    parametricCoord, &
                                                    tag, &
                                                    returnParametricCoord, &
                                                    ierr)
        interface
        subroutine C_API(elementType, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         tag, &
                         returnParametricCoord, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetNodesByElementType")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          type(c_ptr), intent(out) :: api_parametricCoord_
          integer(c_size_t) :: api_parametricCoord_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: returnParametricCoord
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        real(c_double), dimension(:), allocatable, intent(out) :: parametricCoord
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: returnParametricCoord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        type(c_ptr) :: api_parametricCoord_
        integer(c_size_t) :: api_parametricCoord_n_
        call C_API(elementType=int(elementType, c_int), &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             api_parametricCoord_=api_parametricCoord_, &
             api_parametricCoord_n_=api_parametricCoord_n_, &
             tag=optval_c_int(-1, tag), &
             returnParametricCoord=optval_c_bool(.true., returnParametricCoord), &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
        parametricCoord = ovectordouble_(api_parametricCoord_, &
          api_parametricCoord_n_)
      end subroutine gmshModelMeshGetNodesByElementType
    
      !> Get the coordinates and the parametric coordinates (if any) of the node
      !! with tag `tag', as well as the dimension `dim' and tag `tag' of the entity
      !! on which the node is classified. This function relies on an internal cache
      !! (a vector in case of dense node numbering, a map otherwise); for large
      !! meshes accessing nodes in bulk is often preferable.
      subroutine gmshModelMeshGetNode(nodeTag, &
                                      coord, &
                                      parametricCoord, &
                                      dim, &
                                      tag, &
                                      ierr)
        interface
        subroutine C_API(nodeTag, &
                         api_coord_, &
                         api_coord_n_, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         dim, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetNode")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), value, intent(in) :: nodeTag
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          type(c_ptr), intent(out) :: api_parametricCoord_
          integer(c_size_t) :: api_parametricCoord_n_
          integer(c_int) :: dim
          integer(c_int) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: nodeTag
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        real(c_double), dimension(:), allocatable, intent(out) :: parametricCoord
        integer(c_int) :: dim
        integer(c_int) :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        type(c_ptr) :: api_parametricCoord_
        integer(c_size_t) :: api_parametricCoord_n_
        call C_API(nodeTag=int(nodeTag, c_size_t), &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             api_parametricCoord_=api_parametricCoord_, &
             api_parametricCoord_n_=api_parametricCoord_n_, &
             dim=dim, &
             tag=tag, &
             ierr_=ierr)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
        parametricCoord = ovectordouble_(api_parametricCoord_, &
          api_parametricCoord_n_)
      end subroutine gmshModelMeshGetNode
    
      !> Set the coordinates and the parametric coordinates (if any) of the node
      !! with tag `tag'. This function relies on an internal cache (a vector in case
      !! of dense node numbering, a map otherwise); for large meshes accessing nodes
      !! in bulk is often preferable.
      subroutine gmshModelMeshSetNode(nodeTag, &
                                      coord, &
                                      parametricCoord, &
                                      ierr)
        interface
        subroutine C_API(nodeTag, &
                         api_coord_, &
                         api_coord_n_, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetNode")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), value, intent(in) :: nodeTag
          real(c_double), dimension(*) :: api_coord_
          integer(c_size_t), value, intent(in) :: api_coord_n_
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: nodeTag
        real(c_double), dimension(:), intent(in) :: coord
        real(c_double), dimension(:), intent(in) :: parametricCoord
        integer(c_int), intent(out), optional :: ierr
        call C_API(nodeTag=int(nodeTag, c_size_t), &
             api_coord_=coord, &
             api_coord_n_=size_gmsh_double(coord), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetNode
    
      !> Rebuild the node cache.
      subroutine gmshModelMeshRebuildNodeCache(onlyIfNecessary, &
                                               ierr)
        interface
        subroutine C_API(onlyIfNecessary, &
                         ierr_) &
          bind(C, name="gmshModelMeshRebuildNodeCache")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: onlyIfNecessary
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        logical, intent(in), optional :: onlyIfNecessary
        integer(c_int), intent(out), optional :: ierr
        call C_API(onlyIfNecessary=optval_c_bool(.true., onlyIfNecessary), &
             ierr_=ierr)
      end subroutine gmshModelMeshRebuildNodeCache
    
      !> Rebuild the element cache.
      subroutine gmshModelMeshRebuildElementCache(onlyIfNecessary, &
                                                  ierr)
        interface
        subroutine C_API(onlyIfNecessary, &
                         ierr_) &
          bind(C, name="gmshModelMeshRebuildElementCache")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: onlyIfNecessary
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        logical, intent(in), optional :: onlyIfNecessary
        integer(c_int), intent(out), optional :: ierr
        call C_API(onlyIfNecessary=optval_c_bool(.true., onlyIfNecessary), &
             ierr_=ierr)
      end subroutine gmshModelMeshRebuildElementCache
    
      !> Get the nodes from all the elements belonging to the physical group of
      !! dimension `dim' and tag `tag'. `nodeTags' contains the node tags; `coord'
      !! is a vector of length 3 times the length of `nodeTags' that contains the x,
      !! y, z coordinates of the nodes, concatenated: [n1x, n1y, n1z, n2x, ...].
      subroutine gmshModelMeshGetNodesForPhysicalGroup(dim, &
                                                       tag, &
                                                       nodeTags, &
                                                       coord, &
                                                       ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetNodesForPhysicalGroup")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
      end subroutine gmshModelMeshGetNodesForPhysicalGroup
    
      !> Get the maximum tag `maxTag' of a node in the mesh.
      subroutine gmshModelMeshGetMaxNodeTag(maxTag, &
                                            ierr)
        interface
        subroutine C_API(maxTag, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetMaxNodeTag")
          use, intrinsic :: iso_c_binding
          integer(c_size_t) :: maxTag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t) :: maxTag
        integer(c_int), intent(out), optional :: ierr
        call C_API(maxTag=maxTag, &
             ierr_=ierr)
      end subroutine gmshModelMeshGetMaxNodeTag
    
      !> Add nodes classified on the model entity of dimension `dim' and tag `tag'.
      !! `nodeTags' contains the node tags (their unique, strictly positive
      !! identification numbers). `coord' is a vector of length 3 times the length
      !! of `nodeTags' that contains the x, y, z coordinates of the nodes,
      !! concatenated: [n1x, n1y, n1z, n2x, ...]. The optional `parametricCoord'
      !! vector contains the parametric coordinates of the nodes, if any. The length
      !! of `parametricCoord' can be 0 or `dim' times the length of `nodeTags'. If
      !! the `nodeTags' vector is empty, new tags are automatically assigned to the
      !! nodes.
      subroutine gmshModelMeshAddNodes(dim, &
                                       tag, &
                                       nodeTags, &
                                       coord, &
                                       parametricCoord, &
                                       ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshAddNodes")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_size_t), dimension(*) :: api_nodeTags_
          integer(c_size_t), value, intent(in) :: api_nodeTags_n_
          real(c_double), dimension(*) :: api_coord_
          integer(c_size_t), value, intent(in) :: api_coord_n_
          real(c_double), dimension(*), optional :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_size_t), dimension(:), intent(in) :: nodeTags
        real(c_double), dimension(:), intent(in) :: coord
        real(c_double), dimension(:), intent(in), optional :: parametricCoord
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_nodeTags_=nodeTags, &
             api_nodeTags_n_=size_gmsh_size(nodeTags), &
             api_coord_=coord, &
             api_coord_n_=size_gmsh_double(coord), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             ierr_=ierr)
      end subroutine gmshModelMeshAddNodes
    
      !> Reclassify all nodes on their associated model entity, based on the
      !! elements. Can be used when importing nodes in bulk (e.g. by associating
      !! them all to a single volume), to reclassify them correctly on model
      !! surfaces, curves, etc. after the elements have been set.
      subroutine gmshModelMeshReclassifyNodes(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelMeshReclassifyNodes")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelMeshReclassifyNodes
    
      !> Relocate the nodes classified on the entity of dimension `dim' and tag
      !! `tag' using their parametric coordinates. If `tag' < 0, relocate the nodes
      !! for all entities of dimension `dim'. If `dim' and `tag' are negative,
      !! relocate all the nodes in the mesh.
      subroutine gmshModelMeshRelocateNodes(dim, &
                                            tag, &
                                            ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshRelocateNodes")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in), optional :: dim
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=optval_c_int(-1, dim), &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
      end subroutine gmshModelMeshRelocateNodes
    
      !> Get the elements classified on the entity of dimension `dim' and tag `tag'.
      !! If `tag' < 0, get the elements for all entities of dimension `dim'. If
      !! `dim' and `tag' are negative, get all the elements in the mesh.
      !! `elementTypes' contains the MSH types of the elements (e.g. `2' for 3-node
      !! triangles: see `getElementProperties' to obtain the properties for a given
      !! element type). `elementTags' is a vector of the same length as
      !! `elementTypes'; each entry is a vector containing the tags (unique,
      !! strictly positive identifiers) of the elements of the corresponding type.
      !! `nodeTags' is also a vector of the same length as `elementTypes'; each
      !! entry is a vector of length equal to the number of elements of the given
      !! type times the number N of nodes for this type of element, that contains
      !! the node tags of all the elements of the given type, concatenated: [e1n1,
      !! e1n2, ..., e1nN, e2n1, ...].
      subroutine gmshModelMeshGetElements(elementTypes, &
                                          elementTags, &
                                          elementTags_n, &
                                          nodeTags, &
                                          nodeTags_n, &
                                          dim, &
                                          tag, &
                                          ierr)
        interface
        subroutine C_API(api_elementTypes_, &
                         api_elementTypes_n_, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         api_elementTags_nn_, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_nodeTags_nn_, &
                         dim, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElements")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_elementTypes_
          integer(c_size_t), intent(out) :: api_elementTypes_n_
          type(c_ptr), intent(out) :: api_elementTags_
          type(c_ptr), intent(out) :: api_elementTags_n_
          integer(c_size_t), intent(out) :: api_elementTags_nn_
          type(c_ptr), intent(out) :: api_nodeTags_
          type(c_ptr), intent(out) :: api_nodeTags_n_
          integer(c_size_t), intent(out) :: api_nodeTags_nn_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), allocatable, intent(out) :: elementTypes
        integer(c_size_t), dimension(:), allocatable, intent(out) :: elementTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: elementTags_n
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags_n
        integer, intent(in), optional :: dim
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementTypes_
        integer(c_size_t) :: api_elementTypes_n_
        type(c_ptr) :: api_elementTags_, api_elementTags_n_
        integer(c_size_t) :: api_elementTags_nn_
        type(c_ptr) :: api_nodeTags_, api_nodeTags_n_
        integer(c_size_t) :: api_nodeTags_nn_
        call C_API(api_elementTypes_=api_elementTypes_, &
             api_elementTypes_n_=api_elementTypes_n_, &
             api_elementTags_=api_elementTags_, &
             api_elementTags_n_=api_elementTags_n_, &
             api_elementTags_nn_=api_elementTags_nn_, &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             api_nodeTags_nn_=api_nodeTags_nn_, &
             dim=optval_c_int(-1, dim), &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
        elementTypes = ovectorint_(api_elementTypes_, &
          api_elementTypes_n_)
        call ovectorvectorsize_(api_elementTags_, &
          api_elementTags_n_, &
          api_elementTags_nn_, &
          elementTags, &
          elementTags_n)
        call ovectorvectorsize_(api_nodeTags_, &
          api_nodeTags_n_, &
          api_nodeTags_nn_, &
          nodeTags, &
          nodeTags_n)
      end subroutine gmshModelMeshGetElements
    
      !> Get the type and node tags of the element with tag `tag', as well as the
      !! dimension `dim' and tag `tag' of the entity on which the element is
      !! classified. This function relies on an internal cache (a vector in case of
      !! dense element numbering, a map otherwise); for large meshes accessing
      !! elements in bulk is often preferable.
      subroutine gmshModelMeshGetElement(elementTag, &
                                         elementType, &
                                         nodeTags, &
                                         dim, &
                                         tag, &
                                         ierr)
        interface
        subroutine C_API(elementTag, &
                         elementType, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         dim, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElement")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), value, intent(in) :: elementTag
          integer(c_int) :: elementType
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          integer(c_int) :: dim
          integer(c_int) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementTag
        integer(c_int) :: elementType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        integer(c_int) :: dim
        integer(c_int) :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        call C_API(elementTag=int(elementTag, c_size_t), &
             elementType=elementType, &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             dim=dim, &
             tag=tag, &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
      end subroutine gmshModelMeshGetElement
    
      !> Search the mesh for an element located at coordinates (`x', `y', `z'). This
      !! function performs a search in a spatial octree. If an element is found,
      !! return its tag, type and node tags, as well as the local coordinates (`u',
      !! `v', `w') within the reference element corresponding to search location. If
      !! `dim' is >= 0, only search for elements of the given dimension. If `strict'
      !! is not set, use a tolerance to find elements near the search location.
      subroutine gmshModelMeshGetElementByCoordinates(x, &
                                                      y, &
                                                      z, &
                                                      elementTag, &
                                                      elementType, &
                                                      nodeTags, &
                                                      u, &
                                                      v, &
                                                      w, &
                                                      dim, &
                                                      strict, &
                                                      ierr)
        interface
        subroutine C_API(x, &
                         y, &
                         z, &
                         elementTag, &
                         elementType, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         u, &
                         v, &
                         w, &
                         dim, &
                         strict, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElementByCoordinates")
          use, intrinsic :: iso_c_binding
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          integer(c_size_t) :: elementTag
          integer(c_int) :: elementType
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          real(c_double) :: u
          real(c_double) :: v
          real(c_double) :: w
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: strict
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        integer(c_size_t) :: elementTag
        integer(c_int) :: elementType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        real(c_double) :: u
        real(c_double) :: v
        real(c_double) :: w
        integer, intent(in), optional :: dim
        logical, intent(in), optional :: strict
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        call C_API(x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             elementTag=elementTag, &
             elementType=elementType, &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             u=u, &
             v=v, &
             w=w, &
             dim=optval_c_int(-1, dim), &
             strict=optval_c_bool(.false., strict), &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
      end subroutine gmshModelMeshGetElementByCoordinates
    
      !> Search the mesh for element(s) located at coordinates (`x', `y', `z'). This
      !! function performs a search in a spatial octree. Return the tags of all
      !! found elements in `elementTags'. Additional information about the elements
      !! can be accessed through `getElement' and `getLocalCoordinatesInElement'. If
      !! `dim' is >= 0, only search for elements of the given dimension. If `strict'
      !! is not set, use a tolerance to find elements near the search location.
      subroutine gmshModelMeshGetElementsByCoordinates(x, &
                                                       y, &
                                                       z, &
                                                       elementTags, &
                                                       dim, &
                                                       strict, &
                                                       ierr)
        interface
        subroutine C_API(x, &
                         y, &
                         z, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         dim, &
                         strict, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElementsByCoordinates")
          use, intrinsic :: iso_c_binding
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          type(c_ptr), intent(out) :: api_elementTags_
          integer(c_size_t), intent(out) :: api_elementTags_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: strict
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        integer(c_size_t), dimension(:), allocatable, intent(out) :: elementTags
        integer, intent(in), optional :: dim
        logical, intent(in), optional :: strict
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementTags_
        integer(c_size_t) :: api_elementTags_n_
        call C_API(x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             api_elementTags_=api_elementTags_, &
             api_elementTags_n_=api_elementTags_n_, &
             dim=optval_c_int(-1, dim), &
             strict=optval_c_bool(.false., strict), &
             ierr_=ierr)
        elementTags = ovectorsize_(api_elementTags_, &
          api_elementTags_n_)
      end subroutine gmshModelMeshGetElementsByCoordinates
    
      !> Return the local coordinates (`u', `v', `w') within the element
      !! `elementTag' corresponding to the model coordinates (`x', `y', `z'). This
      !! function relies on an internal cache (a vector in case of dense element
      !! numbering, a map otherwise); for large meshes accessing elements in bulk is
      !! often preferable.
      subroutine gmshModelMeshGetLocalCoordinatesInElement(elementTag, &
                                                           x, &
                                                           y, &
                                                           z, &
                                                           u, &
                                                           v, &
                                                           w, &
                                                           ierr)
        interface
        subroutine C_API(elementTag, &
                         x, &
                         y, &
                         z, &
                         u, &
                         v, &
                         w, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetLocalCoordinatesInElement")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), value, intent(in) :: elementTag
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double) :: u
          real(c_double) :: v
          real(c_double) :: w
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementTag
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double) :: u
        real(c_double) :: v
        real(c_double) :: w
        integer(c_int), intent(out), optional :: ierr
        call C_API(elementTag=int(elementTag, c_size_t), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             u=u, &
             v=v, &
             w=w, &
             ierr_=ierr)
      end subroutine gmshModelMeshGetLocalCoordinatesInElement
    
      !> Get the types of elements in the entity of dimension `dim' and tag `tag'.
      !! If `tag' < 0, get the types for all entities of dimension `dim'. If `dim'
      !! and `tag' are negative, get all the types in the mesh.
      subroutine gmshModelMeshGetElementTypes(elementTypes, &
                                              dim, &
                                              tag, &
                                              ierr)
        interface
        subroutine C_API(api_elementTypes_, &
                         api_elementTypes_n_, &
                         dim, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElementTypes")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_elementTypes_
          integer(c_size_t), intent(out) :: api_elementTypes_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), allocatable, intent(out) :: elementTypes
        integer, intent(in), optional :: dim
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementTypes_
        integer(c_size_t) :: api_elementTypes_n_
        call C_API(api_elementTypes_=api_elementTypes_, &
             api_elementTypes_n_=api_elementTypes_n_, &
             dim=optval_c_int(-1, dim), &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
        elementTypes = ovectorint_(api_elementTypes_, &
          api_elementTypes_n_)
      end subroutine gmshModelMeshGetElementTypes
    
      !> Return an element type given its family name `familyName' ("Point", "Line",
      !! "Triangle", "Quadrangle", "Tetrahedron", "Pyramid", "Prism", "Hexahedron")
      !! and polynomial order `order'. If `serendip' is true, return the
      !! corresponding serendip element type (element without interior nodes).
      function gmshModelMeshGetElementType(familyName, &
                                           order, &
                                           serendip, &
                                           ierr)
        interface
        function C_API(familyName, &
                       order, &
                       serendip, &
                       ierr_) &
          bind(C, name="gmshModelMeshGetElementType")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          character(len=1, kind=c_char), dimension(*), intent(in) :: familyName
          integer(c_int), value, intent(in) :: order
          integer(c_int), value, intent(in) :: serendip
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelMeshGetElementType
        character(len=*), intent(in) :: familyName
        integer, intent(in) :: order
        logical, intent(in), optional :: serendip
        integer(c_int), intent(out), optional :: ierr
        gmshModelMeshGetElementType = C_API(familyName=istring_(familyName), &
                                      order=int(order, c_int), &
                                      serendip=optval_c_bool(.false., serendip), &
                                      ierr_=ierr)
      end function gmshModelMeshGetElementType
    
      !> Get the properties of an element of type `elementType': its name
      !! (`elementName'), dimension (`dim'), order (`order'), number of nodes
      !! (`numNodes'), local coordinates of the nodes in the reference element
      !! (`localNodeCoord' vector, of length `dim' times `numNodes') and number of
      !! primary (first order) nodes (`numPrimaryNodes').
      subroutine gmshModelMeshGetElementProperties(elementType, &
                                                   elementName, &
                                                   dim, &
                                                   order, &
                                                   numNodes, &
                                                   localNodeCoord, &
                                                   numPrimaryNodes, &
                                                   ierr)
        interface
        subroutine C_API(elementType, &
                         api_elementName_, &
                         dim, &
                         order, &
                         numNodes, &
                         api_localNodeCoord_, &
                         api_localNodeCoord_n_, &
                         numPrimaryNodes, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElementProperties")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          type(c_ptr), intent(out) :: api_elementName_
          integer(c_int) :: dim
          integer(c_int) :: order
          integer(c_int) :: numNodes
          type(c_ptr), intent(out) :: api_localNodeCoord_
          integer(c_size_t) :: api_localNodeCoord_n_
          integer(c_int) :: numPrimaryNodes
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        character(len=:), allocatable, intent(out) :: elementName
        integer(c_int) :: dim
        integer(c_int) :: order
        integer(c_int) :: numNodes
        real(c_double), dimension(:), allocatable, intent(out) :: localNodeCoord
        integer(c_int) :: numPrimaryNodes
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementName_
        type(c_ptr) :: api_localNodeCoord_
        integer(c_size_t) :: api_localNodeCoord_n_
        call C_API(elementType=int(elementType, c_int), &
             api_elementName_=api_elementName_, &
             dim=dim, &
             order=order, &
             numNodes=numNodes, &
             api_localNodeCoord_=api_localNodeCoord_, &
             api_localNodeCoord_n_=api_localNodeCoord_n_, &
             numPrimaryNodes=numPrimaryNodes, &
             ierr_=ierr)
        elementName = ostring_(api_elementName_)
        localNodeCoord = ovectordouble_(api_localNodeCoord_, &
          api_localNodeCoord_n_)
      end subroutine gmshModelMeshGetElementProperties
    
      !> Get the elements of type `elementType' classified on the entity of tag
      !! `tag'. If `tag' < 0, get the elements for all entities. `elementTags' is a
      !! vector containing the tags (unique, strictly positive identifiers) of the
      !! elements of the corresponding type. `nodeTags' is a vector of length equal
      !! to the number of elements of the given type times the number N of nodes for
      !! this type of element, that contains the node tags of all the elements of
      !! the given type, concatenated: [e1n1, e1n2, ..., e1nN, e2n1, ...]. If
      !! `numTasks' > 1, only compute and return the part of the data indexed by
      !! `task' (for C++ only; output vectors must be preallocated).
      subroutine gmshModelMeshGetElementsByType(elementType, &
                                                elementTags, &
                                                nodeTags, &
                                                tag, &
                                                task, &
                                                numTasks, &
                                                ierr)
        interface
        subroutine C_API(elementType, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         tag, &
                         task, &
                         numTasks, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElementsByType")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          type(c_ptr), intent(out) :: api_elementTags_
          integer(c_size_t), intent(out) :: api_elementTags_n_
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_size_t), value, intent(in) :: task
          integer(c_size_t), value, intent(in) :: numTasks
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: elementTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        integer, intent(in), optional :: tag
        integer, intent(in), optional :: task
        integer, intent(in), optional :: numTasks
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementTags_
        integer(c_size_t) :: api_elementTags_n_
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        call C_API(elementType=int(elementType, c_int), &
             api_elementTags_=api_elementTags_, &
             api_elementTags_n_=api_elementTags_n_, &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             tag=optval_c_int(-1, tag), &
             task=optval_c_size_t(0, task), &
             numTasks=optval_c_size_t(1, numTasks), &
             ierr_=ierr)
        elementTags = ovectorsize_(api_elementTags_, &
          api_elementTags_n_)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
      end subroutine gmshModelMeshGetElementsByType
    
      !> Get the maximum tag `maxTag' of an element in the mesh.
      subroutine gmshModelMeshGetMaxElementTag(maxTag, &
                                               ierr)
        interface
        subroutine C_API(maxTag, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetMaxElementTag")
          use, intrinsic :: iso_c_binding
          integer(c_size_t) :: maxTag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t) :: maxTag
        integer(c_int), intent(out), optional :: ierr
        call C_API(maxTag=maxTag, &
             ierr_=ierr)
      end subroutine gmshModelMeshGetMaxElementTag
    
      !> Preallocate data before calling `getElementsByType' with `numTasks' > 1.
      !! For C++ only.
      subroutine gmshModelMeshPreallocateElementsByType(elementType, &
                                                        elementTag, &
                                                        nodeTag, &
                                                        elementTags, &
                                                        nodeTags, &
                                                        tag, &
                                                        ierr)
        interface
        subroutine C_API(elementType, &
                         elementTag, &
                         nodeTag, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshPreallocateElementsByType")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          integer(c_int), value, intent(in) :: elementTag
          integer(c_int), value, intent(in) :: nodeTag
          type(c_ptr), intent(out) :: api_elementTags_
          integer(c_size_t), intent(out) :: api_elementTags_n_
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        logical, intent(in) :: elementTag
        logical, intent(in) :: nodeTag
        integer(c_size_t), dimension(:), allocatable, intent(out) :: elementTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementTags_
        integer(c_size_t) :: api_elementTags_n_
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        call C_API(elementType=int(elementType, c_int), &
             elementTag=merge(1_c_int, 0_c_int, elementTag), &
             nodeTag=merge(1_c_int, 0_c_int, nodeTag), &
             api_elementTags_=api_elementTags_, &
             api_elementTags_n_=api_elementTags_n_, &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
        elementTags = ovectorsize_(api_elementTags_, &
          api_elementTags_n_)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
      end subroutine gmshModelMeshPreallocateElementsByType
    
      !> Get the quality `elementQualities' of the elements with tags `elementTags'.
      !! `qualityType' is the requested quality measure: "minDetJac" and "maxDetJac"
      !! for the adaptively computed minimal and maximal Jacobian determinant,
      !! "minSJ" for the sampled minimal scaled jacobien, "minSICN" for the sampled
      !! minimal signed inverted condition number, "minSIGE" for the sampled signed
      !! inverted gradient error, "gamma" for the ratio of the inscribed to
      !! circumcribed sphere radius, "innerRadius" for the inner radius,
      !! "outerRadius" for the outerRadius, "minIsotropy" for the minimum isotropy
      !! measure, "angleShape" for the angle shape measure, "minEdge" for the
      !! minimum straight edge length, "maxEdge" for the maximum straight edge
      !! length, "volume" for the volume. If `numTasks' > 1, only compute and return
      !! the part of the data indexed by `task' (for C++ only; output vector must be
      !! preallocated).
      subroutine gmshModelMeshGetElementQualities(elementTags, &
                                                  elementsQuality, &
                                                  qualityName, &
                                                  task, &
                                                  numTasks, &
                                                  ierr)
        interface
        subroutine C_API(api_elementTags_, &
                         api_elementTags_n_, &
                         api_elementsQuality_, &
                         api_elementsQuality_n_, &
                         qualityName, &
                         task, &
                         numTasks, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElementQualities")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), dimension(*) :: api_elementTags_
          integer(c_size_t), value, intent(in) :: api_elementTags_n_
          type(c_ptr), intent(out) :: api_elementsQuality_
          integer(c_size_t) :: api_elementsQuality_n_
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: qualityName
          integer(c_size_t), value, intent(in) :: task
          integer(c_size_t), value, intent(in) :: numTasks
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), intent(in) :: elementTags
        real(c_double), dimension(:), allocatable, intent(out) :: elementsQuality
        character(len=*), intent(in), optional :: qualityName
        integer, intent(in), optional :: task
        integer, intent(in), optional :: numTasks
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementsQuality_
        integer(c_size_t) :: api_elementsQuality_n_
        call C_API(api_elementTags_=elementTags, &
             api_elementTags_n_=size_gmsh_size(elementTags), &
             api_elementsQuality_=api_elementsQuality_, &
             api_elementsQuality_n_=api_elementsQuality_n_, &
             qualityName=istring_(optval_c_str("minSICN", qualityName)), &
             task=optval_c_size_t(0, task), &
             numTasks=optval_c_size_t(1, numTasks), &
             ierr_=ierr)
        elementsQuality = ovectordouble_(api_elementsQuality_, &
          api_elementsQuality_n_)
      end subroutine gmshModelMeshGetElementQualities
    
      !> Add elements classified on the entity of dimension `dim' and tag `tag'.
      !! `types' contains the MSH types of the elements (e.g. `2' for 3-node
      !! triangles: see the Gmsh reference manual). `elementTags' is a vector of the
      !! same length as `types'; each entry is a vector containing the tags (unique,
      !! strictly positive identifiers) of the elements of the corresponding type.
      !! `nodeTags' is also a vector of the same length as `types'; each entry is a
      !! vector of length equal to the number of elements of the given type times
      !! the number N of nodes per element, that contains the node tags of all the
      !! elements of the given type, concatenated: [e1n1, e1n2, ..., e1nN, e2n1,
      !! ...].
      subroutine gmshModelMeshAddElements(dim, &
                                          tag, &
                                          elementTypes, &
                                          elementTags, &
                                          elementTags_n, &
                                          nodeTags, &
                                          nodeTags_n, &
                                          ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_elementTypes_, &
                         api_elementTypes_n_, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         api_elementTags_nn_, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_nodeTags_nn_, &
                         ierr_) &
          bind(C, name="gmshModelMeshAddElements")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), dimension(*) :: api_elementTypes_
          integer(c_size_t), value, intent(in) :: api_elementTypes_n_
          type(c_ptr), intent(in) :: api_elementTags_
          type(c_ptr), intent(in) :: api_elementTags_n_
          integer(c_size_t), value, intent(in) :: api_elementTags_nn_
          type(c_ptr), intent(in) :: api_nodeTags_
          type(c_ptr), intent(in) :: api_nodeTags_n_
          integer(c_size_t), value, intent(in) :: api_nodeTags_nn_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int), dimension(:), intent(in) :: elementTypes
        integer(c_size_t), dimension(:), intent(in) :: elementTags
        integer(c_size_t), dimension(:), intent(in) :: elementTags_n
        integer(c_size_t), dimension(:), intent(in) :: nodeTags
        integer(c_size_t), dimension(:), intent(in) :: nodeTags_n
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementTags_
        type(c_ptr) :: api_elementTags_n_
        integer(c_size_t) :: api_elementTags_nn_
        type(c_ptr) :: api_nodeTags_
        type(c_ptr) :: api_nodeTags_n_
        integer(c_size_t) :: api_nodeTags_nn_
        call ivectorvectorsize_(elementTags, &
          elementTags_n, &
          api_elementTags_, &
          api_elementTags_n_, &
          api_elementTags_nn_)
        call ivectorvectorsize_(nodeTags, &
          nodeTags_n, &
          api_nodeTags_, &
          api_nodeTags_n_, &
          api_nodeTags_nn_)
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_elementTypes_=elementTypes, &
             api_elementTypes_n_=size_gmsh_int(elementTypes), &
             api_elementTags_=api_elementTags_, &
             api_elementTags_n_=api_elementTags_n_, &
             api_elementTags_nn_=api_elementTags_nn_, &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             api_nodeTags_nn_=api_nodeTags_nn_, &
             ierr_=ierr)
      end subroutine gmshModelMeshAddElements
    
      !> Add elements of type `elementType' classified on the entity of tag `tag'.
      !! `elementTags' contains the tags (unique, strictly positive identifiers) of
      !! the elements of the corresponding type. `nodeTags' is a vector of length
      !! equal to the number of elements times the number N of nodes per element,
      !! that contains the node tags of all the elements, concatenated: [e1n1, e1n2,
      !! ..., e1nN, e2n1, ...]. If the `elementTag' vector is empty, new tags are
      !! automatically assigned to the elements.
      subroutine gmshModelMeshAddElementsByType(tag, &
                                                elementType, &
                                                elementTags, &
                                                nodeTags, &
                                                ierr)
        interface
        subroutine C_API(tag, &
                         elementType, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshAddElementsByType")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: elementType
          integer(c_size_t), dimension(*) :: api_elementTags_
          integer(c_size_t), value, intent(in) :: api_elementTags_n_
          integer(c_size_t), dimension(*) :: api_nodeTags_
          integer(c_size_t), value, intent(in) :: api_nodeTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: elementType
        integer(c_size_t), dimension(:), intent(in) :: elementTags
        integer(c_size_t), dimension(:), intent(in) :: nodeTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             elementType=int(elementType, c_int), &
             api_elementTags_=elementTags, &
             api_elementTags_n_=size_gmsh_size(elementTags), &
             api_nodeTags_=nodeTags, &
             api_nodeTags_n_=size_gmsh_size(nodeTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshAddElementsByType
    
      !> Get the numerical quadrature information for the given element type
      !! `elementType' and integration rule `integrationType', where
      !! `integrationType' concatenates the integration rule family name with the
      !! desired order (e.g. "Gauss4" for a quadrature suited for integrating 4th
      !! order polynomials). The "CompositeGauss" family uses tensor-product rules
      !! based the 1D Gauss-Legendre rule; the "Gauss" family uses an economic
      !! scheme when available (i.e. with a minimal number of points), and falls
      !! back to "CompositeGauss" otherwise. Note that integration points for the
      !! "Gauss" family can fall outside of the reference element for high-order
      !! rules. `localCoord' contains the u, v, w coordinates of the G integration
      !! points in the reference element: [g1u, g1v, g1w, ..., gGu, gGv, gGw].
      !! `weights' contains the associated weights: [g1q, ..., gGq].
      subroutine gmshModelMeshGetIntegrationPoints(elementType, &
                                                   integrationType, &
                                                   localCoord, &
                                                   weights, &
                                                   ierr)
        interface
        subroutine C_API(elementType, &
                         integrationType, &
                         api_localCoord_, &
                         api_localCoord_n_, &
                         api_weights_, &
                         api_weights_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetIntegrationPoints")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          character(len=1, kind=c_char), dimension(*), intent(in) :: integrationType
          type(c_ptr), intent(out) :: api_localCoord_
          integer(c_size_t) :: api_localCoord_n_
          type(c_ptr), intent(out) :: api_weights_
          integer(c_size_t) :: api_weights_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        character(len=*), intent(in) :: integrationType
        real(c_double), dimension(:), allocatable, intent(out) :: localCoord
        real(c_double), dimension(:), allocatable, intent(out) :: weights
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_localCoord_
        integer(c_size_t) :: api_localCoord_n_
        type(c_ptr) :: api_weights_
        integer(c_size_t) :: api_weights_n_
        call C_API(elementType=int(elementType, c_int), &
             integrationType=istring_(integrationType), &
             api_localCoord_=api_localCoord_, &
             api_localCoord_n_=api_localCoord_n_, &
             api_weights_=api_weights_, &
             api_weights_n_=api_weights_n_, &
             ierr_=ierr)
        localCoord = ovectordouble_(api_localCoord_, &
          api_localCoord_n_)
        weights = ovectordouble_(api_weights_, &
          api_weights_n_)
      end subroutine gmshModelMeshGetIntegrationPoints
    
      !> Get the Jacobians of all the elements of type `elementType' classified on
      !! the entity of tag `tag', at the G evaluation points `localCoord' given as
      !! concatenated u, v, w coordinates in the reference element [g1u, g1v, g1w,
      !! ..., gGu, gGv, gGw]. Data is returned by element, with elements in the same
      !! order as in `getElements' and `getElementsByType'. `jacobians' contains for
      !! each element the 9 entries of the 3x3 Jacobian matrix at each evaluation
      !! point. The matrix is returned by column: [e1g1Jxu, e1g1Jyu, e1g1Jzu,
      !! e1g1Jxv, ..., e1g1Jzw, e1g2Jxu, ..., e1gGJzw, e2g1Jxu, ...], with Jxu =
      !! dx/du, Jyu = dy/du, etc. `determinants' contains for each element the
      !! determinant of the Jacobian matrix at each evaluation point: [e1g1, e1g2,
      !! ... e1gG, e2g1, ...]. `coord' contains for each element the x, y, z
      !! coordinates of the evaluation points. If `tag' < 0, get the Jacobian data
      !! for all entities. If `numTasks' > 1, only compute and return the part of
      !! the data indexed by `task' (for C++ only; output vectors must be
      !! preallocated).
      subroutine gmshModelMeshGetJacobians(elementType, &
                                           localCoord, &
                                           jacobians, &
                                           determinants, &
                                           coord, &
                                           tag, &
                                           task, &
                                           numTasks, &
                                           ierr)
        interface
        subroutine C_API(elementType, &
                         api_localCoord_, &
                         api_localCoord_n_, &
                         api_jacobians_, &
                         api_jacobians_n_, &
                         api_determinants_, &
                         api_determinants_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         tag, &
                         task, &
                         numTasks, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetJacobians")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          real(c_double), dimension(*) :: api_localCoord_
          integer(c_size_t), value, intent(in) :: api_localCoord_n_
          type(c_ptr), intent(out) :: api_jacobians_
          integer(c_size_t) :: api_jacobians_n_
          type(c_ptr), intent(out) :: api_determinants_
          integer(c_size_t) :: api_determinants_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_size_t), value, intent(in) :: task
          integer(c_size_t), value, intent(in) :: numTasks
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        real(c_double), dimension(:), intent(in) :: localCoord
        real(c_double), dimension(:), allocatable, intent(out) :: jacobians
        real(c_double), dimension(:), allocatable, intent(out) :: determinants
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        integer, intent(in), optional :: tag
        integer, intent(in), optional :: task
        integer, intent(in), optional :: numTasks
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_jacobians_
        integer(c_size_t) :: api_jacobians_n_
        type(c_ptr) :: api_determinants_
        integer(c_size_t) :: api_determinants_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        call C_API(elementType=int(elementType, c_int), &
             api_localCoord_=localCoord, &
             api_localCoord_n_=size_gmsh_double(localCoord), &
             api_jacobians_=api_jacobians_, &
             api_jacobians_n_=api_jacobians_n_, &
             api_determinants_=api_determinants_, &
             api_determinants_n_=api_determinants_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             tag=optval_c_int(-1, tag), &
             task=optval_c_size_t(0, task), &
             numTasks=optval_c_size_t(1, numTasks), &
             ierr_=ierr)
        jacobians = ovectordouble_(api_jacobians_, &
          api_jacobians_n_)
        determinants = ovectordouble_(api_determinants_, &
          api_determinants_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
      end subroutine gmshModelMeshGetJacobians
    
      !> Preallocate data before calling `getJacobians' with `numTasks' > 1. For C++
      !! only.
      subroutine gmshModelMeshPreallocateJacobians(elementType, &
                                                   numEvaluationPoints, &
                                                   allocateJacobians, &
                                                   allocateDeterminants, &
                                                   allocateCoord, &
                                                   jacobians, &
                                                   determinants, &
                                                   coord, &
                                                   tag, &
                                                   ierr)
        interface
        subroutine C_API(elementType, &
                         numEvaluationPoints, &
                         allocateJacobians, &
                         allocateDeterminants, &
                         allocateCoord, &
                         api_jacobians_, &
                         api_jacobians_n_, &
                         api_determinants_, &
                         api_determinants_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshPreallocateJacobians")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          integer(c_int), value, intent(in) :: numEvaluationPoints
          integer(c_int), value, intent(in) :: allocateJacobians
          integer(c_int), value, intent(in) :: allocateDeterminants
          integer(c_int), value, intent(in) :: allocateCoord
          type(c_ptr), intent(out) :: api_jacobians_
          integer(c_size_t) :: api_jacobians_n_
          type(c_ptr), intent(out) :: api_determinants_
          integer(c_size_t) :: api_determinants_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        integer, intent(in) :: numEvaluationPoints
        logical, intent(in) :: allocateJacobians
        logical, intent(in) :: allocateDeterminants
        logical, intent(in) :: allocateCoord
        real(c_double), dimension(:), allocatable, intent(out) :: jacobians
        real(c_double), dimension(:), allocatable, intent(out) :: determinants
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_jacobians_
        integer(c_size_t) :: api_jacobians_n_
        type(c_ptr) :: api_determinants_
        integer(c_size_t) :: api_determinants_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        call C_API(elementType=int(elementType, c_int), &
             numEvaluationPoints=int(numEvaluationPoints, c_int), &
             allocateJacobians=merge(1_c_int, 0_c_int, allocateJacobians), &
             allocateDeterminants=merge(1_c_int, 0_c_int, allocateDeterminants), &
             allocateCoord=merge(1_c_int, 0_c_int, allocateCoord), &
             api_jacobians_=api_jacobians_, &
             api_jacobians_n_=api_jacobians_n_, &
             api_determinants_=api_determinants_, &
             api_determinants_n_=api_determinants_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
        jacobians = ovectordouble_(api_jacobians_, &
          api_jacobians_n_)
        determinants = ovectordouble_(api_determinants_, &
          api_determinants_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
      end subroutine gmshModelMeshPreallocateJacobians
    
      !> Get the Jacobian for a single element `elementTag', at the G evaluation
      !! points `localCoord' given as concatenated u, v, w coordinates in the
      !! reference element [g1u, g1v, g1w, ..., gGu, gGv, gGw]. `jacobians' contains
      !! the 9 entries of the 3x3 Jacobian matrix at each evaluation point. The
      !! matrix is returned by column: [e1g1Jxu, e1g1Jyu, e1g1Jzu, e1g1Jxv, ...,
      !! e1g1Jzw, e1g2Jxu, ..., e1gGJzw, e2g1Jxu, ...], with Jxu = dx/du, Jyu =
      !! dy/du, etc. `determinants' contains the determinant of the Jacobian matrix
      !! at each evaluation point. `coord' contains the x, y, z coordinates of the
      !! evaluation points. This function relies on an internal cache (a vector in
      !! case of dense element numbering, a map otherwise); for large meshes
      !! accessing Jacobians in bulk is often preferable.
      subroutine gmshModelMeshGetJacobian(elementTag, &
                                          localCoord, &
                                          jacobians, &
                                          determinants, &
                                          coord, &
                                          ierr)
        interface
        subroutine C_API(elementTag, &
                         api_localCoord_, &
                         api_localCoord_n_, &
                         api_jacobians_, &
                         api_jacobians_n_, &
                         api_determinants_, &
                         api_determinants_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetJacobian")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), value, intent(in) :: elementTag
          real(c_double), dimension(*) :: api_localCoord_
          integer(c_size_t), value, intent(in) :: api_localCoord_n_
          type(c_ptr), intent(out) :: api_jacobians_
          integer(c_size_t) :: api_jacobians_n_
          type(c_ptr), intent(out) :: api_determinants_
          integer(c_size_t) :: api_determinants_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementTag
        real(c_double), dimension(:), intent(in) :: localCoord
        real(c_double), dimension(:), allocatable, intent(out) :: jacobians
        real(c_double), dimension(:), allocatable, intent(out) :: determinants
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_jacobians_
        integer(c_size_t) :: api_jacobians_n_
        type(c_ptr) :: api_determinants_
        integer(c_size_t) :: api_determinants_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        call C_API(elementTag=int(elementTag, c_size_t), &
             api_localCoord_=localCoord, &
             api_localCoord_n_=size_gmsh_double(localCoord), &
             api_jacobians_=api_jacobians_, &
             api_jacobians_n_=api_jacobians_n_, &
             api_determinants_=api_determinants_, &
             api_determinants_n_=api_determinants_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             ierr_=ierr)
        jacobians = ovectordouble_(api_jacobians_, &
          api_jacobians_n_)
        determinants = ovectordouble_(api_determinants_, &
          api_determinants_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
      end subroutine gmshModelMeshGetJacobian
    
      !> Get the basis functions of the element of type `elementType' at the
      !! evaluation points `localCoord' (given as concatenated u, v, w coordinates
      !! in the reference element [g1u, g1v, g1w, ..., gGu, gGv, gGw]), for the
      !! function space `functionSpaceType'. Currently supported function spaces
      !! include "Lagrange" and "GradLagrange" for isoparametric Lagrange basis
      !! functions and their gradient in the u, v, w coordinates of the reference
      !! element; "LagrangeN" and "GradLagrangeN", with N = 1, 2, ..., for N-th
      !! order Lagrange basis functions; "H1LegendreN" and "GradH1LegendreN", with N
      !! = 1, 2, ..., for N-th order hierarchical H1 Legendre functions;
      !! "HcurlLegendreN" and "CurlHcurlLegendreN", with N = 1, 2, ..., for N-th
      !! order curl-conforming basis functions. `numComponents' returns the number C
      !! of components of a basis function (e.g. 1 for scalar functions and 3 for
      !! vector functions). `basisFunctions' returns the value of the N basis
      !! functions at the evaluation points, i.e. [g1f1, g1f2, ..., g1fN, g2f1, ...]
      !! when C == 1 or [g1f1u, g1f1v, g1f1w, g1f2u, ..., g1fNw, g2f1u, ...] when C
      !! == 3. For basis functions that depend on the orientation of the elements,
      !! all values for the first orientation are returned first, followed by values
      !! for the second, etc. `numOrientations' returns the overall number of
      !! orientations. If the `wantedOrientations' vector is not empty, only return
      !! the values for the desired orientation indices.
      subroutine gmshModelMeshGetBasisFunctions(elementType, &
                                                localCoord, &
                                                functionSpaceType, &
                                                numComponents, &
                                                basisFunctions, &
                                                numOrientations, &
                                                wantedOrientations, &
                                                ierr)
        interface
        subroutine C_API(elementType, &
                         api_localCoord_, &
                         api_localCoord_n_, &
                         functionSpaceType, &
                         numComponents, &
                         api_basisFunctions_, &
                         api_basisFunctions_n_, &
                         numOrientations, &
                         api_wantedOrientations_, &
                         api_wantedOrientations_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetBasisFunctions")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          real(c_double), dimension(*) :: api_localCoord_
          integer(c_size_t), value, intent(in) :: api_localCoord_n_
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          integer(c_int) :: numComponents
          type(c_ptr), intent(out) :: api_basisFunctions_
          integer(c_size_t) :: api_basisFunctions_n_
          integer(c_int) :: numOrientations
          integer(c_int), dimension(*), optional :: api_wantedOrientations_
          integer(c_size_t), value, intent(in) :: api_wantedOrientations_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        real(c_double), dimension(:), intent(in) :: localCoord
        character(len=*), intent(in) :: functionSpaceType
        integer(c_int) :: numComponents
        real(c_double), dimension(:), allocatable, intent(out) :: basisFunctions
        integer(c_int) :: numOrientations
        integer(c_int), dimension(:), intent(in), optional :: wantedOrientations
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_basisFunctions_
        integer(c_size_t) :: api_basisFunctions_n_
        call C_API(elementType=int(elementType, c_int), &
             api_localCoord_=localCoord, &
             api_localCoord_n_=size_gmsh_double(localCoord), &
             functionSpaceType=istring_(functionSpaceType), &
             numComponents=numComponents, &
             api_basisFunctions_=api_basisFunctions_, &
             api_basisFunctions_n_=api_basisFunctions_n_, &
             numOrientations=numOrientations, &
             api_wantedOrientations_=wantedOrientations, &
             api_wantedOrientations_n_=size_gmsh_int(wantedOrientations), &
             ierr_=ierr)
        basisFunctions = ovectordouble_(api_basisFunctions_, &
          api_basisFunctions_n_)
      end subroutine gmshModelMeshGetBasisFunctions
    
      !> Get the orientation index of the elements of type `elementType' in the
      !! entity of tag `tag'. The arguments have the same meaning as in
      !! `getBasisFunctions'. `basisFunctionsOrientation' is a vector giving for
      !! each element the orientation index in the values returned by
      !! `getBasisFunctions'. For Lagrange basis functions the call is superfluous
      !! as it will return a vector of zeros. If `numTasks' > 1, only compute and
      !! return the part of the data indexed by `task' (for C++ only; output vector
      !! must be preallocated).
      subroutine gmshModelMeshGetBasisFunctionsOrientation(elementType, &
                                                           functionSpaceType, &
                                                           basisFunctionsOrientation, &
                                                           tag, &
                                                           task, &
                                                           numTasks, &
                                                           ierr)
        interface
        subroutine C_API(elementType, &
                         functionSpaceType, &
                         api_basisFunctionsOrientation_, &
                         api_basisFunctionsOrientation_n_, &
                         tag, &
                         task, &
                         numTasks, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetBasisFunctionsOrientation")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          type(c_ptr), intent(out) :: api_basisFunctionsOrientation_
          integer(c_size_t), intent(out) :: api_basisFunctionsOrientation_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_size_t), value, intent(in) :: task
          integer(c_size_t), value, intent(in) :: numTasks
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        character(len=*), intent(in) :: functionSpaceType
        integer(c_int), dimension(:), allocatable, intent(out) :: basisFunctionsOrientation
        integer, intent(in), optional :: tag
        integer, intent(in), optional :: task
        integer, intent(in), optional :: numTasks
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_basisFunctionsOrientation_
        integer(c_size_t) :: api_basisFunctionsOrientation_n_
        call C_API(elementType=int(elementType, c_int), &
             functionSpaceType=istring_(functionSpaceType), &
             api_basisFunctionsOrientation_=api_basisFunctionsOrientation_, &
             api_basisFunctionsOrientation_n_=api_basisFunctionsOrientation_n_, &
             tag=optval_c_int(-1, tag), &
             task=optval_c_size_t(0, task), &
             numTasks=optval_c_size_t(1, numTasks), &
             ierr_=ierr)
        basisFunctionsOrientation = ovectorint_(api_basisFunctionsOrientation_, &
          api_basisFunctionsOrientation_n_)
      end subroutine gmshModelMeshGetBasisFunctionsOrientation
    
      !> Get the orientation of a single element `elementTag'.
      subroutine gmshModelMeshGetBasisFunctionsOrientationForElement(elementTag, &
                                                                     functionSpaceType, &
                                                                     basisFunctionsOrientation, &
                                                                     ierr)
        interface
        subroutine C_API(elementTag, &
                         functionSpaceType, &
                         basisFunctionsOrientation, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetBasisFunctionsOrientationForElement")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), value, intent(in) :: elementTag
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          integer(c_int) :: basisFunctionsOrientation
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementTag
        character(len=*), intent(in) :: functionSpaceType
        integer(c_int) :: basisFunctionsOrientation
        integer(c_int), intent(out), optional :: ierr
        call C_API(elementTag=int(elementTag, c_size_t), &
             functionSpaceType=istring_(functionSpaceType), &
             basisFunctionsOrientation=basisFunctionsOrientation, &
             ierr_=ierr)
      end subroutine gmshModelMeshGetBasisFunctionsOrientationForElement
    
      !> Get the number of possible orientations for elements of type `elementType'
      !! and function space named `functionSpaceType'.
      function gmshModelMeshGetNumberOfOrientations(elementType, &
                                                    functionSpaceType, &
                                                    ierr)
        interface
        function C_API(elementType, &
                       functionSpaceType, &
                       ierr_) &
          bind(C, name="gmshModelMeshGetNumberOfOrientations")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: elementType
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelMeshGetNumberOfOrientations
        integer, intent(in) :: elementType
        character(len=*), intent(in) :: functionSpaceType
        integer(c_int), intent(out), optional :: ierr
        gmshModelMeshGetNumberOfOrientations = C_API(elementType=int(elementType, c_int), &
                                               functionSpaceType=istring_(functionSpaceType), &
                                               ierr_=ierr)
      end function gmshModelMeshGetNumberOfOrientations
    
      !> Preallocate data before calling `getBasisFunctionsOrientation' with
      !! `numTasks' > 1. For C++ only.
      subroutine gmshModelMeshPreallocateBasisFunctionsOrientation(elementType, &
                                                                   basisFunctionsOrientation, &
                                                                   tag, &
                                                                   ierr)
        interface
        subroutine C_API(elementType, &
                         api_basisFunctionsOrientation_, &
                         api_basisFunctionsOrientation_n_, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshPreallocateBasisFunctionsOrientation")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          type(c_ptr), intent(out) :: api_basisFunctionsOrientation_
          integer(c_size_t), intent(out) :: api_basisFunctionsOrientation_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        integer(c_int), dimension(:), allocatable, intent(out) :: basisFunctionsOrientation
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_basisFunctionsOrientation_
        integer(c_size_t) :: api_basisFunctionsOrientation_n_
        call C_API(elementType=int(elementType, c_int), &
             api_basisFunctionsOrientation_=api_basisFunctionsOrientation_, &
             api_basisFunctionsOrientation_n_=api_basisFunctionsOrientation_n_, &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
        basisFunctionsOrientation = ovectorint_(api_basisFunctionsOrientation_, &
          api_basisFunctionsOrientation_n_)
      end subroutine gmshModelMeshPreallocateBasisFunctionsOrientation
    
      !> Get the global unique mesh edge identifiers `edgeTags' and orientations
      !! `edgeOrientation' for an input list of node tag pairs defining these edges,
      !! concatenated in the vector `nodeTags'. Mesh edges are created e.g. by
      !! `createEdges()', `getKeys()' or `addEdges()'. The reference positive
      !! orientation is n1 < n2, where n1 and n2 are the tags of the two edge nodes,
      !! which corresponds to the local orientation of edge-based basis functions as
      !! well.
      subroutine gmshModelMeshGetEdges(nodeTags, &
                                       edgeTags, &
                                       edgeOrientations, &
                                       ierr)
        interface
        subroutine C_API(api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_edgeTags_, &
                         api_edgeTags_n_, &
                         api_edgeOrientations_, &
                         api_edgeOrientations_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetEdges")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), dimension(*) :: api_nodeTags_
          integer(c_size_t), value, intent(in) :: api_nodeTags_n_
          type(c_ptr), intent(out) :: api_edgeTags_
          integer(c_size_t), intent(out) :: api_edgeTags_n_
          type(c_ptr), intent(out) :: api_edgeOrientations_
          integer(c_size_t), intent(out) :: api_edgeOrientations_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), intent(in) :: nodeTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: edgeTags
        integer(c_int), dimension(:), allocatable, intent(out) :: edgeOrientations
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_edgeTags_
        integer(c_size_t) :: api_edgeTags_n_
        type(c_ptr) :: api_edgeOrientations_
        integer(c_size_t) :: api_edgeOrientations_n_
        call C_API(api_nodeTags_=nodeTags, &
             api_nodeTags_n_=size_gmsh_size(nodeTags), &
             api_edgeTags_=api_edgeTags_, &
             api_edgeTags_n_=api_edgeTags_n_, &
             api_edgeOrientations_=api_edgeOrientations_, &
             api_edgeOrientations_n_=api_edgeOrientations_n_, &
             ierr_=ierr)
        edgeTags = ovectorsize_(api_edgeTags_, &
          api_edgeTags_n_)
        edgeOrientations = ovectorint_(api_edgeOrientations_, &
          api_edgeOrientations_n_)
      end subroutine gmshModelMeshGetEdges
    
      !> Get the global unique mesh face identifiers `faceTags' and orientations
      !! `faceOrientations' for an input list of a multiple of three (if `faceType'
      !! == 3) or four (if `faceType' == 4) node tags defining these faces,
      !! concatenated in the vector `nodeTags'. Mesh faces are created e.g. by
      !! `createFaces()', `getKeys()' or `addFaces()'.
      subroutine gmshModelMeshGetFaces(faceType, &
                                       nodeTags, &
                                       faceTags, &
                                       faceOrientations, &
                                       ierr)
        interface
        subroutine C_API(faceType, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_faceTags_, &
                         api_faceTags_n_, &
                         api_faceOrientations_, &
                         api_faceOrientations_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetFaces")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: faceType
          integer(c_size_t), dimension(*) :: api_nodeTags_
          integer(c_size_t), value, intent(in) :: api_nodeTags_n_
          type(c_ptr), intent(out) :: api_faceTags_
          integer(c_size_t), intent(out) :: api_faceTags_n_
          type(c_ptr), intent(out) :: api_faceOrientations_
          integer(c_size_t), intent(out) :: api_faceOrientations_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: faceType
        integer(c_size_t), dimension(:), intent(in) :: nodeTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: faceTags
        integer(c_int), dimension(:), allocatable, intent(out) :: faceOrientations
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_faceTags_
        integer(c_size_t) :: api_faceTags_n_
        type(c_ptr) :: api_faceOrientations_
        integer(c_size_t) :: api_faceOrientations_n_
        call C_API(faceType=int(faceType, c_int), &
             api_nodeTags_=nodeTags, &
             api_nodeTags_n_=size_gmsh_size(nodeTags), &
             api_faceTags_=api_faceTags_, &
             api_faceTags_n_=api_faceTags_n_, &
             api_faceOrientations_=api_faceOrientations_, &
             api_faceOrientations_n_=api_faceOrientations_n_, &
             ierr_=ierr)
        faceTags = ovectorsize_(api_faceTags_, &
          api_faceTags_n_)
        faceOrientations = ovectorint_(api_faceOrientations_, &
          api_faceOrientations_n_)
      end subroutine gmshModelMeshGetFaces
    
      !> Create unique mesh edges for the entities `dimTags', given as a vector of
      !! (dim, tag) pairs.
      subroutine gmshModelMeshCreateEdges(dimTags, &
                                          ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshCreateEdges")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshCreateEdges
    
      !> Create unique mesh faces for the entities `dimTags', given as a vector of
      !! (dim, tag) pairs.
      subroutine gmshModelMeshCreateFaces(dimTags, &
                                          ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshCreateFaces")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshCreateFaces
    
      !> Get the global unique identifiers `edgeTags' and the nodes `edgeNodes' of
      !! the edges in the mesh. Mesh edges are created e.g. by `createEdges()',
      !! `getKeys()' or addEdges().
      subroutine gmshModelMeshGetAllEdges(edgeTags, &
                                          edgeNodes, &
                                          ierr)
        interface
        subroutine C_API(api_edgeTags_, &
                         api_edgeTags_n_, &
                         api_edgeNodes_, &
                         api_edgeNodes_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetAllEdges")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_edgeTags_
          integer(c_size_t), intent(out) :: api_edgeTags_n_
          type(c_ptr), intent(out) :: api_edgeNodes_
          integer(c_size_t), intent(out) :: api_edgeNodes_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), allocatable, intent(out) :: edgeTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: edgeNodes
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_edgeTags_
        integer(c_size_t) :: api_edgeTags_n_
        type(c_ptr) :: api_edgeNodes_
        integer(c_size_t) :: api_edgeNodes_n_
        call C_API(api_edgeTags_=api_edgeTags_, &
             api_edgeTags_n_=api_edgeTags_n_, &
             api_edgeNodes_=api_edgeNodes_, &
             api_edgeNodes_n_=api_edgeNodes_n_, &
             ierr_=ierr)
        edgeTags = ovectorsize_(api_edgeTags_, &
          api_edgeTags_n_)
        edgeNodes = ovectorsize_(api_edgeNodes_, &
          api_edgeNodes_n_)
      end subroutine gmshModelMeshGetAllEdges
    
      !> Get the global unique identifiers `faceTags' and the nodes `faceNodes' of
      !! the faces of type `faceType' in the mesh. Mesh faces are created e.g. by
      !! `createFaces()', `getKeys()' or addFaces().
      subroutine gmshModelMeshGetAllFaces(faceType, &
                                          faceTags, &
                                          faceNodes, &
                                          ierr)
        interface
        subroutine C_API(faceType, &
                         api_faceTags_, &
                         api_faceTags_n_, &
                         api_faceNodes_, &
                         api_faceNodes_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetAllFaces")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: faceType
          type(c_ptr), intent(out) :: api_faceTags_
          integer(c_size_t), intent(out) :: api_faceTags_n_
          type(c_ptr), intent(out) :: api_faceNodes_
          integer(c_size_t), intent(out) :: api_faceNodes_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: faceType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: faceTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: faceNodes
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_faceTags_
        integer(c_size_t) :: api_faceTags_n_
        type(c_ptr) :: api_faceNodes_
        integer(c_size_t) :: api_faceNodes_n_
        call C_API(faceType=int(faceType, c_int), &
             api_faceTags_=api_faceTags_, &
             api_faceTags_n_=api_faceTags_n_, &
             api_faceNodes_=api_faceNodes_, &
             api_faceNodes_n_=api_faceNodes_n_, &
             ierr_=ierr)
        faceTags = ovectorsize_(api_faceTags_, &
          api_faceTags_n_)
        faceNodes = ovectorsize_(api_faceNodes_, &
          api_faceNodes_n_)
      end subroutine gmshModelMeshGetAllFaces
    
      !> Add mesh edges defined by their global unique identifiers `edgeTags' and
      !! their nodes `edgeNodes'.
      subroutine gmshModelMeshAddEdges(edgeTags, &
                                       edgeNodes, &
                                       ierr)
        interface
        subroutine C_API(api_edgeTags_, &
                         api_edgeTags_n_, &
                         api_edgeNodes_, &
                         api_edgeNodes_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshAddEdges")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), dimension(*) :: api_edgeTags_
          integer(c_size_t), value, intent(in) :: api_edgeTags_n_
          integer(c_size_t), dimension(*) :: api_edgeNodes_
          integer(c_size_t), value, intent(in) :: api_edgeNodes_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), intent(in) :: edgeTags
        integer(c_size_t), dimension(:), intent(in) :: edgeNodes
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_edgeTags_=edgeTags, &
             api_edgeTags_n_=size_gmsh_size(edgeTags), &
             api_edgeNodes_=edgeNodes, &
             api_edgeNodes_n_=size_gmsh_size(edgeNodes), &
             ierr_=ierr)
      end subroutine gmshModelMeshAddEdges
    
      !> Add mesh faces of type `faceType' defined by their global unique
      !! identifiers `faceTags' and their nodes `faceNodes'.
      subroutine gmshModelMeshAddFaces(faceType, &
                                       faceTags, &
                                       faceNodes, &
                                       ierr)
        interface
        subroutine C_API(faceType, &
                         api_faceTags_, &
                         api_faceTags_n_, &
                         api_faceNodes_, &
                         api_faceNodes_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshAddFaces")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: faceType
          integer(c_size_t), dimension(*) :: api_faceTags_
          integer(c_size_t), value, intent(in) :: api_faceTags_n_
          integer(c_size_t), dimension(*) :: api_faceNodes_
          integer(c_size_t), value, intent(in) :: api_faceNodes_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: faceType
        integer(c_size_t), dimension(:), intent(in) :: faceTags
        integer(c_size_t), dimension(:), intent(in) :: faceNodes
        integer(c_int), intent(out), optional :: ierr
        call C_API(faceType=int(faceType, c_int), &
             api_faceTags_=faceTags, &
             api_faceTags_n_=size_gmsh_size(faceTags), &
             api_faceNodes_=faceNodes, &
             api_faceNodes_n_=size_gmsh_size(faceNodes), &
             ierr_=ierr)
      end subroutine gmshModelMeshAddFaces
    
      !> Generate the pair of keys for the elements of type `elementType' in the
      !! entity of tag `tag', for the `functionSpaceType' function space. Each pair
      !! (`typeKey', `entityKey') uniquely identifies a basis function in the
      !! function space. If `returnCoord' is set, the `coord' vector contains the x,
      !! y, z coordinates locating basis functions for sorting purposes. Warning:
      !! this is an experimental feature and will probably change in a future
      !! release.
      subroutine gmshModelMeshGetKeys(elementType, &
                                      functionSpaceType, &
                                      typeKeys, &
                                      entityKeys, &
                                      coord, &
                                      tag, &
                                      returnCoord, &
                                      ierr)
        interface
        subroutine C_API(elementType, &
                         functionSpaceType, &
                         api_typeKeys_, &
                         api_typeKeys_n_, &
                         api_entityKeys_, &
                         api_entityKeys_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         tag, &
                         returnCoord, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetKeys")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          type(c_ptr), intent(out) :: api_typeKeys_
          integer(c_size_t), intent(out) :: api_typeKeys_n_
          type(c_ptr), intent(out) :: api_entityKeys_
          integer(c_size_t), intent(out) :: api_entityKeys_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: returnCoord
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        character(len=*), intent(in) :: functionSpaceType
        integer(c_int), dimension(:), allocatable, intent(out) :: typeKeys
        integer(c_size_t), dimension(:), allocatable, intent(out) :: entityKeys
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: returnCoord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_typeKeys_
        integer(c_size_t) :: api_typeKeys_n_
        type(c_ptr) :: api_entityKeys_
        integer(c_size_t) :: api_entityKeys_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        call C_API(elementType=int(elementType, c_int), &
             functionSpaceType=istring_(functionSpaceType), &
             api_typeKeys_=api_typeKeys_, &
             api_typeKeys_n_=api_typeKeys_n_, &
             api_entityKeys_=api_entityKeys_, &
             api_entityKeys_n_=api_entityKeys_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             tag=optval_c_int(-1, tag), &
             returnCoord=optval_c_bool(.true., returnCoord), &
             ierr_=ierr)
        typeKeys = ovectorint_(api_typeKeys_, &
          api_typeKeys_n_)
        entityKeys = ovectorsize_(api_entityKeys_, &
          api_entityKeys_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
      end subroutine gmshModelMeshGetKeys
    
      !> Get the pair of keys for a single element `elementTag'.
      subroutine gmshModelMeshGetKeysForElement(elementTag, &
                                                functionSpaceType, &
                                                typeKeys, &
                                                entityKeys, &
                                                coord, &
                                                returnCoord, &
                                                ierr)
        interface
        subroutine C_API(elementTag, &
                         functionSpaceType, &
                         api_typeKeys_, &
                         api_typeKeys_n_, &
                         api_entityKeys_, &
                         api_entityKeys_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         returnCoord, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetKeysForElement")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), value, intent(in) :: elementTag
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          type(c_ptr), intent(out) :: api_typeKeys_
          integer(c_size_t), intent(out) :: api_typeKeys_n_
          type(c_ptr), intent(out) :: api_entityKeys_
          integer(c_size_t), intent(out) :: api_entityKeys_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          integer(c_int), value, intent(in) :: returnCoord
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementTag
        character(len=*), intent(in) :: functionSpaceType
        integer(c_int), dimension(:), allocatable, intent(out) :: typeKeys
        integer(c_size_t), dimension(:), allocatable, intent(out) :: entityKeys
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        logical, intent(in), optional :: returnCoord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_typeKeys_
        integer(c_size_t) :: api_typeKeys_n_
        type(c_ptr) :: api_entityKeys_
        integer(c_size_t) :: api_entityKeys_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        call C_API(elementTag=int(elementTag, c_size_t), &
             functionSpaceType=istring_(functionSpaceType), &
             api_typeKeys_=api_typeKeys_, &
             api_typeKeys_n_=api_typeKeys_n_, &
             api_entityKeys_=api_entityKeys_, &
             api_entityKeys_n_=api_entityKeys_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             returnCoord=optval_c_bool(.true., returnCoord), &
             ierr_=ierr)
        typeKeys = ovectorint_(api_typeKeys_, &
          api_typeKeys_n_)
        entityKeys = ovectorsize_(api_entityKeys_, &
          api_entityKeys_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
      end subroutine gmshModelMeshGetKeysForElement
    
      !> Get the number of keys by elements of type `elementType' for function space
      !! named `functionSpaceType'.
      function gmshModelMeshGetNumberOfKeys(elementType, &
                                            functionSpaceType, &
                                            ierr)
        interface
        function C_API(elementType, &
                       functionSpaceType, &
                       ierr_) &
          bind(C, name="gmshModelMeshGetNumberOfKeys")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: elementType
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelMeshGetNumberOfKeys
        integer, intent(in) :: elementType
        character(len=*), intent(in) :: functionSpaceType
        integer(c_int), intent(out), optional :: ierr
        gmshModelMeshGetNumberOfKeys = C_API(elementType=int(elementType, c_int), &
                                       functionSpaceType=istring_(functionSpaceType), &
                                       ierr_=ierr)
      end function gmshModelMeshGetNumberOfKeys
    
      !> Get information about the pair of `keys'. `infoKeys' returns information
      !! about the functions associated with the pairs (`typeKeys', `entityKey').
      !! `infoKeys[0].first' describes the type of function (0 for  vertex function,
      !! 1 for edge function, 2 for face function and 3 for bubble function).
      !! `infoKeys[0].second' gives the order of the function associated with the
      !! key. Warning: this is an experimental feature and will probably change in a
      !! future release.
      subroutine gmshModelMeshGetKeysInformation(typeKeys, &
                                                 entityKeys, &
                                                 elementType, &
                                                 functionSpaceType, &
                                                 infoKeys, &
                                                 ierr)
        interface
        subroutine C_API(api_typeKeys_, &
                         api_typeKeys_n_, &
                         api_entityKeys_, &
                         api_entityKeys_n_, &
                         elementType, &
                         functionSpaceType, &
                         api_infoKeys_, &
                         api_infoKeys_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetKeysInformation")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_typeKeys_
          integer(c_size_t), value, intent(in) :: api_typeKeys_n_
          integer(c_size_t), dimension(*) :: api_entityKeys_
          integer(c_size_t), value, intent(in) :: api_entityKeys_n_
          integer(c_int), value, intent(in) :: elementType
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          type(c_ptr), intent(out) :: api_infoKeys_
          integer(c_size_t), intent(out) :: api_infoKeys_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), intent(in) :: typeKeys
        integer(c_size_t), dimension(:), intent(in) :: entityKeys
        integer, intent(in) :: elementType
        character(len=*), intent(in) :: functionSpaceType
        integer(c_int), dimension(:,:), allocatable, intent(out) :: infoKeys
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_infoKeys_
        integer(c_size_t) :: api_infoKeys_n_
        call C_API(api_typeKeys_=typeKeys, &
             api_typeKeys_n_=size_gmsh_int(typeKeys), &
             api_entityKeys_=entityKeys, &
             api_entityKeys_n_=size_gmsh_size(entityKeys), &
             elementType=int(elementType, c_int), &
             functionSpaceType=istring_(functionSpaceType), &
             api_infoKeys_=api_infoKeys_, &
             api_infoKeys_n_=api_infoKeys_n_, &
             ierr_=ierr)
        infoKeys = ovectorpair_(api_infoKeys_, &
          api_infoKeys_n_)
      end subroutine gmshModelMeshGetKeysInformation
    
      !> Get the barycenters of all elements of type `elementType' classified on the
      !! entity of tag `tag'. If `primary' is set, only the primary nodes of the
      !! elements are taken into account for the barycenter calculation. If `fast'
      !! is set, the function returns the sum of the primary node coordinates
      !! (without normalizing by the number of nodes). If `tag' < 0, get the
      !! barycenters for all entities. If `numTasks' > 1, only compute and return
      !! the part of the data indexed by `task' (for C++ only; output vector must be
      !! preallocated).
      subroutine gmshModelMeshGetBarycenters(elementType, &
                                             tag, &
                                             fast, &
                                             primary, &
                                             barycenters, &
                                             task, &
                                             numTasks, &
                                             ierr)
        interface
        subroutine C_API(elementType, &
                         tag, &
                         fast, &
                         primary, &
                         api_barycenters_, &
                         api_barycenters_n_, &
                         task, &
                         numTasks, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetBarycenters")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: fast
          integer(c_int), value, intent(in) :: primary
          type(c_ptr), intent(out) :: api_barycenters_
          integer(c_size_t) :: api_barycenters_n_
          integer(c_size_t), value, intent(in) :: task
          integer(c_size_t), value, intent(in) :: numTasks
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        integer, intent(in) :: tag
        logical, intent(in) :: fast
        logical, intent(in) :: primary
        real(c_double), dimension(:), allocatable, intent(out) :: barycenters
        integer, intent(in), optional :: task
        integer, intent(in), optional :: numTasks
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_barycenters_
        integer(c_size_t) :: api_barycenters_n_
        call C_API(elementType=int(elementType, c_int), &
             tag=int(tag, c_int), &
             fast=merge(1_c_int, 0_c_int, fast), &
             primary=merge(1_c_int, 0_c_int, primary), &
             api_barycenters_=api_barycenters_, &
             api_barycenters_n_=api_barycenters_n_, &
             task=optval_c_size_t(0, task), &
             numTasks=optval_c_size_t(1, numTasks), &
             ierr_=ierr)
        barycenters = ovectordouble_(api_barycenters_, &
          api_barycenters_n_)
      end subroutine gmshModelMeshGetBarycenters
    
      !> Preallocate data before calling `getBarycenters' with `numTasks' > 1. For
      !! C++ only.
      subroutine gmshModelMeshPreallocateBarycenters(elementType, &
                                                     barycenters, &
                                                     tag, &
                                                     ierr)
        interface
        subroutine C_API(elementType, &
                         api_barycenters_, &
                         api_barycenters_n_, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshPreallocateBarycenters")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          type(c_ptr), intent(out) :: api_barycenters_
          integer(c_size_t) :: api_barycenters_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        real(c_double), dimension(:), allocatable, intent(out) :: barycenters
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_barycenters_
        integer(c_size_t) :: api_barycenters_n_
        call C_API(elementType=int(elementType, c_int), &
             api_barycenters_=api_barycenters_, &
             api_barycenters_n_=api_barycenters_n_, &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
        barycenters = ovectordouble_(api_barycenters_, &
          api_barycenters_n_)
      end subroutine gmshModelMeshPreallocateBarycenters
    
      !> Get the nodes on the edges of all elements of type `elementType' classified
      !! on the entity of tag `tag'. `nodeTags' contains the node tags of the edges
      !! for all the elements: [e1a1n1, e1a1n2, e1a2n1, ...]. Data is returned by
      !! element, with elements in the same order as in `getElements' and
      !! `getElementsByType'. If `primary' is set, only the primary (begin/end)
      !! nodes of the edges are returned. If `tag' < 0, get the edge nodes for all
      !! entities. If `numTasks' > 1, only compute and return the part of the data
      !! indexed by `task' (for C++ only; output vector must be preallocated).
      subroutine gmshModelMeshGetElementEdgeNodes(elementType, &
                                                  nodeTags, &
                                                  tag, &
                                                  primary, &
                                                  task, &
                                                  numTasks, &
                                                  ierr)
        interface
        subroutine C_API(elementType, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         tag, &
                         primary, &
                         task, &
                         numTasks, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElementEdgeNodes")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: primary
          integer(c_size_t), value, intent(in) :: task
          integer(c_size_t), value, intent(in) :: numTasks
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: primary
        integer, intent(in), optional :: task
        integer, intent(in), optional :: numTasks
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        call C_API(elementType=int(elementType, c_int), &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             tag=optval_c_int(-1, tag), &
             primary=optval_c_bool(.false., primary), &
             task=optval_c_size_t(0, task), &
             numTasks=optval_c_size_t(1, numTasks), &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
      end subroutine gmshModelMeshGetElementEdgeNodes
    
      !> Get the nodes on the faces of type `faceType' (3 for triangular faces, 4
      !! for quadrangular faces) of all elements of type `elementType' classified on
      !! the entity of tag `tag'. `nodeTags' contains the node tags of the faces for
      !! all elements: [e1f1n1, ..., e1f1nFaceType, e1f2n1, ...]. Data is returned
      !! by element, with elements in the same order as in `getElements' and
      !! `getElementsByType'. If `primary' is set, only the primary (corner) nodes
      !! of the faces are returned. If `tag' < 0, get the face nodes for all
      !! entities. If `numTasks' > 1, only compute and return the part of the data
      !! indexed by `task' (for C++ only; output vector must be preallocated).
      subroutine gmshModelMeshGetElementFaceNodes(elementType, &
                                                  faceType, &
                                                  nodeTags, &
                                                  tag, &
                                                  primary, &
                                                  task, &
                                                  numTasks, &
                                                  ierr)
        interface
        subroutine C_API(elementType, &
                         faceType, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         tag, &
                         primary, &
                         task, &
                         numTasks, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetElementFaceNodes")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          integer(c_int), value, intent(in) :: faceType
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: primary
          integer(c_size_t), value, intent(in) :: task
          integer(c_size_t), value, intent(in) :: numTasks
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        integer, intent(in) :: faceType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: primary
        integer, intent(in), optional :: task
        integer, intent(in), optional :: numTasks
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        call C_API(elementType=int(elementType, c_int), &
             faceType=int(faceType, c_int), &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             tag=optval_c_int(-1, tag), &
             primary=optval_c_bool(.false., primary), &
             task=optval_c_size_t(0, task), &
             numTasks=optval_c_size_t(1, numTasks), &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
      end subroutine gmshModelMeshGetElementFaceNodes
    
      !> Get the ghost elements `elementTags' and their associated `partitions'
      !! stored in the ghost entity of dimension `dim' and tag `tag'.
      subroutine gmshModelMeshGetGhostElements(dim, &
                                               tag, &
                                               elementTags, &
                                               partitions, &
                                               ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         api_partitions_, &
                         api_partitions_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetGhostElements")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_elementTags_
          integer(c_size_t), intent(out) :: api_elementTags_n_
          type(c_ptr), intent(out) :: api_partitions_
          integer(c_size_t), intent(out) :: api_partitions_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_size_t), dimension(:), allocatable, intent(out) :: elementTags
        integer(c_int), dimension(:), allocatable, intent(out) :: partitions
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementTags_
        integer(c_size_t) :: api_elementTags_n_
        type(c_ptr) :: api_partitions_
        integer(c_size_t) :: api_partitions_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_elementTags_=api_elementTags_, &
             api_elementTags_n_=api_elementTags_n_, &
             api_partitions_=api_partitions_, &
             api_partitions_n_=api_partitions_n_, &
             ierr_=ierr)
        elementTags = ovectorsize_(api_elementTags_, &
          api_elementTags_n_)
        partitions = ovectorint_(api_partitions_, &
          api_partitions_n_)
      end subroutine gmshModelMeshGetGhostElements
    
      !> Set a mesh size constraint on the model entities `dimTags', given as a
      !! vector of (dim, tag) pairs. Currently only entities of dimension 0 (points)
      !! are handled.
      subroutine gmshModelMeshSetSize(dimTags, &
                                      size, &
                                      ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         size, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetSize")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: size
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: size
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             size=real(size, c_double), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetSize
    
      !> Get the mesh size constraints (if any) associated with the model entities
      !! `dimTags', given as a vector of (dim, tag) pairs. A zero entry in the
      !! output `sizes' vector indicates that no size constraint is specified on the
      !! corresponding entity.
      subroutine gmshModelMeshGetSizes(dimTags, &
                                       sizes, &
                                       ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         api_sizes_, &
                         api_sizes_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetSizes")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          type(c_ptr), intent(out) :: api_sizes_
          integer(c_size_t) :: api_sizes_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), dimension(:), allocatable, intent(out) :: sizes
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_sizes_
        integer(c_size_t) :: api_sizes_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             api_sizes_=api_sizes_, &
             api_sizes_n_=api_sizes_n_, &
             ierr_=ierr)
        sizes = ovectordouble_(api_sizes_, &
          api_sizes_n_)
      end subroutine gmshModelMeshGetSizes
    
      !> 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.
      subroutine gmshModelMeshSetSizeAtParametricPoints(dim, &
                                                        tag, &
                                                        parametricCoord, &
                                                        sizes, &
                                                        ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_parametricCoord_, &
                         api_parametricCoord_n_, &
                         api_sizes_, &
                         api_sizes_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetSizeAtParametricPoints")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_parametricCoord_
          integer(c_size_t), value, intent(in) :: api_parametricCoord_n_
          real(c_double), dimension(*) :: api_sizes_
          integer(c_size_t), value, intent(in) :: api_sizes_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: parametricCoord
        real(c_double), dimension(:), intent(in) :: sizes
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_parametricCoord_=parametricCoord, &
             api_parametricCoord_n_=size_gmsh_double(parametricCoord), &
             api_sizes_=sizes, &
             api_sizes_n_=size_gmsh_double(sizes), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetSizeAtParametricPoints
    
      !> Set a mesh size callback for the current model. The callback function
      !! should take six arguments as input (`dim', `tag', `x', `y', `z' and `lc').
      !! The first two integer arguments correspond to the dimension `dim' and tag
      !! `tag' of the entity being meshed. The next four double precision arguments
      !! correspond to the coordinates `x', `y' and `z' around which to prescribe
      !! the mesh size and to the mesh size `lc' that would be prescribed if the
      !! callback had not been called. The callback function should return a double
      !! precision number specifying the desired mesh size; returning `lc' is
      !! equivalent to a no-op.
      subroutine gmshModelMeshSetSizeCallback(callback, &
                                              ierr)
        interface
        subroutine C_API(callback, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetSizeCallback")
          use, intrinsic :: iso_c_binding
          type(c_funptr), value, intent(in) :: callback
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        type(c_funptr), value, intent(in) :: callback
        integer(c_int), intent(out), optional :: ierr
        call C_API(callback=callback, &
             ierr_=ierr)
      end subroutine gmshModelMeshSetSizeCallback
    
      !> Remove the mesh size callback from the current model.
      subroutine gmshModelMeshRemoveSizeCallback(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelMeshRemoveSizeCallback")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelMeshRemoveSizeCallback
    
      !> 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'), "Bump"
      !! (refinement toward both extremities of the curve) and "Beta" (beta law).
      subroutine gmshModelMeshSetTransfiniteCurve(tag, &
                                                  numNodes, &
                                                  meshType, &
                                                  coef, &
                                                  ierr)
        interface
        subroutine C_API(tag, &
                         numNodes, &
                         meshType, &
                         coef, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetTransfiniteCurve")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: numNodes
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: meshType
          real(c_double), value, intent(in) :: coef
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: numNodes
        character(len=*), intent(in), optional :: meshType
        real(c_double), intent(in), optional :: coef
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             numNodes=int(numNodes, c_int), &
             meshType=istring_(optval_c_str("Progression", meshType)), &
             coef=optval_c_double(1., coef), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetTransfiniteCurve
    
      !> Set a transfinite meshing constraint on the surface `tag'. `arrangement'
      !! describes the arrangement of the triangles when the surface is not flagged
      !! as recombined: currently supported values are "Left", "Right",
      !! "AlternateLeft" and "AlternateRight". `cornerTags' can be used to specify
      !! the (3 or 4) corners of the transfinite interpolation explicitly;
      !! specifying the corners explicitly is mandatory if the surface has more that
      !! 3 or 4 points on its boundary.
      subroutine gmshModelMeshSetTransfiniteSurface(tag, &
                                                    arrangement, &
                                                    cornerTags, &
                                                    ierr)
        interface
        subroutine C_API(tag, &
                         arrangement, &
                         api_cornerTags_, &
                         api_cornerTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetTransfiniteSurface")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: arrangement
          integer(c_int), dimension(*), optional :: api_cornerTags_
          integer(c_size_t), value, intent(in) :: api_cornerTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in), optional :: arrangement
        integer(c_int), dimension(:), intent(in), optional :: cornerTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             arrangement=istring_(optval_c_str("Left", arrangement)), &
             api_cornerTags_=cornerTags, &
             api_cornerTags_n_=size_gmsh_int(cornerTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetTransfiniteSurface
    
      !> Set a transfinite meshing constraint on the surface `tag'. `cornerTags' can
      !! be used to specify the (6 or 8) corners of the transfinite interpolation
      !! explicitly.
      subroutine gmshModelMeshSetTransfiniteVolume(tag, &
                                                   cornerTags, &
                                                   ierr)
        interface
        subroutine C_API(tag, &
                         api_cornerTags_, &
                         api_cornerTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetTransfiniteVolume")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), dimension(*), optional :: api_cornerTags_
          integer(c_size_t), value, intent(in) :: api_cornerTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer(c_int), dimension(:), intent(in), optional :: cornerTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             api_cornerTags_=cornerTags, &
             api_cornerTags_n_=size_gmsh_int(cornerTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetTransfiniteVolume
    
      !> Set transfinite meshing constraints on the model entities in `dimTags',
      !! given as a vector of (dim, tag) pairs. Transfinite meshing constraints are
      !! added to the curves of the quadrangular surfaces and to the faces of
      !! 6-sided volumes. Quadragular faces with a corner angle superior to
      !! `cornerAngle' (in radians) are ignored. The number of points is
      !! automatically determined from the sizing constraints. If `dimTag' is empty,
      !! the constraints are applied to all entities in the model. If `recombine' is
      !! true, the recombine flag is automatically set on the transfinite surfaces.
      subroutine gmshModelMeshSetTransfiniteAutomatic(dimTags, &
                                                      cornerAngle, &
                                                      recombine, &
                                                      ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         cornerAngle, &
                         recombine, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetTransfiniteAutomatic")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: cornerAngle
          integer(c_int), value, intent(in) :: recombine
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        real(c_double), intent(in), optional :: cornerAngle
        logical, intent(in), optional :: recombine
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             cornerAngle=optval_c_double(2.35, cornerAngle), &
             recombine=optval_c_bool(.true., recombine), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetTransfiniteAutomatic
    
      !> Set a recombination meshing constraint on the model entity of dimension
      !! `dim' and tag `tag'. Currently only entities of dimension 2 (to recombine
      !! triangles into quadrangles) are supported; `angle' specifies the threshold
      !! angle for the simple recombination algorithm..
      subroutine gmshModelMeshSetRecombine(dim, &
                                           tag, &
                                           angle, &
                                           ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         angle, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetRecombine")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: angle
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), intent(in), optional :: angle
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             angle=optval_c_double(45., angle), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetRecombine
    
      !> Set a smoothing meshing constraint on the model entity of dimension `dim'
      !! and tag `tag'. `val' iterations of a Laplace smoother are applied.
      subroutine gmshModelMeshSetSmoothing(dim, &
                                           tag, &
                                           val, &
                                           ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         val, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetSmoothing")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: val
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer, intent(in) :: val
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             val=int(val, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetSmoothing
    
      !> Set a reverse meshing constraint on the model entity of dimension `dim' and
      !! tag `tag'. If `val' is true, the mesh orientation will be reversed with
      !! respect to the natural mesh orientation (i.e. the orientation consistent
      !! with the orientation of the geometry). If `val' is false, the mesh is left
      !! as-is.
      subroutine gmshModelMeshSetReverse(dim, &
                                         tag, &
                                         val, &
                                         ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         val, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetReverse")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: val
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        logical, intent(in), optional :: val
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             val=optval_c_bool(.true., val), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetReverse
    
      !> Set the meshing algorithm on the model entity of dimension `dim' and tag
      !! `tag'. Supported values are those of the `Mesh.Algorithm' option, as listed
      !! in the Gmsh reference manual. Currently only supported for `dim' == 2.
      subroutine gmshModelMeshSetAlgorithm(dim, &
                                           tag, &
                                           val, &
                                           ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         val, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetAlgorithm")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: val
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer, intent(in) :: val
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             val=int(val, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetAlgorithm
    
      !> Force the mesh size to be extended from the boundary, or not, for the model
      !! entity of dimension `dim' and tag `tag'. Currently only supported for `dim'
      !! == 2.
      subroutine gmshModelMeshSetSizeFromBoundary(dim, &
                                                  tag, &
                                                  val, &
                                                  ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         val, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetSizeFromBoundary")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: val
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer, intent(in) :: val
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             val=int(val, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetSizeFromBoundary
    
      !> Set a compound meshing constraint on the model entities of dimension `dim'
      !! and tags `tags'. During meshing, compound entities are treated as a single
      !! discrete entity, which is automatically reparametrized.
      subroutine gmshModelMeshSetCompound(dim, &
                                          tags, &
                                          ierr)
        interface
        subroutine C_API(dim, &
                         api_tags_, &
                         api_tags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetCompound")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), dimension(*) :: api_tags_
          integer(c_size_t), value, intent(in) :: api_tags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer(c_int), dimension(:), intent(in) :: tags
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             api_tags_=tags, &
             api_tags_n_=size_gmsh_int(tags), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetCompound
    
      !> Set meshing constraints on the bounding surfaces of the volume of tag `tag'
      !! so that all surfaces are oriented with outward pointing normals; and if a
      !! mesh already exists, reorient it. Currently only available with the
      !! OpenCASCADE kernel, as it relies on the STL triangulation.
      subroutine gmshModelMeshSetOutwardOrientation(tag, &
                                                    ierr)
        interface
        subroutine C_API(tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetOutwardOrientation")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetOutwardOrientation
    
      !> Remove all meshing constraints from the model entities `dimTags', given as
      !! a vector of (dim, tag) pairs. If `dimTags' is empty, remove all
      !! constraings.
      subroutine gmshModelMeshRemoveConstraints(dimTags, &
                                                ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshRemoveConstraints")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshRemoveConstraints
    
      !> Embed the model entities of dimension `dim' and tags `tags' in the
      !! (`inDim', `inTag') model entity. The dimension `dim' can 0, 1 or 2 and must
      !! be strictly smaller than `inDim', which must be either 2 or 3. The embedded
      !! entities should not intersect each other or be part of the boundary of the
      !! entity `inTag', whose mesh will conform to the mesh of the embedded
      !! entities. With the OpenCASCADE kernel, if the `fragment' operation is
      !! applied to entities of different dimensions, the lower dimensional entities
      !! will be automatically embedded in the higher dimensional entities if they
      !! are not on their boundary.
      subroutine gmshModelMeshEmbed(dim, &
                                    tags, &
                                    inDim, &
                                    inTag, &
                                    ierr)
        interface
        subroutine C_API(dim, &
                         api_tags_, &
                         api_tags_n_, &
                         inDim, &
                         inTag, &
                         ierr_) &
          bind(C, name="gmshModelMeshEmbed")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), dimension(*) :: api_tags_
          integer(c_size_t), value, intent(in) :: api_tags_n_
          integer(c_int), value, intent(in) :: inDim
          integer(c_int), value, intent(in) :: inTag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer(c_int), dimension(:), intent(in) :: tags
        integer, intent(in) :: inDim
        integer, intent(in) :: inTag
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             api_tags_=tags, &
             api_tags_n_=size_gmsh_int(tags), &
             inDim=int(inDim, c_int), &
             inTag=int(inTag, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshEmbed
    
      !> Remove embedded entities from the model entities `dimTags', given as a
      !! vector of (dim, tag) pairs. if `dim' is >= 0, only remove embedded entities
      !! of the given dimension (e.g. embedded points if `dim' == 0).
      subroutine gmshModelMeshRemoveEmbedded(dimTags, &
                                             dim, &
                                             ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         dim, &
                         ierr_) &
          bind(C, name="gmshModelMeshRemoveEmbedded")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             dim=optval_c_int(-1, dim), &
             ierr_=ierr)
      end subroutine gmshModelMeshRemoveEmbedded
    
      !> Get the entities (if any) embedded in the model entity of dimension `dim'
      !! and tag `tag'.
      subroutine gmshModelMeshGetEmbedded(dim, &
                                          tag, &
                                          dimTags, &
                                          ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetEmbedded")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelMeshGetEmbedded
    
      !> Reorder the elements of type `elementType' classified on the entity of tag
      !! `tag' according to the `ordering' vector.
      subroutine gmshModelMeshReorderElements(elementType, &
                                              tag, &
                                              ordering, &
                                              ierr)
        interface
        subroutine C_API(elementType, &
                         tag, &
                         api_ordering_, &
                         api_ordering_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshReorderElements")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          integer(c_int), value, intent(in) :: tag
          integer(c_size_t), dimension(*) :: api_ordering_
          integer(c_size_t), value, intent(in) :: api_ordering_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        integer, intent(in) :: tag
        integer(c_size_t), dimension(:), intent(in) :: ordering
        integer(c_int), intent(out), optional :: ierr
        call C_API(elementType=int(elementType, c_int), &
             tag=int(tag, c_int), &
             api_ordering_=ordering, &
             api_ordering_n_=size_gmsh_size(ordering), &
             ierr_=ierr)
      end subroutine gmshModelMeshReorderElements
    
      !> Compute a renumbering vector `newTags' corresponding to the input tags
      !! `oldTags' for a given list of element tags `elementTags'. If `elementTags'
      !! is empty, compute the renumbering on the full mesh. If `method' is equal to
      !! "RCMK", compute a node renumering with Reverse Cuthill McKee. If `method'
      !! is equal to "Hilbert", compute a node renumering along a Hilbert curve. If
      !! `method' is equal to "Metis", compute a node renumering using Metis.
      !! Element renumbering is not available yet.
      subroutine gmshModelMeshComputeRenumbering(oldTags, &
                                                 newTags, &
                                                 method, &
                                                 elementTags, &
                                                 ierr)
        interface
        subroutine C_API(api_oldTags_, &
                         api_oldTags_n_, &
                         api_newTags_, &
                         api_newTags_n_, &
                         method, &
                         api_elementTags_, &
                         api_elementTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshComputeRenumbering")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_oldTags_
          integer(c_size_t), intent(out) :: api_oldTags_n_
          type(c_ptr), intent(out) :: api_newTags_
          integer(c_size_t), intent(out) :: api_newTags_n_
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: method
          integer(c_size_t), dimension(*), optional :: api_elementTags_
          integer(c_size_t), value, intent(in) :: api_elementTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), allocatable, intent(out) :: oldTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: newTags
        character(len=*), intent(in), optional :: method
        integer(c_size_t), dimension(:), intent(in), optional :: elementTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_oldTags_
        integer(c_size_t) :: api_oldTags_n_
        type(c_ptr) :: api_newTags_
        integer(c_size_t) :: api_newTags_n_
        call C_API(api_oldTags_=api_oldTags_, &
             api_oldTags_n_=api_oldTags_n_, &
             api_newTags_=api_newTags_, &
             api_newTags_n_=api_newTags_n_, &
             method=istring_(optval_c_str("RCMK", method)), &
             api_elementTags_=elementTags, &
             api_elementTags_n_=size_gmsh_size(elementTags), &
             ierr_=ierr)
        oldTags = ovectorsize_(api_oldTags_, &
          api_oldTags_n_)
        newTags = ovectorsize_(api_newTags_, &
          api_newTags_n_)
      end subroutine gmshModelMeshComputeRenumbering
    
      !> Renumber the node tags. If no explicit renumbering is provided through the
      !! `oldTags' and `newTags' vectors, renumber the nodes in a continuous
      !! sequence, taking into account the subset of elements to be saved later on
      !! if the option "Mesh.SaveAll" is not set.
      subroutine gmshModelMeshRenumberNodes(oldTags, &
                                            newTags, &
                                            ierr)
        interface
        subroutine C_API(api_oldTags_, &
                         api_oldTags_n_, &
                         api_newTags_, &
                         api_newTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshRenumberNodes")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), dimension(*), optional :: api_oldTags_
          integer(c_size_t), value, intent(in) :: api_oldTags_n_
          integer(c_size_t), dimension(*), optional :: api_newTags_
          integer(c_size_t), value, intent(in) :: api_newTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), intent(in), optional :: oldTags
        integer(c_size_t), dimension(:), intent(in), optional :: newTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_oldTags_=oldTags, &
             api_oldTags_n_=size_gmsh_size(oldTags), &
             api_newTags_=newTags, &
             api_newTags_n_=size_gmsh_size(newTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshRenumberNodes
    
      !> Renumber the element tags in a continuous sequence. If no explicit
      !! renumbering is provided through the `oldTags' and `newTags' vectors,
      !! renumber the elements in a continuous sequence, taking into account the
      !! subset of elements to be saved later on if the option "Mesh.SaveAll" is not
      !! set.
      subroutine gmshModelMeshRenumberElements(oldTags, &
                                               newTags, &
                                               ierr)
        interface
        subroutine C_API(api_oldTags_, &
                         api_oldTags_n_, &
                         api_newTags_, &
                         api_newTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshRenumberElements")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), dimension(*), optional :: api_oldTags_
          integer(c_size_t), value, intent(in) :: api_oldTags_n_
          integer(c_size_t), dimension(*), optional :: api_newTags_
          integer(c_size_t), value, intent(in) :: api_newTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), intent(in), optional :: oldTags
        integer(c_size_t), dimension(:), intent(in), optional :: newTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_oldTags_=oldTags, &
             api_oldTags_n_=size_gmsh_size(oldTags), &
             api_newTags_=newTags, &
             api_newTags_n_=size_gmsh_size(newTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshRenumberElements
    
      !> Set the meshes of the entities of dimension `dim' and tag `tags' as
      !! periodic copies of the meshes of entities `tagsMaster', using the affine
      !! transformation specified in `affineTransformation' (16 entries of a 4x4
      !! matrix, by row). If used after meshing, generate the periodic node
      !! correspondence information assuming the meshes of entities `tags'
      !! effectively match the meshes of entities `tagsMaster' (useful for
      !! structured and extruded meshes). Currently only available for @code{dim} ==
      !! 1 and @code{dim} == 2.
      subroutine gmshModelMeshSetPeriodic(dim, &
                                          tags, &
                                          tagsMaster, &
                                          affineTransform, &
                                          ierr)
        interface
        subroutine C_API(dim, &
                         api_tags_, &
                         api_tags_n_, &
                         api_tagsMaster_, &
                         api_tagsMaster_n_, &
                         api_affineTransform_, &
                         api_affineTransform_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetPeriodic")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), dimension(*) :: api_tags_
          integer(c_size_t), value, intent(in) :: api_tags_n_
          integer(c_int), dimension(*) :: api_tagsMaster_
          integer(c_size_t), value, intent(in) :: api_tagsMaster_n_
          real(c_double), dimension(*) :: api_affineTransform_
          integer(c_size_t), value, intent(in) :: api_affineTransform_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer(c_int), dimension(:), intent(in) :: tags
        integer(c_int), dimension(:), intent(in) :: tagsMaster
        real(c_double), dimension(:), intent(in) :: affineTransform
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             api_tags_=tags, &
             api_tags_n_=size_gmsh_int(tags), &
             api_tagsMaster_=tagsMaster, &
             api_tagsMaster_n_=size_gmsh_int(tagsMaster), &
             api_affineTransform_=affineTransform, &
             api_affineTransform_n_=size_gmsh_double(affineTransform), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetPeriodic
    
      !> Get master entities `tagsMaster' for the entities of dimension `dim' and
      !! tags `tags'.
      subroutine gmshModelMeshGetPeriodic(dim, &
                                          tags, &
                                          tagMaster, &
                                          ierr)
        interface
        subroutine C_API(dim, &
                         api_tags_, &
                         api_tags_n_, &
                         api_tagMaster_, &
                         api_tagMaster_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetPeriodic")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), dimension(*) :: api_tags_
          integer(c_size_t), value, intent(in) :: api_tags_n_
          type(c_ptr), intent(out) :: api_tagMaster_
          integer(c_size_t), intent(out) :: api_tagMaster_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer(c_int), dimension(:), intent(in) :: tags
        integer(c_int), dimension(:), allocatable, intent(out) :: tagMaster
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_tagMaster_
        integer(c_size_t) :: api_tagMaster_n_
        call C_API(dim=int(dim, c_int), &
             api_tags_=tags, &
             api_tags_n_=size_gmsh_int(tags), &
             api_tagMaster_=api_tagMaster_, &
             api_tagMaster_n_=api_tagMaster_n_, &
             ierr_=ierr)
        tagMaster = ovectorint_(api_tagMaster_, &
          api_tagMaster_n_)
      end subroutine gmshModelMeshGetPeriodic
    
      !> Get the master entity `tagMaster', the node tags `nodeTags' and their
      !! corresponding master node tags `nodeTagsMaster', and the affine transform
      !! `affineTransform' for the entity of dimension `dim' and tag `tag'. If
      !! `includeHighOrderNodes' is set, include high-order nodes in the returned
      !! data.
      subroutine gmshModelMeshGetPeriodicNodes(dim, &
                                               tag, &
                                               tagMaster, &
                                               nodeTags, &
                                               nodeTagsMaster, &
                                               affineTransform, &
                                               includeHighOrderNodes, &
                                               ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         tagMaster, &
                         api_nodeTags_, &
                         api_nodeTags_n_, &
                         api_nodeTagsMaster_, &
                         api_nodeTagsMaster_n_, &
                         api_affineTransform_, &
                         api_affineTransform_n_, &
                         includeHighOrderNodes, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetPeriodicNodes")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int) :: tagMaster
          type(c_ptr), intent(out) :: api_nodeTags_
          integer(c_size_t), intent(out) :: api_nodeTags_n_
          type(c_ptr), intent(out) :: api_nodeTagsMaster_
          integer(c_size_t), intent(out) :: api_nodeTagsMaster_n_
          type(c_ptr), intent(out) :: api_affineTransform_
          integer(c_size_t) :: api_affineTransform_n_
          integer(c_int), value, intent(in) :: includeHighOrderNodes
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int) :: tagMaster
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: nodeTagsMaster
        real(c_double), dimension(:), allocatable, intent(out) :: affineTransform
        logical, intent(in), optional :: includeHighOrderNodes
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_nodeTags_
        integer(c_size_t) :: api_nodeTags_n_
        type(c_ptr) :: api_nodeTagsMaster_
        integer(c_size_t) :: api_nodeTagsMaster_n_
        type(c_ptr) :: api_affineTransform_
        integer(c_size_t) :: api_affineTransform_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             tagMaster=tagMaster, &
             api_nodeTags_=api_nodeTags_, &
             api_nodeTags_n_=api_nodeTags_n_, &
             api_nodeTagsMaster_=api_nodeTagsMaster_, &
             api_nodeTagsMaster_n_=api_nodeTagsMaster_n_, &
             api_affineTransform_=api_affineTransform_, &
             api_affineTransform_n_=api_affineTransform_n_, &
             includeHighOrderNodes=optval_c_bool(.false., includeHighOrderNodes), &
             ierr_=ierr)
        nodeTags = ovectorsize_(api_nodeTags_, &
          api_nodeTags_n_)
        nodeTagsMaster = ovectorsize_(api_nodeTagsMaster_, &
          api_nodeTagsMaster_n_)
        affineTransform = ovectordouble_(api_affineTransform_, &
          api_affineTransform_n_)
      end subroutine gmshModelMeshGetPeriodicNodes
    
      !> Get the master entity `tagMaster' and the key pairs (`typeKeyMaster',
      !! `entityKeyMaster') corresponding to the entity `tag' and the key pairs
      !! (`typeKey', `entityKey') for the elements of type `elementType' and
      !! function space type `functionSpaceType'. If `returnCoord' is set, the
      !! `coord' and `coordMaster' vectors contain the x, y, z coordinates locating
      !! basis functions for sorting purposes.
      subroutine gmshModelMeshGetPeriodicKeys(elementType, &
                                              functionSpaceType, &
                                              tag, &
                                              tagMaster, &
                                              typeKeys, &
                                              typeKeysMaster, &
                                              entityKeys, &
                                              entityKeysMaster, &
                                              coord, &
                                              coordMaster, &
                                              returnCoord, &
                                              ierr)
        interface
        subroutine C_API(elementType, &
                         functionSpaceType, &
                         tag, &
                         tagMaster, &
                         api_typeKeys_, &
                         api_typeKeys_n_, &
                         api_typeKeysMaster_, &
                         api_typeKeysMaster_n_, &
                         api_entityKeys_, &
                         api_entityKeys_n_, &
                         api_entityKeysMaster_, &
                         api_entityKeysMaster_n_, &
                         api_coord_, &
                         api_coord_n_, &
                         api_coordMaster_, &
                         api_coordMaster_n_, &
                         returnCoord, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetPeriodicKeys")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: elementType
          character(len=1, kind=c_char), dimension(*), intent(in) :: functionSpaceType
          integer(c_int), value, intent(in) :: tag
          integer(c_int) :: tagMaster
          type(c_ptr), intent(out) :: api_typeKeys_
          integer(c_size_t), intent(out) :: api_typeKeys_n_
          type(c_ptr), intent(out) :: api_typeKeysMaster_
          integer(c_size_t), intent(out) :: api_typeKeysMaster_n_
          type(c_ptr), intent(out) :: api_entityKeys_
          integer(c_size_t), intent(out) :: api_entityKeys_n_
          type(c_ptr), intent(out) :: api_entityKeysMaster_
          integer(c_size_t), intent(out) :: api_entityKeysMaster_n_
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          type(c_ptr), intent(out) :: api_coordMaster_
          integer(c_size_t) :: api_coordMaster_n_
          integer(c_int), value, intent(in) :: returnCoord
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: elementType
        character(len=*), intent(in) :: functionSpaceType
        integer, intent(in) :: tag
        integer(c_int) :: tagMaster
        integer(c_int), dimension(:), allocatable, intent(out) :: typeKeys
        integer(c_int), dimension(:), allocatable, intent(out) :: typeKeysMaster
        integer(c_size_t), dimension(:), allocatable, intent(out) :: entityKeys
        integer(c_size_t), dimension(:), allocatable, intent(out) :: entityKeysMaster
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        real(c_double), dimension(:), allocatable, intent(out) :: coordMaster
        logical, intent(in), optional :: returnCoord
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_typeKeys_
        integer(c_size_t) :: api_typeKeys_n_
        type(c_ptr) :: api_typeKeysMaster_
        integer(c_size_t) :: api_typeKeysMaster_n_
        type(c_ptr) :: api_entityKeys_
        integer(c_size_t) :: api_entityKeys_n_
        type(c_ptr) :: api_entityKeysMaster_
        integer(c_size_t) :: api_entityKeysMaster_n_
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        type(c_ptr) :: api_coordMaster_
        integer(c_size_t) :: api_coordMaster_n_
        call C_API(elementType=int(elementType, c_int), &
             functionSpaceType=istring_(functionSpaceType), &
             tag=int(tag, c_int), &
             tagMaster=tagMaster, &
             api_typeKeys_=api_typeKeys_, &
             api_typeKeys_n_=api_typeKeys_n_, &
             api_typeKeysMaster_=api_typeKeysMaster_, &
             api_typeKeysMaster_n_=api_typeKeysMaster_n_, &
             api_entityKeys_=api_entityKeys_, &
             api_entityKeys_n_=api_entityKeys_n_, &
             api_entityKeysMaster_=api_entityKeysMaster_, &
             api_entityKeysMaster_n_=api_entityKeysMaster_n_, &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             api_coordMaster_=api_coordMaster_, &
             api_coordMaster_n_=api_coordMaster_n_, &
             returnCoord=optval_c_bool(.true., returnCoord), &
             ierr_=ierr)
        typeKeys = ovectorint_(api_typeKeys_, &
          api_typeKeys_n_)
        typeKeysMaster = ovectorint_(api_typeKeysMaster_, &
          api_typeKeysMaster_n_)
        entityKeys = ovectorsize_(api_entityKeys_, &
          api_entityKeys_n_)
        entityKeysMaster = ovectorsize_(api_entityKeysMaster_, &
          api_entityKeysMaster_n_)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
        coordMaster = ovectordouble_(api_coordMaster_, &
          api_coordMaster_n_)
      end subroutine gmshModelMeshGetPeriodicKeys
    
      !> Import the model STL representation (if available) as the current mesh.
      subroutine gmshModelMeshImportStl(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelMeshImportStl")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelMeshImportStl
    
      !> Get the `tags' of any duplicate nodes in the mesh of the entities
      !! `dimTags', given as a vector of (dim, tag) pairs. If `dimTags' is empty,
      !! consider the whole mesh.
      subroutine gmshModelMeshGetDuplicateNodes(tags, &
                                                dimTags, &
                                                ierr)
        interface
        subroutine C_API(api_tags_, &
                         api_tags_n_, &
                         api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetDuplicateNodes")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_tags_
          integer(c_size_t), intent(out) :: api_tags_n_
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), allocatable, intent(out) :: tags
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_tags_
        integer(c_size_t) :: api_tags_n_
        call C_API(api_tags_=api_tags_, &
             api_tags_n_=api_tags_n_, &
             api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
        tags = ovectorsize_(api_tags_, &
          api_tags_n_)
      end subroutine gmshModelMeshGetDuplicateNodes
    
      !> Remove duplicate nodes in the mesh of the entities `dimTags', given as a
      !! vector of (dim, tag) pairs. If `dimTags' is empty, consider the whole mesh.
      subroutine gmshModelMeshRemoveDuplicateNodes(dimTags, &
                                                   ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshRemoveDuplicateNodes")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshRemoveDuplicateNodes
    
      !> Remove duplicate elements (defined by the same nodes, in the same entity)
      !! in the mesh of the entities `dimTags', given as a vector of (dim, tag)
      !! pairs. If `dimTags' is empty, consider the whole mesh.
      subroutine gmshModelMeshRemoveDuplicateElements(dimTags, &
                                                      ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshRemoveDuplicateElements")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshRemoveDuplicateElements
    
      !> Split (into two triangles) all quadrangles in surface `tag' whose quality
      !! is lower than `quality'. If `tag' < 0, split quadrangles in all surfaces.
      subroutine gmshModelMeshSplitQuadrangles(quality, &
                                               tag, &
                                               ierr)
        interface
        subroutine C_API(quality, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshSplitQuadrangles")
          use, intrinsic :: iso_c_binding
          real(c_double), value, intent(in) :: quality
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), intent(in), optional :: quality
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(quality=optval_c_double(1., quality), &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
      end subroutine gmshModelMeshSplitQuadrangles
    
      !> Set the visibility of the elements of tags `elementTags' to `value'.
      subroutine gmshModelMeshSetVisibility(elementTags, &
                                            value, &
                                            ierr)
        interface
        subroutine C_API(api_elementTags_, &
                         api_elementTags_n_, &
                         value, &
                         ierr_) &
          bind(C, name="gmshModelMeshSetVisibility")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), dimension(*) :: api_elementTags_
          integer(c_size_t), value, intent(in) :: api_elementTags_n_
          integer(c_int), value, intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), intent(in) :: elementTags
        integer, intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_elementTags_=elementTags, &
             api_elementTags_n_=size_gmsh_size(elementTags), &
             value=int(value, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshSetVisibility
    
      !> Get the visibility of the elements of tags `elementTags'.
      subroutine gmshModelMeshGetVisibility(elementTags, &
                                            values, &
                                            ierr)
        interface
        subroutine C_API(api_elementTags_, &
                         api_elementTags_n_, &
                         api_values_, &
                         api_values_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshGetVisibility")
          use, intrinsic :: iso_c_binding
          integer(c_size_t), dimension(*) :: api_elementTags_
          integer(c_size_t), value, intent(in) :: api_elementTags_n_
          type(c_ptr), intent(out) :: api_values_
          integer(c_size_t), intent(out) :: api_values_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_size_t), dimension(:), intent(in) :: elementTags
        integer(c_int), dimension(:), allocatable, intent(out) :: values
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_values_
        integer(c_size_t) :: api_values_n_
        call C_API(api_elementTags_=elementTags, &
             api_elementTags_n_=size_gmsh_size(elementTags), &
             api_values_=api_values_, &
             api_values_n_=api_values_n_, &
             ierr_=ierr)
        values = ovectorint_(api_values_, &
          api_values_n_)
      end subroutine gmshModelMeshGetVisibility
    
      !> Classify ("color") the surface mesh based on the angle threshold `angle'
      !! (in radians), and create new discrete surfaces, curves and points
      !! accordingly. If `boundary' is set, also create discrete curves on the
      !! boundary if the surface is open. If `forReparametrization' is set, create
      !! curves and surfaces that can be reparametrized using a single map. If
      !! `curveAngle' is less than Pi, also force curves to be split according to
      !! `curveAngle'. If `exportDiscrete' is set, clear any built-in CAD kernel
      !! entities and export the discrete entities in the built-in CAD kernel.
      subroutine gmshModelMeshClassifySurfaces(angle, &
                                               boundary, &
                                               forReparametrization, &
                                               curveAngle, &
                                               exportDiscrete, &
                                               ierr)
        interface
        subroutine C_API(angle, &
                         boundary, &
                         forReparametrization, &
                         curveAngle, &
                         exportDiscrete, &
                         ierr_) &
          bind(C, name="gmshModelMeshClassifySurfaces")
          use, intrinsic :: iso_c_binding
          real(c_double), value, intent(in) :: angle
          integer(c_int), value, intent(in) :: boundary
          integer(c_int), value, intent(in) :: forReparametrization
          real(c_double), value, intent(in) :: curveAngle
          integer(c_int), value, intent(in) :: exportDiscrete
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), intent(in) :: angle
        logical, intent(in), optional :: boundary
        logical, intent(in), optional :: forReparametrization
        real(c_double), intent(in), optional :: curveAngle
        logical, intent(in), optional :: exportDiscrete
        integer(c_int), intent(out), optional :: ierr
        call C_API(angle=real(angle, c_double), &
             boundary=optval_c_bool(.true., boundary), &
             forReparametrization=optval_c_bool(.false., forReparametrization), &
             curveAngle=optval_c_double(M_PI, curveAngle), &
             exportDiscrete=optval_c_bool(.true., exportDiscrete), &
             ierr_=ierr)
      end subroutine gmshModelMeshClassifySurfaces
    
      !> Create a geometry for the discrete entities `dimTags' (given as a vector of
      !! (dim, tag) pairs) represented solely by a mesh (without an underlying CAD
      !! description), i.e. create a parametrization for discrete curves and
      !! surfaces, assuming that each can be parametrized with a single map. If
      !! `dimTags' is empty, create a geometry for all the discrete entities.
      subroutine gmshModelMeshCreateGeometry(dimTags, &
                                             ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshCreateGeometry")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelMeshCreateGeometry
    
      !> Create a boundary representation from the mesh if the model does not have
      !! one (e.g. when imported from mesh file formats with no BRep representation
      !! of the underlying model). If `makeSimplyConnected' is set, enforce simply
      !! connected discrete surfaces and volumes. If `exportDiscrete' is set, clear
      !! any built-in CAD kernel entities and export the discrete entities in the
      !! built-in CAD kernel.
      subroutine gmshModelMeshCreateTopology(makeSimplyConnected, &
                                             exportDiscrete, &
                                             ierr)
        interface
        subroutine C_API(makeSimplyConnected, &
                         exportDiscrete, &
                         ierr_) &
          bind(C, name="gmshModelMeshCreateTopology")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: makeSimplyConnected
          integer(c_int), value, intent(in) :: exportDiscrete
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        logical, intent(in), optional :: makeSimplyConnected
        logical, intent(in), optional :: exportDiscrete
        integer(c_int), intent(out), optional :: ierr
        call C_API(makeSimplyConnected=optval_c_bool(.true., makeSimplyConnected), &
             exportDiscrete=optval_c_bool(.true., exportDiscrete), &
             ierr_=ierr)
      end subroutine gmshModelMeshCreateTopology
    
      !> Add a request to compute a basis representation for homology spaces (if
      !! `type' == "Homology") or cohomology spaces (if `type' == "Cohomology"). The
      !! computation domain is given in a list of physical group tags `domainTags';
      !! if empty, the whole mesh is the domain. The computation subdomain for
      !! relative (co)homology computation is given in a list of physical group tags
      !! `subdomainTags'; if empty, absolute (co)homology is computed. The
      !! dimensions of the (co)homology bases to be computed are given in the list
      !! `dim'; if empty, all bases are computed. Resulting basis representation
      !! (co)chains are stored as physical groups in the mesh. If the request is
      !! added before mesh generation, the computation will be performed at the end
      !! of the meshing pipeline.
      subroutine gmshModelMeshAddHomologyRequest(type, &
                                                 domainTags, &
                                                 subdomainTags, &
                                                 dims, &
                                                 ierr)
        interface
        subroutine C_API(type, &
                         api_domainTags_, &
                         api_domainTags_n_, &
                         api_subdomainTags_, &
                         api_subdomainTags_n_, &
                         api_dims_, &
                         api_dims_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshAddHomologyRequest")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: type
          integer(c_int), dimension(*), optional :: api_domainTags_
          integer(c_size_t), value, intent(in) :: api_domainTags_n_
          integer(c_int), dimension(*), optional :: api_subdomainTags_
          integer(c_size_t), value, intent(in) :: api_subdomainTags_n_
          integer(c_int), dimension(*), optional :: api_dims_
          integer(c_size_t), value, intent(in) :: api_dims_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in), optional :: type
        integer(c_int), dimension(:), intent(in), optional :: domainTags
        integer(c_int), dimension(:), intent(in), optional :: subdomainTags
        integer(c_int), dimension(:), intent(in), optional :: dims
        integer(c_int), intent(out), optional :: ierr
        call C_API(type=istring_(optval_c_str("Homology", type)), &
             api_domainTags_=domainTags, &
             api_domainTags_n_=size_gmsh_int(domainTags), &
             api_subdomainTags_=subdomainTags, &
             api_subdomainTags_n_=size_gmsh_int(subdomainTags), &
             api_dims_=dims, &
             api_dims_n_=size_gmsh_int(dims), &
             ierr_=ierr)
      end subroutine gmshModelMeshAddHomologyRequest
    
      !> Clear all (co)homology computation requests.
      subroutine gmshModelMeshClearHomologyRequests(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelMeshClearHomologyRequests")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelMeshClearHomologyRequests
    
      !> Perform the (co)homology computations requested by addHomologyRequest().
      !! The newly created physical groups are returned in `dimTags' as a vector of
      !! (dim, tag) pairs.
      subroutine gmshModelMeshComputeHomology(dimTags, &
                                              ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshComputeHomology")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelMeshComputeHomology
    
      !> Compute a cross field for the current mesh. The function creates 3 views:
      !! the H function, the Theta function and cross directions. Return the tags of
      !! the views.
      subroutine gmshModelMeshComputeCrossField(viewTags, &
                                                ierr)
        interface
        subroutine C_API(api_viewTags_, &
                         api_viewTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshComputeCrossField")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_viewTags_
          integer(c_size_t), intent(out) :: api_viewTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), allocatable, intent(out) :: viewTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_viewTags_
        integer(c_size_t) :: api_viewTags_n_
        call C_API(api_viewTags_=api_viewTags_, &
             api_viewTags_n_=api_viewTags_n_, &
             ierr_=ierr)
        viewTags = ovectorint_(api_viewTags_, &
          api_viewTags_n_)
      end subroutine gmshModelMeshComputeCrossField
    
      !> Triangulate the points given in the `coord' vector as pairs of u, v
      !! coordinates, and return the node tags (with numbering starting at 1) of the
      !! resulting triangles in `tri'.
      subroutine gmshModelMeshTriangulate(coord, &
                                          tri, &
                                          ierr)
        interface
        subroutine C_API(api_coord_, &
                         api_coord_n_, &
                         api_tri_, &
                         api_tri_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshTriangulate")
          use, intrinsic :: iso_c_binding
          real(c_double), dimension(*) :: api_coord_
          integer(c_size_t), value, intent(in) :: api_coord_n_
          type(c_ptr), intent(out) :: api_tri_
          integer(c_size_t), intent(out) :: api_tri_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), dimension(:), intent(in) :: coord
        integer(c_size_t), dimension(:), allocatable, intent(out) :: tri
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_tri_
        integer(c_size_t) :: api_tri_n_
        call C_API(api_coord_=coord, &
             api_coord_n_=size_gmsh_double(coord), &
             api_tri_=api_tri_, &
             api_tri_n_=api_tri_n_, &
             ierr_=ierr)
        tri = ovectorsize_(api_tri_, &
          api_tri_n_)
      end subroutine gmshModelMeshTriangulate
    
      !> Tetrahedralize the points given in the `coord' vector as x, y, z
      !! coordinates, concatenated, and return the node tags (with numbering
      !! starting at 1) of the resulting tetrahedra in `tetra'.
      subroutine gmshModelMeshTetrahedralize(coord, &
                                             tetra, &
                                             ierr)
        interface
        subroutine C_API(api_coord_, &
                         api_coord_n_, &
                         api_tetra_, &
                         api_tetra_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshTetrahedralize")
          use, intrinsic :: iso_c_binding
          real(c_double), dimension(*) :: api_coord_
          integer(c_size_t), value, intent(in) :: api_coord_n_
          type(c_ptr), intent(out) :: api_tetra_
          integer(c_size_t), intent(out) :: api_tetra_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), dimension(:), intent(in) :: coord
        integer(c_size_t), dimension(:), allocatable, intent(out) :: tetra
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_tetra_
        integer(c_size_t) :: api_tetra_n_
        call C_API(api_coord_=coord, &
             api_coord_n_=size_gmsh_double(coord), &
             api_tetra_=api_tetra_, &
             api_tetra_n_=api_tetra_n_, &
             ierr_=ierr)
        tetra = ovectorsize_(api_tetra_, &
          api_tetra_n_)
      end subroutine gmshModelMeshTetrahedralize
    
      !> Add a new mesh size field of type `fieldType'. If `tag' is positive, assign
      !! the tag explicitly; otherwise a new tag is assigned automatically. Return
      !! the field tag. Available field types are listed in the "Gmsh mesh size
      !! fields" chapter of the Gmsh reference manual
      !! (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-mesh-size-fields).
      function gmshModelMeshFieldAdd(fieldType, &
                                     tag, &
                                     ierr)
        interface
        function C_API(fieldType, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelMeshFieldAdd")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          character(len=1, kind=c_char), dimension(*), intent(in) :: fieldType
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelMeshFieldAdd
        character(len=*), intent(in) :: fieldType
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelMeshFieldAdd = C_API(fieldType=istring_(fieldType), &
                                tag=optval_c_int(-1, tag), &
                                ierr_=ierr)
      end function gmshModelMeshFieldAdd
    
      !> Remove the field with tag `tag'.
      subroutine gmshModelMeshFieldRemove(tag, &
                                          ierr)
        interface
        subroutine C_API(tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldRemove")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshFieldRemove
    
      !> Get the list of all fields.
      subroutine gmshModelMeshFieldList(tags, &
                                        ierr)
        interface
        subroutine C_API(api_tags_, &
                         api_tags_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldList")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_tags_
          integer(c_size_t), intent(out) :: api_tags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), allocatable, intent(out) :: tags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_tags_
        integer(c_size_t) :: api_tags_n_
        call C_API(api_tags_=api_tags_, &
             api_tags_n_=api_tags_n_, &
             ierr_=ierr)
        tags = ovectorint_(api_tags_, &
          api_tags_n_)
      end subroutine gmshModelMeshFieldList
    
      !> Get the type `fieldType' of the field with tag `tag'.
      subroutine gmshModelMeshFieldGetType(tag, &
                                           fileType, &
                                           ierr)
        interface
        subroutine C_API(tag, &
                         api_fileType_, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldGetType")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_fileType_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=:), allocatable, intent(out) :: fileType
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_fileType_
        call C_API(tag=int(tag, c_int), &
             api_fileType_=api_fileType_, &
             ierr_=ierr)
        fileType = ostring_(api_fileType_)
      end subroutine gmshModelMeshFieldGetType
    
      !> Set the numerical option `option' to value `value' for field `tag'.
      subroutine gmshModelMeshFieldSetNumber(tag, &
                                             option, &
                                             value, &
                                             ierr)
        interface
        subroutine C_API(tag, &
                         option, &
                         value, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldSetNumber")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: option
          real(c_double), value, intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: option
        real(c_double), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             option=istring_(option), &
             value=real(value, c_double), &
             ierr_=ierr)
      end subroutine gmshModelMeshFieldSetNumber
    
      !> Get the value of the numerical option `option' for field `tag'.
      subroutine gmshModelMeshFieldGetNumber(tag, &
                                             option, &
                                             value, &
                                             ierr)
        interface
        subroutine C_API(tag, &
                         option, &
                         value, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldGetNumber")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: option
          real(c_double) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: option
        real(c_double) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             option=istring_(option), &
             value=value, &
             ierr_=ierr)
      end subroutine gmshModelMeshFieldGetNumber
    
      !> Set the string option `option' to value `value' for field `tag'.
      subroutine gmshModelMeshFieldSetString(tag, &
                                             option, &
                                             value, &
                                             ierr)
        interface
        subroutine C_API(tag, &
                         option, &
                         value, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldSetString")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: option
          character(len=1, kind=c_char), dimension(*), intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: option
        character(len=*), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             option=istring_(option), &
             value=istring_(value), &
             ierr_=ierr)
      end subroutine gmshModelMeshFieldSetString
    
      !> Get the value of the string option `option' for field `tag'.
      subroutine gmshModelMeshFieldGetString(tag, &
                                             option, &
                                             value, &
                                             ierr)
        interface
        subroutine C_API(tag, &
                         option, &
                         api_value_, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldGetString")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: option
          type(c_ptr), intent(out) :: api_value_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: option
        character(len=:), allocatable, intent(out) :: value
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_value_
        call C_API(tag=int(tag, c_int), &
             option=istring_(option), &
             api_value_=api_value_, &
             ierr_=ierr)
        value = ostring_(api_value_)
      end subroutine gmshModelMeshFieldGetString
    
      !> Set the numerical list option `option' to value `values' for field `tag'.
      subroutine gmshModelMeshFieldSetNumbers(tag, &
                                              option, &
                                              values, &
                                              ierr)
        interface
        subroutine C_API(tag, &
                         option, &
                         api_values_, &
                         api_values_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldSetNumbers")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: option
          real(c_double), dimension(*) :: api_values_
          integer(c_size_t), value, intent(in) :: api_values_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: option
        real(c_double), dimension(:), intent(in) :: values
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             option=istring_(option), &
             api_values_=values, &
             api_values_n_=size_gmsh_double(values), &
             ierr_=ierr)
      end subroutine gmshModelMeshFieldSetNumbers
    
      !> Get the value of the numerical list option `option' for field `tag'.
      subroutine gmshModelMeshFieldGetNumbers(tag, &
                                              option, &
                                              values, &
                                              ierr)
        interface
        subroutine C_API(tag, &
                         option, &
                         api_values_, &
                         api_values_n_, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldGetNumbers")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: option
          type(c_ptr), intent(out) :: api_values_
          integer(c_size_t) :: api_values_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: option
        real(c_double), dimension(:), allocatable, intent(out) :: values
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_values_
        integer(c_size_t) :: api_values_n_
        call C_API(tag=int(tag, c_int), &
             option=istring_(option), &
             api_values_=api_values_, &
             api_values_n_=api_values_n_, &
             ierr_=ierr)
        values = ovectordouble_(api_values_, &
          api_values_n_)
      end subroutine gmshModelMeshFieldGetNumbers
    
      !> Set the field `tag' as the background mesh size field.
      subroutine gmshModelMeshFieldSetAsBackgroundMesh(tag, &
                                                       ierr)
        interface
        subroutine C_API(tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldSetAsBackgroundMesh")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshFieldSetAsBackgroundMesh
    
      !> Set the field `tag' as a boundary layer size field.
      subroutine gmshModelMeshFieldSetAsBoundaryLayer(tag, &
                                                      ierr)
        interface
        subroutine C_API(tag, &
                         ierr_) &
          bind(C, name="gmshModelMeshFieldSetAsBoundaryLayer")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             ierr_=ierr)
      end subroutine gmshModelMeshFieldSetAsBoundaryLayer
    
      !> Add a geometrical point in the built-in CAD representation, at coordinates
      !! (`x', `y', `z'). If `meshSize' is > 0, add a meshing constraint at that
      !! point. If `tag' is positive, set the tag explicitly; otherwise a new tag is
      !! selected automatically. Return the tag of the point. (Note that the point
      !! will be added in the current model only after `synchronize' is called. This
      !! behavior holds for all the entities added in the geo module.)
      function gmshModelGeoAddPoint(x, &
                                    y, &
                                    z, &
                                    meshSize, &
                                    tag, &
                                    ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       meshSize, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddPoint")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: meshSize
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddPoint
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in), optional :: meshSize
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddPoint = C_API(x=real(x, c_double), &
                               y=real(y, c_double), &
                               z=real(z, c_double), &
                               meshSize=optval_c_double(0., meshSize), &
                               tag=optval_c_int(-1, tag), &
                               ierr_=ierr)
      end function gmshModelGeoAddPoint
    
      !> Add a straight line segment in the built-in CAD representation, between the
      !! two points with tags `startTag' and `endTag'. If `tag' is positive, set the
      !! tag explicitly; otherwise a new tag is selected automatically. Return the
      !! tag of the line.
      function gmshModelGeoAddLine(startTag, &
                                   endTag, &
                                   tag, &
                                   ierr)
        interface
        function C_API(startTag, &
                       endTag, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddLine")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: startTag
          integer(c_int), value, intent(in) :: endTag
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddLine
        integer, intent(in) :: startTag
        integer, intent(in) :: endTag
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddLine = C_API(startTag=int(startTag, c_int), &
                              endTag=int(endTag, c_int), &
                              tag=optval_c_int(-1, tag), &
                              ierr_=ierr)
      end function gmshModelGeoAddLine
    
      !> Add a circle arc (strictly smaller than Pi) in the built-in CAD
      !! representation, between the two points with tags `startTag' and `endTag',
      !! and with center `centerTag'. If `tag' is positive, set the tag explicitly;
      !! otherwise a new tag is selected automatically. If (`nx', `ny', `nz') != (0,
      !! 0, 0), explicitly set the plane of the circle arc. Return the tag of the
      !! circle arc.
      function gmshModelGeoAddCircleArc(startTag, &
                                        centerTag, &
                                        endTag, &
                                        tag, &
                                        nx, &
                                        ny, &
                                        nz, &
                                        ierr)
        interface
        function C_API(startTag, &
                       centerTag, &
                       endTag, &
                       tag, &
                       nx, &
                       ny, &
                       nz, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddCircleArc")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: startTag
          integer(c_int), value, intent(in) :: centerTag
          integer(c_int), value, intent(in) :: endTag
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: nx
          real(c_double), value, intent(in) :: ny
          real(c_double), value, intent(in) :: nz
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddCircleArc
        integer, intent(in) :: startTag
        integer, intent(in) :: centerTag
        integer, intent(in) :: endTag
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: nx
        real(c_double), intent(in), optional :: ny
        real(c_double), intent(in), optional :: nz
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddCircleArc = C_API(startTag=int(startTag, c_int), &
                                   centerTag=int(centerTag, c_int), &
                                   endTag=int(endTag, c_int), &
                                   tag=optval_c_int(-1, tag), &
                                   nx=optval_c_double(0., nx), &
                                   ny=optval_c_double(0., ny), &
                                   nz=optval_c_double(0., nz), &
                                   ierr_=ierr)
      end function gmshModelGeoAddCircleArc
    
      !> Add an ellipse arc (strictly smaller than Pi) in the built-in CAD
      !! representation, between the two points `startTag' and `endTag', and with
      !! center `centerTag' and major axis point `majorTag'. If `tag' is positive,
      !! set the tag explicitly; otherwise a new tag is selected automatically. If
      !! (`nx', `ny', `nz') != (0, 0, 0), explicitly set the plane of the circle
      !! arc. Return the tag of the ellipse arc.
      function gmshModelGeoAddEllipseArc(startTag, &
                                         centerTag, &
                                         majorTag, &
                                         endTag, &
                                         tag, &
                                         nx, &
                                         ny, &
                                         nz, &
                                         ierr)
        interface
        function C_API(startTag, &
                       centerTag, &
                       majorTag, &
                       endTag, &
                       tag, &
                       nx, &
                       ny, &
                       nz, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddEllipseArc")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: startTag
          integer(c_int), value, intent(in) :: centerTag
          integer(c_int), value, intent(in) :: majorTag
          integer(c_int), value, intent(in) :: endTag
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: nx
          real(c_double), value, intent(in) :: ny
          real(c_double), value, intent(in) :: nz
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddEllipseArc
        integer, intent(in) :: startTag
        integer, intent(in) :: centerTag
        integer, intent(in) :: majorTag
        integer, intent(in) :: endTag
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: nx
        real(c_double), intent(in), optional :: ny
        real(c_double), intent(in), optional :: nz
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddEllipseArc = C_API(startTag=int(startTag, c_int), &
                                    centerTag=int(centerTag, c_int), &
                                    majorTag=int(majorTag, c_int), &
                                    endTag=int(endTag, c_int), &
                                    tag=optval_c_int(-1, tag), &
                                    nx=optval_c_double(0., nx), &
                                    ny=optval_c_double(0., ny), &
                                    nz=optval_c_double(0., nz), &
                                    ierr_=ierr)
      end function gmshModelGeoAddEllipseArc
    
      !> Add a spline (Catmull-Rom) curve in the built-in CAD representation, going
      !! through the points `pointTags'. If `tag' is positive, set the tag
      !! explicitly; otherwise a new tag is selected automatically. Create a
      !! periodic curve if the first and last points are the same. Return the tag of
      !! the spline curve.
      function gmshModelGeoAddSpline(pointTags, &
                                     tag, &
                                     ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddSpline")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddSpline
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddSpline = C_API(api_pointTags_=pointTags, &
                                api_pointTags_n_=size_gmsh_int(pointTags), &
                                tag=optval_c_int(-1, tag), &
                                ierr_=ierr)
      end function gmshModelGeoAddSpline
    
      !> Add a cubic b-spline curve in the built-in CAD representation, with
      !! `pointTags' control points. If `tag' is positive, set the tag explicitly;
      !! otherwise a new tag is selected automatically. Creates a periodic curve if
      !! the first and last points are the same. Return the tag of the b-spline
      !! curve.
      function gmshModelGeoAddBSpline(pointTags, &
                                      tag, &
                                      ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddBSpline")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddBSpline
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddBSpline = C_API(api_pointTags_=pointTags, &
                                 api_pointTags_n_=size_gmsh_int(pointTags), &
                                 tag=optval_c_int(-1, tag), &
                                 ierr_=ierr)
      end function gmshModelGeoAddBSpline
    
      !> Add a Bezier curve in the built-in CAD representation, with `pointTags'
      !! control points. If `tag' is positive, set the tag explicitly; otherwise a
      !! new tag is selected automatically.  Return the tag of the Bezier curve.
      function gmshModelGeoAddBezier(pointTags, &
                                     tag, &
                                     ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddBezier")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddBezier
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddBezier = C_API(api_pointTags_=pointTags, &
                                api_pointTags_n_=size_gmsh_int(pointTags), &
                                tag=optval_c_int(-1, tag), &
                                ierr_=ierr)
      end function gmshModelGeoAddBezier
    
      !> Add a polyline curve in the built-in CAD representation, going through the
      !! points `pointTags'. If `tag' is positive, set the tag explicitly; otherwise
      !! a new tag is selected automatically. Create a periodic curve if the first
      !! and last points are the same. Return the tag of the polyline curve.
      function gmshModelGeoAddPolyline(pointTags, &
                                       tag, &
                                       ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddPolyline")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddPolyline
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddPolyline = C_API(api_pointTags_=pointTags, &
                                  api_pointTags_n_=size_gmsh_int(pointTags), &
                                  tag=optval_c_int(-1, tag), &
                                  ierr_=ierr)
      end function gmshModelGeoAddPolyline
    
      !> Add a spline (Catmull-Rom) curve in the built-in CAD representation, going
      !! through points sampling the curves in `curveTags'. The density of sampling
      !! points on each curve is governed by `numIntervals'. If `tag' is positive,
      !! set the tag explicitly; otherwise a new tag is selected automatically.
      !! Return the tag of the spline.
      function gmshModelGeoAddCompoundSpline(curveTags, &
                                             numIntervals, &
                                             tag, &
                                             ierr)
        interface
        function C_API(api_curveTags_, &
                       api_curveTags_n_, &
                       numIntervals, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddCompoundSpline")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_curveTags_
          integer(c_size_t), value, intent(in) :: api_curveTags_n_
          integer(c_int), value, intent(in) :: numIntervals
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddCompoundSpline
        integer(c_int), dimension(:), intent(in) :: curveTags
        integer, intent(in), optional :: numIntervals
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddCompoundSpline = C_API(api_curveTags_=curveTags, &
                                        api_curveTags_n_=size_gmsh_int(curveTags), &
                                        numIntervals=optval_c_int(5, numIntervals), &
                                        tag=optval_c_int(-1, tag), &
                                        ierr_=ierr)
      end function gmshModelGeoAddCompoundSpline
    
      !> Add a b-spline curve in the built-in CAD representation, with control
      !! points sampling the curves in `curveTags'. The density of sampling points
      !! on each curve is governed by `numIntervals'. If `tag' is positive, set the
      !! tag explicitly; otherwise a new tag is selected automatically. Return the
      !! tag of the b-spline.
      function gmshModelGeoAddCompoundBSpline(curveTags, &
                                              numIntervals, &
                                              tag, &
                                              ierr)
        interface
        function C_API(api_curveTags_, &
                       api_curveTags_n_, &
                       numIntervals, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddCompoundBSpline")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_curveTags_
          integer(c_size_t), value, intent(in) :: api_curveTags_n_
          integer(c_int), value, intent(in) :: numIntervals
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddCompoundBSpline
        integer(c_int), dimension(:), intent(in) :: curveTags
        integer, intent(in), optional :: numIntervals
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddCompoundBSpline = C_API(api_curveTags_=curveTags, &
                                         api_curveTags_n_=size_gmsh_int(curveTags), &
                                         numIntervals=optval_c_int(20, numIntervals), &
                                         tag=optval_c_int(-1, tag), &
                                         ierr_=ierr)
      end function gmshModelGeoAddCompoundBSpline
    
      !> Add a curve loop (a closed wire) in the built-in CAD representation, formed
      !! by the curves `curveTags'. `curveTags' should contain (signed) tags of
      !! model entities of dimension 1 forming a closed loop: a negative tag
      !! signifies that the underlying curve is considered with reversed
      !! orientation. If `tag' is positive, set the tag explicitly; otherwise a new
      !! tag is selected automatically. If `reorient' is set, automatically reorient
      !! the curves if necessary. Return the tag of the curve loop.
      function gmshModelGeoAddCurveLoop(curveTags, &
                                        tag, &
                                        reorient, &
                                        ierr)
        interface
        function C_API(api_curveTags_, &
                       api_curveTags_n_, &
                       tag, &
                       reorient, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddCurveLoop")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_curveTags_
          integer(c_size_t), value, intent(in) :: api_curveTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: reorient
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddCurveLoop
        integer(c_int), dimension(:), intent(in) :: curveTags
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: reorient
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddCurveLoop = C_API(api_curveTags_=curveTags, &
                                   api_curveTags_n_=size_gmsh_int(curveTags), &
                                   tag=optval_c_int(-1, tag), &
                                   reorient=optval_c_bool(.false., reorient), &
                                   ierr_=ierr)
      end function gmshModelGeoAddCurveLoop
    
      !> Add curve loops in the built-in CAD representation based on the curves
      !! `curveTags'. Return the `tags' of found curve loops, if any.
      subroutine gmshModelGeoAddCurveLoops(curveTags, &
                                           tags, &
                                           ierr)
        interface
        subroutine C_API(api_curveTags_, &
                         api_curveTags_n_, &
                         api_tags_, &
                         api_tags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGeoAddCurveLoops")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_curveTags_
          integer(c_size_t), value, intent(in) :: api_curveTags_n_
          type(c_ptr), intent(out) :: api_tags_
          integer(c_size_t), intent(out) :: api_tags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), intent(in) :: curveTags
        integer(c_int), dimension(:), allocatable, intent(out) :: tags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_tags_
        integer(c_size_t) :: api_tags_n_
        call C_API(api_curveTags_=curveTags, &
             api_curveTags_n_=size_gmsh_int(curveTags), &
             api_tags_=api_tags_, &
             api_tags_n_=api_tags_n_, &
             ierr_=ierr)
        tags = ovectorint_(api_tags_, &
          api_tags_n_)
      end subroutine gmshModelGeoAddCurveLoops
    
      !> Add a plane surface in the built-in CAD representation, defined by one or
      !! more curve loops `wireTags'. The first curve loop defines the exterior
      !! contour; additional curve loop define holes. If `tag' is positive, set the
      !! tag explicitly; otherwise a new tag is selected automatically. Return the
      !! tag of the surface.
      function gmshModelGeoAddPlaneSurface(wireTags, &
                                           tag, &
                                           ierr)
        interface
        function C_API(api_wireTags_, &
                       api_wireTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddPlaneSurface")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_wireTags_
          integer(c_size_t), value, intent(in) :: api_wireTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddPlaneSurface
        integer(c_int), dimension(:), intent(in) :: wireTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddPlaneSurface = C_API(api_wireTags_=wireTags, &
                                      api_wireTags_n_=size_gmsh_int(wireTags), &
                                      tag=optval_c_int(-1, tag), &
                                      ierr_=ierr)
      end function gmshModelGeoAddPlaneSurface
    
      !> Add a surface in the built-in CAD representation, filling the curve loops
      !! in `wireTags' using transfinite interpolation. Currently only a single
      !! curve loop is supported; this curve loop should be composed by 3 or 4
      !! curves only. If `tag' is positive, set the tag explicitly; otherwise a new
      !! tag is selected automatically. Return the tag of the surface.
      function gmshModelGeoAddSurfaceFilling(wireTags, &
                                             tag, &
                                             sphereCenterTag, &
                                             ierr)
        interface
        function C_API(api_wireTags_, &
                       api_wireTags_n_, &
                       tag, &
                       sphereCenterTag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddSurfaceFilling")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_wireTags_
          integer(c_size_t), value, intent(in) :: api_wireTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: sphereCenterTag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddSurfaceFilling
        integer(c_int), dimension(:), intent(in) :: wireTags
        integer, intent(in), optional :: tag
        integer, intent(in), optional :: sphereCenterTag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddSurfaceFilling = C_API(api_wireTags_=wireTags, &
                                        api_wireTags_n_=size_gmsh_int(wireTags), &
                                        tag=optval_c_int(-1, tag), &
                                        sphereCenterTag=optval_c_int(-1, sphereCenterTag), &
                                        ierr_=ierr)
      end function gmshModelGeoAddSurfaceFilling
    
      !> Add a surface loop (a closed shell) formed by `surfaceTags' in the built-in
      !! CAD representation.  If `tag' is positive, set the tag explicitly;
      !! otherwise a new tag is selected automatically. Return the tag of the shell.
      function gmshModelGeoAddSurfaceLoop(surfaceTags, &
                                          tag, &
                                          ierr)
        interface
        function C_API(api_surfaceTags_, &
                       api_surfaceTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddSurfaceLoop")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_surfaceTags_
          integer(c_size_t), value, intent(in) :: api_surfaceTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddSurfaceLoop
        integer(c_int), dimension(:), intent(in) :: surfaceTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddSurfaceLoop = C_API(api_surfaceTags_=surfaceTags, &
                                     api_surfaceTags_n_=size_gmsh_int(surfaceTags), &
                                     tag=optval_c_int(-1, tag), &
                                     ierr_=ierr)
      end function gmshModelGeoAddSurfaceLoop
    
      !> Add a volume (a region) in the built-in CAD representation, defined by one
      !! or more shells `shellTags'. The first surface loop defines the exterior
      !! boundary; additional surface loop define holes. If `tag' is positive, set
      !! the tag explicitly; otherwise a new tag is selected automatically. Return
      !! the tag of the volume.
      function gmshModelGeoAddVolume(shellTags, &
                                     tag, &
                                     ierr)
        interface
        function C_API(api_shellTags_, &
                       api_shellTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddVolume")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_shellTags_
          integer(c_size_t), value, intent(in) :: api_shellTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddVolume
        integer(c_int), dimension(:), intent(in) :: shellTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddVolume = C_API(api_shellTags_=shellTags, &
                                api_shellTags_n_=size_gmsh_int(shellTags), &
                                tag=optval_c_int(-1, tag), &
                                ierr_=ierr)
      end function gmshModelGeoAddVolume
    
      !> Add a `geometry' in the built-in CAD representation. `geometry' can
      !! currently be one of "Sphere" or "PolarSphere" (where `numbers' should
      !! contain the x, y, z coordinates of the center, followed by the radius), or
      !! "Parametric" (where `strings' should contains three expression evaluating
      !! to the x, y and z coordinates. If `tag' is positive, set the tag of the
      !! geometry explicitly; otherwise a new tag is selected automatically. Return
      !! the tag of the geometry.
      function gmshModelGeoAddGeometry(geometry, &
                                       numbers, &
                                       strings, &
                                       tag, &
                                       ierr)
        interface
        function C_API(geometry, &
                       api_numbers_, &
                       api_numbers_n_, &
                       api_strings_, &
                       api_strings_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddGeometry")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          character(len=1, kind=c_char), dimension(*), intent(in) :: geometry
          real(c_double), dimension(*), optional :: api_numbers_
          integer(c_size_t), value, intent(in) :: api_numbers_n_
          type(c_ptr), dimension(*), optional :: api_strings_
          integer(c_size_t), value, intent(in) :: api_strings_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddGeometry
        character(len=*), intent(in) :: geometry
        real(c_double), dimension(:), intent(in), optional :: numbers
        character(len=*), dimension(:), intent(in), optional :: strings
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        character(len=GMSH_API_MAX_STR_LEN, kind=c_char), allocatable :: api_strings_strs(:)
        type(c_ptr), allocatable :: api_strings_(:)
        call ivectorstring_(strings, &
          api_strings_strs, &
          api_strings_)
        gmshModelGeoAddGeometry = C_API(geometry=istring_(geometry), &
                                  api_numbers_=numbers, &
                                  api_numbers_n_=size_gmsh_double(numbers), &
                                  api_strings_=api_strings_, &
                                  api_strings_n_=size_gmsh_str(strings), &
                                  tag=optval_c_int(-1, tag), &
                                  ierr_=ierr)
      end function gmshModelGeoAddGeometry
    
      !> Add a point in the built-in CAD representation, at coordinates (`x', `y',
      !! `z') on the geometry `geometryTag'. If `meshSize' is > 0, add a meshing
      !! constraint at that point. If `tag' is positive, set the tag explicitly;
      !! otherwise a new tag is selected automatically. Return the tag of the point.
      !! For surface geometries, only the `x' and `y' coordinates are used.
      function gmshModelGeoAddPointOnGeometry(geometryTag, &
                                              x, &
                                              y, &
                                              z, &
                                              meshSize, &
                                              tag, &
                                              ierr)
        interface
        function C_API(geometryTag, &
                       x, &
                       y, &
                       z, &
                       meshSize, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddPointOnGeometry")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: geometryTag
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: meshSize
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddPointOnGeometry
        integer, intent(in) :: geometryTag
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in), optional :: z
        real(c_double), intent(in), optional :: meshSize
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddPointOnGeometry = C_API(geometryTag=int(geometryTag, c_int), &
                                         x=real(x, c_double), &
                                         y=real(y, c_double), &
                                         z=optval_c_double(0., z), &
                                         meshSize=optval_c_double(0., meshSize), &
                                         tag=optval_c_int(-1, tag), &
                                         ierr_=ierr)
      end function gmshModelGeoAddPointOnGeometry
    
      !> Extrude the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation, using a translation along (`dx', `dy',
      !! `dz'). Return extruded entities in `outDimTags'. If the `numElements'
      !! vector is not empty, also extrude the mesh: the entries in `numElements'
      !! give the number of elements in each layer. If the `height' vector is not
      !! empty, it provides the (cumulative) height of the different layers,
      !! normalized to 1. If `recombine' is set, recombine the mesh in the layers.
      subroutine gmshModelGeoExtrude(dimTags, &
                                     dx, &
                                     dy, &
                                     dz, &
                                     outDimTags, &
                                     numElements, &
                                     heights, &
                                     recombine, &
                                     ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         dx, &
                         dy, &
                         dz, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_numElements_, &
                         api_numElements_n_, &
                         api_heights_, &
                         api_heights_n_, &
                         recombine, &
                         ierr_) &
          bind(C, name="gmshModelGeoExtrude")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), dimension(*), optional :: api_numElements_
          integer(c_size_t), value, intent(in) :: api_numElements_n_
          real(c_double), dimension(*), optional :: api_heights_
          integer(c_size_t), value, intent(in) :: api_heights_n_
          integer(c_int), value, intent(in) :: recombine
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:), intent(in), optional :: numElements
        real(c_double), dimension(:), intent(in), optional :: heights
        logical, intent(in), optional :: recombine
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             dx=real(dx, c_double), &
             dy=real(dy, c_double), &
             dz=real(dz, c_double), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_numElements_=numElements, &
             api_numElements_n_=size_gmsh_int(numElements), &
             api_heights_=heights, &
             api_heights_n_=size_gmsh_double(heights), &
             recombine=optval_c_bool(.false., recombine), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelGeoExtrude
    
      !> Extrude the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation, using a rotation of `angle' radians around
      !! the axis of revolution defined by the point (`x', `y', `z') and the
      !! direction (`ax', `ay', `az'). The angle should be strictly smaller than Pi.
      !! Return extruded entities in `outDimTags'. If the `numElements' vector is
      !! not empty, also extrude the mesh: the entries in `numElements' give the
      !! number of elements in each layer. If the `height' vector is not empty, it
      !! provides the (cumulative) height of the different layers, normalized to 1.
      !! If `recombine' is set, recombine the mesh in the layers.
      subroutine gmshModelGeoRevolve(dimTags, &
                                     x, &
                                     y, &
                                     z, &
                                     ax, &
                                     ay, &
                                     az, &
                                     angle, &
                                     outDimTags, &
                                     numElements, &
                                     heights, &
                                     recombine, &
                                     ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         x, &
                         y, &
                         z, &
                         ax, &
                         ay, &
                         az, &
                         angle, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_numElements_, &
                         api_numElements_n_, &
                         api_heights_, &
                         api_heights_n_, &
                         recombine, &
                         ierr_) &
          bind(C, name="gmshModelGeoRevolve")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: ax
          real(c_double), value, intent(in) :: ay
          real(c_double), value, intent(in) :: az
          real(c_double), value, intent(in) :: angle
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), dimension(*), optional :: api_numElements_
          integer(c_size_t), value, intent(in) :: api_numElements_n_
          real(c_double), dimension(*), optional :: api_heights_
          integer(c_size_t), value, intent(in) :: api_heights_n_
          integer(c_int), value, intent(in) :: recombine
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: ax
        real(c_double), intent(in) :: ay
        real(c_double), intent(in) :: az
        real(c_double), intent(in) :: angle
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:), intent(in), optional :: numElements
        real(c_double), dimension(:), intent(in), optional :: heights
        logical, intent(in), optional :: recombine
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             ax=real(ax, c_double), &
             ay=real(ay, c_double), &
             az=real(az, c_double), &
             angle=real(angle, c_double), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_numElements_=numElements, &
             api_numElements_n_=size_gmsh_int(numElements), &
             api_heights_=heights, &
             api_heights_n_=size_gmsh_double(heights), &
             recombine=optval_c_bool(.false., recombine), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelGeoRevolve
    
      !> Extrude the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation, using a combined translation and rotation
      !! of `angle' radians, along (`dx', `dy', `dz') and around the axis of
      !! revolution defined by the point (`x', `y', `z') and the direction (`ax',
      !! `ay', `az'). The angle should be strictly smaller than Pi. Return extruded
      !! entities in `outDimTags'. If the `numElements' vector is not empty, also
      !! extrude the mesh: the entries in `numElements' give the number of elements
      !! in each layer. If the `height' vector is not empty, it provides the
      !! (cumulative) height of the different layers, normalized to 1. If
      !! `recombine' is set, recombine the mesh in the layers.
      subroutine gmshModelGeoTwist(dimTags, &
                                   x, &
                                   y, &
                                   z, &
                                   dx, &
                                   dy, &
                                   dz, &
                                   ax, &
                                   ay, &
                                   az, &
                                   angle, &
                                   outDimTags, &
                                   numElements, &
                                   heights, &
                                   recombine, &
                                   ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         x, &
                         y, &
                         z, &
                         dx, &
                         dy, &
                         dz, &
                         ax, &
                         ay, &
                         az, &
                         angle, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_numElements_, &
                         api_numElements_n_, &
                         api_heights_, &
                         api_heights_n_, &
                         recombine, &
                         ierr_) &
          bind(C, name="gmshModelGeoTwist")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          real(c_double), value, intent(in) :: ax
          real(c_double), value, intent(in) :: ay
          real(c_double), value, intent(in) :: az
          real(c_double), value, intent(in) :: angle
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), dimension(*), optional :: api_numElements_
          integer(c_size_t), value, intent(in) :: api_numElements_n_
          real(c_double), dimension(*), optional :: api_heights_
          integer(c_size_t), value, intent(in) :: api_heights_n_
          integer(c_int), value, intent(in) :: recombine
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        real(c_double), intent(in) :: ax
        real(c_double), intent(in) :: ay
        real(c_double), intent(in) :: az
        real(c_double), intent(in) :: angle
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:), intent(in), optional :: numElements
        real(c_double), dimension(:), intent(in), optional :: heights
        logical, intent(in), optional :: recombine
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             dx=real(dx, c_double), &
             dy=real(dy, c_double), &
             dz=real(dz, c_double), &
             ax=real(ax, c_double), &
             ay=real(ay, c_double), &
             az=real(az, c_double), &
             angle=real(angle, c_double), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_numElements_=numElements, &
             api_numElements_n_=size_gmsh_int(numElements), &
             api_heights_=heights, &
             api_heights_n_=size_gmsh_double(heights), &
             recombine=optval_c_bool(.false., recombine), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelGeoTwist
    
      !> Extrude the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation along the normals of the mesh, creating
      !! discrete boundary layer entities. Return extruded entities in `outDimTags'.
      !! The entries in `numElements' give the number of elements in each layer. If
      !! the `height' vector is not empty, it provides the (cumulative) height of
      !! the different layers. If `recombine' is set, recombine the mesh in the
      !! layers. A second boundary layer can be created from the same entities if
      !! `second' is set. If `viewIndex' is >= 0, use the corresponding view to
      !! either specify the normals (if the view contains a vector field) or scale
      !! the normals (if the view is scalar).
      subroutine gmshModelGeoExtrudeBoundaryLayer(dimTags, &
                                                  outDimTags, &
                                                  numElements, &
                                                  heights, &
                                                  recombine, &
                                                  second, &
                                                  viewIndex, &
                                                  ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_numElements_, &
                         api_numElements_n_, &
                         api_heights_, &
                         api_heights_n_, &
                         recombine, &
                         second, &
                         viewIndex, &
                         ierr_) &
          bind(C, name="gmshModelGeoExtrudeBoundaryLayer")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), dimension(*), optional :: api_numElements_
          integer(c_size_t), value, intent(in) :: api_numElements_n_
          real(c_double), dimension(*), optional :: api_heights_
          integer(c_size_t), value, intent(in) :: api_heights_n_
          integer(c_int), value, intent(in) :: recombine
          integer(c_int), value, intent(in) :: second
          integer(c_int), value, intent(in) :: viewIndex
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:), intent(in), optional :: numElements
        real(c_double), dimension(:), intent(in), optional :: heights
        logical, intent(in), optional :: recombine
        logical, intent(in), optional :: second
        integer, intent(in), optional :: viewIndex
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_numElements_=numElements, &
             api_numElements_n_=size_gmsh_int(numElements), &
             api_heights_=heights, &
             api_heights_n_=size_gmsh_double(heights), &
             recombine=optval_c_bool(.false., recombine), &
             second=optval_c_bool(.false., second), &
             viewIndex=optval_c_int(-1, viewIndex), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelGeoExtrudeBoundaryLayer
    
      !> Translate the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation along (`dx', `dy', `dz').
      subroutine gmshModelGeoTranslate(dimTags, &
                                       dx, &
                                       dy, &
                                       dz, &
                                       ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         dx, &
                         dy, &
                         dz, &
                         ierr_) &
          bind(C, name="gmshModelGeoTranslate")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             dx=real(dx, c_double), &
             dy=real(dy, c_double), &
             dz=real(dz, c_double), &
             ierr_=ierr)
      end subroutine gmshModelGeoTranslate
    
      !> Rotate the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation by `angle' radians around the axis of
      !! revolution defined by the point (`x', `y', `z') and the direction (`ax',
      !! `ay', `az').
      subroutine gmshModelGeoRotate(dimTags, &
                                    x, &
                                    y, &
                                    z, &
                                    ax, &
                                    ay, &
                                    az, &
                                    angle, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         x, &
                         y, &
                         z, &
                         ax, &
                         ay, &
                         az, &
                         angle, &
                         ierr_) &
          bind(C, name="gmshModelGeoRotate")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: ax
          real(c_double), value, intent(in) :: ay
          real(c_double), value, intent(in) :: az
          real(c_double), value, intent(in) :: angle
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: ax
        real(c_double), intent(in) :: ay
        real(c_double), intent(in) :: az
        real(c_double), intent(in) :: angle
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             ax=real(ax, c_double), &
             ay=real(ay, c_double), &
             az=real(az, c_double), &
             angle=real(angle, c_double), &
             ierr_=ierr)
      end subroutine gmshModelGeoRotate
    
      !> Scale the entities `dimTags' (given as a vector of (dim, tag) pairs) in the
      !! built-in CAD representation by factors `a', `b' and `c' along the three
      !! coordinate axes; use (`x', `y', `z') as the center of the homothetic
      !! transformation.
      subroutine gmshModelGeoDilate(dimTags, &
                                    x, &
                                    y, &
                                    z, &
                                    a, &
                                    b, &
                                    c, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         x, &
                         y, &
                         z, &
                         a, &
                         b, &
                         c, &
                         ierr_) &
          bind(C, name="gmshModelGeoDilate")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: a
          real(c_double), value, intent(in) :: b
          real(c_double), value, intent(in) :: c
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: a
        real(c_double), intent(in) :: b
        real(c_double), intent(in) :: c
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             a=real(a, c_double), &
             b=real(b, c_double), &
             c=real(c, c_double), &
             ierr_=ierr)
      end subroutine gmshModelGeoDilate
    
      !> Mirror the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation, with respect to the plane of equation `a'
      !! * x + `b' * y + `c' * z + `d' = 0.
      subroutine gmshModelGeoMirror(dimTags, &
                                    a, &
                                    b, &
                                    c, &
                                    d, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         a, &
                         b, &
                         c, &
                         d, &
                         ierr_) &
          bind(C, name="gmshModelGeoMirror")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: a
          real(c_double), value, intent(in) :: b
          real(c_double), value, intent(in) :: c
          real(c_double), value, intent(in) :: d
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: a
        real(c_double), intent(in) :: b
        real(c_double), intent(in) :: c
        real(c_double), intent(in) :: d
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             a=real(a, c_double), &
             b=real(b, c_double), &
             c=real(c, c_double), &
             d=real(d, c_double), &
             ierr_=ierr)
      end subroutine gmshModelGeoMirror
    
      !> Mirror the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation, with respect to the plane of equation `a'
      !! * x + `b' * y + `c' * z + `d' = 0. (This is a synonym for `mirror', which
      !! will be deprecated in a future release.)
      subroutine gmshModelGeoSymmetrize(dimTags, &
                                        a, &
                                        b, &
                                        c, &
                                        d, &
                                        ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         a, &
                         b, &
                         c, &
                         d, &
                         ierr_) &
          bind(C, name="gmshModelGeoSymmetrize")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: a
          real(c_double), value, intent(in) :: b
          real(c_double), value, intent(in) :: c
          real(c_double), value, intent(in) :: d
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: a
        real(c_double), intent(in) :: b
        real(c_double), intent(in) :: c
        real(c_double), intent(in) :: d
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             a=real(a, c_double), &
             b=real(b, c_double), &
             c=real(c, c_double), &
             d=real(d, c_double), &
             ierr_=ierr)
      end subroutine gmshModelGeoSymmetrize
    
      !> Copy the entities `dimTags' (given as a vector of (dim, tag) pairs) in the
      !! built-in CAD representation; the new entities are returned in `outDimTags'.
      subroutine gmshModelGeoCopy(dimTags, &
                                  outDimTags, &
                                  ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGeoCopy")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelGeoCopy
    
      !> Remove the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the built-in CAD representation, provided that they are not on the boundary
      !! of higher-dimensional entities. If `recursive' is true, remove all the
      !! entities on their boundaries, down to dimension 0.
      subroutine gmshModelGeoRemove(dimTags, &
                                    recursive, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         recursive, &
                         ierr_) &
          bind(C, name="gmshModelGeoRemove")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: recursive
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        logical, intent(in), optional :: recursive
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             recursive=optval_c_bool(.false., recursive), &
             ierr_=ierr)
      end subroutine gmshModelGeoRemove
    
      !> Remove all duplicate entities in the built-in CAD representation (different
      !! entities at the same geometrical location).
      subroutine gmshModelGeoRemoveAllDuplicates(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelGeoRemoveAllDuplicates")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelGeoRemoveAllDuplicates
    
      !> Split the curve of tag `tag' in the built-in CAD representation, on the
      !! specified control points `pointTags'. This feature is only available for
      !! lines, splines and b-splines. Return the tag(s) `curveTags' of the newly
      !! created curve(s).
      subroutine gmshModelGeoSplitCurve(tag, &
                                        pointTags, &
                                        curveTags, &
                                        ierr)
        interface
        subroutine C_API(tag, &
                         api_pointTags_, &
                         api_pointTags_n_, &
                         api_curveTags_, &
                         api_curveTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGeoSplitCurve")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          type(c_ptr), intent(out) :: api_curveTags_
          integer(c_size_t), intent(out) :: api_curveTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer(c_int), dimension(:), allocatable, intent(out) :: curveTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_curveTags_
        integer(c_size_t) :: api_curveTags_n_
        call C_API(tag=int(tag, c_int), &
             api_pointTags_=pointTags, &
             api_pointTags_n_=size_gmsh_int(pointTags), &
             api_curveTags_=api_curveTags_, &
             api_curveTags_n_=api_curveTags_n_, &
             ierr_=ierr)
        curveTags = ovectorint_(api_curveTags_, &
          api_curveTags_n_)
      end subroutine gmshModelGeoSplitCurve
    
      !> Get the maximum tag of entities of dimension `dim' in the built-in CAD
      !! representation.
      function gmshModelGeoGetMaxTag(dim, &
                                     ierr)
        interface
        function C_API(dim, &
                       ierr_) &
          bind(C, name="gmshModelGeoGetMaxTag")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoGetMaxTag
        integer, intent(in) :: dim
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoGetMaxTag = C_API(dim=int(dim, c_int), &
                                ierr_=ierr)
      end function gmshModelGeoGetMaxTag
    
      !> Set the maximum tag `maxTag' for entities of dimension `dim' in the built-
      !! in CAD representation.
      subroutine gmshModelGeoSetMaxTag(dim, &
                                       maxTag, &
                                       ierr)
        interface
        subroutine C_API(dim, &
                         maxTag, &
                         ierr_) &
          bind(C, name="gmshModelGeoSetMaxTag")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: maxTag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: maxTag
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             maxTag=int(maxTag, c_int), &
             ierr_=ierr)
      end subroutine gmshModelGeoSetMaxTag
    
      !> Add a physical group of dimension `dim', grouping the entities with tags
      !! `tags' in the built-in CAD representation. Return the tag of the physical
      !! group, equal to `tag' if `tag' is positive, or a new tag if `tag' < 0. Set
      !! the name of the physical group if `name' is not empty.
      function gmshModelGeoAddPhysicalGroup(dim, &
                                            tags, &
                                            tag, &
                                            name, &
                                            ierr)
        interface
        function C_API(dim, &
                       api_tags_, &
                       api_tags_n_, &
                       tag, &
                       name, &
                       ierr_) &
          bind(C, name="gmshModelGeoAddPhysicalGroup")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: dim
          integer(c_int), dimension(*) :: api_tags_
          integer(c_size_t), value, intent(in) :: api_tags_n_
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: name
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelGeoAddPhysicalGroup
        integer, intent(in) :: dim
        integer(c_int), dimension(:), intent(in) :: tags
        integer, intent(in), optional :: tag
        character(len=*), intent(in), optional :: name
        integer(c_int), intent(out), optional :: ierr
        gmshModelGeoAddPhysicalGroup = C_API(dim=int(dim, c_int), &
                                       api_tags_=tags, &
                                       api_tags_n_=size_gmsh_int(tags), &
                                       tag=optval_c_int(-1, tag), &
                                       name=istring_(optval_c_str("", name)), &
                                       ierr_=ierr)
      end function gmshModelGeoAddPhysicalGroup
    
      !> Remove the physical groups `dimTags' (given as a vector of (dim, tag)
      !! pairs) from the built-in CAD representation. If `dimTags' is empty, remove
      !! all groups.
      subroutine gmshModelGeoRemovePhysicalGroups(dimTags, &
                                                  ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGeoRemovePhysicalGroups")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelGeoRemovePhysicalGroups
    
      !> Synchronize the built-in CAD representation with the current Gmsh model.
      !! This can be called at any time, but since it involves a non trivial amount
      !! of processing, the number of synchronization points should normally be
      !! minimized. Without synchronization the entities in the built-in CAD
      !! representation are not available to any function outside of the built-in
      !! CAD kernel functions.
      subroutine gmshModelGeoSynchronize(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelGeoSynchronize")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelGeoSynchronize
    
      !> Set a mesh size constraint on the entities `dimTags' (given as a vector of
      !! (dim, tag) pairs) in the built-in CAD kernel representation. Currently only
      !! entities of dimension 0 (points) are handled.
      subroutine gmshModelGeoMeshSetSize(dimTags, &
                                         size, &
                                         ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         size, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetSize")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: size
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: size
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             size=real(size, c_double), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetSize
    
      !> Set a transfinite meshing constraint on the curve `tag' in the built-in CAD
      !! kernel representation, 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).
      subroutine gmshModelGeoMeshSetTransfiniteCurve(tag, &
                                                     nPoints, &
                                                     meshType, &
                                                     coef, &
                                                     ierr)
        interface
        subroutine C_API(tag, &
                         nPoints, &
                         meshType, &
                         coef, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetTransfiniteCurve")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: nPoints
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: meshType
          real(c_double), value, intent(in) :: coef
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: nPoints
        character(len=*), intent(in), optional :: meshType
        real(c_double), intent(in), optional :: coef
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             nPoints=int(nPoints, c_int), &
             meshType=istring_(optval_c_str("Progression", meshType)), &
             coef=optval_c_double(1., coef), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetTransfiniteCurve
    
      !> Set a transfinite meshing constraint on the surface `tag' in the built-in
      !! CAD kernel representation. `arrangement' describes the arrangement of the
      !! triangles when the surface is not flagged as recombined: currently
      !! supported values are "Left", "Right", "AlternateLeft" and "AlternateRight".
      !! `cornerTags' can be used to specify the (3 or 4) corners of the transfinite
      !! interpolation explicitly; specifying the corners explicitly is mandatory if
      !! the surface has more that 3 or 4 points on its boundary.
      subroutine gmshModelGeoMeshSetTransfiniteSurface(tag, &
                                                       arrangement, &
                                                       cornerTags, &
                                                       ierr)
        interface
        subroutine C_API(tag, &
                         arrangement, &
                         api_cornerTags_, &
                         api_cornerTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetTransfiniteSurface")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: arrangement
          integer(c_int), dimension(*), optional :: api_cornerTags_
          integer(c_size_t), value, intent(in) :: api_cornerTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in), optional :: arrangement
        integer(c_int), dimension(:), intent(in), optional :: cornerTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             arrangement=istring_(optval_c_str("Left", arrangement)), &
             api_cornerTags_=cornerTags, &
             api_cornerTags_n_=size_gmsh_int(cornerTags), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetTransfiniteSurface
    
      !> Set a transfinite meshing constraint on the surface `tag' in the built-in
      !! CAD kernel representation. `cornerTags' can be used to specify the (6 or 8)
      !! corners of the transfinite interpolation explicitly.
      subroutine gmshModelGeoMeshSetTransfiniteVolume(tag, &
                                                      cornerTags, &
                                                      ierr)
        interface
        subroutine C_API(tag, &
                         api_cornerTags_, &
                         api_cornerTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetTransfiniteVolume")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), dimension(*), optional :: api_cornerTags_
          integer(c_size_t), value, intent(in) :: api_cornerTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer(c_int), dimension(:), intent(in), optional :: cornerTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             api_cornerTags_=cornerTags, &
             api_cornerTags_n_=size_gmsh_int(cornerTags), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetTransfiniteVolume
    
      !> Set a recombination meshing constraint on the entity of dimension `dim' and
      !! tag `tag' in the built-in CAD kernel representation. Currently only
      !! entities of dimension 2 (to recombine triangles into quadrangles) are
      !! supported; `angle' specifies the threshold angle for the simple
      !! recombination algorithm.
      subroutine gmshModelGeoMeshSetRecombine(dim, &
                                              tag, &
                                              angle, &
                                              ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         angle, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetRecombine")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: angle
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), intent(in), optional :: angle
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             angle=optval_c_double(45., angle), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetRecombine
    
      !> Set a smoothing meshing constraint on the entity of dimension `dim' and tag
      !! `tag' in the built-in CAD kernel representation. `val' iterations of a
      !! Laplace smoother are applied.
      subroutine gmshModelGeoMeshSetSmoothing(dim, &
                                              tag, &
                                              val, &
                                              ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         val, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetSmoothing")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: val
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer, intent(in) :: val
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             val=int(val, c_int), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetSmoothing
    
      !> Set a reverse meshing constraint on the entity of dimension `dim' and tag
      !! `tag' in the built-in CAD kernel representation. If `val' is true, the mesh
      !! orientation will be reversed with respect to the natural mesh orientation
      !! (i.e. the orientation consistent with the orientation of the geometry). If
      !! `val' is false, the mesh is left as-is.
      subroutine gmshModelGeoMeshSetReverse(dim, &
                                            tag, &
                                            val, &
                                            ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         val, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetReverse")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: val
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        logical, intent(in), optional :: val
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             val=optval_c_bool(.true., val), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetReverse
    
      !> Set the meshing algorithm on the entity of dimension `dim' and tag `tag' in
      !! the built-in CAD kernel representation. Currently only supported for `dim'
      !! == 2.
      subroutine gmshModelGeoMeshSetAlgorithm(dim, &
                                              tag, &
                                              val, &
                                              ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         val, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetAlgorithm")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: val
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer, intent(in) :: val
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             val=int(val, c_int), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetAlgorithm
    
      !> Force the mesh size to be extended from the boundary, or not, for the
      !! entity of dimension `dim' and tag `tag' in the built-in CAD kernel
      !! representation. Currently only supported for `dim' == 2.
      subroutine gmshModelGeoMeshSetSizeFromBoundary(dim, &
                                                     tag, &
                                                     val, &
                                                     ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         val, &
                         ierr_) &
          bind(C, name="gmshModelGeoMeshSetSizeFromBoundary")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: val
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer, intent(in) :: val
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             val=int(val, c_int), &
             ierr_=ierr)
      end subroutine gmshModelGeoMeshSetSizeFromBoundary
    
      !> Add a geometrical point in the OpenCASCADE CAD representation, at
      !! coordinates (`x', `y', `z'). If `meshSize' is > 0, add a meshing constraint
      !! at that point. If `tag' is positive, set the tag explicitly; otherwise a
      !! new tag is selected automatically. Return the tag of the point. (Note that
      !! the point will be added in the current model only after `synchronize' is
      !! called. This behavior holds for all the entities added in the occ module.)
      function gmshModelOccAddPoint(x, &
                                    y, &
                                    z, &
                                    meshSize, &
                                    tag, &
                                    ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       meshSize, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddPoint")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: meshSize
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddPoint
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in), optional :: meshSize
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddPoint = C_API(x=real(x, c_double), &
                               y=real(y, c_double), &
                               z=real(z, c_double), &
                               meshSize=optval_c_double(0., meshSize), &
                               tag=optval_c_int(-1, tag), &
                               ierr_=ierr)
      end function gmshModelOccAddPoint
    
      !> Add a straight line segment in the OpenCASCADE CAD representation, between
      !! the two points with tags `startTag' and `endTag'. If `tag' is positive, set
      !! the tag explicitly; otherwise a new tag is selected automatically. Return
      !! the tag of the line.
      function gmshModelOccAddLine(startTag, &
                                   endTag, &
                                   tag, &
                                   ierr)
        interface
        function C_API(startTag, &
                       endTag, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddLine")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: startTag
          integer(c_int), value, intent(in) :: endTag
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddLine
        integer, intent(in) :: startTag
        integer, intent(in) :: endTag
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddLine = C_API(startTag=int(startTag, c_int), &
                              endTag=int(endTag, c_int), &
                              tag=optval_c_int(-1, tag), &
                              ierr_=ierr)
      end function gmshModelOccAddLine
    
      !> Add a circle arc in the OpenCASCADE CAD representation, between the two
      !! points with tags `startTag' and `endTag', with middle point `middleTag'. If
      !! `center' is true, the middle point is the center of the circle; otherwise
      !! the circle goes through the middle point. If `tag' is positive, set the tag
      !! explicitly; otherwise a new tag is selected automatically. Return the tag
      !! of the circle arc.
      function gmshModelOccAddCircleArc(startTag, &
                                        middleTag, &
                                        endTag, &
                                        tag, &
                                        center, &
                                        ierr)
        interface
        function C_API(startTag, &
                       middleTag, &
                       endTag, &
                       tag, &
                       center, &
                       ierr_) &
          bind(C, name="gmshModelOccAddCircleArc")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: startTag
          integer(c_int), value, intent(in) :: middleTag
          integer(c_int), value, intent(in) :: endTag
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: center
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddCircleArc
        integer, intent(in) :: startTag
        integer, intent(in) :: middleTag
        integer, intent(in) :: endTag
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: center
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddCircleArc = C_API(startTag=int(startTag, c_int), &
                                   middleTag=int(middleTag, c_int), &
                                   endTag=int(endTag, c_int), &
                                   tag=optval_c_int(-1, tag), &
                                   center=optval_c_bool(.true., center), &
                                   ierr_=ierr)
      end function gmshModelOccAddCircleArc
    
      !> Add a circle of center (`x', `y', `z') and radius `r' in the OpenCASCADE
      !! CAD representation. If `tag' is positive, set the tag explicitly; otherwise
      !! a new tag is selected automatically. If `angle1' and `angle2' are
      !! specified, create a circle arc between the two angles. If a vector `zAxis'
      !! of size 3 is provided, use it as the normal to the circle plane (z-axis).
      !! If a vector `xAxis' of size 3 is provided in addition to `zAxis', use it to
      !! define the x-axis. Return the tag of the circle.
      function gmshModelOccAddCircle(x, &
                                     y, &
                                     z, &
                                     r, &
                                     tag, &
                                     angle1, &
                                     angle2, &
                                     zAxis, &
                                     xAxis, &
                                     ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       r, &
                       tag, &
                       angle1, &
                       angle2, &
                       api_zAxis_, &
                       api_zAxis_n_, &
                       api_xAxis_, &
                       api_xAxis_n_, &
                       ierr_) &
          bind(C, name="gmshModelOccAddCircle")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: r
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: angle1
          real(c_double), value, intent(in) :: angle2
          real(c_double), dimension(*), optional :: api_zAxis_
          integer(c_size_t), value, intent(in) :: api_zAxis_n_
          real(c_double), dimension(*), optional :: api_xAxis_
          integer(c_size_t), value, intent(in) :: api_xAxis_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddCircle
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: r
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: angle1
        real(c_double), intent(in), optional :: angle2
        real(c_double), dimension(:), intent(in), optional :: zAxis
        real(c_double), dimension(:), intent(in), optional :: xAxis
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddCircle = C_API(x=real(x, c_double), &
                                y=real(y, c_double), &
                                z=real(z, c_double), &
                                r=real(r, c_double), &
                                tag=optval_c_int(-1, tag), &
                                angle1=optval_c_double(0., angle1), &
                                angle2=optval_c_double(2*M_PI, angle2), &
                                api_zAxis_=zAxis, &
                                api_zAxis_n_=size_gmsh_double(zAxis), &
                                api_xAxis_=xAxis, &
                                api_xAxis_n_=size_gmsh_double(xAxis), &
                                ierr_=ierr)
      end function gmshModelOccAddCircle
    
      !> Add an ellipse arc in the OpenCASCADE CAD representation, between the two
      !! points `startTag' and `endTag', and with center `centerTag' and major axis
      !! point `majorTag'. If `tag' is positive, set the tag explicitly; otherwise a
      !! new tag is selected automatically. Return the tag of the ellipse arc. Note
      !! that OpenCASCADE does not allow creating ellipse arcs with the major radius
      !! smaller than the minor radius.
      function gmshModelOccAddEllipseArc(startTag, &
                                         centerTag, &
                                         majorTag, &
                                         endTag, &
                                         tag, &
                                         ierr)
        interface
        function C_API(startTag, &
                       centerTag, &
                       majorTag, &
                       endTag, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddEllipseArc")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: startTag
          integer(c_int), value, intent(in) :: centerTag
          integer(c_int), value, intent(in) :: majorTag
          integer(c_int), value, intent(in) :: endTag
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddEllipseArc
        integer, intent(in) :: startTag
        integer, intent(in) :: centerTag
        integer, intent(in) :: majorTag
        integer, intent(in) :: endTag
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddEllipseArc = C_API(startTag=int(startTag, c_int), &
                                    centerTag=int(centerTag, c_int), &
                                    majorTag=int(majorTag, c_int), &
                                    endTag=int(endTag, c_int), &
                                    tag=optval_c_int(-1, tag), &
                                    ierr_=ierr)
      end function gmshModelOccAddEllipseArc
    
      !> Add an ellipse of center (`x', `y', `z') and radii `r1' and `r2' (with `r1'
      !! >= `r2') along the x- and y-axes, respectively, in the OpenCASCADE CAD
      !! representation. If `tag' is positive, set the tag explicitly; otherwise a
      !! new tag is selected automatically. If `angle1' and `angle2' are specified,
      !! create an ellipse arc between the two angles. If a vector `zAxis' of size 3
      !! is provided, use it as the normal to the ellipse plane (z-axis). If a
      !! vector `xAxis' of size 3 is provided in addition to `zAxis', use it to
      !! define the x-axis. Return the tag of the ellipse.
      function gmshModelOccAddEllipse(x, &
                                      y, &
                                      z, &
                                      r1, &
                                      r2, &
                                      tag, &
                                      angle1, &
                                      angle2, &
                                      zAxis, &
                                      xAxis, &
                                      ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       r1, &
                       r2, &
                       tag, &
                       angle1, &
                       angle2, &
                       api_zAxis_, &
                       api_zAxis_n_, &
                       api_xAxis_, &
                       api_xAxis_n_, &
                       ierr_) &
          bind(C, name="gmshModelOccAddEllipse")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: r1
          real(c_double), value, intent(in) :: r2
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: angle1
          real(c_double), value, intent(in) :: angle2
          real(c_double), dimension(*), optional :: api_zAxis_
          integer(c_size_t), value, intent(in) :: api_zAxis_n_
          real(c_double), dimension(*), optional :: api_xAxis_
          integer(c_size_t), value, intent(in) :: api_xAxis_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddEllipse
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: r1
        real(c_double), intent(in) :: r2
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: angle1
        real(c_double), intent(in), optional :: angle2
        real(c_double), dimension(:), intent(in), optional :: zAxis
        real(c_double), dimension(:), intent(in), optional :: xAxis
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddEllipse = C_API(x=real(x, c_double), &
                                 y=real(y, c_double), &
                                 z=real(z, c_double), &
                                 r1=real(r1, c_double), &
                                 r2=real(r2, c_double), &
                                 tag=optval_c_int(-1, tag), &
                                 angle1=optval_c_double(0., angle1), &
                                 angle2=optval_c_double(2*M_PI, angle2), &
                                 api_zAxis_=zAxis, &
                                 api_zAxis_n_=size_gmsh_double(zAxis), &
                                 api_xAxis_=xAxis, &
                                 api_xAxis_n_=size_gmsh_double(xAxis), &
                                 ierr_=ierr)
      end function gmshModelOccAddEllipse
    
      !> Add a spline (C2 b-spline) curve in the OpenCASCADE CAD representation,
      !! going through the points `pointTags'. If `tag' is positive, set the tag
      !! explicitly; otherwise a new tag is selected automatically. Create a
      !! periodic curve if the first and last points are the same. Return the tag of
      !! the spline curve. If the `tangents' vector contains 6 entries, use them as
      !! concatenated x, y, z components of the initial and final tangents of the
      !! b-spline; if it contains 3 times as many entries as the number of points,
      !! use them as concatenated x, y, z components of the tangents at each point,
      !! unless the norm of the tangent is zero.
      function gmshModelOccAddSpline(pointTags, &
                                     tag, &
                                     tangents, &
                                     ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       tag, &
                       api_tangents_, &
                       api_tangents_n_, &
                       ierr_) &
          bind(C, name="gmshModelOccAddSpline")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*), optional :: api_tangents_
          integer(c_size_t), value, intent(in) :: api_tangents_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddSpline
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in), optional :: tag
        real(c_double), dimension(:), intent(in), optional :: tangents
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddSpline = C_API(api_pointTags_=pointTags, &
                                api_pointTags_n_=size_gmsh_int(pointTags), &
                                tag=optval_c_int(-1, tag), &
                                api_tangents_=tangents, &
                                api_tangents_n_=size_gmsh_double(tangents), &
                                ierr_=ierr)
      end function gmshModelOccAddSpline
    
      !> Add a b-spline curve of degree `degree' in the OpenCASCADE CAD
      !! representation, with `pointTags' control points. If `weights', `knots' or
      !! `multiplicities' are not provided, default parameters are computed
      !! automatically. If `tag' is positive, set the tag explicitly; otherwise a
      !! new tag is selected automatically. Create a periodic curve if the first and
      !! last points are the same. Return the tag of the b-spline curve.
      function gmshModelOccAddBSpline(pointTags, &
                                      tag, &
                                      degree, &
                                      weights, &
                                      knots, &
                                      multiplicities, &
                                      ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       tag, &
                       degree, &
                       api_weights_, &
                       api_weights_n_, &
                       api_knots_, &
                       api_knots_n_, &
                       api_multiplicities_, &
                       api_multiplicities_n_, &
                       ierr_) &
          bind(C, name="gmshModelOccAddBSpline")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: degree
          real(c_double), dimension(*), optional :: api_weights_
          integer(c_size_t), value, intent(in) :: api_weights_n_
          real(c_double), dimension(*), optional :: api_knots_
          integer(c_size_t), value, intent(in) :: api_knots_n_
          integer(c_int), dimension(*), optional :: api_multiplicities_
          integer(c_size_t), value, intent(in) :: api_multiplicities_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddBSpline
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in), optional :: tag
        integer, intent(in), optional :: degree
        real(c_double), dimension(:), intent(in), optional :: weights
        real(c_double), dimension(:), intent(in), optional :: knots
        integer(c_int), dimension(:), intent(in), optional :: multiplicities
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddBSpline = C_API(api_pointTags_=pointTags, &
                                 api_pointTags_n_=size_gmsh_int(pointTags), &
                                 tag=optval_c_int(-1, tag), &
                                 degree=optval_c_int(3, degree), &
                                 api_weights_=weights, &
                                 api_weights_n_=size_gmsh_double(weights), &
                                 api_knots_=knots, &
                                 api_knots_n_=size_gmsh_double(knots), &
                                 api_multiplicities_=multiplicities, &
                                 api_multiplicities_n_=size_gmsh_int(multiplicities), &
                                 ierr_=ierr)
      end function gmshModelOccAddBSpline
    
      !> Add a Bezier curve in the OpenCASCADE CAD representation, with `pointTags'
      !! control points. If `tag' is positive, set the tag explicitly; otherwise a
      !! new tag is selected automatically. Return the tag of the Bezier curve.
      function gmshModelOccAddBezier(pointTags, &
                                     tag, &
                                     ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddBezier")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddBezier
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddBezier = C_API(api_pointTags_=pointTags, &
                                api_pointTags_n_=size_gmsh_int(pointTags), &
                                tag=optval_c_int(-1, tag), &
                                ierr_=ierr)
      end function gmshModelOccAddBezier
    
      !> Add a wire (open or closed) in the OpenCASCADE CAD representation, formed
      !! by the curves `curveTags'. Note that an OpenCASCADE wire can be made of
      !! curves that share geometrically identical (but topologically different)
      !! points. If `tag' is positive, set the tag explicitly; otherwise a new tag
      !! is selected automatically. Return the tag of the wire.
      function gmshModelOccAddWire(curveTags, &
                                   tag, &
                                   checkClosed, &
                                   ierr)
        interface
        function C_API(api_curveTags_, &
                       api_curveTags_n_, &
                       tag, &
                       checkClosed, &
                       ierr_) &
          bind(C, name="gmshModelOccAddWire")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_curveTags_
          integer(c_size_t), value, intent(in) :: api_curveTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: checkClosed
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddWire
        integer(c_int), dimension(:), intent(in) :: curveTags
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: checkClosed
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddWire = C_API(api_curveTags_=curveTags, &
                              api_curveTags_n_=size_gmsh_int(curveTags), &
                              tag=optval_c_int(-1, tag), &
                              checkClosed=optval_c_bool(.false., checkClosed), &
                              ierr_=ierr)
      end function gmshModelOccAddWire
    
      !> Add a curve loop (a closed wire) in the OpenCASCADE CAD representation,
      !! formed by the curves `curveTags'. `curveTags' should contain tags of curves
      !! forming a closed loop. Negative tags can be specified for compatibility
      !! with the built-in kernel, but are simply ignored: the wire is oriented
      !! according to the orientation of its first curve. Note that an OpenCASCADE
      !! curve loop can be made of curves that share geometrically identical (but
      !! topologically different) points. If `tag' is positive, set the tag
      !! explicitly; otherwise a new tag is selected automatically. Return the tag
      !! of the curve loop.
      function gmshModelOccAddCurveLoop(curveTags, &
                                        tag, &
                                        ierr)
        interface
        function C_API(api_curveTags_, &
                       api_curveTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddCurveLoop")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_curveTags_
          integer(c_size_t), value, intent(in) :: api_curveTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddCurveLoop
        integer(c_int), dimension(:), intent(in) :: curveTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddCurveLoop = C_API(api_curveTags_=curveTags, &
                                   api_curveTags_n_=size_gmsh_int(curveTags), &
                                   tag=optval_c_int(-1, tag), &
                                   ierr_=ierr)
      end function gmshModelOccAddCurveLoop
    
      !> Add a rectangle in the OpenCASCADE CAD representation, with lower left
      !! corner at (`x', `y', `z') and upper right corner at (`x' + `dx', `y' +
      !! `dy', `z'). If `tag' is positive, set the tag explicitly; otherwise a new
      !! tag is selected automatically. Round the corners if `roundedRadius' is
      !! nonzero. Return the tag of the rectangle.
      function gmshModelOccAddRectangle(x, &
                                        y, &
                                        z, &
                                        dx, &
                                        dy, &
                                        tag, &
                                        roundedRadius, &
                                        ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       dx, &
                       dy, &
                       tag, &
                       roundedRadius, &
                       ierr_) &
          bind(C, name="gmshModelOccAddRectangle")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: roundedRadius
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddRectangle
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: roundedRadius
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddRectangle = C_API(x=real(x, c_double), &
                                   y=real(y, c_double), &
                                   z=real(z, c_double), &
                                   dx=real(dx, c_double), &
                                   dy=real(dy, c_double), &
                                   tag=optval_c_int(-1, tag), &
                                   roundedRadius=optval_c_double(0., roundedRadius), &
                                   ierr_=ierr)
      end function gmshModelOccAddRectangle
    
      !> Add a disk in the OpenCASCADE CAD representation, with center (`xc', `yc',
      !! `zc') and radius `rx' along the x-axis and `ry' along the y-axis (`rx' >=
      !! `ry'). If `tag' is positive, set the tag explicitly; otherwise a new tag is
      !! selected automatically. If a vector `zAxis' of size 3 is provided, use it
      !! as the normal to the disk (z-axis). If a vector `xAxis' of size 3 is
      !! provided in addition to `zAxis', use it to define the x-axis. Return the
      !! tag of the disk.
      function gmshModelOccAddDisk(xc, &
                                   yc, &
                                   zc, &
                                   rx, &
                                   ry, &
                                   tag, &
                                   zAxis, &
                                   xAxis, &
                                   ierr)
        interface
        function C_API(xc, &
                       yc, &
                       zc, &
                       rx, &
                       ry, &
                       tag, &
                       api_zAxis_, &
                       api_zAxis_n_, &
                       api_xAxis_, &
                       api_xAxis_n_, &
                       ierr_) &
          bind(C, name="gmshModelOccAddDisk")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: xc
          real(c_double), value, intent(in) :: yc
          real(c_double), value, intent(in) :: zc
          real(c_double), value, intent(in) :: rx
          real(c_double), value, intent(in) :: ry
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*), optional :: api_zAxis_
          integer(c_size_t), value, intent(in) :: api_zAxis_n_
          real(c_double), dimension(*), optional :: api_xAxis_
          integer(c_size_t), value, intent(in) :: api_xAxis_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddDisk
        real(c_double), intent(in) :: xc
        real(c_double), intent(in) :: yc
        real(c_double), intent(in) :: zc
        real(c_double), intent(in) :: rx
        real(c_double), intent(in) :: ry
        integer, intent(in), optional :: tag
        real(c_double), dimension(:), intent(in), optional :: zAxis
        real(c_double), dimension(:), intent(in), optional :: xAxis
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddDisk = C_API(xc=real(xc, c_double), &
                              yc=real(yc, c_double), &
                              zc=real(zc, c_double), &
                              rx=real(rx, c_double), &
                              ry=real(ry, c_double), &
                              tag=optval_c_int(-1, tag), &
                              api_zAxis_=zAxis, &
                              api_zAxis_n_=size_gmsh_double(zAxis), &
                              api_xAxis_=xAxis, &
                              api_xAxis_n_=size_gmsh_double(xAxis), &
                              ierr_=ierr)
      end function gmshModelOccAddDisk
    
      !> Add a plane surface in the OpenCASCADE CAD representation, defined by one
      !! or more curve loops (or closed wires) `wireTags'. The first curve loop
      !! defines the exterior contour; additional curve loop define holes. If `tag'
      !! is positive, set the tag explicitly; otherwise a new tag is selected
      !! automatically. Return the tag of the surface.
      function gmshModelOccAddPlaneSurface(wireTags, &
                                           tag, &
                                           ierr)
        interface
        function C_API(api_wireTags_, &
                       api_wireTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddPlaneSurface")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_wireTags_
          integer(c_size_t), value, intent(in) :: api_wireTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddPlaneSurface
        integer(c_int), dimension(:), intent(in) :: wireTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddPlaneSurface = C_API(api_wireTags_=wireTags, &
                                      api_wireTags_n_=size_gmsh_int(wireTags), &
                                      tag=optval_c_int(-1, tag), &
                                      ierr_=ierr)
      end function gmshModelOccAddPlaneSurface
    
      !> Add a surface in the OpenCASCADE CAD representation, filling the curve loop
      !! `wireTag'. If `tag' is positive, set the tag explicitly; otherwise a new
      !! tag is selected automatically. Return the tag of the surface. If
      !! `pointTags' are provided, force the surface to pass through the given
      !! points. The other optional arguments are `degree' (the degree of the energy
      !! criterion to minimize for computing the deformation of the surface),
      !! `numPointsOnCurves' (the average number of points for discretisation of the
      !! bounding curves), `numIter' (the maximum number of iterations of the
      !! optimization process), `anisotropic' (improve performance when the ratio of
      !! the length along the two parametric coordinates of the surface is high),
      !! `tol2d' (tolerance to the constraints in the parametric plane of the
      !! surface), `tol3d' (the maximum distance allowed between the support surface
      !! and the constraints), `tolAng' (the maximum angle allowed between the
      !! normal of the surface and the constraints), `tolCurv' (the maximum
      !! difference of curvature allowed between the surface and the constraint),
      !! `maxDegree' (the highest degree which the polynomial defining the filling
      !! surface can have) and, `maxSegments' (the largest number of segments which
      !! the filling surface can have).
      function gmshModelOccAddSurfaceFilling(wireTag, &
                                             tag, &
                                             pointTags, &
                                             degree, &
                                             numPointsOnCurves, &
                                             numIter, &
                                             anisotropic, &
                                             tol2d, &
                                             tol3d, &
                                             tolAng, &
                                             tolCurv, &
                                             maxDegree, &
                                             maxSegments, &
                                             ierr)
        interface
        function C_API(wireTag, &
                       tag, &
                       api_pointTags_, &
                       api_pointTags_n_, &
                       degree, &
                       numPointsOnCurves, &
                       numIter, &
                       anisotropic, &
                       tol2d, &
                       tol3d, &
                       tolAng, &
                       tolCurv, &
                       maxDegree, &
                       maxSegments, &
                       ierr_) &
          bind(C, name="gmshModelOccAddSurfaceFilling")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: wireTag
          integer(c_int), value, intent(in) :: tag
          integer(c_int), dimension(*), optional :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: degree
          integer(c_int), value, intent(in) :: numPointsOnCurves
          integer(c_int), value, intent(in) :: numIter
          integer(c_int), value, intent(in) :: anisotropic
          real(c_double), value, intent(in) :: tol2d
          real(c_double), value, intent(in) :: tol3d
          real(c_double), value, intent(in) :: tolAng
          real(c_double), value, intent(in) :: tolCurv
          integer(c_int), value, intent(in) :: maxDegree
          integer(c_int), value, intent(in) :: maxSegments
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddSurfaceFilling
        integer, intent(in) :: wireTag
        integer, intent(in), optional :: tag
        integer(c_int), dimension(:), intent(in), optional :: pointTags
        integer, intent(in), optional :: degree
        integer, intent(in), optional :: numPointsOnCurves
        integer, intent(in), optional :: numIter
        logical, intent(in), optional :: anisotropic
        real(c_double), intent(in), optional :: tol2d
        real(c_double), intent(in), optional :: tol3d
        real(c_double), intent(in), optional :: tolAng
        real(c_double), intent(in), optional :: tolCurv
        integer, intent(in), optional :: maxDegree
        integer, intent(in), optional :: maxSegments
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddSurfaceFilling = C_API(wireTag=int(wireTag, c_int), &
                                        tag=optval_c_int(-1, tag), &
                                        api_pointTags_=pointTags, &
                                        api_pointTags_n_=size_gmsh_int(pointTags), &
                                        degree=optval_c_int(2, degree), &
                                        numPointsOnCurves=optval_c_int(15, numPointsOnCurves), &
                                        numIter=optval_c_int(2, numIter), &
                                        anisotropic=optval_c_bool(.false., anisotropic), &
                                        tol2d=optval_c_double(0.00001, tol2d), &
                                        tol3d=optval_c_double(0.0001, tol3d), &
                                        tolAng=optval_c_double(0.01, tolAng), &
                                        tolCurv=optval_c_double(0.1, tolCurv), &
                                        maxDegree=optval_c_int(8, maxDegree), &
                                        maxSegments=optval_c_int(9, maxSegments), &
                                        ierr_=ierr)
      end function gmshModelOccAddSurfaceFilling
    
      !> Add a BSpline surface in the OpenCASCADE CAD representation, filling the
      !! curve loop `wireTag'. The curve loop should be made of 2, 3 or 4 curves.
      !! The optional `type' argument specifies the type of filling: "Stretch"
      !! creates the flattest patch, "Curved" (the default) creates the most rounded
      !! patch, and "Coons" creates a rounded patch with less depth than "Curved".
      !! If `tag' is positive, set the tag explicitly; otherwise a new tag is
      !! selected automatically. Return the tag of the surface.
      function gmshModelOccAddBSplineFilling(wireTag, &
                                             tag, &
                                             type, &
                                             ierr)
        interface
        function C_API(wireTag, &
                       tag, &
                       type, &
                       ierr_) &
          bind(C, name="gmshModelOccAddBSplineFilling")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: wireTag
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: type
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddBSplineFilling
        integer, intent(in) :: wireTag
        integer, intent(in), optional :: tag
        character(len=*), intent(in), optional :: type
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddBSplineFilling = C_API(wireTag=int(wireTag, c_int), &
                                        tag=optval_c_int(-1, tag), &
                                        type=istring_(optval_c_str("", type)), &
                                        ierr_=ierr)
      end function gmshModelOccAddBSplineFilling
    
      !> Add a Bezier surface in the OpenCASCADE CAD representation, filling the
      !! curve loop `wireTag'. The curve loop should be made of 2, 3 or 4 Bezier
      !! curves. The optional `type' argument specifies the type of filling:
      !! "Stretch" creates the flattest patch, "Curved" (the default) creates the
      !! most rounded patch, and "Coons" creates a rounded patch with less depth
      !! than "Curved". If `tag' is positive, set the tag explicitly; otherwise a
      !! new tag is selected automatically. Return the tag of the surface.
      function gmshModelOccAddBezierFilling(wireTag, &
                                            tag, &
                                            type, &
                                            ierr)
        interface
        function C_API(wireTag, &
                       tag, &
                       type, &
                       ierr_) &
          bind(C, name="gmshModelOccAddBezierFilling")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: wireTag
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: type
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddBezierFilling
        integer, intent(in) :: wireTag
        integer, intent(in), optional :: tag
        character(len=*), intent(in), optional :: type
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddBezierFilling = C_API(wireTag=int(wireTag, c_int), &
                                       tag=optval_c_int(-1, tag), &
                                       type=istring_(optval_c_str("", type)), &
                                       ierr_=ierr)
      end function gmshModelOccAddBezierFilling
    
      !> Add a b-spline surface of degree `degreeU' x `degreeV' in the OpenCASCADE
      !! CAD representation, with `pointTags' control points given as a single
      !! vector [Pu1v1, ... Pu`numPointsU'v1, Pu1v2, ...]. If `weights', `knotsU',
      !! `knotsV', `multiplicitiesU' or `multiplicitiesV' are not provided, default
      !! parameters are computed automatically. If `tag' is positive, set the tag
      !! explicitly; otherwise a new tag is selected automatically. If `wireTags' is
      !! provided, trim the b-spline patch using the provided wires: the first wire
      !! defines the external contour, the others define holes. If `wire3D' is set,
      !! consider wire curves as 3D curves and project them on the b-spline surface;
      !! otherwise consider the wire curves as defined in the parametric space of
      !! the surface. Return the tag of the b-spline surface.
      function gmshModelOccAddBSplineSurface(pointTags, &
                                             numPointsU, &
                                             tag, &
                                             degreeU, &
                                             degreeV, &
                                             weights, &
                                             knotsU, &
                                             knotsV, &
                                             multiplicitiesU, &
                                             multiplicitiesV, &
                                             wireTags, &
                                             wire3D, &
                                             ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       numPointsU, &
                       tag, &
                       degreeU, &
                       degreeV, &
                       api_weights_, &
                       api_weights_n_, &
                       api_knotsU_, &
                       api_knotsU_n_, &
                       api_knotsV_, &
                       api_knotsV_n_, &
                       api_multiplicitiesU_, &
                       api_multiplicitiesU_n_, &
                       api_multiplicitiesV_, &
                       api_multiplicitiesV_n_, &
                       api_wireTags_, &
                       api_wireTags_n_, &
                       wire3D, &
                       ierr_) &
          bind(C, name="gmshModelOccAddBSplineSurface")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: numPointsU
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: degreeU
          integer(c_int), value, intent(in) :: degreeV
          real(c_double), dimension(*), optional :: api_weights_
          integer(c_size_t), value, intent(in) :: api_weights_n_
          real(c_double), dimension(*), optional :: api_knotsU_
          integer(c_size_t), value, intent(in) :: api_knotsU_n_
          real(c_double), dimension(*), optional :: api_knotsV_
          integer(c_size_t), value, intent(in) :: api_knotsV_n_
          integer(c_int), dimension(*), optional :: api_multiplicitiesU_
          integer(c_size_t), value, intent(in) :: api_multiplicitiesU_n_
          integer(c_int), dimension(*), optional :: api_multiplicitiesV_
          integer(c_size_t), value, intent(in) :: api_multiplicitiesV_n_
          integer(c_int), dimension(*), optional :: api_wireTags_
          integer(c_size_t), value, intent(in) :: api_wireTags_n_
          integer(c_int), value, intent(in) :: wire3D
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddBSplineSurface
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in) :: numPointsU
        integer, intent(in), optional :: tag
        integer, intent(in), optional :: degreeU
        integer, intent(in), optional :: degreeV
        real(c_double), dimension(:), intent(in), optional :: weights
        real(c_double), dimension(:), intent(in), optional :: knotsU
        real(c_double), dimension(:), intent(in), optional :: knotsV
        integer(c_int), dimension(:), intent(in), optional :: multiplicitiesU
        integer(c_int), dimension(:), intent(in), optional :: multiplicitiesV
        integer(c_int), dimension(:), intent(in), optional :: wireTags
        logical, intent(in), optional :: wire3D
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddBSplineSurface = C_API(api_pointTags_=pointTags, &
                                        api_pointTags_n_=size_gmsh_int(pointTags), &
                                        numPointsU=int(numPointsU, c_int), &
                                        tag=optval_c_int(-1, tag), &
                                        degreeU=optval_c_int(3, degreeU), &
                                        degreeV=optval_c_int(3, degreeV), &
                                        api_weights_=weights, &
                                        api_weights_n_=size_gmsh_double(weights), &
                                        api_knotsU_=knotsU, &
                                        api_knotsU_n_=size_gmsh_double(knotsU), &
                                        api_knotsV_=knotsV, &
                                        api_knotsV_n_=size_gmsh_double(knotsV), &
                                        api_multiplicitiesU_=multiplicitiesU, &
                                        api_multiplicitiesU_n_=size_gmsh_int(multiplicitiesU), &
                                        api_multiplicitiesV_=multiplicitiesV, &
                                        api_multiplicitiesV_n_=size_gmsh_int(multiplicitiesV), &
                                        api_wireTags_=wireTags, &
                                        api_wireTags_n_=size_gmsh_int(wireTags), &
                                        wire3D=optval_c_bool(.false., wire3D), &
                                        ierr_=ierr)
      end function gmshModelOccAddBSplineSurface
    
      !> Add a Bezier surface in the OpenCASCADE CAD representation, with
      !! `pointTags' control points given as a single vector [Pu1v1, ...
      !! Pu`numPointsU'v1, Pu1v2, ...]. If `tag' is positive, set the tag
      !! explicitly; otherwise a new tag is selected automatically. If `wireTags' is
      !! provided, trim the Bezier patch using the provided wires: the first wire
      !! defines the external contour, the others define holes. If `wire3D' is set,
      !! consider wire curves as 3D curves and project them on the Bezier surface;
      !! otherwise consider the wire curves as defined in the parametric space of
      !! the surface. Return the tag of the Bezier surface.
      function gmshModelOccAddBezierSurface(pointTags, &
                                            numPointsU, &
                                            tag, &
                                            wireTags, &
                                            wire3D, &
                                            ierr)
        interface
        function C_API(api_pointTags_, &
                       api_pointTags_n_, &
                       numPointsU, &
                       tag, &
                       api_wireTags_, &
                       api_wireTags_n_, &
                       wire3D, &
                       ierr_) &
          bind(C, name="gmshModelOccAddBezierSurface")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_pointTags_
          integer(c_size_t), value, intent(in) :: api_pointTags_n_
          integer(c_int), value, intent(in) :: numPointsU
          integer(c_int), value, intent(in) :: tag
          integer(c_int), dimension(*), optional :: api_wireTags_
          integer(c_size_t), value, intent(in) :: api_wireTags_n_
          integer(c_int), value, intent(in) :: wire3D
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddBezierSurface
        integer(c_int), dimension(:), intent(in) :: pointTags
        integer, intent(in) :: numPointsU
        integer, intent(in), optional :: tag
        integer(c_int), dimension(:), intent(in), optional :: wireTags
        logical, intent(in), optional :: wire3D
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddBezierSurface = C_API(api_pointTags_=pointTags, &
                                       api_pointTags_n_=size_gmsh_int(pointTags), &
                                       numPointsU=int(numPointsU, c_int), &
                                       tag=optval_c_int(-1, tag), &
                                       api_wireTags_=wireTags, &
                                       api_wireTags_n_=size_gmsh_int(wireTags), &
                                       wire3D=optval_c_bool(.false., wire3D), &
                                       ierr_=ierr)
      end function gmshModelOccAddBezierSurface
    
      !> Trim the surface `surfaceTag' with the wires `wireTags', replacing any
      !! existing trimming curves. The first wire defines the external contour, the
      !! others define holes. If `wire3D' is set, consider wire curves as 3D curves
      !! and project them on the surface; otherwise consider the wire curves as
      !! defined in the parametric space of the surface. If `tag' is positive, set
      !! the tag explicitly; otherwise a new tag is selected automatically. Return
      !! the tag of the trimmed surface.
      function gmshModelOccAddTrimmedSurface(surfaceTag, &
                                             wireTags, &
                                             wire3D, &
                                             tag, &
                                             ierr)
        interface
        function C_API(surfaceTag, &
                       api_wireTags_, &
                       api_wireTags_n_, &
                       wire3D, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddTrimmedSurface")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: surfaceTag
          integer(c_int), dimension(*), optional :: api_wireTags_
          integer(c_size_t), value, intent(in) :: api_wireTags_n_
          integer(c_int), value, intent(in) :: wire3D
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddTrimmedSurface
        integer, intent(in) :: surfaceTag
        integer(c_int), dimension(:), intent(in), optional :: wireTags
        logical, intent(in), optional :: wire3D
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddTrimmedSurface = C_API(surfaceTag=int(surfaceTag, c_int), &
                                        api_wireTags_=wireTags, &
                                        api_wireTags_n_=size_gmsh_int(wireTags), &
                                        wire3D=optval_c_bool(.false., wire3D), &
                                        tag=optval_c_int(-1, tag), &
                                        ierr_=ierr)
      end function gmshModelOccAddTrimmedSurface
    
      !> Add a surface loop (a closed shell) in the OpenCASCADE CAD representation,
      !! formed by `surfaceTags'.  If `tag' is positive, set the tag explicitly;
      !! otherwise a new tag is selected automatically. Return the tag of the
      !! surface loop. Setting `sewing' allows one to build a shell made of surfaces
      !! that share geometrically identical (but topologically different) curves.
      function gmshModelOccAddSurfaceLoop(surfaceTags, &
                                          tag, &
                                          sewing, &
                                          ierr)
        interface
        function C_API(api_surfaceTags_, &
                       api_surfaceTags_n_, &
                       tag, &
                       sewing, &
                       ierr_) &
          bind(C, name="gmshModelOccAddSurfaceLoop")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_surfaceTags_
          integer(c_size_t), value, intent(in) :: api_surfaceTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: sewing
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddSurfaceLoop
        integer(c_int), dimension(:), intent(in) :: surfaceTags
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: sewing
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddSurfaceLoop = C_API(api_surfaceTags_=surfaceTags, &
                                     api_surfaceTags_n_=size_gmsh_int(surfaceTags), &
                                     tag=optval_c_int(-1, tag), &
                                     sewing=optval_c_bool(.false., sewing), &
                                     ierr_=ierr)
      end function gmshModelOccAddSurfaceLoop
    
      !> Add a volume (a region) in the OpenCASCADE CAD representation, defined by
      !! one or more surface loops `shellTags'. The first surface loop defines the
      !! exterior boundary; additional surface loop define holes. If `tag' is
      !! positive, set the tag explicitly; otherwise a new tag is selected
      !! automatically. Return the tag of the volume.
      function gmshModelOccAddVolume(shellTags, &
                                     tag, &
                                     ierr)
        interface
        function C_API(api_shellTags_, &
                       api_shellTags_n_, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddVolume")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), dimension(*) :: api_shellTags_
          integer(c_size_t), value, intent(in) :: api_shellTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddVolume
        integer(c_int), dimension(:), intent(in) :: shellTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddVolume = C_API(api_shellTags_=shellTags, &
                                api_shellTags_n_=size_gmsh_int(shellTags), &
                                tag=optval_c_int(-1, tag), &
                                ierr_=ierr)
      end function gmshModelOccAddVolume
    
      !> Add a sphere of center (`xc', `yc', `zc') and radius `r' in the OpenCASCADE
      !! CAD representation. The optional `angle1' and `angle2' arguments define the
      !! polar angle opening (from -Pi/2 to Pi/2). The optional `angle3' argument
      !! defines the azimuthal opening (from 0 to 2*Pi). If `tag' is positive, set
      !! the tag explicitly; otherwise a new tag is selected automatically. Return
      !! the tag of the sphere.
      function gmshModelOccAddSphere(xc, &
                                     yc, &
                                     zc, &
                                     radius, &
                                     tag, &
                                     angle1, &
                                     angle2, &
                                     angle3, &
                                     ierr)
        interface
        function C_API(xc, &
                       yc, &
                       zc, &
                       radius, &
                       tag, &
                       angle1, &
                       angle2, &
                       angle3, &
                       ierr_) &
          bind(C, name="gmshModelOccAddSphere")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: xc
          real(c_double), value, intent(in) :: yc
          real(c_double), value, intent(in) :: zc
          real(c_double), value, intent(in) :: radius
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: angle1
          real(c_double), value, intent(in) :: angle2
          real(c_double), value, intent(in) :: angle3
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddSphere
        real(c_double), intent(in) :: xc
        real(c_double), intent(in) :: yc
        real(c_double), intent(in) :: zc
        real(c_double), intent(in) :: radius
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: angle1
        real(c_double), intent(in), optional :: angle2
        real(c_double), intent(in), optional :: angle3
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddSphere = C_API(xc=real(xc, c_double), &
                                yc=real(yc, c_double), &
                                zc=real(zc, c_double), &
                                radius=real(radius, c_double), &
                                tag=optval_c_int(-1, tag), &
                                angle1=optval_c_double(-M_PI/2, angle1), &
                                angle2=optval_c_double(M_PI/2, angle2), &
                                angle3=optval_c_double(2*M_PI, angle3), &
                                ierr_=ierr)
      end function gmshModelOccAddSphere
    
      !> Add a parallelepipedic box in the OpenCASCADE CAD representation, defined
      !! by a point (`x', `y', `z') and the extents along the x-, y- and z-axes. If
      !! `tag' is positive, set the tag explicitly; otherwise a new tag is selected
      !! automatically. Return the tag of the box.
      function gmshModelOccAddBox(x, &
                                  y, &
                                  z, &
                                  dx, &
                                  dy, &
                                  dz, &
                                  tag, &
                                  ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       dx, &
                       dy, &
                       dz, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccAddBox")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddBox
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddBox = C_API(x=real(x, c_double), &
                             y=real(y, c_double), &
                             z=real(z, c_double), &
                             dx=real(dx, c_double), &
                             dy=real(dy, c_double), &
                             dz=real(dz, c_double), &
                             tag=optval_c_int(-1, tag), &
                             ierr_=ierr)
      end function gmshModelOccAddBox
    
      !> Add a cylinder in the OpenCASCADE CAD representation, defined by the center
      !! (`x', `y', `z') of its first circular face, the 3 components (`dx', `dy',
      !! `dz') of the vector defining its axis and its radius `r'. The optional
      !! `angle' argument defines the angular opening (from 0 to 2*Pi). If `tag' is
      !! positive, set the tag explicitly; otherwise a new tag is selected
      !! automatically. Return the tag of the cylinder.
      function gmshModelOccAddCylinder(x, &
                                       y, &
                                       z, &
                                       dx, &
                                       dy, &
                                       dz, &
                                       r, &
                                       tag, &
                                       angle, &
                                       ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       dx, &
                       dy, &
                       dz, &
                       r, &
                       tag, &
                       angle, &
                       ierr_) &
          bind(C, name="gmshModelOccAddCylinder")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          real(c_double), value, intent(in) :: r
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: angle
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddCylinder
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        real(c_double), intent(in) :: r
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: angle
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddCylinder = C_API(x=real(x, c_double), &
                                  y=real(y, c_double), &
                                  z=real(z, c_double), &
                                  dx=real(dx, c_double), &
                                  dy=real(dy, c_double), &
                                  dz=real(dz, c_double), &
                                  r=real(r, c_double), &
                                  tag=optval_c_int(-1, tag), &
                                  angle=optval_c_double(2*M_PI, angle), &
                                  ierr_=ierr)
      end function gmshModelOccAddCylinder
    
      !> Add a cone in the OpenCASCADE CAD representation, defined by the center
      !! (`x', `y', `z') of its first circular face, the 3 components of the vector
      !! (`dx', `dy', `dz') defining its axis and the two radii `r1' and `r2' of the
      !! faces (these radii can be zero). If `tag' is positive, set the tag
      !! explicitly; otherwise a new tag is selected automatically. `angle' defines
      !! the optional angular opening (from 0 to 2*Pi). Return the tag of the cone.
      function gmshModelOccAddCone(x, &
                                   y, &
                                   z, &
                                   dx, &
                                   dy, &
                                   dz, &
                                   r1, &
                                   r2, &
                                   tag, &
                                   angle, &
                                   ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       dx, &
                       dy, &
                       dz, &
                       r1, &
                       r2, &
                       tag, &
                       angle, &
                       ierr_) &
          bind(C, name="gmshModelOccAddCone")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          real(c_double), value, intent(in) :: r1
          real(c_double), value, intent(in) :: r2
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: angle
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddCone
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        real(c_double), intent(in) :: r1
        real(c_double), intent(in) :: r2
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: angle
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddCone = C_API(x=real(x, c_double), &
                              y=real(y, c_double), &
                              z=real(z, c_double), &
                              dx=real(dx, c_double), &
                              dy=real(dy, c_double), &
                              dz=real(dz, c_double), &
                              r1=real(r1, c_double), &
                              r2=real(r2, c_double), &
                              tag=optval_c_int(-1, tag), &
                              angle=optval_c_double(2*M_PI, angle), &
                              ierr_=ierr)
      end function gmshModelOccAddCone
    
      !> Add a right angular wedge in the OpenCASCADE CAD representation, defined by
      !! the right-angle point (`x', `y', `z') and the 3 extends along the x-, y-
      !! and z-axes (`dx', `dy', `dz'). If `tag' is positive, set the tag
      !! explicitly; otherwise a new tag is selected automatically. The optional
      !! argument `ltx' defines the top extent along the x-axis. If a vector `zAxis'
      !! of size 3 is provided, use it to define the z-axis. Return the tag of the
      !! wedge.
      function gmshModelOccAddWedge(x, &
                                    y, &
                                    z, &
                                    dx, &
                                    dy, &
                                    dz, &
                                    tag, &
                                    ltx, &
                                    zAxis, &
                                    ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       dx, &
                       dy, &
                       dz, &
                       tag, &
                       ltx, &
                       api_zAxis_, &
                       api_zAxis_n_, &
                       ierr_) &
          bind(C, name="gmshModelOccAddWedge")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: ltx
          real(c_double), dimension(*), optional :: api_zAxis_
          integer(c_size_t), value, intent(in) :: api_zAxis_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddWedge
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: ltx
        real(c_double), dimension(:), intent(in), optional :: zAxis
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddWedge = C_API(x=real(x, c_double), &
                               y=real(y, c_double), &
                               z=real(z, c_double), &
                               dx=real(dx, c_double), &
                               dy=real(dy, c_double), &
                               dz=real(dz, c_double), &
                               tag=optval_c_int(-1, tag), &
                               ltx=optval_c_double(0., ltx), &
                               api_zAxis_=zAxis, &
                               api_zAxis_n_=size_gmsh_double(zAxis), &
                               ierr_=ierr)
      end function gmshModelOccAddWedge
    
      !> Add a torus in the OpenCASCADE CAD representation, defined by its center
      !! (`x', `y', `z') and its 2 radii `r' and `r2'. If `tag' is positive, set the
      !! tag explicitly; otherwise a new tag is selected automatically. The optional
      !! argument `angle' defines the angular opening (from 0 to 2*Pi). If a vector
      !! `zAxis' of size 3 is provided, use it to define the z-axis. Return the tag
      !! of the torus.
      function gmshModelOccAddTorus(x, &
                                    y, &
                                    z, &
                                    r1, &
                                    r2, &
                                    tag, &
                                    angle, &
                                    zAxis, &
                                    ierr)
        interface
        function C_API(x, &
                       y, &
                       z, &
                       r1, &
                       r2, &
                       tag, &
                       angle, &
                       api_zAxis_, &
                       api_zAxis_n_, &
                       ierr_) &
          bind(C, name="gmshModelOccAddTorus")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: r1
          real(c_double), value, intent(in) :: r2
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: angle
          real(c_double), dimension(*), optional :: api_zAxis_
          integer(c_size_t), value, intent(in) :: api_zAxis_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccAddTorus
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: r1
        real(c_double), intent(in) :: r2
        integer, intent(in), optional :: tag
        real(c_double), intent(in), optional :: angle
        real(c_double), dimension(:), intent(in), optional :: zAxis
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccAddTorus = C_API(x=real(x, c_double), &
                               y=real(y, c_double), &
                               z=real(z, c_double), &
                               r1=real(r1, c_double), &
                               r2=real(r2, c_double), &
                               tag=optval_c_int(-1, tag), &
                               angle=optval_c_double(2*M_PI, angle), &
                               api_zAxis_=zAxis, &
                               api_zAxis_n_=size_gmsh_double(zAxis), &
                               ierr_=ierr)
      end function gmshModelOccAddTorus
    
      !> Add a volume (if the optional argument `makeSolid' is set) or surfaces in
      !! the OpenCASCADE CAD representation, defined through the open or closed
      !! wires `wireTags'. If `tag' is positive, set the tag explicitly; otherwise a
      !! new tag is selected automatically. The new entities are returned in
      !! `outDimTags' as a vector of (dim, tag) pairs. If the optional argument
      !! `makeRuled' is set, the surfaces created on the boundary are forced to be
      !! ruled surfaces. If `maxDegree' is positive, set the maximal degree of
      !! resulting surface. The optional argument `continuity' allows to specify the
      !! continuity of the resulting shape ("C0", "G1", "C1", "G2", "C2", "C3",
      !! "CN"). The optional argument `parametrization' sets the parametrization
      !! type ("ChordLength", "Centripetal", "IsoParametric"). The optional argument
      !! `smoothing' determines if smoothing is applied.
      subroutine gmshModelOccAddThruSections(wireTags, &
                                             outDimTags, &
                                             tag, &
                                             makeSolid, &
                                             makeRuled, &
                                             maxDegree, &
                                             continuity, &
                                             parametrization, &
                                             smoothing, &
                                             ierr)
        interface
        subroutine C_API(api_wireTags_, &
                         api_wireTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         tag, &
                         makeSolid, &
                         makeRuled, &
                         maxDegree, &
                         continuity, &
                         parametrization, &
                         smoothing, &
                         ierr_) &
          bind(C, name="gmshModelOccAddThruSections")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_wireTags_
          integer(c_size_t), value, intent(in) :: api_wireTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: makeSolid
          integer(c_int), value, intent(in) :: makeRuled
          integer(c_int), value, intent(in) :: maxDegree
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: continuity
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: parametrization
          integer(c_int), value, intent(in) :: smoothing
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), intent(in) :: wireTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: makeSolid
        logical, intent(in), optional :: makeRuled
        integer, intent(in), optional :: maxDegree
        character(len=*), intent(in), optional :: continuity
        character(len=*), intent(in), optional :: parametrization
        logical, intent(in), optional :: smoothing
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_wireTags_=wireTags, &
             api_wireTags_n_=size_gmsh_int(wireTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             tag=optval_c_int(-1, tag), &
             makeSolid=optval_c_bool(.true., makeSolid), &
             makeRuled=optval_c_bool(.false., makeRuled), &
             maxDegree=optval_c_int(-1, maxDegree), &
             continuity=istring_(optval_c_str("", continuity)), &
             parametrization=istring_(optval_c_str("", parametrization)), &
             smoothing=optval_c_bool(.false., smoothing), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccAddThruSections
    
      !> Add a hollowed volume in the OpenCASCADE CAD representation, built from an
      !! initial volume `volumeTag' and a set of faces from this volume
      !! `excludeSurfaceTags', which are to be removed. The remaining faces of the
      !! volume become the walls of the hollowed solid, with thickness `offset'. If
      !! `tag' is positive, set the tag explicitly; otherwise a new tag is selected
      !! automatically.
      subroutine gmshModelOccAddThickSolid(volumeTag, &
                                           excludeSurfaceTags, &
                                           offset, &
                                           outDimTags, &
                                           tag, &
                                           ierr)
        interface
        subroutine C_API(volumeTag, &
                         api_excludeSurfaceTags_, &
                         api_excludeSurfaceTags_n_, &
                         offset, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshModelOccAddThickSolid")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: volumeTag
          integer(c_int), dimension(*) :: api_excludeSurfaceTags_
          integer(c_size_t), value, intent(in) :: api_excludeSurfaceTags_n_
          real(c_double), value, intent(in) :: offset
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: volumeTag
        integer(c_int), dimension(:), intent(in) :: excludeSurfaceTags
        real(c_double), intent(in) :: offset
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(volumeTag=int(volumeTag, c_int), &
             api_excludeSurfaceTags_=excludeSurfaceTags, &
             api_excludeSurfaceTags_n_=size_gmsh_int(excludeSurfaceTags), &
             offset=real(offset, c_double), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             tag=optval_c_int(-1, tag), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccAddThickSolid
    
      !> Extrude the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the OpenCASCADE CAD representation, using a translation along (`dx', `dy',
      !! `dz'). Return extruded entities in `outDimTags'. If the `numElements'
      !! vector is not empty, also extrude the mesh: the entries in `numElements'
      !! give the number of elements in each layer. If the `height' vector is not
      !! empty, it provides the (cumulative) height of the different layers,
      !! normalized to 1. If `recombine' is set, recombine the mesh in the layers.
      subroutine gmshModelOccExtrude(dimTags, &
                                     dx, &
                                     dy, &
                                     dz, &
                                     outDimTags, &
                                     numElements, &
                                     heights, &
                                     recombine, &
                                     ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         dx, &
                         dy, &
                         dz, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_numElements_, &
                         api_numElements_n_, &
                         api_heights_, &
                         api_heights_n_, &
                         recombine, &
                         ierr_) &
          bind(C, name="gmshModelOccExtrude")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), dimension(*), optional :: api_numElements_
          integer(c_size_t), value, intent(in) :: api_numElements_n_
          real(c_double), dimension(*), optional :: api_heights_
          integer(c_size_t), value, intent(in) :: api_heights_n_
          integer(c_int), value, intent(in) :: recombine
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:), intent(in), optional :: numElements
        real(c_double), dimension(:), intent(in), optional :: heights
        logical, intent(in), optional :: recombine
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             dx=real(dx, c_double), &
             dy=real(dy, c_double), &
             dz=real(dz, c_double), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_numElements_=numElements, &
             api_numElements_n_=size_gmsh_int(numElements), &
             api_heights_=heights, &
             api_heights_n_=size_gmsh_double(heights), &
             recombine=optval_c_bool(.false., recombine), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccExtrude
    
      !> Extrude the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the OpenCASCADE CAD representation, using a rotation of `angle' radians
      !! around the axis of revolution defined by the point (`x', `y', `z') and the
      !! direction (`ax', `ay', `az'). Return extruded entities in `outDimTags'. If
      !! the `numElements' vector is not empty, also extrude the mesh: the entries
      !! in `numElements' give the number of elements in each layer. If the `height'
      !! vector is not empty, it provides the (cumulative) height of the different
      !! layers, normalized to 1. When the mesh is extruded the angle should be
      !! strictly smaller than 2*Pi. If `recombine' is set, recombine the mesh in
      !! the layers.
      subroutine gmshModelOccRevolve(dimTags, &
                                     x, &
                                     y, &
                                     z, &
                                     ax, &
                                     ay, &
                                     az, &
                                     angle, &
                                     outDimTags, &
                                     numElements, &
                                     heights, &
                                     recombine, &
                                     ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         x, &
                         y, &
                         z, &
                         ax, &
                         ay, &
                         az, &
                         angle, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_numElements_, &
                         api_numElements_n_, &
                         api_heights_, &
                         api_heights_n_, &
                         recombine, &
                         ierr_) &
          bind(C, name="gmshModelOccRevolve")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: ax
          real(c_double), value, intent(in) :: ay
          real(c_double), value, intent(in) :: az
          real(c_double), value, intent(in) :: angle
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), dimension(*), optional :: api_numElements_
          integer(c_size_t), value, intent(in) :: api_numElements_n_
          real(c_double), dimension(*), optional :: api_heights_
          integer(c_size_t), value, intent(in) :: api_heights_n_
          integer(c_int), value, intent(in) :: recombine
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: ax
        real(c_double), intent(in) :: ay
        real(c_double), intent(in) :: az
        real(c_double), intent(in) :: angle
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:), intent(in), optional :: numElements
        real(c_double), dimension(:), intent(in), optional :: heights
        logical, intent(in), optional :: recombine
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             ax=real(ax, c_double), &
             ay=real(ay, c_double), &
             az=real(az, c_double), &
             angle=real(angle, c_double), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_numElements_=numElements, &
             api_numElements_n_=size_gmsh_int(numElements), &
             api_heights_=heights, &
             api_heights_n_=size_gmsh_double(heights), &
             recombine=optval_c_bool(.false., recombine), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccRevolve
    
      !> Add a pipe in the OpenCASCADE CAD representation, by extruding the entities
      !! `dimTags' (given as a vector of (dim, tag) pairs) along the wire `wireTag'.
      !! The type of sweep can be specified with `trihedron' (possible values:
      !! "DiscreteTrihedron", "CorrectedFrenet", "Fixed", "Frenet",
      !! "ConstantNormal", "Darboux", "GuideAC", "GuidePlan", "GuideACWithContact",
      !! "GuidePlanWithContact"). If `trihedron' is not provided,
      !! "DiscreteTrihedron" is assumed. Return the pipe in `outDimTags'.
      subroutine gmshModelOccAddPipe(dimTags, &
                                     wireTag, &
                                     outDimTags, &
                                     trihedron, &
                                     ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         wireTag, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         trihedron, &
                         ierr_) &
          bind(C, name="gmshModelOccAddPipe")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: wireTag
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: trihedron
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer, intent(in) :: wireTag
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        character(len=*), intent(in), optional :: trihedron
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             wireTag=int(wireTag, c_int), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             trihedron=istring_(optval_c_str("", trihedron)), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccAddPipe
    
      !> Fillet the volumes `volumeTags' on the curves `curveTags' with radii
      !! `radii'. The `radii' vector can either contain a single radius, as many
      !! radii as `curveTags', or twice as many as `curveTags' (in which case
      !! different radii are provided for the begin and end points of the curves).
      !! Return the filleted entities in `outDimTags' as a vector of (dim, tag)
      !! pairs. Remove the original volume if `removeVolume' is set.
      subroutine gmshModelOccFillet(volumeTags, &
                                    curveTags, &
                                    radii, &
                                    outDimTags, &
                                    removeVolume, &
                                    ierr)
        interface
        subroutine C_API(api_volumeTags_, &
                         api_volumeTags_n_, &
                         api_curveTags_, &
                         api_curveTags_n_, &
                         api_radii_, &
                         api_radii_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         removeVolume, &
                         ierr_) &
          bind(C, name="gmshModelOccFillet")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_volumeTags_
          integer(c_size_t), value, intent(in) :: api_volumeTags_n_
          integer(c_int), dimension(*) :: api_curveTags_
          integer(c_size_t), value, intent(in) :: api_curveTags_n_
          real(c_double), dimension(*) :: api_radii_
          integer(c_size_t), value, intent(in) :: api_radii_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), value, intent(in) :: removeVolume
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), intent(in) :: volumeTags
        integer(c_int), dimension(:), intent(in) :: curveTags
        real(c_double), dimension(:), intent(in) :: radii
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        logical, intent(in), optional :: removeVolume
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_volumeTags_=volumeTags, &
             api_volumeTags_n_=size_gmsh_int(volumeTags), &
             api_curveTags_=curveTags, &
             api_curveTags_n_=size_gmsh_int(curveTags), &
             api_radii_=radii, &
             api_radii_n_=size_gmsh_double(radii), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             removeVolume=optval_c_bool(.true., removeVolume), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccFillet
    
      !> Chamfer the volumes `volumeTags' on the curves `curveTags' with distances
      !! `distances' measured on surfaces `surfaceTags'. The `distances' vector can
      !! either contain a single distance, as many distances as `curveTags' and
      !! `surfaceTags', or twice as many as `curveTags' and `surfaceTags' (in which
      !! case the first in each pair is measured on the corresponding surface in
      !! `surfaceTags', the other on the other adjacent surface). Return the
      !! chamfered entities in `outDimTags'. Remove the original volume if
      !! `removeVolume' is set.
      subroutine gmshModelOccChamfer(volumeTags, &
                                     curveTags, &
                                     surfaceTags, &
                                     distances, &
                                     outDimTags, &
                                     removeVolume, &
                                     ierr)
        interface
        subroutine C_API(api_volumeTags_, &
                         api_volumeTags_n_, &
                         api_curveTags_, &
                         api_curveTags_n_, &
                         api_surfaceTags_, &
                         api_surfaceTags_n_, &
                         api_distances_, &
                         api_distances_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         removeVolume, &
                         ierr_) &
          bind(C, name="gmshModelOccChamfer")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_volumeTags_
          integer(c_size_t), value, intent(in) :: api_volumeTags_n_
          integer(c_int), dimension(*) :: api_curveTags_
          integer(c_size_t), value, intent(in) :: api_curveTags_n_
          integer(c_int), dimension(*) :: api_surfaceTags_
          integer(c_size_t), value, intent(in) :: api_surfaceTags_n_
          real(c_double), dimension(*) :: api_distances_
          integer(c_size_t), value, intent(in) :: api_distances_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), value, intent(in) :: removeVolume
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), intent(in) :: volumeTags
        integer(c_int), dimension(:), intent(in) :: curveTags
        integer(c_int), dimension(:), intent(in) :: surfaceTags
        real(c_double), dimension(:), intent(in) :: distances
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        logical, intent(in), optional :: removeVolume
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_volumeTags_=volumeTags, &
             api_volumeTags_n_=size_gmsh_int(volumeTags), &
             api_curveTags_=curveTags, &
             api_curveTags_n_=size_gmsh_int(curveTags), &
             api_surfaceTags_=surfaceTags, &
             api_surfaceTags_n_=size_gmsh_int(surfaceTags), &
             api_distances_=distances, &
             api_distances_n_=size_gmsh_double(distances), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             removeVolume=optval_c_bool(.true., removeVolume), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccChamfer
    
      !> Defeature the volumes `volumeTags' by removing the surfaces `surfaceTags'.
      !! Return the defeatured entities in `outDimTags'. Remove the original volume
      !! if `removeVolume' is set.
      subroutine gmshModelOccDefeature(volumeTags, &
                                       surfaceTags, &
                                       outDimTags, &
                                       removeVolume, &
                                       ierr)
        interface
        subroutine C_API(api_volumeTags_, &
                         api_volumeTags_n_, &
                         api_surfaceTags_, &
                         api_surfaceTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         removeVolume, &
                         ierr_) &
          bind(C, name="gmshModelOccDefeature")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_volumeTags_
          integer(c_size_t), value, intent(in) :: api_volumeTags_n_
          integer(c_int), dimension(*) :: api_surfaceTags_
          integer(c_size_t), value, intent(in) :: api_surfaceTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), value, intent(in) :: removeVolume
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), intent(in) :: volumeTags
        integer(c_int), dimension(:), intent(in) :: surfaceTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        logical, intent(in), optional :: removeVolume
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_volumeTags_=volumeTags, &
             api_volumeTags_n_=size_gmsh_int(volumeTags), &
             api_surfaceTags_=surfaceTags, &
             api_surfaceTags_n_=size_gmsh_int(surfaceTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             removeVolume=optval_c_bool(.true., removeVolume), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccDefeature
    
      !> Create a fillet edge between edges `edgeTag1' and `edgeTag2' with radius
      !! `radius'. The modifed edges keep their tag. If `tag' is positive, set the
      !! tag explicitly; otherwise a new tag is selected automatically.
      function gmshModelOccFillet2D(edgeTag1, &
                                    edgeTag2, &
                                    radius, &
                                    tag, &
                                    ierr)
        interface
        function C_API(edgeTag1, &
                       edgeTag2, &
                       radius, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccFillet2D")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: edgeTag1
          integer(c_int), value, intent(in) :: edgeTag2
          real(c_double), value, intent(in) :: radius
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccFillet2D
        integer, intent(in) :: edgeTag1
        integer, intent(in) :: edgeTag2
        real(c_double), intent(in) :: radius
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccFillet2D = C_API(edgeTag1=int(edgeTag1, c_int), &
                               edgeTag2=int(edgeTag2, c_int), &
                               radius=real(radius, c_double), &
                               tag=optval_c_int(-1, tag), &
                               ierr_=ierr)
      end function gmshModelOccFillet2D
    
      !> Create a chamfer edge between edges `edgeTag1' and `edgeTag2' with
      !! distance1 `distance1' and distance2 `distance2'. The modifed edges keep
      !! their tag. If `tag' is positive, set the tag explicitly; otherwise a new
      !! tag is selected automatically.
      function gmshModelOccChamfer2D(edgeTag1, &
                                     edgeTag2, &
                                     distance1, &
                                     distance2, &
                                     tag, &
                                     ierr)
        interface
        function C_API(edgeTag1, &
                       edgeTag2, &
                       distance1, &
                       distance2, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshModelOccChamfer2D")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: edgeTag1
          integer(c_int), value, intent(in) :: edgeTag2
          real(c_double), value, intent(in) :: distance1
          real(c_double), value, intent(in) :: distance2
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccChamfer2D
        integer, intent(in) :: edgeTag1
        integer, intent(in) :: edgeTag2
        real(c_double), intent(in) :: distance1
        real(c_double), intent(in) :: distance2
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccChamfer2D = C_API(edgeTag1=int(edgeTag1, c_int), &
                                edgeTag2=int(edgeTag2, c_int), &
                                distance1=real(distance1, c_double), &
                                distance2=real(distance2, c_double), &
                                tag=optval_c_int(-1, tag), &
                                ierr_=ierr)
      end function gmshModelOccChamfer2D
    
      !> Create an offset curve based on the curve loop `curveLoopTag' with offset
      !! `offset'. Return the offset curves in `outDimTags' as a vector of (dim,
      !! tag) pairs.
      subroutine gmshModelOccOffsetCurve(curveLoopTag, &
                                         offset, &
                                         outDimTags, &
                                         ierr)
        interface
        subroutine C_API(curveLoopTag, &
                         offset, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelOccOffsetCurve")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: curveLoopTag
          real(c_double), value, intent(in) :: offset
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: curveLoopTag
        real(c_double), intent(in) :: offset
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(curveLoopTag=int(curveLoopTag, c_int), &
             offset=real(offset, c_double), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccOffsetCurve
    
      !> Find the minimal distance between shape with `dim1' and `tag1' and shape
      !! with `dim2' and `tag2' and the according coordinates. Return the distance
      !! in `distance' and the coordinate of the points as `x1', `y1', `z1' and
      !! `x2', `y2', `z2'.
      subroutine gmshModelOccGetDistance(dim1, &
                                         tag1, &
                                         dim2, &
                                         tag2, &
                                         distance, &
                                         x1, &
                                         y1, &
                                         z1, &
                                         x2, &
                                         y2, &
                                         z2, &
                                         ierr)
        interface
        subroutine C_API(dim1, &
                         tag1, &
                         dim2, &
                         tag2, &
                         distance, &
                         x1, &
                         y1, &
                         z1, &
                         x2, &
                         y2, &
                         z2, &
                         ierr_) &
          bind(C, name="gmshModelOccGetDistance")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim1
          integer(c_int), value, intent(in) :: tag1
          integer(c_int), value, intent(in) :: dim2
          integer(c_int), value, intent(in) :: tag2
          real(c_double) :: distance
          real(c_double) :: x1
          real(c_double) :: y1
          real(c_double) :: z1
          real(c_double) :: x2
          real(c_double) :: y2
          real(c_double) :: z2
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim1
        integer, intent(in) :: tag1
        integer, intent(in) :: dim2
        integer, intent(in) :: tag2
        real(c_double) :: distance
        real(c_double) :: x1
        real(c_double) :: y1
        real(c_double) :: z1
        real(c_double) :: x2
        real(c_double) :: y2
        real(c_double) :: z2
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim1=int(dim1, c_int), &
             tag1=int(tag1, c_int), &
             dim2=int(dim2, c_int), &
             tag2=int(tag2, c_int), &
             distance=distance, &
             x1=x1, &
             y1=y1, &
             z1=z1, &
             x2=x2, &
             y2=y2, &
             z2=z2, &
             ierr_=ierr)
      end subroutine gmshModelOccGetDistance
    
      !> Compute the boolean union (the fusion) of the entities `objectDimTags' and
      !! `toolDimTags' (vectors of (dim, tag) pairs) in the OpenCASCADE CAD
      !! representation. Return the resulting entities in `outDimTags'. If `tag' is
      !! positive, try to set the tag explicitly (only valid if the boolean
      !! operation results in a single entity). Remove the object if `removeObject'
      !! is set. Remove the tool if `removeTool' is set.
      subroutine gmshModelOccFuse(objectDimTags, &
                                  toolDimTags, &
                                  outDimTags, &
                                  outDimTagsMap, &
                                  outDimTagsMap_n, &
                                  tag, &
                                  removeObject, &
                                  removeTool, &
                                  ierr)
        interface
        subroutine C_API(api_objectDimTags_, &
                         api_objectDimTags_n_, &
                         api_toolDimTags_, &
                         api_toolDimTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_outDimTagsMap_, &
                         api_outDimTagsMap_n_, &
                         api_outDimTagsMap_nn_, &
                         tag, &
                         removeObject, &
                         removeTool, &
                         ierr_) &
          bind(C, name="gmshModelOccFuse")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_objectDimTags_
          integer(c_size_t), value, intent(in) :: api_objectDimTags_n_
          integer(c_int), dimension(*) :: api_toolDimTags_
          integer(c_size_t), value, intent(in) :: api_toolDimTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          type(c_ptr), intent(out) :: api_outDimTagsMap_
          type(c_ptr), intent(out) :: api_outDimTagsMap_n_
          integer(c_size_t) :: api_outDimTagsMap_nn_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: removeObject
          integer(c_int), value, intent(in) :: removeTool
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: objectDimTags
        integer(c_int), dimension(:,:), intent(in) :: toolDimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTagsMap
        integer(c_size_t), dimension(:), allocatable, intent(out) :: outDimTagsMap_n
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: removeObject
        logical, intent(in), optional :: removeTool
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        type(c_ptr) :: api_outDimTagsMap_, api_outDimTagsMap_n_
        integer(c_size_t) :: api_outDimTagsMap_nn_
        call C_API(api_objectDimTags_=objectDimTags, &
             api_objectDimTags_n_=size_gmsh_pair(objectDimTags), &
             api_toolDimTags_=toolDimTags, &
             api_toolDimTags_n_=size_gmsh_pair(toolDimTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_outDimTagsMap_=api_outDimTagsMap_, &
             api_outDimTagsMap_n_=api_outDimTagsMap_n_, &
             api_outDimTagsMap_nn_=api_outDimTagsMap_nn_, &
             tag=optval_c_int(-1, tag), &
             removeObject=optval_c_bool(.true., removeObject), &
             removeTool=optval_c_bool(.true., removeTool), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
        call ovectorvectorpair_(api_outDimTagsMap_, &
          api_outDimTagsMap_n_, &
          api_outDimTagsMap_nn_, &
          outDimTagsMap, &
          outDimTagsMap_n)
      end subroutine gmshModelOccFuse
    
      !> Compute the boolean intersection (the common parts) of the entities
      !! `objectDimTags' and `toolDimTags' (vectors of (dim, tag) pairs) in the
      !! OpenCASCADE CAD representation. Return the resulting entities in
      !! `outDimTags'. If `tag' is positive, try to set the tag explicitly (only
      !! valid if the boolean operation results in a single entity). Remove the
      !! object if `removeObject' is set. Remove the tool if `removeTool' is set.
      subroutine gmshModelOccIntersect(objectDimTags, &
                                       toolDimTags, &
                                       outDimTags, &
                                       outDimTagsMap, &
                                       outDimTagsMap_n, &
                                       tag, &
                                       removeObject, &
                                       removeTool, &
                                       ierr)
        interface
        subroutine C_API(api_objectDimTags_, &
                         api_objectDimTags_n_, &
                         api_toolDimTags_, &
                         api_toolDimTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_outDimTagsMap_, &
                         api_outDimTagsMap_n_, &
                         api_outDimTagsMap_nn_, &
                         tag, &
                         removeObject, &
                         removeTool, &
                         ierr_) &
          bind(C, name="gmshModelOccIntersect")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_objectDimTags_
          integer(c_size_t), value, intent(in) :: api_objectDimTags_n_
          integer(c_int), dimension(*) :: api_toolDimTags_
          integer(c_size_t), value, intent(in) :: api_toolDimTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          type(c_ptr), intent(out) :: api_outDimTagsMap_
          type(c_ptr), intent(out) :: api_outDimTagsMap_n_
          integer(c_size_t) :: api_outDimTagsMap_nn_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: removeObject
          integer(c_int), value, intent(in) :: removeTool
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: objectDimTags
        integer(c_int), dimension(:,:), intent(in) :: toolDimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTagsMap
        integer(c_size_t), dimension(:), allocatable, intent(out) :: outDimTagsMap_n
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: removeObject
        logical, intent(in), optional :: removeTool
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        type(c_ptr) :: api_outDimTagsMap_, api_outDimTagsMap_n_
        integer(c_size_t) :: api_outDimTagsMap_nn_
        call C_API(api_objectDimTags_=objectDimTags, &
             api_objectDimTags_n_=size_gmsh_pair(objectDimTags), &
             api_toolDimTags_=toolDimTags, &
             api_toolDimTags_n_=size_gmsh_pair(toolDimTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_outDimTagsMap_=api_outDimTagsMap_, &
             api_outDimTagsMap_n_=api_outDimTagsMap_n_, &
             api_outDimTagsMap_nn_=api_outDimTagsMap_nn_, &
             tag=optval_c_int(-1, tag), &
             removeObject=optval_c_bool(.true., removeObject), &
             removeTool=optval_c_bool(.true., removeTool), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
        call ovectorvectorpair_(api_outDimTagsMap_, &
          api_outDimTagsMap_n_, &
          api_outDimTagsMap_nn_, &
          outDimTagsMap, &
          outDimTagsMap_n)
      end subroutine gmshModelOccIntersect
    
      !> Compute the boolean difference between the entities `objectDimTags' and
      !! `toolDimTags' (given as vectors of (dim, tag) pairs) in the OpenCASCADE CAD
      !! representation. Return the resulting entities in `outDimTags'. If `tag' is
      !! positive, try to set the tag explicitly (only valid if the boolean
      !! operation results in a single entity). Remove the object if `removeObject'
      !! is set. Remove the tool if `removeTool' is set.
      subroutine gmshModelOccCut(objectDimTags, &
                                 toolDimTags, &
                                 outDimTags, &
                                 outDimTagsMap, &
                                 outDimTagsMap_n, &
                                 tag, &
                                 removeObject, &
                                 removeTool, &
                                 ierr)
        interface
        subroutine C_API(api_objectDimTags_, &
                         api_objectDimTags_n_, &
                         api_toolDimTags_, &
                         api_toolDimTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_outDimTagsMap_, &
                         api_outDimTagsMap_n_, &
                         api_outDimTagsMap_nn_, &
                         tag, &
                         removeObject, &
                         removeTool, &
                         ierr_) &
          bind(C, name="gmshModelOccCut")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_objectDimTags_
          integer(c_size_t), value, intent(in) :: api_objectDimTags_n_
          integer(c_int), dimension(*) :: api_toolDimTags_
          integer(c_size_t), value, intent(in) :: api_toolDimTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          type(c_ptr), intent(out) :: api_outDimTagsMap_
          type(c_ptr), intent(out) :: api_outDimTagsMap_n_
          integer(c_size_t) :: api_outDimTagsMap_nn_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: removeObject
          integer(c_int), value, intent(in) :: removeTool
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: objectDimTags
        integer(c_int), dimension(:,:), intent(in) :: toolDimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTagsMap
        integer(c_size_t), dimension(:), allocatable, intent(out) :: outDimTagsMap_n
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: removeObject
        logical, intent(in), optional :: removeTool
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        type(c_ptr) :: api_outDimTagsMap_, api_outDimTagsMap_n_
        integer(c_size_t) :: api_outDimTagsMap_nn_
        call C_API(api_objectDimTags_=objectDimTags, &
             api_objectDimTags_n_=size_gmsh_pair(objectDimTags), &
             api_toolDimTags_=toolDimTags, &
             api_toolDimTags_n_=size_gmsh_pair(toolDimTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_outDimTagsMap_=api_outDimTagsMap_, &
             api_outDimTagsMap_n_=api_outDimTagsMap_n_, &
             api_outDimTagsMap_nn_=api_outDimTagsMap_nn_, &
             tag=optval_c_int(-1, tag), &
             removeObject=optval_c_bool(.true., removeObject), &
             removeTool=optval_c_bool(.true., removeTool), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
        call ovectorvectorpair_(api_outDimTagsMap_, &
          api_outDimTagsMap_n_, &
          api_outDimTagsMap_nn_, &
          outDimTagsMap, &
          outDimTagsMap_n)
      end subroutine gmshModelOccCut
    
      !> Compute the boolean fragments (general fuse) resulting from the
      !! intersection of the entities `objectDimTags' and `toolDimTags' (given as
      !! vectors of (dim, tag) pairs) in the OpenCASCADE CAD representation, making
      !! all interfaces conformal. When applied to entities of different dimensions,
      !! the lower dimensional entities will be automatically embedded in the higher
      !! dimensional entities if they are not on their boundary. Return the
      !! resulting entities in `outDimTags'. If `tag' is positive, try to set the
      !! tag explicitly (only valid if the boolean operation results in a single
      !! entity). Remove the object if `removeObject' is set. Remove the tool if
      !! `removeTool' is set.
      subroutine gmshModelOccFragment(objectDimTags, &
                                      toolDimTags, &
                                      outDimTags, &
                                      outDimTagsMap, &
                                      outDimTagsMap_n, &
                                      tag, &
                                      removeObject, &
                                      removeTool, &
                                      ierr)
        interface
        subroutine C_API(api_objectDimTags_, &
                         api_objectDimTags_n_, &
                         api_toolDimTags_, &
                         api_toolDimTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_outDimTagsMap_, &
                         api_outDimTagsMap_n_, &
                         api_outDimTagsMap_nn_, &
                         tag, &
                         removeObject, &
                         removeTool, &
                         ierr_) &
          bind(C, name="gmshModelOccFragment")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_objectDimTags_
          integer(c_size_t), value, intent(in) :: api_objectDimTags_n_
          integer(c_int), dimension(*) :: api_toolDimTags_
          integer(c_size_t), value, intent(in) :: api_toolDimTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          type(c_ptr), intent(out) :: api_outDimTagsMap_
          type(c_ptr), intent(out) :: api_outDimTagsMap_n_
          integer(c_size_t) :: api_outDimTagsMap_nn_
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: removeObject
          integer(c_int), value, intent(in) :: removeTool
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: objectDimTags
        integer(c_int), dimension(:,:), intent(in) :: toolDimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTagsMap
        integer(c_size_t), dimension(:), allocatable, intent(out) :: outDimTagsMap_n
        integer, intent(in), optional :: tag
        logical, intent(in), optional :: removeObject
        logical, intent(in), optional :: removeTool
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        type(c_ptr) :: api_outDimTagsMap_, api_outDimTagsMap_n_
        integer(c_size_t) :: api_outDimTagsMap_nn_
        call C_API(api_objectDimTags_=objectDimTags, &
             api_objectDimTags_n_=size_gmsh_pair(objectDimTags), &
             api_toolDimTags_=toolDimTags, &
             api_toolDimTags_n_=size_gmsh_pair(toolDimTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_outDimTagsMap_=api_outDimTagsMap_, &
             api_outDimTagsMap_n_=api_outDimTagsMap_n_, &
             api_outDimTagsMap_nn_=api_outDimTagsMap_nn_, &
             tag=optval_c_int(-1, tag), &
             removeObject=optval_c_bool(.true., removeObject), &
             removeTool=optval_c_bool(.true., removeTool), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
        call ovectorvectorpair_(api_outDimTagsMap_, &
          api_outDimTagsMap_n_, &
          api_outDimTagsMap_nn_, &
          outDimTagsMap, &
          outDimTagsMap_n)
      end subroutine gmshModelOccFragment
    
      !> Translate the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the OpenCASCADE CAD representation along (`dx', `dy', `dz').
      subroutine gmshModelOccTranslate(dimTags, &
                                       dx, &
                                       dy, &
                                       dz, &
                                       ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         dx, &
                         dy, &
                         dz, &
                         ierr_) &
          bind(C, name="gmshModelOccTranslate")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: dx
          real(c_double), value, intent(in) :: dy
          real(c_double), value, intent(in) :: dz
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: dx
        real(c_double), intent(in) :: dy
        real(c_double), intent(in) :: dz
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             dx=real(dx, c_double), &
             dy=real(dy, c_double), &
             dz=real(dz, c_double), &
             ierr_=ierr)
      end subroutine gmshModelOccTranslate
    
      !> Rotate the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the OpenCASCADE CAD representation by `angle' radians around the axis of
      !! revolution defined by the point (`x', `y', `z') and the direction (`ax',
      !! `ay', `az').
      subroutine gmshModelOccRotate(dimTags, &
                                    x, &
                                    y, &
                                    z, &
                                    ax, &
                                    ay, &
                                    az, &
                                    angle, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         x, &
                         y, &
                         z, &
                         ax, &
                         ay, &
                         az, &
                         angle, &
                         ierr_) &
          bind(C, name="gmshModelOccRotate")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: ax
          real(c_double), value, intent(in) :: ay
          real(c_double), value, intent(in) :: az
          real(c_double), value, intent(in) :: angle
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: ax
        real(c_double), intent(in) :: ay
        real(c_double), intent(in) :: az
        real(c_double), intent(in) :: angle
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             ax=real(ax, c_double), &
             ay=real(ay, c_double), &
             az=real(az, c_double), &
             angle=real(angle, c_double), &
             ierr_=ierr)
      end subroutine gmshModelOccRotate
    
      !> Scale the entities `dimTags' (given as a vector of (dim, tag) pairs) in the
      !! OpenCASCADE CAD representation by factors `a', `b' and `c' along the three
      !! coordinate axes; use (`x', `y', `z') as the center of the homothetic
      !! transformation.
      subroutine gmshModelOccDilate(dimTags, &
                                    x, &
                                    y, &
                                    z, &
                                    a, &
                                    b, &
                                    c, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         x, &
                         y, &
                         z, &
                         a, &
                         b, &
                         c, &
                         ierr_) &
          bind(C, name="gmshModelOccDilate")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          real(c_double), value, intent(in) :: a
          real(c_double), value, intent(in) :: b
          real(c_double), value, intent(in) :: c
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), intent(in) :: a
        real(c_double), intent(in) :: b
        real(c_double), intent(in) :: c
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             a=real(a, c_double), &
             b=real(b, c_double), &
             c=real(c, c_double), &
             ierr_=ierr)
      end subroutine gmshModelOccDilate
    
      !> Mirror the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the OpenCASCADE CAD representation, with respect to the plane of equation
      !! `a' * x + `b' * y + `c' * z + `d' = 0.
      subroutine gmshModelOccMirror(dimTags, &
                                    a, &
                                    b, &
                                    c, &
                                    d, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         a, &
                         b, &
                         c, &
                         d, &
                         ierr_) &
          bind(C, name="gmshModelOccMirror")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: a
          real(c_double), value, intent(in) :: b
          real(c_double), value, intent(in) :: c
          real(c_double), value, intent(in) :: d
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: a
        real(c_double), intent(in) :: b
        real(c_double), intent(in) :: c
        real(c_double), intent(in) :: d
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             a=real(a, c_double), &
             b=real(b, c_double), &
             c=real(c, c_double), &
             d=real(d, c_double), &
             ierr_=ierr)
      end subroutine gmshModelOccMirror
    
      !> Mirror the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the OpenCASCADE CAD representation, with respect to the plane of equation
      !! `a' * x + `b' * y + `c' * z + `d' = 0. (This is a deprecated synonym for
      !! `mirror'.)
      subroutine gmshModelOccSymmetrize(dimTags, &
                                        a, &
                                        b, &
                                        c, &
                                        d, &
                                        ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         a, &
                         b, &
                         c, &
                         d, &
                         ierr_) &
          bind(C, name="gmshModelOccSymmetrize")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: a
          real(c_double), value, intent(in) :: b
          real(c_double), value, intent(in) :: c
          real(c_double), value, intent(in) :: d
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: a
        real(c_double), intent(in) :: b
        real(c_double), intent(in) :: c
        real(c_double), intent(in) :: d
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             a=real(a, c_double), &
             b=real(b, c_double), &
             c=real(c, c_double), &
             d=real(d, c_double), &
             ierr_=ierr)
      end subroutine gmshModelOccSymmetrize
    
      !> Apply a general affine transformation matrix `affineTransform' (16 entries
      !! of a 4x4 matrix, by row; only the 12 first can be provided for convenience)
      !! to the entities `dimTags' (given as a vector of (dim, tag) pairs) in the
      !! OpenCASCADE CAD representation.
      subroutine gmshModelOccAffineTransform(dimTags, &
                                             affineTransform, &
                                             ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         api_affineTransform_, &
                         api_affineTransform_n_, &
                         ierr_) &
          bind(C, name="gmshModelOccAffineTransform")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), dimension(*) :: api_affineTransform_
          integer(c_size_t), value, intent(in) :: api_affineTransform_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), dimension(:), intent(in) :: affineTransform
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             api_affineTransform_=affineTransform, &
             api_affineTransform_n_=size_gmsh_double(affineTransform), &
             ierr_=ierr)
      end subroutine gmshModelOccAffineTransform
    
      !> Copy the entities `dimTags' in the OpenCASCADE CAD representation; the new
      !! entities are returned in `outDimTags'.
      subroutine gmshModelOccCopy(dimTags, &
                                  outDimTags, &
                                  ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelOccCopy")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccCopy
    
      !> Remove the entities `dimTags' (given as a vector of (dim, tag) pairs) in
      !! the OpenCASCADE CAD representation, provided that they are not on the
      !! boundary of higher-dimensional entities. If `recursive' is true, remove all
      !! the entities on their boundaries, down to dimension 0.
      subroutine gmshModelOccRemove(dimTags, &
                                    recursive, &
                                    ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         recursive, &
                         ierr_) &
          bind(C, name="gmshModelOccRemove")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: recursive
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        logical, intent(in), optional :: recursive
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             recursive=optval_c_bool(.false., recursive), &
             ierr_=ierr)
      end subroutine gmshModelOccRemove
    
      !> Remove all duplicate entities in the OpenCASCADE CAD representation
      !! (different entities at the same geometrical location) after intersecting
      !! (using boolean fragments) all highest dimensional entities.
      subroutine gmshModelOccRemoveAllDuplicates(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelOccRemoveAllDuplicates")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelOccRemoveAllDuplicates
    
      !> Apply various healing procedures to the entities `dimTags' (given as a
      !! vector of (dim, tag) pairs), or to all the entities in the model if
      !! `dimTags' is empty, in the OpenCASCADE CAD representation. Return the
      !! healed entities in `outDimTags'.
      subroutine gmshModelOccHealShapes(outDimTags, &
                                        dimTags, &
                                        tolerance, &
                                        fixDegenerated, &
                                        fixSmallEdges, &
                                        fixSmallFaces, &
                                        sewFaces, &
                                        makeSolids, &
                                        ierr)
        interface
        subroutine C_API(api_outDimTags_, &
                         api_outDimTags_n_, &
                         api_dimTags_, &
                         api_dimTags_n_, &
                         tolerance, &
                         fixDegenerated, &
                         fixSmallEdges, &
                         fixSmallFaces, &
                         sewFaces, &
                         makeSolids, &
                         ierr_) &
          bind(C, name="gmshModelOccHealShapes")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), dimension(*), optional :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: tolerance
          integer(c_int), value, intent(in) :: fixDegenerated
          integer(c_int), value, intent(in) :: fixSmallEdges
          integer(c_int), value, intent(in) :: fixSmallFaces
          integer(c_int), value, intent(in) :: sewFaces
          integer(c_int), value, intent(in) :: makeSolids
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        integer(c_int), dimension(:,:), intent(in), optional :: dimTags
        real(c_double), intent(in), optional :: tolerance
        logical, intent(in), optional :: fixDegenerated
        logical, intent(in), optional :: fixSmallEdges
        logical, intent(in), optional :: fixSmallFaces
        logical, intent(in), optional :: sewFaces
        logical, intent(in), optional :: makeSolids
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             tolerance=optval_c_double(1e-8, tolerance), &
             fixDegenerated=optval_c_bool(.true., fixDegenerated), &
             fixSmallEdges=optval_c_bool(.true., fixSmallEdges), &
             fixSmallFaces=optval_c_bool(.true., fixSmallFaces), &
             sewFaces=optval_c_bool(.true., sewFaces), &
             makeSolids=optval_c_bool(.true., makeSolids), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccHealShapes
    
      !> Convert the entities `dimTags' to NURBS.
      subroutine gmshModelOccConvertToNURBS(dimTags, &
                                            ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         ierr_) &
          bind(C, name="gmshModelOccConvertToNURBS")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             ierr_=ierr)
      end subroutine gmshModelOccConvertToNURBS
    
      !> Import BREP, STEP or IGES shapes from the file `fileName' in the
      !! OpenCASCADE CAD representation. The imported entities are returned in
      !! `outDimTags', as a vector of (dim, tag) pairs. If the optional argument
      !! `highestDimOnly' is set, only import the highest dimensional entities in
      !! the file. The optional argument `format' can be used to force the format of
      !! the file (currently "brep", "step" or "iges").
      subroutine gmshModelOccImportShapes(fileName, &
                                          outDimTags, &
                                          highestDimOnly, &
                                          format, &
                                          ierr)
        interface
        subroutine C_API(fileName, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         highestDimOnly, &
                         format, &
                         ierr_) &
          bind(C, name="gmshModelOccImportShapes")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: fileName
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), value, intent(in) :: highestDimOnly
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: format
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: fileName
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        logical, intent(in), optional :: highestDimOnly
        character(len=*), intent(in), optional :: format
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(fileName=istring_(fileName), &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             highestDimOnly=optval_c_bool(.true., highestDimOnly), &
             format=istring_(optval_c_str("", format)), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccImportShapes
    
      !> Import an OpenCASCADE `shape' by providing a pointer to a native
      !! OpenCASCADE `TopoDS_Shape' object (passed as a pointer to void). The
      !! imported entities are returned in `outDimTags' as a vector of (dim, tag)
      !! pairs. If the optional argument `highestDimOnly' is set, only import the
      !! highest dimensional entities in `shape'. In Python, this function can be
      !! used for integration with PythonOCC, in which the SwigPyObject pointer of
      !! `TopoDS_Shape' must be passed as an int to `shape', i.e., `shape =
      !! int(pythonocc_shape.this)'. Warning: this function is unsafe, as providing
      !! an invalid pointer will lead to undefined behavior.
      subroutine gmshModelOccImportShapesNativePointer(shape, &
                                                       outDimTags, &
                                                       highestDimOnly, &
                                                       ierr)
        interface
        subroutine C_API(shape, &
                         api_outDimTags_, &
                         api_outDimTags_n_, &
                         highestDimOnly, &
                         ierr_) &
          bind(C, name="gmshModelOccImportShapesNativePointer")
          use, intrinsic :: iso_c_binding
          type(c_ptr), value, intent(in) :: shape
          type(c_ptr), intent(out) :: api_outDimTags_
          integer(c_size_t), intent(out) :: api_outDimTags_n_
          integer(c_int), value, intent(in) :: highestDimOnly
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        type(c_ptr), intent(in) :: shape
        integer(c_int), dimension(:,:), allocatable, intent(out) :: outDimTags
        logical, intent(in), optional :: highestDimOnly
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_outDimTags_
        integer(c_size_t) :: api_outDimTags_n_
        call C_API(shape=shape, &
             api_outDimTags_=api_outDimTags_, &
             api_outDimTags_n_=api_outDimTags_n_, &
             highestDimOnly=optval_c_bool(.true., highestDimOnly), &
             ierr_=ierr)
        outDimTags = ovectorpair_(api_outDimTags_, &
          api_outDimTags_n_)
      end subroutine gmshModelOccImportShapesNativePointer
    
      !> Get all the OpenCASCADE entities. If `dim' is >= 0, return only the
      !! entities of the specified dimension (e.g. points if `dim' == 0). The
      !! entities are returned as a vector of (dim, tag) pairs.
      subroutine gmshModelOccGetEntities(dimTags, &
                                         dim, &
                                         ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         dim, &
                         ierr_) &
          bind(C, name="gmshModelOccGetEntities")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             dim=optval_c_int(-1, dim), &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelOccGetEntities
    
      !> Get the OpenCASCADE entities in the bounding box defined by the two points
      !! (`xmin', `ymin', `zmin') and (`xmax', `ymax', `zmax'). If `dim' is >= 0,
      !! return only the entities of the specified dimension (e.g. points if `dim'
      !! == 0).
      subroutine gmshModelOccGetEntitiesInBoundingBox(xmin, &
                                                      ymin, &
                                                      zmin, &
                                                      xmax, &
                                                      ymax, &
                                                      zmax, &
                                                      dimTags, &
                                                      dim, &
                                                      ierr)
        interface
        subroutine C_API(xmin, &
                         ymin, &
                         zmin, &
                         xmax, &
                         ymax, &
                         zmax, &
                         api_dimTags_, &
                         api_dimTags_n_, &
                         dim, &
                         ierr_) &
          bind(C, name="gmshModelOccGetEntitiesInBoundingBox")
          use, intrinsic :: iso_c_binding
          real(c_double), value, intent(in) :: xmin
          real(c_double), value, intent(in) :: ymin
          real(c_double), value, intent(in) :: zmin
          real(c_double), value, intent(in) :: xmax
          real(c_double), value, intent(in) :: ymax
          real(c_double), value, intent(in) :: zmax
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), intent(in) :: xmin
        real(c_double), intent(in) :: ymin
        real(c_double), intent(in) :: zmin
        real(c_double), intent(in) :: xmax
        real(c_double), intent(in) :: ymax
        real(c_double), intent(in) :: zmax
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        call C_API(xmin=real(xmin, c_double), &
             ymin=real(ymin, c_double), &
             zmin=real(zmin, c_double), &
             xmax=real(xmax, c_double), &
             ymax=real(ymax, c_double), &
             zmax=real(zmax, c_double), &
             api_dimTags_=api_dimTags_, &
             api_dimTags_n_=api_dimTags_n_, &
             dim=optval_c_int(-1, dim), &
             ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end subroutine gmshModelOccGetEntitiesInBoundingBox
    
      !> Get the bounding box (`xmin', `ymin', `zmin'), (`xmax', `ymax', `zmax') of
      !! the OpenCASCADE entity of dimension `dim' and tag `tag'.
      subroutine gmshModelOccGetBoundingBox(dim, &
                                            tag, &
                                            xmin, &
                                            ymin, &
                                            zmin, &
                                            xmax, &
                                            ymax, &
                                            zmax, &
                                            ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         xmin, &
                         ymin, &
                         zmin, &
                         xmax, &
                         ymax, &
                         zmax, &
                         ierr_) &
          bind(C, name="gmshModelOccGetBoundingBox")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double) :: xmin
          real(c_double) :: ymin
          real(c_double) :: zmin
          real(c_double) :: xmax
          real(c_double) :: ymax
          real(c_double) :: zmax
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double) :: xmin
        real(c_double) :: ymin
        real(c_double) :: zmin
        real(c_double) :: xmax
        real(c_double) :: ymax
        real(c_double) :: zmax
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             xmin=xmin, &
             ymin=ymin, &
             zmin=zmin, &
             xmax=xmax, &
             ymax=ymax, &
             zmax=zmax, &
             ierr_=ierr)
      end subroutine gmshModelOccGetBoundingBox
    
      !> Get the tags `curveLoopTags' of the curve loops making up the surface of
      !! tag `surfaceTag', as well as the tags `curveTags' of the curves making up
      !! each curve loop.
      subroutine gmshModelOccGetCurveLoops(surfaceTag, &
                                           curveLoopTags, &
                                           curveTags, &
                                           curveTags_n, &
                                           ierr)
        interface
        subroutine C_API(surfaceTag, &
                         api_curveLoopTags_, &
                         api_curveLoopTags_n_, &
                         api_curveTags_, &
                         api_curveTags_n_, &
                         api_curveTags_nn_, &
                         ierr_) &
          bind(C, name="gmshModelOccGetCurveLoops")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: surfaceTag
          type(c_ptr), intent(out) :: api_curveLoopTags_
          integer(c_size_t), intent(out) :: api_curveLoopTags_n_
          type(c_ptr), intent(out) :: api_curveTags_
          type(c_ptr), intent(out) :: api_curveTags_n_
          integer(c_size_t), intent(out) :: api_curveTags_nn_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: surfaceTag
        integer(c_int), dimension(:), allocatable, intent(out) :: curveLoopTags
        integer(c_int), dimension(:), allocatable, intent(out) :: curveTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: curveTags_n
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_curveLoopTags_
        integer(c_size_t) :: api_curveLoopTags_n_
        type(c_ptr) :: api_curveTags_, api_curveTags_n_
        integer(c_size_t) :: api_curveTags_nn_
        call C_API(surfaceTag=int(surfaceTag, c_int), &
             api_curveLoopTags_=api_curveLoopTags_, &
             api_curveLoopTags_n_=api_curveLoopTags_n_, &
             api_curveTags_=api_curveTags_, &
             api_curveTags_n_=api_curveTags_n_, &
             api_curveTags_nn_=api_curveTags_nn_, &
             ierr_=ierr)
        curveLoopTags = ovectorint_(api_curveLoopTags_, &
          api_curveLoopTags_n_)
        call ovectorvectorint_(api_curveTags_, &
          api_curveTags_n_, &
          api_curveTags_nn_, &
          curveTags, &
          curveTags_n)
      end subroutine gmshModelOccGetCurveLoops
    
      !> Get the tags `surfaceLoopTags' of the surface loops making up the volume of
      !! tag `volumeTag', as well as the tags `surfaceTags' of the surfaces making
      !! up each surface loop.
      subroutine gmshModelOccGetSurfaceLoops(volumeTag, &
                                             surfaceLoopTags, &
                                             surfaceTags, &
                                             surfaceTags_n, &
                                             ierr)
        interface
        subroutine C_API(volumeTag, &
                         api_surfaceLoopTags_, &
                         api_surfaceLoopTags_n_, &
                         api_surfaceTags_, &
                         api_surfaceTags_n_, &
                         api_surfaceTags_nn_, &
                         ierr_) &
          bind(C, name="gmshModelOccGetSurfaceLoops")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: volumeTag
          type(c_ptr), intent(out) :: api_surfaceLoopTags_
          integer(c_size_t), intent(out) :: api_surfaceLoopTags_n_
          type(c_ptr), intent(out) :: api_surfaceTags_
          type(c_ptr), intent(out) :: api_surfaceTags_n_
          integer(c_size_t), intent(out) :: api_surfaceTags_nn_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: volumeTag
        integer(c_int), dimension(:), allocatable, intent(out) :: surfaceLoopTags
        integer(c_int), dimension(:), allocatable, intent(out) :: surfaceTags
        integer(c_size_t), dimension(:), allocatable, intent(out) :: surfaceTags_n
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_surfaceLoopTags_
        integer(c_size_t) :: api_surfaceLoopTags_n_
        type(c_ptr) :: api_surfaceTags_, api_surfaceTags_n_
        integer(c_size_t) :: api_surfaceTags_nn_
        call C_API(volumeTag=int(volumeTag, c_int), &
             api_surfaceLoopTags_=api_surfaceLoopTags_, &
             api_surfaceLoopTags_n_=api_surfaceLoopTags_n_, &
             api_surfaceTags_=api_surfaceTags_, &
             api_surfaceTags_n_=api_surfaceTags_n_, &
             api_surfaceTags_nn_=api_surfaceTags_nn_, &
             ierr_=ierr)
        surfaceLoopTags = ovectorint_(api_surfaceLoopTags_, &
          api_surfaceLoopTags_n_)
        call ovectorvectorint_(api_surfaceTags_, &
          api_surfaceTags_n_, &
          api_surfaceTags_nn_, &
          surfaceTags, &
          surfaceTags_n)
      end subroutine gmshModelOccGetSurfaceLoops
    
      !> Get the mass of the OpenCASCADE entity of dimension `dim' and tag `tag'. If
      !! no density is attached to the entity (the default), the value corresponds
      !! respectively to the length, area and volume for `dim' = 1, 2 and 3.
      subroutine gmshModelOccGetMass(dim, &
                                     tag, &
                                     mass, &
                                     ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         mass, &
                         ierr_) &
          bind(C, name="gmshModelOccGetMass")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double) :: mass
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double) :: mass
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             mass=mass, &
             ierr_=ierr)
      end subroutine gmshModelOccGetMass
    
      !> Get the center of mass of the OpenCASCADE entity of dimension `dim' and tag
      !! `tag'.
      subroutine gmshModelOccGetCenterOfMass(dim, &
                                             tag, &
                                             x, &
                                             y, &
                                             z, &
                                             ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         x, &
                         y, &
                         z, &
                         ierr_) &
          bind(C, name="gmshModelOccGetCenterOfMass")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          real(c_double) :: x
          real(c_double) :: y
          real(c_double) :: z
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double) :: x
        real(c_double) :: y
        real(c_double) :: z
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             x=x, &
             y=y, &
             z=z, &
             ierr_=ierr)
      end subroutine gmshModelOccGetCenterOfMass
    
      !> Get the matrix of inertia (by row) of the OpenCASCADE entity of dimension
      !! `dim' and tag `tag'.
      subroutine gmshModelOccGetMatrixOfInertia(dim, &
                                                tag, &
                                                mat, &
                                                ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         api_mat_, &
                         api_mat_n_, &
                         ierr_) &
          bind(C, name="gmshModelOccGetMatrixOfInertia")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_mat_
          integer(c_size_t) :: api_mat_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        real(c_double), dimension(:), allocatable, intent(out) :: mat
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_mat_
        integer(c_size_t) :: api_mat_n_
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             api_mat_=api_mat_, &
             api_mat_n_=api_mat_n_, &
             ierr_=ierr)
        mat = ovectordouble_(api_mat_, &
          api_mat_n_)
      end subroutine gmshModelOccGetMatrixOfInertia
    
      !> Get the maximum tag of entities of dimension `dim' in the OpenCASCADE CAD
      !! representation.
      function gmshModelOccGetMaxTag(dim, &
                                     ierr)
        interface
        function C_API(dim, &
                       ierr_) &
          bind(C, name="gmshModelOccGetMaxTag")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshModelOccGetMaxTag
        integer, intent(in) :: dim
        integer(c_int), intent(out), optional :: ierr
        gmshModelOccGetMaxTag = C_API(dim=int(dim, c_int), &
                                ierr_=ierr)
      end function gmshModelOccGetMaxTag
    
      !> Set the maximum tag `maxTag' for entities of dimension `dim' in the
      !! OpenCASCADE CAD representation.
      subroutine gmshModelOccSetMaxTag(dim, &
                                       maxTag, &
                                       ierr)
        interface
        subroutine C_API(dim, &
                         maxTag, &
                         ierr_) &
          bind(C, name="gmshModelOccSetMaxTag")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: maxTag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: maxTag
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             maxTag=int(maxTag, c_int), &
             ierr_=ierr)
      end subroutine gmshModelOccSetMaxTag
    
      !> Synchronize the OpenCASCADE CAD representation with the current Gmsh model.
      !! This can be called at any time, but since it involves a non trivial amount
      !! of processing, the number of synchronization points should normally be
      !! minimized. Without synchronization the entities in the OpenCASCADE CAD
      !! representation are not available to any function outside of the OpenCASCADE
      !! CAD kernel functions.
      subroutine gmshModelOccSynchronize(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshModelOccSynchronize")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshModelOccSynchronize
    
      !> Set a mesh size constraint on the entities `dimTags' (given as a vector of
      !! (dim, tag) pairs) in the OpenCASCADE CAD representation. Currently only
      !! entities of dimension 0 (points) are handled.
      subroutine gmshModelOccMeshSetSize(dimTags, &
                                         size, &
                                         ierr)
        interface
        subroutine C_API(api_dimTags_, &
                         api_dimTags_n_, &
                         size, &
                         ierr_) &
          bind(C, name="gmshModelOccMeshSetSize")
          use, intrinsic :: iso_c_binding
          integer(c_int), dimension(*) :: api_dimTags_
          integer(c_size_t), value, intent(in) :: api_dimTags_n_
          real(c_double), value, intent(in) :: size
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:,:), intent(in) :: dimTags
        real(c_double), intent(in) :: size
        integer(c_int), intent(out), optional :: ierr
        call C_API(api_dimTags_=dimTags, &
             api_dimTags_n_=size_gmsh_pair(dimTags), &
             size=real(size, c_double), &
             ierr_=ierr)
      end subroutine gmshModelOccMeshSetSize
    
      !> Add a new post-processing view, with name `name'. If `tag' is positive use
      !! it (and remove the view with that tag if it already exists), otherwise
      !! associate a new tag. Return the view tag.
      function gmshViewAdd(name, &
                           tag, &
                           ierr)
        interface
        function C_API(name, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshViewAdd")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshViewAdd
        character(len=*), intent(in) :: name
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshViewAdd = C_API(name=istring_(name), &
                      tag=optval_c_int(-1, tag), &
                      ierr_=ierr)
      end function gmshViewAdd
    
      !> Remove the view with tag `tag'.
      subroutine gmshViewRemove(tag, &
                                ierr)
        interface
        subroutine C_API(tag, &
                         ierr_) &
          bind(C, name="gmshViewRemove")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             ierr_=ierr)
      end subroutine gmshViewRemove
    
      !> Get the index of the view with tag `tag' in the list of currently loaded
      !! views. This dynamic index (it can change when views are removed) is used to
      !! access view options.
      function gmshViewGetIndex(tag, &
                                ierr)
        interface
        function C_API(tag, &
                       ierr_) &
          bind(C, name="gmshViewGetIndex")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshViewGetIndex
        integer, intent(in) :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshViewGetIndex = C_API(tag=int(tag, c_int), &
                           ierr_=ierr)
      end function gmshViewGetIndex
    
      !> Get the tags of all views.
      subroutine gmshViewGetTags(tags, &
                                 ierr)
        interface
        subroutine C_API(api_tags_, &
                         api_tags_n_, &
                         ierr_) &
          bind(C, name="gmshViewGetTags")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_tags_
          integer(c_size_t), intent(out) :: api_tags_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), dimension(:), allocatable, intent(out) :: tags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_tags_
        integer(c_size_t) :: api_tags_n_
        call C_API(api_tags_=api_tags_, &
             api_tags_n_=api_tags_n_, &
             ierr_=ierr)
        tags = ovectorint_(api_tags_, &
          api_tags_n_)
      end subroutine gmshViewGetTags
    
      !> Add model-based post-processing data to the view with tag `tag'.
      !! `modelName' identifies the model the data is attached to. `dataType'
      !! specifies the type of data, currently either "NodeData", "ElementData" or
      !! "ElementNodeData". `step' specifies the identifier (>= 0) of the data in a
      !! sequence. `tags' gives the tags of the nodes or elements in the mesh to
      !! which the data is associated. `data' is a vector of the same length as
      !! `tags': each entry is the vector of double precision numbers representing
      !! the data associated with the corresponding tag. The optional `time'
      !! argument associate a time value with the data. `numComponents' gives the
      !! number of data components (1 for scalar data, 3 for vector data, etc.) per
      !! entity; if negative, it is automatically inferred (when possible) from the
      !! input data. `partition' allows one to specify data in several sub-sets.
      subroutine gmshViewAddModelData(tag, &
                                      step, &
                                      modelName, &
                                      dataType, &
                                      tags, &
                                      data, &
                                      data_n, &
                                      time, &
                                      numComponents, &
                                      partition, &
                                      ierr)
        interface
        subroutine C_API(tag, &
                         step, &
                         modelName, &
                         dataType, &
                         api_tags_, &
                         api_tags_n_, &
                         api_data_, &
                         api_data_n_, &
                         api_data_nn_, &
                         time, &
                         numComponents, &
                         partition, &
                         ierr_) &
          bind(C, name="gmshViewAddModelData")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: step
          character(len=1, kind=c_char), dimension(*), intent(in) :: modelName
          character(len=1, kind=c_char), dimension(*), intent(in) :: dataType
          integer(c_size_t), dimension(*) :: api_tags_
          integer(c_size_t), value, intent(in) :: api_tags_n_
          type(c_ptr), intent(in) :: api_data_
          type(c_ptr), intent(in) :: api_data_n_
          integer(c_size_t), value, intent(in) :: api_data_nn_
          real(c_double), value, intent(in) :: time
          integer(c_int), value, intent(in) :: numComponents
          integer(c_int), value, intent(in) :: partition
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: step
        character(len=*), intent(in) :: modelName
        character(len=*), intent(in) :: dataType
        integer(c_size_t), dimension(:), intent(in) :: tags
        real(c_double), dimension(:), intent(in) :: data
        integer(c_size_t), dimension(:), intent(in) :: data_n
        real(c_double), intent(in), optional :: time
        integer, intent(in), optional :: numComponents
        integer, intent(in), optional :: partition
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_data_
        type(c_ptr) :: api_data_n_
        integer(c_size_t) :: api_data_nn_
        call ivectorvectordouble_(data, &
          data_n, &
          api_data_, &
          api_data_n_, &
          api_data_nn_)
        call C_API(tag=int(tag, c_int), &
             step=int(step, c_int), &
             modelName=istring_(modelName), &
             dataType=istring_(dataType), &
             api_tags_=tags, &
             api_tags_n_=size_gmsh_size(tags), &
             api_data_=api_data_, &
             api_data_n_=api_data_n_, &
             api_data_nn_=api_data_nn_, &
             time=optval_c_double(0., time), &
             numComponents=optval_c_int(-1, numComponents), &
             partition=optval_c_int(0, partition), &
             ierr_=ierr)
      end subroutine gmshViewAddModelData
    
      !> Add homogeneous model-based post-processing data to the view with tag
      !! `tag'. The arguments have the same meaning as in `addModelData', except
      !! that `data' is supposed to be homogeneous and is thus flattened in a single
      !! vector. For data types that can lead to different data sizes per tag (like
      !! "ElementNodeData"), the data should be padded.
      subroutine gmshViewAddHomogeneousModelData(tag, &
                                                 step, &
                                                 modelName, &
                                                 dataType, &
                                                 tags, &
                                                 data, &
                                                 time, &
                                                 numComponents, &
                                                 partition, &
                                                 ierr)
        interface
        subroutine C_API(tag, &
                         step, &
                         modelName, &
                         dataType, &
                         api_tags_, &
                         api_tags_n_, &
                         api_data_, &
                         api_data_n_, &
                         time, &
                         numComponents, &
                         partition, &
                         ierr_) &
          bind(C, name="gmshViewAddHomogeneousModelData")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: step
          character(len=1, kind=c_char), dimension(*), intent(in) :: modelName
          character(len=1, kind=c_char), dimension(*), intent(in) :: dataType
          integer(c_size_t), dimension(*) :: api_tags_
          integer(c_size_t), value, intent(in) :: api_tags_n_
          real(c_double), dimension(*) :: api_data_
          integer(c_size_t), value, intent(in) :: api_data_n_
          real(c_double), value, intent(in) :: time
          integer(c_int), value, intent(in) :: numComponents
          integer(c_int), value, intent(in) :: partition
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: step
        character(len=*), intent(in) :: modelName
        character(len=*), intent(in) :: dataType
        integer(c_size_t), dimension(:), intent(in) :: tags
        real(c_double), dimension(:), intent(in) :: data
        real(c_double), intent(in), optional :: time
        integer, intent(in), optional :: numComponents
        integer, intent(in), optional :: partition
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             step=int(step, c_int), &
             modelName=istring_(modelName), &
             dataType=istring_(dataType), &
             api_tags_=tags, &
             api_tags_n_=size_gmsh_size(tags), &
             api_data_=data, &
             api_data_n_=size_gmsh_double(data), &
             time=optval_c_double(0., time), &
             numComponents=optval_c_int(-1, numComponents), &
             partition=optval_c_int(0, partition), &
             ierr_=ierr)
      end subroutine gmshViewAddHomogeneousModelData
    
      !> Get model-based post-processing data from the view with tag `tag' at step
      !! `step'. Return the `data' associated to the nodes or the elements with tags
      !! `tags', as well as the `dataType' and the number of components
      !! `numComponents'.
      subroutine gmshViewGetModelData(tag, &
                                      step, &
                                      dataType, &
                                      tags, &
                                      data, &
                                      data_n, &
                                      time, &
                                      numComponents, &
                                      ierr)
        interface
        subroutine C_API(tag, &
                         step, &
                         api_dataType_, &
                         api_tags_, &
                         api_tags_n_, &
                         api_data_, &
                         api_data_n_, &
                         api_data_nn_, &
                         time, &
                         numComponents, &
                         ierr_) &
          bind(C, name="gmshViewGetModelData")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: step
          type(c_ptr), intent(out) :: api_dataType_
          type(c_ptr), intent(out) :: api_tags_
          integer(c_size_t), intent(out) :: api_tags_n_
          type(c_ptr), intent(out) :: api_data_
          type(c_ptr), intent(out) :: api_data_n_
          integer(c_size_t), intent(out) :: api_data_nn_
          real(c_double) :: time
          integer(c_int) :: numComponents
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: step
        character(len=:), allocatable, intent(out) :: dataType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: tags
        real(c_double), dimension(:), allocatable, intent(out) :: data
        integer(c_size_t), dimension(:), allocatable, intent(out) :: data_n
        real(c_double) :: time
        integer(c_int) :: numComponents
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dataType_
        type(c_ptr) :: api_tags_
        integer(c_size_t) :: api_tags_n_
        type(c_ptr) :: api_data_, api_data_n_
        integer(c_size_t) :: api_data_nn_
        call C_API(tag=int(tag, c_int), &
             step=int(step, c_int), &
             api_dataType_=api_dataType_, &
             api_tags_=api_tags_, &
             api_tags_n_=api_tags_n_, &
             api_data_=api_data_, &
             api_data_n_=api_data_n_, &
             api_data_nn_=api_data_nn_, &
             time=time, &
             numComponents=numComponents, &
             ierr_=ierr)
        dataType = ostring_(api_dataType_)
        tags = ovectorsize_(api_tags_, &
          api_tags_n_)
        call ovectorvectordouble_(api_data_, &
          api_data_n_, &
          api_data_nn_, &
          data, &
          data_n)
      end subroutine gmshViewGetModelData
    
      !> Get homogeneous model-based post-processing data from the view with tag
      !! `tag' at step `step'. The arguments have the same meaning as in
      !! `getModelData', except that `data' is returned flattened in a single
      !! vector, with the appropriate padding if necessary.
      subroutine gmshViewGetHomogeneousModelData(tag, &
                                                 step, &
                                                 dataType, &
                                                 tags, &
                                                 data, &
                                                 time, &
                                                 numComponents, &
                                                 ierr)
        interface
        subroutine C_API(tag, &
                         step, &
                         api_dataType_, &
                         api_tags_, &
                         api_tags_n_, &
                         api_data_, &
                         api_data_n_, &
                         time, &
                         numComponents, &
                         ierr_) &
          bind(C, name="gmshViewGetHomogeneousModelData")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: step
          type(c_ptr), intent(out) :: api_dataType_
          type(c_ptr), intent(out) :: api_tags_
          integer(c_size_t), intent(out) :: api_tags_n_
          type(c_ptr), intent(out) :: api_data_
          integer(c_size_t) :: api_data_n_
          real(c_double) :: time
          integer(c_int) :: numComponents
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: step
        character(len=:), allocatable, intent(out) :: dataType
        integer(c_size_t), dimension(:), allocatable, intent(out) :: tags
        real(c_double), dimension(:), allocatable, intent(out) :: data
        real(c_double) :: time
        integer(c_int) :: numComponents
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dataType_
        type(c_ptr) :: api_tags_
        integer(c_size_t) :: api_tags_n_
        type(c_ptr) :: api_data_
        integer(c_size_t) :: api_data_n_
        call C_API(tag=int(tag, c_int), &
             step=int(step, c_int), &
             api_dataType_=api_dataType_, &
             api_tags_=api_tags_, &
             api_tags_n_=api_tags_n_, &
             api_data_=api_data_, &
             api_data_n_=api_data_n_, &
             time=time, &
             numComponents=numComponents, &
             ierr_=ierr)
        dataType = ostring_(api_dataType_)
        tags = ovectorsize_(api_tags_, &
          api_tags_n_)
        data = ovectordouble_(api_data_, &
          api_data_n_)
      end subroutine gmshViewGetHomogeneousModelData
    
      !> Add list-based post-processing data to the view with tag `tag'. List-based
      !! datasets are independent from any model and any mesh. `dataType' identifies
      !! the data by concatenating the field type ("S" for scalar, "V" for vector,
      !! "T" for tensor) and the element type ("P" for point, "L" for line, "T" for
      !! triangle, "S" for tetrahedron, "I" for prism, "H" for hexaHedron, "Y" for
      !! pyramid). For example `dataType' should be "ST" for a scalar field on
      !! triangles. `numEle' gives the number of elements in the data. `data'
      !! contains the data for the `numEle' elements, concatenated, with node
      !! coordinates followed by values per node, repeated for each step: [e1x1,
      !! ..., e1xn, e1y1, ..., e1yn, e1z1, ..., e1zn, e1v1..., e1vN, e2x1, ...].
      subroutine gmshViewAddListData(tag, &
                                     dataType, &
                                     numEle, &
                                     data, &
                                     ierr)
        interface
        subroutine C_API(tag, &
                         dataType, &
                         numEle, &
                         api_data_, &
                         api_data_n_, &
                         ierr_) &
          bind(C, name="gmshViewAddListData")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: dataType
          integer(c_int), value, intent(in) :: numEle
          real(c_double), dimension(*) :: api_data_
          integer(c_size_t), value, intent(in) :: api_data_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: dataType
        integer, intent(in) :: numEle
        real(c_double), dimension(:), intent(in) :: data
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             dataType=istring_(dataType), &
             numEle=int(numEle, c_int), &
             api_data_=data, &
             api_data_n_=size_gmsh_double(data), &
             ierr_=ierr)
      end subroutine gmshViewAddListData
    
      !> Get list-based post-processing data from the view with tag `tag'. Return
      !! the types `dataTypes', the number of elements `numElements' for each data
      !! type and the `data' for each data type. If `returnAdaptive' is set, return
      !! the data obtained after adaptive refinement, if available.
      subroutine gmshViewGetListData(tag, &
                                     dataType, &
                                     numElements, &
                                     data, &
                                     data_n, &
                                     returnAdaptive, &
                                     ierr)
        interface
        subroutine C_API(tag, &
                         api_dataType_, &
                         api_dataType_n_, &
                         api_numElements_, &
                         api_numElements_n_, &
                         api_data_, &
                         api_data_n_, &
                         api_data_nn_, &
                         returnAdaptive, &
                         ierr_) &
          bind(C, name="gmshViewGetListData")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          type(c_ptr), intent(out) :: api_dataType_
          integer(c_size_t), intent(out) :: api_dataType_n_
          type(c_ptr), intent(out) :: api_numElements_
          integer(c_size_t), intent(out) :: api_numElements_n_
          type(c_ptr), intent(out) :: api_data_
          type(c_ptr), intent(out) :: api_data_n_
          integer(c_size_t), intent(out) :: api_data_nn_
          integer(c_int), value, intent(in) :: returnAdaptive
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: dataType
        integer(c_int), dimension(:), allocatable, intent(out) :: numElements
        real(c_double), dimension(:), allocatable, intent(out) :: data
        integer(c_size_t), dimension(:), allocatable, intent(out) :: data_n
        logical, intent(in), optional :: returnAdaptive
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dataType_
        integer(c_size_t) :: api_dataType_n_
        type(c_ptr) :: api_numElements_
        integer(c_size_t) :: api_numElements_n_
        type(c_ptr) :: api_data_, api_data_n_
        integer(c_size_t) :: api_data_nn_
        call C_API(tag=int(tag, c_int), &
             api_dataType_=api_dataType_, &
             api_dataType_n_=api_dataType_n_, &
             api_numElements_=api_numElements_, &
             api_numElements_n_=api_numElements_n_, &
             api_data_=api_data_, &
             api_data_n_=api_data_n_, &
             api_data_nn_=api_data_nn_, &
             returnAdaptive=optval_c_bool(.false., returnAdaptive), &
             ierr_=ierr)
        dataType = ovectorstring_(api_dataType_, &
          api_dataType_n_)
        numElements = ovectorint_(api_numElements_, &
          api_numElements_n_)
        call ovectorvectordouble_(api_data_, &
          api_data_n_, &
          api_data_nn_, &
          data, &
          data_n)
      end subroutine gmshViewGetListData
    
      !> Add a string to a list-based post-processing view with tag `tag'. If
      !! `coord' contains 3 coordinates the string is positioned in the 3D model
      !! space ("3D string"); if it contains 2 coordinates it is positioned in the
      !! 2D graphics viewport ("2D string"). `data' contains one or more (for
      !! multistep views) strings. `style' contains key-value pairs of styling
      !! parameters, concatenated. Available keys are "Font" (possible values:
      !! "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
      !! "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-
      !! BoldOblique", "Courier", "Courier-Bold", "Courier-Oblique", "Courier-
      !! BoldOblique", "Symbol", "ZapfDingbats", "Screen"), "FontSize" and "Align"
      !! (possible values: "Left" or "BottomLeft", "Center" or "BottomCenter",
      !! "Right" or "BottomRight", "TopLeft", "TopCenter", "TopRight", "CenterLeft",
      !! "CenterCenter", "CenterRight").
      subroutine gmshViewAddListDataString(tag, &
                                           coord, &
                                           data, &
                                           style, &
                                           ierr)
        interface
        subroutine C_API(tag, &
                         api_coord_, &
                         api_coord_n_, &
                         api_data_, &
                         api_data_n_, &
                         api_style_, &
                         api_style_n_, &
                         ierr_) &
          bind(C, name="gmshViewAddListDataString")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          real(c_double), dimension(*) :: api_coord_
          integer(c_size_t), value, intent(in) :: api_coord_n_
          type(c_ptr), dimension(*) :: api_data_
          integer(c_size_t), value, intent(in) :: api_data_n_
          type(c_ptr), dimension(*), optional :: api_style_
          integer(c_size_t), value, intent(in) :: api_style_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        real(c_double), dimension(:), intent(in) :: coord
        character(len=*), dimension(:), intent(in) :: data
        character(len=*), dimension(:), intent(in), optional :: style
        integer(c_int), intent(out), optional :: ierr
        character(len=GMSH_API_MAX_STR_LEN, kind=c_char), allocatable :: api_data_strs(:)
        type(c_ptr), allocatable :: api_data_(:)
        character(len=GMSH_API_MAX_STR_LEN, kind=c_char), allocatable :: api_style_strs(:)
        type(c_ptr), allocatable :: api_style_(:)
        call ivectorstring_(data, &
          api_data_strs, &
          api_data_)
        call ivectorstring_(style, &
          api_style_strs, &
          api_style_)
        call C_API(tag=int(tag, c_int), &
             api_coord_=coord, &
             api_coord_n_=size_gmsh_double(coord), &
             api_data_=api_data_, &
             api_data_n_=size_gmsh_str(data), &
             api_style_=api_style_, &
             api_style_n_=size_gmsh_str(style), &
             ierr_=ierr)
      end subroutine gmshViewAddListDataString
    
      !> Get list-based post-processing data strings (2D strings if `dim' == 2, 3D
      !! strings if `dim' = 3) from the view with tag `tag'. Return the coordinates
      !! in `coord', the strings in `data' and the styles in `style'.
      subroutine gmshViewGetListDataStrings(tag, &
                                            dim, &
                                            coord, &
                                            data, &
                                            style, &
                                            ierr)
        interface
        subroutine C_API(tag, &
                         dim, &
                         api_coord_, &
                         api_coord_n_, &
                         api_data_, &
                         api_data_n_, &
                         api_style_, &
                         api_style_n_, &
                         ierr_) &
          bind(C, name="gmshViewGetListDataStrings")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: dim
          type(c_ptr), intent(out) :: api_coord_
          integer(c_size_t) :: api_coord_n_
          type(c_ptr), intent(out) :: api_data_
          integer(c_size_t), intent(out) :: api_data_n_
          type(c_ptr), intent(out) :: api_style_
          integer(c_size_t), intent(out) :: api_style_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: dim
        real(c_double), dimension(:), allocatable, intent(out) :: coord
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: data
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: style
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_coord_
        integer(c_size_t) :: api_coord_n_
        type(c_ptr) :: api_data_
        integer(c_size_t) :: api_data_n_
        type(c_ptr) :: api_style_
        integer(c_size_t) :: api_style_n_
        call C_API(tag=int(tag, c_int), &
             dim=int(dim, c_int), &
             api_coord_=api_coord_, &
             api_coord_n_=api_coord_n_, &
             api_data_=api_data_, &
             api_data_n_=api_data_n_, &
             api_style_=api_style_, &
             api_style_n_=api_style_n_, &
             ierr_=ierr)
        coord = ovectordouble_(api_coord_, &
          api_coord_n_)
        data = ovectorstring_(api_data_, &
          api_data_n_)
        style = ovectorstring_(api_style_, &
          api_style_n_)
      end subroutine gmshViewGetListDataStrings
    
      !> Set interpolation matrices for the element family `type' ("Line",
      !! "Triangle", "Quadrangle", "Tetrahedron", "Hexahedron", "Prism", "Pyramid")
      !! in the view `tag'. The approximation of the values over an element is
      !! written as a linear combination of `d' basis functions f_i(u, v, w) =
      !! sum_(j = 0, ..., `d' - 1) `coef'[i][j] u^`exp'[j][0] v^`exp'[j][1]
      !! w^`exp'[j][2], i = 0, ..., `d'-1, with u, v, w the coordinates in the
      !! reference element. The `coef' matrix (of size `d' x `d') and the `exp'
      !! matrix (of size `d' x 3) are stored as vectors, by row. If `dGeo' is
      !! positive, use `coefGeo' and `expGeo' to define the interpolation of the x,
      !! y, z coordinates of the element in terms of the u, v, w coordinates, in
      !! exactly the same way. If `d' < 0, remove the interpolation matrices.
      subroutine gmshViewSetInterpolationMatrices(tag, &
                                                  type, &
                                                  d, &
                                                  coef, &
                                                  exp, &
                                                  dGeo, &
                                                  coefGeo, &
                                                  expGeo, &
                                                  ierr)
        interface
        subroutine C_API(tag, &
                         type, &
                         d, &
                         api_coef_, &
                         api_coef_n_, &
                         api_exp_, &
                         api_exp_n_, &
                         dGeo, &
                         api_coefGeo_, &
                         api_coefGeo_n_, &
                         api_expGeo_, &
                         api_expGeo_n_, &
                         ierr_) &
          bind(C, name="gmshViewSetInterpolationMatrices")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: type
          integer(c_int), value, intent(in) :: d
          real(c_double), dimension(*) :: api_coef_
          integer(c_size_t), value, intent(in) :: api_coef_n_
          real(c_double), dimension(*) :: api_exp_
          integer(c_size_t), value, intent(in) :: api_exp_n_
          integer(c_int), value, intent(in) :: dGeo
          real(c_double), dimension(*), optional :: api_coefGeo_
          integer(c_size_t), value, intent(in) :: api_coefGeo_n_
          real(c_double), dimension(*), optional :: api_expGeo_
          integer(c_size_t), value, intent(in) :: api_expGeo_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: type
        integer, intent(in) :: d
        real(c_double), dimension(:), intent(in) :: coef
        real(c_double), dimension(:), intent(in) :: exp
        integer, intent(in), optional :: dGeo
        real(c_double), dimension(:), intent(in), optional :: coefGeo
        real(c_double), dimension(:), intent(in), optional :: expGeo
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             type=istring_(type), &
             d=int(d, c_int), &
             api_coef_=coef, &
             api_coef_n_=size_gmsh_double(coef), &
             api_exp_=exp, &
             api_exp_n_=size_gmsh_double(exp), &
             dGeo=optval_c_int(0, dGeo), &
             api_coefGeo_=coefGeo, &
             api_coefGeo_n_=size_gmsh_double(coefGeo), &
             api_expGeo_=expGeo, &
             api_expGeo_n_=size_gmsh_double(expGeo), &
             ierr_=ierr)
      end subroutine gmshViewSetInterpolationMatrices
    
      !> Add a post-processing view as an `alias' of the reference view with tag
      !! `refTag'. If `copyOptions' is set, copy the options of the reference view.
      !! If `tag' is positive use it (and remove the view with that tag if it
      !! already exists), otherwise associate a new tag. Return the view tag.
      function gmshViewAddAlias(refTag, &
                                copyOptions, &
                                tag, &
                                ierr)
        interface
        function C_API(refTag, &
                       copyOptions, &
                       tag, &
                       ierr_) &
          bind(C, name="gmshViewAddAlias")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), value, intent(in) :: refTag
          integer(c_int), value, intent(in) :: copyOptions
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshViewAddAlias
        integer, intent(in) :: refTag
        logical, intent(in), optional :: copyOptions
        integer, intent(in), optional :: tag
        integer(c_int), intent(out), optional :: ierr
        gmshViewAddAlias = C_API(refTag=int(refTag, c_int), &
                           copyOptions=optval_c_bool(.false., copyOptions), &
                           tag=optval_c_int(-1, tag), &
                           ierr_=ierr)
      end function gmshViewAddAlias
    
      !> Combine elements (if `what' == "elements") or steps (if `what' == "steps")
      !! of all views (`how' == "all"), all visible views (`how' == "visible") or
      !! all views having the same name (`how' == "name"). Remove original views if
      !! `remove' is set.
      subroutine gmshViewCombine(what, &
                                 how, &
                                 remove, &
                                 copyOptions, &
                                 ierr)
        interface
        subroutine C_API(what, &
                         how, &
                         remove, &
                         copyOptions, &
                         ierr_) &
          bind(C, name="gmshViewCombine")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: what
          character(len=1, kind=c_char), dimension(*), intent(in) :: how
          integer(c_int), value, intent(in) :: remove
          integer(c_int), value, intent(in) :: copyOptions
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: what
        character(len=*), intent(in) :: how
        logical, intent(in), optional :: remove
        logical, intent(in), optional :: copyOptions
        integer(c_int), intent(out), optional :: ierr
        call C_API(what=istring_(what), &
             how=istring_(how), &
             remove=optval_c_bool(.true., remove), &
             copyOptions=optval_c_bool(.true., copyOptions), &
             ierr_=ierr)
      end subroutine gmshViewCombine
    
      !> Probe the view `tag' for its `values' at point (`x', `y', `z'). If no match
      !! is found, `value' is returned empty. Return only the value at step `step'
      !! is `step' is positive. Return only values with `numComp' if `numComp' is
      !! positive. Return the gradient of the `values' if `gradient' is set. If
      !! `distanceMax' is zero, only return a result if an exact match inside an
      !! element in the view is found; if `distanceMax' is positive and an exact
      !! match is not found, return the value at the closest node if it is closer
      !! than `distanceMax'; if `distanceMax' is negative and an exact match is not
      !! found, always return the value at the closest node. The distance to the
      !! match is returned in `distance'. Return the result from the element
      !! described by its coordinates if `xElementCoord', `yElementCoord' and
      !! `zElementCoord' are provided. If `dim' is >= 0, return only matches from
      !! elements of the specified dimension.
      subroutine gmshViewProbe(tag, &
                               x, &
                               y, &
                               z, &
                               values, &
                               distance, &
                               step, &
                               numComp, &
                               gradient, &
                               distanceMax, &
                               xElemCoord, &
                               yElemCoord, &
                               zElemCoord, &
                               dim, &
                               ierr)
        interface
        subroutine C_API(tag, &
                         x, &
                         y, &
                         z, &
                         api_values_, &
                         api_values_n_, &
                         distance, &
                         step, &
                         numComp, &
                         gradient, &
                         distanceMax, &
                         api_xElemCoord_, &
                         api_xElemCoord_n_, &
                         api_yElemCoord_, &
                         api_yElemCoord_n_, &
                         api_zElemCoord_, &
                         api_zElemCoord_n_, &
                         dim, &
                         ierr_) &
          bind(C, name="gmshViewProbe")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          real(c_double), value, intent(in) :: x
          real(c_double), value, intent(in) :: y
          real(c_double), value, intent(in) :: z
          type(c_ptr), intent(out) :: api_values_
          integer(c_size_t) :: api_values_n_
          real(c_double) :: distance
          integer(c_int), value, intent(in) :: step
          integer(c_int), value, intent(in) :: numComp
          integer(c_int), value, intent(in) :: gradient
          real(c_double), value, intent(in) :: distanceMax
          real(c_double), dimension(*), optional :: api_xElemCoord_
          integer(c_size_t), value, intent(in) :: api_xElemCoord_n_
          real(c_double), dimension(*), optional :: api_yElemCoord_
          integer(c_size_t), value, intent(in) :: api_yElemCoord_n_
          real(c_double), dimension(*), optional :: api_zElemCoord_
          integer(c_size_t), value, intent(in) :: api_zElemCoord_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        real(c_double), intent(in) :: x
        real(c_double), intent(in) :: y
        real(c_double), intent(in) :: z
        real(c_double), dimension(:), allocatable, intent(out) :: values
        real(c_double) :: distance
        integer, intent(in), optional :: step
        integer, intent(in), optional :: numComp
        logical, intent(in), optional :: gradient
        real(c_double), intent(in), optional :: distanceMax
        real(c_double), dimension(:), intent(in), optional :: xElemCoord
        real(c_double), dimension(:), intent(in), optional :: yElemCoord
        real(c_double), dimension(:), intent(in), optional :: zElemCoord
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_values_
        integer(c_size_t) :: api_values_n_
        call C_API(tag=int(tag, c_int), &
             x=real(x, c_double), &
             y=real(y, c_double), &
             z=real(z, c_double), &
             api_values_=api_values_, &
             api_values_n_=api_values_n_, &
             distance=distance, &
             step=optval_c_int(-1, step), &
             numComp=optval_c_int(-1, numComp), &
             gradient=optval_c_bool(.false., gradient), &
             distanceMax=optval_c_double(0., distanceMax), &
             api_xElemCoord_=xElemCoord, &
             api_xElemCoord_n_=size_gmsh_double(xElemCoord), &
             api_yElemCoord_=yElemCoord, &
             api_yElemCoord_n_=size_gmsh_double(yElemCoord), &
             api_zElemCoord_=zElemCoord, &
             api_zElemCoord_n_=size_gmsh_double(zElemCoord), &
             dim=optval_c_int(-1, dim), &
             ierr_=ierr)
        values = ovectordouble_(api_values_, &
          api_values_n_)
      end subroutine gmshViewProbe
    
      !> Write the view to a file `fileName'. The export format is determined by the
      !! file extension. Append to the file if `append' is set.
      subroutine gmshViewWrite(tag, &
                               fileName, &
                               append, &
                               ierr)
        interface
        subroutine C_API(tag, &
                         fileName, &
                         append, &
                         ierr_) &
          bind(C, name="gmshViewWrite")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: fileName
          integer(c_int), value, intent(in) :: append
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: fileName
        logical, intent(in), optional :: append
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             fileName=istring_(fileName), &
             append=optval_c_bool(.false., append), &
             ierr_=ierr)
      end subroutine gmshViewWrite
    
      !> Set the global visibility of the view `tag' per window to `value', where
      !! `windowIndex' identifies the window in the window list.
      subroutine gmshViewSetVisibilityPerWindow(tag, &
                                                value, &
                                                windowIndex, &
                                                ierr)
        interface
        subroutine C_API(tag, &
                         value, &
                         windowIndex, &
                         ierr_) &
          bind(C, name="gmshViewSetVisibilityPerWindow")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          integer(c_int), value, intent(in) :: value
          integer(c_int), value, intent(in) :: windowIndex
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        integer, intent(in) :: value
        integer, intent(in), optional :: windowIndex
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             value=int(value, c_int), &
             windowIndex=optval_c_int(0, windowIndex), &
             ierr_=ierr)
      end subroutine gmshViewSetVisibilityPerWindow
    
      !> Set the numerical option `name' to value `value' for the view with tag
      !! `tag'.
      subroutine gmshViewOptionSetNumber(tag, &
                                         name, &
                                         value, &
                                         ierr)
        interface
        subroutine C_API(tag, &
                         name, &
                         value, &
                         ierr_) &
          bind(C, name="gmshViewOptionSetNumber")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          real(c_double), value, intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: name
        real(c_double), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             name=istring_(name), &
             value=real(value, c_double), &
             ierr_=ierr)
      end subroutine gmshViewOptionSetNumber
    
      !> Get the `value' of the numerical option `name' for the view with tag `tag'.
      subroutine gmshViewOptionGetNumber(tag, &
                                         name, &
                                         value, &
                                         ierr)
        interface
        subroutine C_API(tag, &
                         name, &
                         value, &
                         ierr_) &
          bind(C, name="gmshViewOptionGetNumber")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          real(c_double) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: name
        real(c_double) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             name=istring_(name), &
             value=value, &
             ierr_=ierr)
      end subroutine gmshViewOptionGetNumber
    
      !> Set the string option `name' to value `value' for the view with tag `tag'.
      subroutine gmshViewOptionSetString(tag, &
                                         name, &
                                         value, &
                                         ierr)
        interface
        subroutine C_API(tag, &
                         name, &
                         value, &
                         ierr_) &
          bind(C, name="gmshViewOptionSetString")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          character(len=1, kind=c_char), dimension(*), intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: name
        character(len=*), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             name=istring_(name), &
             value=istring_(value), &
             ierr_=ierr)
      end subroutine gmshViewOptionSetString
    
      !> Get the `value' of the string option `name' for the view with tag `tag'.
      subroutine gmshViewOptionGetString(tag, &
                                         name, &
                                         value, &
                                         ierr)
        interface
        subroutine C_API(tag, &
                         name, &
                         api_value_, &
                         ierr_) &
          bind(C, name="gmshViewOptionGetString")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), intent(out) :: api_value_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: name
        character(len=:), allocatable, intent(out) :: value
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_value_
        call C_API(tag=int(tag, c_int), &
             name=istring_(name), &
             api_value_=api_value_, &
             ierr_=ierr)
        value = ostring_(api_value_)
      end subroutine gmshViewOptionGetString
    
      !> Set the color option `name' to the RGBA value (`r', `g', `b', `a') for the
      !! view with tag `tag', where where `r', `g', `b' and `a' should be integers
      !! between 0 and 255.
      subroutine gmshViewOptionSetColor(tag, &
                                        name, &
                                        r, &
                                        g, &
                                        b, &
                                        a, &
                                        ierr)
        interface
        subroutine C_API(tag, &
                         name, &
                         r, &
                         g, &
                         b, &
                         a, &
                         ierr_) &
          bind(C, name="gmshViewOptionSetColor")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), value, intent(in) :: r
          integer(c_int), value, intent(in) :: g
          integer(c_int), value, intent(in) :: b
          integer(c_int), value, intent(in) :: a
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: name
        integer, intent(in) :: r
        integer, intent(in) :: g
        integer, intent(in) :: b
        integer, intent(in), optional :: a
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             name=istring_(name), &
             r=int(r, c_int), &
             g=int(g, c_int), &
             b=int(b, c_int), &
             a=optval_c_int(255, a), &
             ierr_=ierr)
      end subroutine gmshViewOptionSetColor
    
      !> Get the `r', `g', `b', `a' value of the color option `name' for the view
      !! with tag `tag'.
      subroutine gmshViewOptionGetColor(tag, &
                                        name, &
                                        r, &
                                        g, &
                                        b, &
                                        a, &
                                        ierr)
        interface
        subroutine C_API(tag, &
                         name, &
                         r, &
                         g, &
                         b, &
                         a, &
                         ierr_) &
          bind(C, name="gmshViewOptionGetColor")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: tag
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int) :: r
          integer(c_int) :: g
          integer(c_int) :: b
          integer(c_int) :: a
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: tag
        character(len=*), intent(in) :: name
        integer(c_int) :: r
        integer(c_int) :: g
        integer(c_int) :: b
        integer(c_int) :: a
        integer(c_int), intent(out), optional :: ierr
        call C_API(tag=int(tag, c_int), &
             name=istring_(name), &
             r=r, &
             g=g, &
             b=b, &
             a=a, &
             ierr_=ierr)
      end subroutine gmshViewOptionGetColor
    
      !> Copy the options from the view with tag `refTag' to the view with tag
      !! `tag'.
      subroutine gmshViewOptionCopy(refTag, &
                                    tag, &
                                    ierr)
        interface
        subroutine C_API(refTag, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshViewOptionCopy")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: refTag
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: refTag
        integer, intent(in) :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(refTag=int(refTag, c_int), &
             tag=int(tag, c_int), &
             ierr_=ierr)
      end subroutine gmshViewOptionCopy
    
      !> Set the numerical option `option' to the value `value' for plugin `name'.
      !! Plugins available in the official Gmsh release are listed in the "Gmsh
      !! plugins" chapter of the Gmsh reference manual
      !! (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-plugins).
      subroutine gmshPluginSetNumber(name, &
                                     option, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         option, &
                         value, &
                         ierr_) &
          bind(C, name="gmshPluginSetNumber")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          character(len=1, kind=c_char), dimension(*), intent(in) :: option
          real(c_double), value, intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=*), intent(in) :: option
        real(c_double), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             option=istring_(option), &
             value=real(value, c_double), &
             ierr_=ierr)
      end subroutine gmshPluginSetNumber
    
      !> Set the string option `option' to the value `value' for plugin `name'.
      !! Plugins available in the official Gmsh release are listed in the "Gmsh
      !! plugins" chapter of the Gmsh reference manual
      !! (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-plugins).
      subroutine gmshPluginSetString(name, &
                                     option, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         option, &
                         value, &
                         ierr_) &
          bind(C, name="gmshPluginSetString")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          character(len=1, kind=c_char), dimension(*), intent(in) :: option
          character(len=1, kind=c_char), dimension(*), intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=*), intent(in) :: option
        character(len=*), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             option=istring_(option), &
             value=istring_(value), &
             ierr_=ierr)
      end subroutine gmshPluginSetString
    
      !> Run the plugin `name'. Return the tag of the created view (if any). Plugins
      !! available in the official Gmsh release are listed in the "Gmsh plugins"
      !! chapter of the Gmsh reference manual
      !! (https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-plugins).
      function gmshPluginRun(name, &
                             ierr)
        interface
        function C_API(name, &
                       ierr_) &
          bind(C, name="gmshPluginRun")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshPluginRun
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        gmshPluginRun = C_API(name=istring_(name), &
                        ierr_=ierr)
      end function gmshPluginRun
    
      !> Draw all the OpenGL scenes.
      subroutine gmshGraphicsDraw(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshGraphicsDraw")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshGraphicsDraw
    
      !> Create the FLTK graphical user interface. Can only be called in the main
      !! thread.
      subroutine gmshFltkInitialize(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshFltkInitialize")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshFltkInitialize
    
      !> Close the FLTK graphical user interface. Can only be called in the main
      !! thread.
      subroutine gmshFltkFinalize(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshFltkFinalize")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshFltkFinalize
    
      !> Wait at most `time' seconds for user interface events and return. If `time'
      !! < 0, wait indefinitely. First automatically create the user interface if it
      !! has not yet been initialized. Can only be called in the main thread.
      subroutine gmshFltkWait(time, &
                              ierr)
        interface
        subroutine C_API(time, &
                         ierr_) &
          bind(C, name="gmshFltkWait")
          use, intrinsic :: iso_c_binding
          real(c_double), value, intent(in) :: time
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        real(c_double), intent(in), optional :: time
        integer(c_int), intent(out), optional :: ierr
        call C_API(time=optval_c_double(-1., time), &
             ierr_=ierr)
      end subroutine gmshFltkWait
    
      !> Update the user interface (potentially creating new widgets and windows).
      !! First automatically create the user interface if it has not yet been
      !! initialized. Can only be called in the main thread: use `awake("update")'
      !! to trigger an update of the user interface from another thread.
      subroutine gmshFltkUpdate(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshFltkUpdate")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshFltkUpdate
    
      !> Awake the main user interface thread and process pending events, and
      !! optionally perform an action (currently the only `action' allowed is
      !! "update").
      subroutine gmshFltkAwake(action, &
                               ierr)
        interface
        subroutine C_API(action, &
                         ierr_) &
          bind(C, name="gmshFltkAwake")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: action
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in), optional :: action
        integer(c_int), intent(out), optional :: ierr
        call C_API(action=istring_(optval_c_str("", action)), &
             ierr_=ierr)
      end subroutine gmshFltkAwake
    
      !> Block the current thread until it can safely modify the user interface.
      subroutine gmshFltkLock(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshFltkLock")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshFltkLock
    
      !> Release the lock that was set using lock.
      subroutine gmshFltkUnlock(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshFltkUnlock")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshFltkUnlock
    
      !> Run the event loop of the graphical user interface, i.e. repeatedly call
      !! `wait()'. First automatically create the user interface if it has not yet
      !! been initialized. Can only be called in the main thread.
      subroutine gmshFltkRun(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshFltkRun")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshFltkRun
    
      !> Check if the user interface is available (e.g. to detect if it has been
      !! closed).
      function gmshFltkIsAvailable(ierr)
        interface
        function C_API(ierr_) &
          bind(C, name="gmshFltkIsAvailable")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshFltkIsAvailable
        integer(c_int), intent(out), optional :: ierr
        gmshFltkIsAvailable = C_API(ierr_=ierr)
      end function gmshFltkIsAvailable
    
      !> Select entities in the user interface. Return the selected entities as a
      !! vector of (dim, tag) pairs. If `dim' is >= 0, return only the entities of
      !! the specified dimension (e.g. points if `dim' == 0).
      function gmshFltkSelectEntities(dimTags, &
                                      dim, &
                                      ierr)
        interface
        function C_API(api_dimTags_, &
                       api_dimTags_n_, &
                       dim, &
                       ierr_) &
          bind(C, name="gmshFltkSelectEntities")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          type(c_ptr), intent(out) :: api_dimTags_
          integer(c_size_t), intent(out) :: api_dimTags_n_
          integer(c_int), value, intent(in) :: dim
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshFltkSelectEntities
        integer(c_int), dimension(:,:), allocatable, intent(out) :: dimTags
        integer, intent(in), optional :: dim
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_dimTags_
        integer(c_size_t) :: api_dimTags_n_
        gmshFltkSelectEntities = C_API(api_dimTags_=api_dimTags_, &
                                 api_dimTags_n_=api_dimTags_n_, &
                                 dim=optval_c_int(-1, dim), &
                                 ierr_=ierr)
        dimTags = ovectorpair_(api_dimTags_, &
          api_dimTags_n_)
      end function gmshFltkSelectEntities
    
      !> Select elements in the user interface.
      function gmshFltkSelectElements(elementTags, &
                                      ierr)
        interface
        function C_API(api_elementTags_, &
                       api_elementTags_n_, &
                       ierr_) &
          bind(C, name="gmshFltkSelectElements")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          type(c_ptr), intent(out) :: api_elementTags_
          integer(c_size_t), intent(out) :: api_elementTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshFltkSelectElements
        integer(c_size_t), dimension(:), allocatable, intent(out) :: elementTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_elementTags_
        integer(c_size_t) :: api_elementTags_n_
        gmshFltkSelectElements = C_API(api_elementTags_=api_elementTags_, &
                                 api_elementTags_n_=api_elementTags_n_, &
                                 ierr_=ierr)
        elementTags = ovectorsize_(api_elementTags_, &
          api_elementTags_n_)
      end function gmshFltkSelectElements
    
      !> Select views in the user interface.
      function gmshFltkSelectViews(viewTags, &
                                   ierr)
        interface
        function C_API(api_viewTags_, &
                       api_viewTags_n_, &
                       ierr_) &
          bind(C, name="gmshFltkSelectViews")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          type(c_ptr), intent(out) :: api_viewTags_
          integer(c_size_t), intent(out) :: api_viewTags_n_
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshFltkSelectViews
        integer(c_int), dimension(:), allocatable, intent(out) :: viewTags
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_viewTags_
        integer(c_size_t) :: api_viewTags_n_
        gmshFltkSelectViews = C_API(api_viewTags_=api_viewTags_, &
                              api_viewTags_n_=api_viewTags_n_, &
                              ierr_=ierr)
        viewTags = ovectorint_(api_viewTags_, &
          api_viewTags_n_)
      end function gmshFltkSelectViews
    
      !> Split the current window horizontally (if `how' == "h") or vertically (if
      !! `how' == "v"), using ratio `ratio'. If `how' == "u", restore a single
      !! window.
      subroutine gmshFltkSplitCurrentWindow(how, &
                                            ratio, &
                                            ierr)
        interface
        subroutine C_API(how, &
                         ratio, &
                         ierr_) &
          bind(C, name="gmshFltkSplitCurrentWindow")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: how
          real(c_double), value, intent(in) :: ratio
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in), optional :: how
        real(c_double), intent(in), optional :: ratio
        integer(c_int), intent(out), optional :: ierr
        call C_API(how=istring_(optval_c_str("v", how)), &
             ratio=optval_c_double(0.5, ratio), &
             ierr_=ierr)
      end subroutine gmshFltkSplitCurrentWindow
    
      !> Set the current window by speficying its index (starting at 0) in the list
      !! of all windows. When new windows are created by splits, new windows are
      !! appended at the end of the list.
      subroutine gmshFltkSetCurrentWindow(windowIndex, &
                                          ierr)
        interface
        subroutine C_API(windowIndex, &
                         ierr_) &
          bind(C, name="gmshFltkSetCurrentWindow")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: windowIndex
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in), optional :: windowIndex
        integer(c_int), intent(out), optional :: ierr
        call C_API(windowIndex=optval_c_int(0, windowIndex), &
             ierr_=ierr)
      end subroutine gmshFltkSetCurrentWindow
    
      !> Set a status message in the current window. If `graphics' is set, display
      !! the message inside the graphic window instead of the status bar.
      subroutine gmshFltkSetStatusMessage(message, &
                                          graphics, &
                                          ierr)
        interface
        subroutine C_API(message, &
                         graphics, &
                         ierr_) &
          bind(C, name="gmshFltkSetStatusMessage")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: message
          integer(c_int), value, intent(in) :: graphics
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: message
        logical, intent(in), optional :: graphics
        integer(c_int), intent(out), optional :: ierr
        call C_API(message=istring_(message), &
             graphics=optval_c_bool(.false., graphics), &
             ierr_=ierr)
      end subroutine gmshFltkSetStatusMessage
    
      !> Show context window for the entity of dimension `dim' and tag `tag'.
      subroutine gmshFltkShowContextWindow(dim, &
                                           tag, &
                                           ierr)
        interface
        subroutine C_API(dim, &
                         tag, &
                         ierr_) &
          bind(C, name="gmshFltkShowContextWindow")
          use, intrinsic :: iso_c_binding
          integer(c_int), value, intent(in) :: dim
          integer(c_int), value, intent(in) :: tag
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer, intent(in) :: dim
        integer, intent(in) :: tag
        integer(c_int), intent(out), optional :: ierr
        call C_API(dim=int(dim, c_int), &
             tag=int(tag, c_int), &
             ierr_=ierr)
      end subroutine gmshFltkShowContextWindow
    
      !> Open the `name' item in the menu tree.
      subroutine gmshFltkOpenTreeItem(name, &
                                      ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshFltkOpenTreeItem")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshFltkOpenTreeItem
    
      !> Close the `name' item in the menu tree.
      subroutine gmshFltkCloseTreeItem(name, &
                                       ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshFltkCloseTreeItem")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             ierr_=ierr)
      end subroutine gmshFltkCloseTreeItem
    
      !> Get the names of the variables in the Gmsh parser matching the `search'
      !! regular expression. If `search' is empty, return all the names.
      subroutine gmshParserGetNames(names, &
                                    search, &
                                    ierr)
        interface
        subroutine C_API(api_names_, &
                         api_names_n_, &
                         search, &
                         ierr_) &
          bind(C, name="gmshParserGetNames")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_names_
          integer(c_size_t), intent(out) :: api_names_n_
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: search
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: names
        character(len=*), intent(in), optional :: search
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_names_
        integer(c_size_t) :: api_names_n_
        call C_API(api_names_=api_names_, &
             api_names_n_=api_names_n_, &
             search=istring_(optval_c_str("", search)), &
             ierr_=ierr)
        names = ovectorstring_(api_names_, &
          api_names_n_)
      end subroutine gmshParserGetNames
    
      !> Set the value of the number variable `name' in the Gmsh parser. Create the
      !! variable if it does not exist; update the value if the variable exists.
      subroutine gmshParserSetNumber(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         api_value_n_, &
                         ierr_) &
          bind(C, name="gmshParserSetNumber")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          real(c_double), dimension(*) :: api_value_
          integer(c_size_t), value, intent(in) :: api_value_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        real(c_double), dimension(:), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             api_value_=value, &
             api_value_n_=size_gmsh_double(value), &
             ierr_=ierr)
      end subroutine gmshParserSetNumber
    
      !> Set the value of the string variable `name' in the Gmsh parser. Create the
      !! variable if it does not exist; update the value if the variable exists.
      subroutine gmshParserSetString(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         api_value_n_, &
                         ierr_) &
          bind(C, name="gmshParserSetString")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), dimension(*) :: api_value_
          integer(c_size_t), value, intent(in) :: api_value_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=*), dimension(:), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        character(len=GMSH_API_MAX_STR_LEN, kind=c_char), allocatable :: api_value_strs(:)
        type(c_ptr), allocatable :: api_value_(:)
        call ivectorstring_(value, &
          api_value_strs, &
          api_value_)
        call C_API(name=istring_(name), &
             api_value_=api_value_, &
             api_value_n_=size_gmsh_str(value), &
             ierr_=ierr)
      end subroutine gmshParserSetString
    
      !> Get the value of the number variable `name' from the Gmsh parser. Return an
      !! empty vector if the variable does not exist.
      subroutine gmshParserGetNumber(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         api_value_n_, &
                         ierr_) &
          bind(C, name="gmshParserGetNumber")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), intent(out) :: api_value_
          integer(c_size_t) :: api_value_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        real(c_double), dimension(:), allocatable, intent(out) :: value
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_value_
        integer(c_size_t) :: api_value_n_
        call C_API(name=istring_(name), &
             api_value_=api_value_, &
             api_value_n_=api_value_n_, &
             ierr_=ierr)
        value = ovectordouble_(api_value_, &
          api_value_n_)
      end subroutine gmshParserGetNumber
    
      !> Get the value of the string variable `name' from the Gmsh parser. Return an
      !! empty vector if the variable does not exist.
      subroutine gmshParserGetString(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         api_value_n_, &
                         ierr_) &
          bind(C, name="gmshParserGetString")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), intent(out) :: api_value_
          integer(c_size_t), intent(out) :: api_value_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: value
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_value_
        integer(c_size_t) :: api_value_n_
        call C_API(name=istring_(name), &
             api_value_=api_value_, &
             api_value_n_=api_value_n_, &
             ierr_=ierr)
        value = ovectorstring_(api_value_, &
          api_value_n_)
      end subroutine gmshParserGetString
    
      !> Clear all the Gmsh parser variables, or remove a single variable if `name'
      !! is given.
      subroutine gmshParserClear(name, &
                                 ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshParserClear")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in), optional :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(optval_c_str("", name)), &
             ierr_=ierr)
      end subroutine gmshParserClear
    
      !> Parse the file `fileName' with the Gmsh parser.
      subroutine gmshParserParse(fileName, &
                                 ierr)
        interface
        subroutine C_API(fileName, &
                         ierr_) &
          bind(C, name="gmshParserParse")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: fileName
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: fileName
        integer(c_int), intent(out), optional :: ierr
        call C_API(fileName=istring_(fileName), &
             ierr_=ierr)
      end subroutine gmshParserParse
    
      !> Set one or more parameters in the ONELAB database, encoded in `format'.
      subroutine gmshOnelabSet(data, &
                               format, &
                               ierr)
        interface
        subroutine C_API(data, &
                         format, &
                         ierr_) &
          bind(C, name="gmshOnelabSet")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: data
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: format
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: data
        character(len=*), intent(in), optional :: format
        integer(c_int), intent(out), optional :: ierr
        call C_API(data=istring_(data), &
             format=istring_(optval_c_str("json", format)), &
             ierr_=ierr)
      end subroutine gmshOnelabSet
    
      !> Get all the parameters (or a single one if `name' is specified) from the
      !! ONELAB database, encoded in `format'.
      subroutine gmshOnelabGet(data, &
                               name, &
                               format, &
                               ierr)
        interface
        subroutine C_API(api_data_, &
                         name, &
                         format, &
                         ierr_) &
          bind(C, name="gmshOnelabGet")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_data_
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: name
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: format
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=:), allocatable, intent(out) :: data
        character(len=*), intent(in), optional :: name
        character(len=*), intent(in), optional :: format
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_data_
        call C_API(api_data_=api_data_, &
             name=istring_(optval_c_str("", name)), &
             format=istring_(optval_c_str("json", format)), &
             ierr_=ierr)
        data = ostring_(api_data_)
      end subroutine gmshOnelabGet
    
      !> Get the names of the parameters in the ONELAB database matching the
      !! `search' regular expression. If `search' is empty, return all the names.
      subroutine gmshOnelabGetNames(names, &
                                    search, &
                                    ierr)
        interface
        subroutine C_API(api_names_, &
                         api_names_n_, &
                         search, &
                         ierr_) &
          bind(C, name="gmshOnelabGetNames")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_names_
          integer(c_size_t), intent(out) :: api_names_n_
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: search
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: names
        character(len=*), intent(in), optional :: search
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_names_
        integer(c_size_t) :: api_names_n_
        call C_API(api_names_=api_names_, &
             api_names_n_=api_names_n_, &
             search=istring_(optval_c_str("", search)), &
             ierr_=ierr)
        names = ovectorstring_(api_names_, &
          api_names_n_)
      end subroutine gmshOnelabGetNames
    
      !> Set the value of the number parameter `name' in the ONELAB database. Create
      !! the parameter if it does not exist; update the value if the parameter
      !! exists.
      subroutine gmshOnelabSetNumber(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         api_value_n_, &
                         ierr_) &
          bind(C, name="gmshOnelabSetNumber")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          real(c_double), dimension(*) :: api_value_
          integer(c_size_t), value, intent(in) :: api_value_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        real(c_double), dimension(:), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             api_value_=value, &
             api_value_n_=size_gmsh_double(value), &
             ierr_=ierr)
      end subroutine gmshOnelabSetNumber
    
      !> Set the value of the string parameter `name' in the ONELAB database. Create
      !! the parameter if it does not exist; update the value if the parameter
      !! exists.
      subroutine gmshOnelabSetString(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         api_value_n_, &
                         ierr_) &
          bind(C, name="gmshOnelabSetString")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), dimension(*) :: api_value_
          integer(c_size_t), value, intent(in) :: api_value_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=*), dimension(:), intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        character(len=GMSH_API_MAX_STR_LEN, kind=c_char), allocatable :: api_value_strs(:)
        type(c_ptr), allocatable :: api_value_(:)
        call ivectorstring_(value, &
          api_value_strs, &
          api_value_)
        call C_API(name=istring_(name), &
             api_value_=api_value_, &
             api_value_n_=size_gmsh_str(value), &
             ierr_=ierr)
      end subroutine gmshOnelabSetString
    
      !> Get the value of the number parameter `name' from the ONELAB database.
      !! Return an empty vector if the parameter does not exist.
      subroutine gmshOnelabGetNumber(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         api_value_n_, &
                         ierr_) &
          bind(C, name="gmshOnelabGetNumber")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), intent(out) :: api_value_
          integer(c_size_t) :: api_value_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        real(c_double), dimension(:), allocatable, intent(out) :: value
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_value_
        integer(c_size_t) :: api_value_n_
        call C_API(name=istring_(name), &
             api_value_=api_value_, &
             api_value_n_=api_value_n_, &
             ierr_=ierr)
        value = ovectordouble_(api_value_, &
          api_value_n_)
      end subroutine gmshOnelabGetNumber
    
      !> Get the value of the string parameter `name' from the ONELAB database.
      !! Return an empty vector if the parameter does not exist.
      subroutine gmshOnelabGetString(name, &
                                     value, &
                                     ierr)
        interface
        subroutine C_API(name, &
                         api_value_, &
                         api_value_n_, &
                         ierr_) &
          bind(C, name="gmshOnelabGetString")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          type(c_ptr), intent(out) :: api_value_
          integer(c_size_t), intent(out) :: api_value_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: value
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_value_
        integer(c_size_t) :: api_value_n_
        call C_API(name=istring_(name), &
             api_value_=api_value_, &
             api_value_n_=api_value_n_, &
             ierr_=ierr)
        value = ovectorstring_(api_value_, &
          api_value_n_)
      end subroutine gmshOnelabGetString
    
      !> Check if any parameters in the ONELAB database used by the client `name'
      !! have been changed.
      function gmshOnelabGetChanged(name, &
                                    ierr)
        interface
        function C_API(name, &
                       ierr_) &
          bind(C, name="gmshOnelabGetChanged")
          use, intrinsic :: iso_c_binding
          integer(c_int) :: C_API
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        integer(c_int) :: gmshOnelabGetChanged
        character(len=*), intent(in) :: name
        integer(c_int), intent(out), optional :: ierr
        gmshOnelabGetChanged = C_API(name=istring_(name), &
                               ierr_=ierr)
      end function gmshOnelabGetChanged
    
      !> Set the changed flag to value `value' for all the parameters in the ONELAB
      !! database used by the client `name'.
      subroutine gmshOnelabSetChanged(name, &
                                      value, &
                                      ierr)
        interface
        subroutine C_API(name, &
                         value, &
                         ierr_) &
          bind(C, name="gmshOnelabSetChanged")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: name
          integer(c_int), value, intent(in) :: value
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: name
        integer, intent(in) :: value
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(name), &
             value=int(value, c_int), &
             ierr_=ierr)
      end subroutine gmshOnelabSetChanged
    
      !> Clear the ONELAB database, or remove a single parameter if `name' is given.
      subroutine gmshOnelabClear(name, &
                                 ierr)
        interface
        subroutine C_API(name, &
                         ierr_) &
          bind(C, name="gmshOnelabClear")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: name
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in), optional :: name
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(optval_c_str("", name)), &
             ierr_=ierr)
      end subroutine gmshOnelabClear
    
      !> Run a ONELAB client. If `name' is provided, create a new ONELAB client with
      !! name `name' and executes `command'. If not, try to run a client that might
      !! be linked to the processed input files.
      subroutine gmshOnelabRun(name, &
                               command, &
                               ierr)
        interface
        subroutine C_API(name, &
                         command, &
                         ierr_) &
          bind(C, name="gmshOnelabRun")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: name
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: command
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in), optional :: name
        character(len=*), intent(in), optional :: command
        integer(c_int), intent(out), optional :: ierr
        call C_API(name=istring_(optval_c_str("", name)), &
             command=istring_(optval_c_str("", command)), &
             ierr_=ierr)
      end subroutine gmshOnelabRun
    
      !> Write a `message'. `level' can be "info", "warning" or "error".
      subroutine gmshLoggerWrite(message, &
                                 level, &
                                 ierr)
        interface
        subroutine C_API(message, &
                         level, &
                         ierr_) &
          bind(C, name="gmshLoggerWrite")
          use, intrinsic :: iso_c_binding
          character(len=1, kind=c_char), dimension(*), intent(in) :: message
          character(len=1, kind=c_char), dimension(*), intent(in), optional :: level
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=*), intent(in) :: message
        character(len=*), intent(in), optional :: level
        integer(c_int), intent(out), optional :: ierr
        call C_API(message=istring_(message), &
             level=istring_(optval_c_str("info", level)), &
             ierr_=ierr)
      end subroutine gmshLoggerWrite
    
      !> Start logging messages.
      subroutine gmshLoggerStart(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshLoggerStart")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshLoggerStart
    
      !> Get logged messages.
      subroutine gmshLoggerGet(log, &
                               ierr)
        interface
        subroutine C_API(api_log_, &
                         api_log_n_, &
                         ierr_) &
          bind(C, name="gmshLoggerGet")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_log_
          integer(c_size_t), intent(out) :: api_log_n_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=GMSH_API_MAX_STR_LEN), dimension(:), allocatable, intent(out) :: log
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_log_
        integer(c_size_t) :: api_log_n_
        call C_API(api_log_=api_log_, &
             api_log_n_=api_log_n_, &
             ierr_=ierr)
        log = ovectorstring_(api_log_, &
          api_log_n_)
      end subroutine gmshLoggerGet
    
      !> Stop logging messages.
      subroutine gmshLoggerStop(ierr)
        interface
        subroutine C_API(ierr_) &
          bind(C, name="gmshLoggerStop")
          use, intrinsic :: iso_c_binding
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        integer(c_int), intent(out), optional :: ierr
        call C_API(ierr_=ierr)
      end subroutine gmshLoggerStop
    
      !> Return wall clock time (in s).
      function gmshLoggerGetWallTime(ierr)
        interface
        function C_API(ierr_) &
          bind(C, name="gmshLoggerGetWallTime")
          use, intrinsic :: iso_c_binding
          real(c_double) :: C_API
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        real(c_double) :: gmshLoggerGetWallTime
        integer(c_int), intent(out), optional :: ierr
        gmshLoggerGetWallTime = C_API(ierr_=ierr)
      end function gmshLoggerGetWallTime
    
      !> Return CPU time (in s).
      function gmshLoggerGetCpuTime(ierr)
        interface
        function C_API(ierr_) &
          bind(C, name="gmshLoggerGetCpuTime")
          use, intrinsic :: iso_c_binding
          real(c_double) :: C_API
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        real(c_double) :: gmshLoggerGetCpuTime
        integer(c_int), intent(out), optional :: ierr
        gmshLoggerGetCpuTime = C_API(ierr_=ierr)
      end function gmshLoggerGetCpuTime
    
      !> Return memory usage (in Mb).
      function gmshLoggerGetMemory(ierr)
        interface
        function C_API(ierr_) &
          bind(C, name="gmshLoggerGetMemory")
          use, intrinsic :: iso_c_binding
          real(c_double) :: C_API
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        real(c_double) :: gmshLoggerGetMemory
        integer(c_int), intent(out), optional :: ierr
        gmshLoggerGetMemory = C_API(ierr_=ierr)
      end function gmshLoggerGetMemory
    
      !> Return total available memory (in Mb).
      function gmshLoggerGetTotalMemory(ierr)
        interface
        function C_API(ierr_) &
          bind(C, name="gmshLoggerGetTotalMemory")
          use, intrinsic :: iso_c_binding
          real(c_double) :: C_API
          integer(c_int), intent(out), optional :: ierr_
        end function C_API
        end interface
        real(c_double) :: gmshLoggerGetTotalMemory
        integer(c_int), intent(out), optional :: ierr
        gmshLoggerGetTotalMemory = C_API(ierr_=ierr)
      end function gmshLoggerGetTotalMemory
    
      !> Return last error message, if any.
      subroutine gmshLoggerGetLastError(error, &
                                        ierr)
        interface
        subroutine C_API(api_error_, &
                         ierr_) &
          bind(C, name="gmshLoggerGetLastError")
          use, intrinsic :: iso_c_binding
          type(c_ptr), intent(out) :: api_error_
          integer(c_int), intent(out), optional :: ierr_
        end subroutine C_API
        end interface
        character(len=:), allocatable, intent(out) :: error
        integer(c_int), intent(out), optional :: ierr
        type(c_ptr) :: api_error_
        call C_API(api_error_=api_error_, &
             ierr_=ierr)
        error = ostring_(api_error_)
      end subroutine gmshLoggerGetLastError
    
      ! ----------------------------------------------------------------------------
      ! GMSH size function
      ! ----------------------------------------------------------------------------
    
      pure integer(c_int) function optval_c_int_1(def, val) result(res)
        integer(c_int), intent(in) :: def
        integer(c_int), optional, intent(in) :: val
        res = int(def, kind=c_int)
        if (present(val)) res = int(val, kind=c_int)
      end function optval_c_int_1
    
      pure integer(c_size_t) function optval_c_size_t_1(def, val) result(res)
        integer, intent(in) :: def
        integer, optional, intent(in) :: val
        res = int(def, kind=c_size_t)
        if (present(val)) res = int(val, kind=c_size_t)
      end function optval_c_size_t_1
    
      pure integer(c_size_t) function optval_c_size_t_2(def, val) result(res)
        integer(c_size_t), intent(in) :: def
        integer(c_size_t), optional, intent(in) :: val
        res = int(def, kind=c_size_t)
        if (present(val)) res = int(val, kind=c_size_t)
      end function optval_c_size_t_2
    
      pure real(c_double) function optval_c_double_1(def, val) result(res)
        real(c_double), intent(in) :: def
        real(c_double), optional, intent(in) :: val
        res = real(def, kind=c_double)
        if (present(val)) res = real(val, kind=c_double)
      end function optval_c_double_1
    
      pure real(c_double) function optval_c_double_2(def, val) result(res)
        real, intent(in) :: def
        real(c_double), optional, intent(in) :: val
        res = real(def, kind=c_double)
        if (present(val)) res = real(val, kind=c_double)
      end function optval_c_double_2
    
      pure integer(c_int) function optval_c_bool(def, val) result(res)
        logical, intent(in) :: def
        logical, optional, intent(in) :: val
        res = merge(1_c_int, 0_c_int, def)
        if (present(val)) res = merge(1_c_int, 0_c_int, val)
      end function optval_c_bool
    
      pure function optval_c_str(def, val) result(res)
        character(len=*), intent(in) :: def
        character(len=*), optional, intent(in) :: val
        character(len=:), allocatable :: res
        if (present(val)) then
          res = val
        else
          res = def
        end if
      end function optval_c_str
    
      pure function optval_str_array(def, val) result(res)
        character(len=*), intent(in) :: def(:)
        character(len=*), optional, intent(in) :: val(:)
        character(len=:), allocatable :: res(:)
        if (present(val)) then
          res = val
        else
          res = def
        end if
      end function optval_str_array
    
      ! ----------------------------------------------------------------------------
      ! GMSH size functions, with handling of optional arguments
      ! ----------------------------------------------------------------------------
    
      pure integer(c_size_t) function size_gmsh_int(v) result(n)
        integer(c_int), optional, intent(in) :: v(:)
        n = 0
        if (present(v)) n = size(v, kind=c_size_t)
      end function size_gmsh_int
    
      pure integer(c_size_t) function size_gmsh_size(v) result(n)
        integer(c_size_t), optional, intent(in) :: v(:)
        n = 0
        if (present(v)) n = size(v, kind=c_size_t)
      end function size_gmsh_size
    
      pure integer(c_size_t) function size_gmsh_double(v) result(n)
        real(c_double), optional, intent(in) :: v(:)
        n = 0
        if (present(v)) n = size(v, kind=c_size_t)
      end function size_gmsh_double
    
      pure integer(c_size_t) function size_gmsh_str(v) result(n)
        character(len=*), optional, intent(in) :: v(:)
        n = 0
        if (present(v)) n = size(v, kind=c_size_t)
      end function size_gmsh_str
    
      pure integer(c_size_t) function size_gmsh_pair(v) result(n)
        integer(c_int), optional, intent(in) :: v(:,:)
        n = 0
        if (present(v)) n = size(v, kind=c_size_t)
      end function size_gmsh_pair
    
      pure integer(c_int) function size_gmsh_str_array(v) result(n)
        character(len=*), optional, intent(in) :: v(:)
        n = 1   ! can't have 0-length commands
        if (present(v)) n = size(v, kind=c_int)
      end function size_gmsh_str_array
    
      ! ----------------------------------------------------------------------------
      ! GMSH C memory management tools
      ! ----------------------------------------------------------------------------
    
      !> Callback to C to free any reserved memory
      subroutine gmshFree(p)
        interface
          subroutine C_API(ptr) bind(C, name="gmshFree")
            use, intrinsic :: iso_c_binding
            type(c_ptr), value :: ptr
          end subroutine C_API
        end interface
        type(c_ptr) :: p
        call C_API(p)
      end subroutine gmshFree
    
      ! ----------------------------------------------------------------------------
      ! Input routines from Fortran to C
      ! ----------------------------------------------------------------------------
    
      function istring_(o) result(v)
        character(len=*), intent(in) :: o
        character(len=:, kind=c_char), allocatable :: v
        v = trim(o)//c_null_char
      end function istring_
    
      function ivectorint_(o) result(v)
        integer(c_int), intent(in) :: o(:)
        integer(c_int), dimension(size(o)) :: v
        v = o
      end function ivectorint_
    
      function ivectorsize_(o) result(v)
        integer(c_size_t), intent(in) :: o(:)
        integer(c_size_t), dimension(size(o)) :: v
        v = o
      end function ivectorsize_
    
      function ivectordouble_(o) result(v)
        real(c_double), intent(in) :: o(:)
        real(c_double), dimension(size(o)) :: v
        v = o
      end function ivectordouble_
    
      subroutine ivectorstring_(o, cstrs, cptrs)
        character(len=*), intent(in) :: o(:)
        character(len=GMSH_API_MAX_STR_LEN, kind=c_char), target, allocatable, intent(out) :: cstrs(:)
        type(c_ptr), allocatable, intent(out) :: cptrs(:)
        integer :: i
        allocate(cstrs(size(o)))    ! Return to keep references from cptrs
        allocate(cptrs(size(o)))
        do i = 1, size(o)
            cstrs(i) = istring_(o(i))
            cptrs(i) = c_loc(cstrs(i))
        end do
      end subroutine ivectorstring_
    
      function ivectorpair_(o) result(v)
        integer(c_int), intent(in) :: o(:,:)
        integer(c_int), dimension(size(o,1),2) :: v
        v = o
      end function ivectorpair_
    
      subroutine ivectorvectorint_(v, dims, cptr1, cptr2, n)
        integer(c_int), target, intent(in) :: v(:)
        integer(c_size_t), target, intent(in) :: dims(:)
        type(c_ptr), intent(out) :: cptr1, cptr2
        integer(c_size_t), intent(out) :: n
    
        n = size(dims, kind=c_size_t)
        cptr1 = c_loc(v)
        cptr2 = c_loc(dims)
      end subroutine ivectorvectorint_
    
      subroutine ivectorvectorsize_(v, dims, cptr1, cptr2, n)
        integer(c_size_t), target, intent(in) :: v(:)
        integer(c_size_t), target, intent(in) :: dims(:)
        type(c_ptr), intent(out) :: cptr1, cptr2
        integer(c_size_t), intent(out) :: n
    
        n = size(dims, kind=c_size_t)
        cptr1 = c_loc(v)
        cptr2 = c_loc(dims)
      end subroutine ivectorvectorsize_
    
      subroutine ivectorvectordouble_(v, dims, cptr1, cptr2, n)
        real(c_double), target, intent(in) :: v(:)
        integer(c_size_t), target, intent(in) :: dims(:)
        type(c_ptr), intent(out) :: cptr1, cptr2
        integer(c_size_t), intent(out) :: n
    
        n = size(dims, kind=c_size_t)
        cptr1 = c_loc(v)
        cptr2 = c_loc(dims)
      end subroutine ivectorvectordouble_
    
      ! subroutine ivectorvectorpair_(v, dims, cptr1, cptr2, n)
      !   integer(c_int), target, intent(in) :: v(:,:)
      !   integer(c_size_t), target, intent(in) :: dims(:)
      !   type(c_ptr), intent(out) :: cptr1, cptr2
      !   integer(c_size_t), intent(out) :: n
      !
      !   n = size(dims, kind=c_size_t)
      !   cptr1 = c_loc(v)
      !   cptr2 = c_loc(dims)
      ! end subroutine ivectorvectorpair_
    
    
      ! ----------------------------------------------------------------------------
      ! Output routines from C to Fortran
      ! ----------------------------------------------------------------------------
    
    
      function ostring_(cptr) result(v)
        type(c_ptr), intent(inout) :: cptr
        character(len=:), allocatable :: v
        character(len=GMSH_API_MAX_STR_LEN), pointer :: fptr
        integer(c_size_t) :: i
        call c_f_pointer(cptr, fptr)
        do i = 1_c_size_t, GMSH_API_MAX_STR_LEN
          if (fptr(i:i) == c_null_char) exit
        end do
        v = fptr(:i)
        call gmshFree(cptr)
      end function ostring_
    
      function ovectorint_(cptr, n) result(v)
        type(c_ptr), intent(inout) :: cptr
        integer(c_size_t), intent(in) :: n
        integer(c_int), allocatable :: v(:)
        integer(c_int), pointer :: v_(:)
        call c_f_pointer(cptr, v_, [n])
        allocate(v, source=v_)
        call gmshFree(cptr)
      end function ovectorint_
    
      function ovectorsize_(cptr, n) result(v)
        type(c_ptr), intent(inout) :: cptr
        integer(c_size_t), intent(in) :: n
        integer(c_size_t), allocatable :: v(:)
        integer(c_size_t), pointer :: v_(:)
        call c_f_pointer(cptr, v_, [n])
        allocate(v, source=v_)
        call gmshFree(cptr)
      end function ovectorsize_
    
      function ovectordouble_(cptr, n) result(v)
        type(c_ptr), intent(inout) :: cptr
        integer(c_size_t), intent(in) :: n
        real(c_double), allocatable :: v(:)
        real(c_double), pointer :: v_(:)
        call c_f_pointer(cptr, v_, [n])
        allocate(v, source=v_)
        call gmshFree(cptr)
      end function ovectordouble_
    
      function ovectorstring_(cptr, n) result(v)
        type(c_ptr), intent(inout) :: cptr
        integer(c_size_t), intent(in) :: n
        character(len=GMSH_API_MAX_STR_LEN), allocatable :: v(:)
    
        integer(c_size_t) :: i
        type(c_array_t), pointer :: c_array(:)
        character(len=GMSH_API_MAX_STR_LEN), pointer :: fptr
    
        call c_f_pointer(cptr, c_array, [n])
        allocate(v(n))
        do i = 1_c_size_t, n
          v(i) = ostring_(c_array(i)%s)
        end do
        call gmshFree(cptr)
      end function ovectorstring_
    
      function ovectorpair_(cptr, n) result(v)
        type(c_ptr), intent(inout) :: cptr
        integer(c_size_t), intent(in) :: n
        integer(c_int), allocatable :: v(:,:)
        integer(c_int), pointer :: v_(:,:)
        call c_f_pointer(cptr, v_, [2_c_size_t, n / 2_c_size_t])
        allocate(v, source=v_)
        call gmshFree(cptr)
      end function ovectorpair_
    
      subroutine ovectorvectorint_(cptr1, cptr2, n, v, dims)
        type(c_ptr), intent(inout) :: cptr1, cptr2
        integer(c_size_t), intent(in) :: n
        integer(c_int), allocatable, intent(out) :: v(:)
        integer(c_size_t), allocatable, intent(out) :: dims(:)
        integer(c_int), pointer :: v_(:)
        integer(c_size_t), pointer :: dims_(:)
        type(c_ptr), pointer :: ptrs(:)
        integer(c_size_t) :: i, istart, iend
        call c_f_pointer(cptr2, dims_, [n])
        allocate(dims, source=dims_)
        allocate(v(sum(dims_)))
        istart = 1
        call c_f_pointer(cptr1, ptrs, [n])
        do i = 1_c_size_t, n
            iend = int(dims(i))
            call c_f_pointer(ptrs(i), v_, [iend])
            v(istart:istart + iend - 1) = v_
            istart = istart + iend
        end do
        do i = 1_c_size_t, n
            call gmshFree(ptrs(i))
        end do
        call gmshFree(cptr1)
        call gmshFree(cptr2)
      end subroutine ovectorvectorint_
    
      subroutine ovectorvectorsize_(cptr1, cptr2, n, v, dims)
        type(c_ptr), intent(inout) :: cptr1, cptr2
        integer(c_size_t), intent(in) :: n
        integer(c_size_t), allocatable, intent(out) :: v(:)
        integer(c_size_t), allocatable, intent(out) :: dims(:)
        integer(c_size_t), pointer :: v_(:)
        integer(c_size_t), pointer :: dims_(:)
        type(c_ptr), pointer :: ptrs(:)
        integer(c_size_t) :: i, istart, iend
        call c_f_pointer(cptr2, dims_, [n])
        allocate(dims, source=dims_)
        allocate(v(sum(dims_)))
        istart = 1
        call c_f_pointer(cptr1, ptrs, [n])
        do i = 1_c_size_t, n
            iend = int(dims(i))
            call c_f_pointer(ptrs(i), v_, [iend])
            v(istart:istart + iend - 1) = v_
            istart = istart + iend
        end do
        do i = 1_c_size_t, n
            call gmshFree(ptrs(i))
        end do
        call gmshFree(cptr1)
        call gmshFree(cptr2)
      end subroutine ovectorvectorsize_
    
      subroutine ovectorvectordouble_(cptr1, cptr2, n, v, dims)
        type(c_ptr), intent(inout) :: cptr1, cptr2
        integer(c_size_t), intent(in) :: n
        real(c_double), allocatable, intent(out) :: v(:)
        integer(c_size_t), allocatable, intent(out) :: dims(:)
        real(c_double), pointer :: v_(:)
        integer(c_size_t), pointer :: dims_(:)
        type(c_ptr), pointer :: ptrs(:)
        integer(c_size_t) :: i, istart, iend
        call c_f_pointer(cptr2, dims_, [n])
        allocate(dims, source=dims_)
        allocate(v(sum(dims_)))
        istart = 1
        call c_f_pointer(cptr1, ptrs, [n])
        do i = 1_c_size_t, n
            iend = int(dims(i))
            call c_f_pointer(ptrs(i), v_, [iend])
            v(istart:istart + iend - 1) = v_
            istart = istart + iend
        end do
        do i = 1_c_size_t, n
            call gmshFree(ptrs(i))
        end do
        call gmshFree(cptr1)
        call gmshFree(cptr2)
      end subroutine ovectorvectordouble_
    
      subroutine ovectorvectorpair_(cptr1, cptr2, n, v, dims)
        type(c_ptr), intent(inout) :: cptr1, cptr2
        integer(c_size_t), intent(in) :: n
        integer(c_int), allocatable, intent(out) :: v(:,:)
        integer(c_size_t), allocatable, intent(out) :: dims(:)
        integer(c_int), pointer :: v_(:,:)
        integer(c_size_t), pointer :: dims_(:)
        type(c_ptr), pointer :: ptrs(:)
        integer(c_size_t) :: i, istart, iend
        call c_f_pointer(cptr2, dims_, [n])
        allocate(dims, source=dims_)
        allocate(v(2, int(sum(dims_)/2)))
        istart = 1
        call c_f_pointer(cptr1, ptrs, [n])
        do i = 1_c_size_t, n
            iend = int(dims(i)/2)
            call c_f_pointer(ptrs(i), v_, [2_c_size_t, iend])
            v(:,istart:istart + iend - 1) = v_
            istart = istart + iend
        end do
        do i = 1_c_size_t, n
            call gmshFree(ptrs(i))
        end do
        call gmshFree(cptr1)
        call gmshFree(cptr2)
      end subroutine ovectorvectorpair_
    
    end module gmsh