/// <summary>
                /// Extrude the model entities `dimTags' by 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'.
                /// </summary>
                /// <param name="dimTags"></param>
                /// <param name="x"></param>
                /// <param name="y"></param>
                /// <param name="z"></param>
                /// <param name="dx"></param>
                /// <param name="dy"></param>
                /// <param name="dz"></param>
                /// <param name="ax"></param>
                /// <param name="ay"></param>
                /// <param name="az"></param>
                /// <param name="angle"></param>
                /// <param name="outDimTags"></param>
                /// <param name="numElements"> If `numElements' is not empty, also extrude the mesh: the entries in `numElements' give the number of elements in each layer. </param>
                /// <param name="heights"> If `height' is not empty, it provides the (cumulative) height of the different layers, normalized to 1. </param>
                /// <param name="recombine"></param>
                public static void Twist(Tuple <int, int>[] dimTags, double x, double y, double z, double dx, double dy, double dz, double ax, double ay, double az, double angle, out Tuple <int, int>[] outDimTags, int[] numElements = default, double[] heights = default, bool recombine = false)
                {
                    IntPtr out_DimTags;
                    long   outDimTags_n;
                    var    arr = IHelpers.FlattenIntTupleArray(dimTags);

                    if (numElements == default)
                    {
                        numElements = new int[0];
                    }
                    if (heights == default)
                    {
                        heights = new double[0];
                    }

                    IWrap.GmshModelGeoTwist(arr, arr.LongLength, x, y, z, dx, dy, dz, ax, ay, az, angle, out out_DimTags, out outDimTags_n, numElements, numElements.LongLength, heights, heights.LongLength, Convert.ToInt32(recombine), ref _ierr);

                    outDimTags = new Tuple <int, int> [0];
                    if (outDimTags_n > 0)
                    {
                        var temp = new int[outDimTags_n];
                        Marshal.Copy(out_DimTags, temp, 0, (int)outDimTags_n);
                        outDimTags = IHelpers.GraftIntTupleArray(temp);
                    }

                    IWrap.GmshFree(out_DimTags);
                }
            /// <summary>
            /// Select entities in the user interface. If `dim' is >= 0, return only the entities of the specified dimension(e.g.points if `dim' == 0).
            /// </summary>
            /// <returns></returns>
            public static int FltkSelectEntities(out Tuple <int, int>[] dimTags, int dim)
            {
                IntPtr dtP;
                long   dimTags_n;
                int    val = IWrap.GmshFltkSelectEntities(out dtP, out dimTags_n, dim, ref _ierr);

                var temp = new int[dimTags_n];

                Marshal.Copy(dtP, temp, 0, (int)dimTags_n);

                dimTags = IHelpers.GraftIntTupleArray(temp);

                Free(dtP);

                return(val);
            }
            /// <summary>
            /// 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) integer pairs.
            /// </summary>
            /// <param name="dim"></param>
            /// <param name="dimTags"></param>
            public static void GetPhysicalGroups(int dim, out Tuple <int, int>[] dimTags)
            {
                IntPtr dtP;
                long   dimTags_n;

                IWrap.GmshModelGetPhysicalGroups(out dtP, out dimTags_n, dim, ref _ierr);

                dimTags = new Tuple <int, int> [0];
                if (dimTags_n > 0)
                {
                    var temp = new int[dimTags_n];
                    ; Marshal.Copy(dtP, temp, 0, (int)dimTags_n);
                    dimTags = IHelpers.GraftIntTupleArray(temp);
                }

                Free(dtP);
            }
                /// <summary>
                /// Copy the entities `dimTags'; the new entities are returned in `outDimTags'.
                /// </summary>
                /// <param name="dimTags"></param>
                /// <param name="outDimTags"></param>
                public static void Copy(Tuple <int, int>[] dimTags, out Tuple <int, int>[] outDimTags)
                {
                    IntPtr dimTags_parse;
                    long   outDimTags_n;
                    var    tagsArr = IHelpers.FlattenIntTupleArray(dimTags);

                    IWrap.GmshModelGeoCopy(tagsArr, tagsArr.LongLength, out dimTags_parse, out outDimTags_n, ref _ierr);

                    outDimTags = new Tuple <int, int> [0];
                    if (outDimTags_n > 0)
                    {
                        var temp = new int[outDimTags_n];
                        Marshal.Copy(dimTags_parse, temp, 0, (int)outDimTags_n);
                        outDimTags = IHelpers.GraftIntTupleArray(temp);
                    }

                    Free(dimTags_parse);
                }
            /// <summary>
            /// 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).
            /// </summary>
            public static void GetEntitiesInBoundingBox(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, out Tuple <int, int>[] tags, int dim = 0)
            {
                IntPtr tP;
                long   tags_n;

                IWrap.GmshModelGetEntitiesInBoundingBox(xmin, ymin, zmin, xmax, ymax, zmax, out tP, out tags_n, dim, ref _ierr);

                tags = new Tuple <int, int> [0];
                if (tags_n > 0)
                {
                    var temp = new int[tags_n];
                    Marshal.Copy(tP, temp, 0, (int)tags_n);

                    tags = IHelpers.GraftIntTupleArray(temp);
                }

                Free(tP);
            }
            /// <summary>
            /// Get the boundary of the model entities `dimTags'. 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.
            /// </summary>
            public static void GetBoundary(Tuple <int, int>[] dimTags, out Tuple <int, int>[] outDimTags, bool combined = false, bool oriented = false, bool recursive = false)
            {
                int[]  dimTags_flatten = IHelpers.FlattenIntTupleArray(dimTags);
                IntPtr outDimTags_parse;
                long   outDimTags_n;

                IWrap.GmshModelGetBoundary(dimTags_flatten, dimTags_flatten.LongLength, out outDimTags_parse, out outDimTags_n, Convert.ToInt32(combined), Convert.ToInt32(oriented), Convert.ToInt32(recursive), ref _ierr);

                outDimTags = new Tuple <int, int> [0];
                if (outDimTags_n > 0)
                {
                    var temp = new int[outDimTags_n];
                    Marshal.Copy(outDimTags_parse, temp, 0, (int)outDimTags_n);

                    outDimTags = IHelpers.GraftIntTupleArray(temp);
                }

                IWrap.GmshFree(outDimTags_parse);
            }
            /// <summary>
            /// Get all the entities in the current model. 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) integer pairs.
            /// </summary>
            /// <param name="dimTags"></param>
            /// <param name="dim"></param>
            public static void GetEntities(out Tuple <int, int>[] dimTags, int dim = -1)
            {
                IntPtr dimTags_parse;
                long   dimTags_n;

                IWrap.GmshModelGetEntities(out dimTags_parse, out dimTags_n, dim, ref _ierr);

                dimTags = null;

                // Tags
                if (dimTags_n > 0)
                {
                    var temp = new int[dimTags_n];
                    Marshal.Copy(dimTags_parse, temp, 0, (int)dimTags_n);

                    dimTags = IHelpers.GraftIntTupleArray(temp);
                }

                // Delete unmanaged allocated memory
                IWrap.GmshFree(dimTags_parse);
            }