Beispiel #1
0
        /// <summary>
        /// Convert <see cref="MeshUnit"/> into an EUM unit integer
        /// </summary>
        public static int ToEum(this MeshUnit meshUnit)
        {
            switch (meshUnit)
            {
            case MeshUnit.Meter: return(1000);

            case MeshUnit.Millimeter: return(1002);

            case MeshUnit.Centimeter: return(1007);

            case MeshUnit.Kilometer: return(1001);

            case MeshUnit.Inch: return(1004);

            case MeshUnit.InchUS: return(1013);

            case MeshUnit.Feet: return(1003);

            case MeshUnit.FeetUS: return(1014);

            case MeshUnit.Yard: return(1006);

            case MeshUnit.YardUS: return(1015);

            case MeshUnit.Mile: return(1005);

            case MeshUnit.MileUS: return(1016);

            default:
                throw new ArgumentOutOfRangeException(nameof(meshUnit), meshUnit, null);
            }
        }
Beispiel #2
0
 public MeshDataBase(IList <MeshNode> nodes, IList <MeshElement> elements, string projection, MeshUnit zUnit)
 {
     Nodes      = nodes;
     Elements   = elements;
     Projection = projection;
     ZUnit      = zUnit;
 }
Beispiel #3
0
        /// <summary>
        /// Create mesh from arrays.
        /// <para>
        /// Note that the <paramref name="connectivity"/> array is using zero-based indices
        /// (as compared to the <see cref="MeshFile.ElementTable"/>, which is using one-based indices)
        /// </para>
        /// </summary>
        public MeshDataBase(string projection, int[] nodeIds, double[] x, double[] y, double[] z, int[] code, int[] elementIds, int[] elementTypes, int[][] connectivity, MeshUnit zUnit = MeshUnit.Meter)
        {
            Projection = projection;
            ZUnit      = zUnit;
            Nodes      = new List <MeshNode>(nodeIds.Length);
            Elements   = new List <MeshElement>(elementIds.Length);

            for (int i = 0; i < nodeIds.Length; i++)
            {
                var node = new MeshNode()
                {
                    Index = i,
                    Id    = nodeIds[i],
                    X     = x[i],
                    Y     = y[i],
                    Z     = z[i],
                    Code  = code[i],
                };
                Nodes.Add(node);
            }

            for (int ielmt = 0; ielmt < elementIds.Length; ielmt++)
            {
                int[] nodeInElmt     = connectivity[ielmt];
                int   numNodesInElmt = nodeInElmt.Length;

                var element = new MeshElement()
                {
                    Index       = ielmt,
                    Id          = elementIds[ielmt],
                    ElementType = elementTypes[ielmt],
                    Nodes       = new List <MeshNode>(numNodesInElmt),
                };
                double xc = 0;
                double yc = 0;
                double zc = 0;

                for (int j = 0; j < numNodesInElmt; j++)
                {
                    int      nodeIndex = nodeInElmt[j];
                    MeshNode meshNode  = Nodes[nodeIndex];
                    element.Nodes.Add(meshNode);
                    xc += meshNode.X;
                    yc += meshNode.Y;
                    zc += meshNode.Z;
                }

                double inumNodesInElmt = 1.0 / numNodesInElmt;
                element.XCenter = xc * inumNodesInElmt; // / numNodesInElmt;
                element.YCenter = yc * inumNodesInElmt; // / numNodesInElmt;
                element.ZCenter = zc * inumNodesInElmt; // / numNodesInElmt;

                Elements.Add(element);
            }
        }
Beispiel #4
0
 public SMeshDataBase(string projection, int[] nodeIds, double[] x, double[] y, double[] z, int[] code, int[] elementIds, int[] elementType, int[][] connectivity, MeshUnit zUnit = MeshUnit.Meter)
 {
     Projection    = projection;
     ZUnit         = zUnit;
     _nodeIds      = nodeIds;
     _x            = x;
     _y            = y;
     _z            = z;
     _code         = code;
     _elementIds   = elementIds;
     _elementType  = elementType;
     _connectivity = connectivity;
 }
Beispiel #5
0
        internal static MeshFile Create(MeshUnit zUnit, string wktString, int[] nodeIds, double[] x, double[] y, double[] z, int[] nodeCode, int[] elmtIds, int[] elmtTypes, int[][] connectivity)
        {
            MeshFile res = new MeshFile();

            res._zUnit        = zUnit;
            res._wktString    = wktString;
            res._nodeIds      = nodeIds;
            res._x            = x;
            res._y            = y;
            res._z            = z;
            res._code         = nodeCode;
            res._elementIds   = elmtIds;
            res._elementType  = elmtTypes;
            res._connectivity = connectivity;
            for (int i = 0; i < connectivity.Length; i++)
            {
                if (connectivity[i].Length == 4)
                {
                    res._hasQuads = true;
                    break;
                }
            }
            return(res);
        }
Beispiel #6
0
 /// <summary>
 /// Create mesh from arrays.
 /// <para>
 /// Note that the <paramref name="connectivity"/> array is using zero-based indices
 /// (as compared to the <see cref="MeshFile.ElementTable"/>, which is using one-based indices)
 /// </para>
 /// </summary>
 public MeshData(string projection, int[] nodeIds, double[] x, double[] y, double[] z, int[] code, int[] elementIds, int[] elementTypes, int[][] connectivity, MeshUnit zUnit = MeshUnit.Meter)
     : base(projection, nodeIds, x, y, z, code, elementIds, elementTypes, connectivity, zUnit = MeshUnit.Meter)
 {
 }
Beispiel #7
0
 public MeshData(IList <MeshNode> nodes, IList <MeshElement> elements, string projection, MeshUnit zUnit)
     : base(nodes, elements, projection, zUnit)
 {
 }
Beispiel #8
0
        /// <summary>
        /// Read .mesh file from reader and load all data.
        /// <para>
        /// If an element specifies a node number of zero, that node number is ignored, and
        /// does not become a part of the mesh data structure. That is the case for e.g.
        /// mixed triangular/quadrilateral meshes, where all elements specify 4 nodes,
        /// and triangular elements specifies the last node as zero.
        /// </para>
        /// </summary>
        public void Read(TextReader tr, string filename)
        {
            string line;

            try
            {
                char[] separator = new char[] { ' ', '\t' };

                // Read header line
                line = tr.ReadLine();
                if (line == null)
                {
                    throw new IOException("Can not load mesh file. File is empty");
                }
                // Remove any leading spaces if present
                line = line.Trim();
                int    noNodes = 0;
                string proj    = null;
                // First try match the 2012 header line format
                Match match = _header2012.Match(line);
                if (match.Success)
                {
                    // We just ignore the itemType integer, assuming it has the EUM value of eumIBathymetry (100079)
                    int itemType = Int32.Parse(match.Groups[1].Value);
                    int itemUnit = Int32.Parse(match.Groups[2].Value);
                    _zUnit  = MeshUnitUtil.FromEum(itemUnit);
                    noNodes = Int32.Parse(match.Groups[3].Value);
                    proj    = match.Groups[4].Value;
                }
                // If not successfull, try match the 2011 header line format
                if (proj == null)
                {
                    match = _header2011.Match(line);
                    if (match.Success)
                    {
                        _zUnit  = MeshUnit.Meter;
                        noNodes = Int32.Parse(match.Groups[1].Value);
                        proj    = match.Groups[2].Value;
                    }
                }
                if (proj == null)
                {
                    throw new IOException(string.Format("Can not load mesh file (failed reading mesh file header line): {0}", filename));
                }
                _wktString = proj.Trim();

                string[] strings;

                // Allocate memory for nodes
                _nodeIds = new int[noNodes];
                _x       = new double[noNodes];
                _y       = new double[noNodes];
                _z       = new double[noNodes];
                _code    = new int[noNodes];

                // Read nodes
                try
                {
                    for (int i = 0; i < noNodes; i++)
                    {
                        line = tr.ReadLine();
                        if (line == null)
                        {
                            throw new IOException("Unexpected end of file"); // used as inner exception
                        }
                        line        = line.Trim();
                        strings     = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                        _nodeIds[i] = int.Parse(strings[0]);
                        _x[i]       = double.Parse(strings[1], NumberFormatInfo.InvariantInfo);
                        _y[i]       = double.Parse(strings[2], NumberFormatInfo.InvariantInfo);
                        _z[i]       = double.Parse(strings[3], NumberFormatInfo.InvariantInfo);
                        _code[i]    = int.Parse(strings[4]);
                    }
                }
                catch (Exception inner)
                {
                    throw new Exception(string.Format("Can not load mesh file (failed reading nodes): {0}", filename), inner);
                }

                // Reading element header line
                int noElements;
                int maxNoNodesPerElement;
                int elmtCode;
                line = tr.ReadLine();
                if (line == null)
                {
                    throw new IOException(string.Format("Can not load mesh file (unexpected end of file): {0}", filename));
                }
                line    = line.Trim();
                strings = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                if (strings.Length != 3)
                {
                    throw new IOException(string.Format("Can not load mesh file (failed reading element header line): {0}", filename));
                }
                try
                {
                    noElements           = int.Parse(strings[0]);
                    maxNoNodesPerElement = int.Parse(strings[1]);
                    elmtCode             = int.Parse(strings[2]);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Can not load mesh file (failed reading element header line): {0}", filename), ex);
                }

                // Element code must be 21 or 25 (21 for triangular meshes, 25 for mixed meshes)
                if (elmtCode != 21 || elmtCode != 25)
                {
                    // TODO: Do we care?
                }

                // Allocate memory for elements
                _elementIds   = new int[noElements];
                _elementType  = new int[noElements];
                _connectivity = new int[noElements][];

                // Temporary (reused) list of nodes in one element
                List <int> nodesInElement = new List <int>(maxNoNodesPerElement);

                // Read all elements
                try
                {
                    for (int i = 0; i < noElements; i++)
                    {
                        nodesInElement.Clear();

                        // Read element header line
                        line = tr.ReadLine();
                        if (line == null)
                        {
                            throw new IOException("Unexpected end of file"); // used as inner exception
                        }
                        line    = line.Trim();
                        strings = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                        // Read element id
                        _elementIds[i] = int.Parse(strings[0]);
                        // figure out number of nodes
                        int noNodesInElmt = strings.Length - 1;
                        for (int j = 0; j < noNodesInElmt; j++)
                        {
                            int nodeNumber = int.Parse(strings[j + 1]);
                            // Check that the node number exists
                            if (nodeNumber < 0 || nodeNumber > noNodes) // used as inner exception:
                            {
                                throw new IOException("Node number in element table is negative or larger than number of nodes");
                            }
                            // It is only a node in the element if the node number is positive
                            if (nodeNumber > 0)
                            {
                                nodesInElement.Add(nodeNumber);
                            }
                        }
                        _connectivity[i] = nodesInElement.ToArray();

                        // Get element type from number of nodes
                        if (_connectivity[i].Length == 3)
                        {
                            _elementType[i] = 21;
                        }
                        else if (_connectivity[i].Length == 4)
                        {
                            _elementType[i] = 25;
                            _hasQuads       = true;
                        }
                        else
                        {
                            _elementType[i] = 0;
                            // TODO: Throw an exception?
                        }
                    }
                }
                catch (Exception inner)
                {
                    throw new Exception(string.Format("Can not load mesh file (failed reading elements): {0}", filename), inner);
                }
            }
            finally
            {
                try
                {
                    tr.Close();
                }
                catch { }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Create mesh from arrays.
        /// </summary>
        public static MeshData CreateMesh(string projection, int[] nodeIds, double[] x, double[] y, double[] z, int[] code, int[] elementIds, int[] elementTypes, int[][] connectivity, MeshUnit zUnit = MeshUnit.Meter)
        {
            MeshData meshData = new MeshData();

            meshData.Projection = projection;
            meshData.ZUnit      = zUnit;
            meshData.Nodes      = new List <MeshNode>(nodeIds.Length);
            meshData.Elements   = new List <MeshElement>(elementIds.Length);

            for (int i = 0; i < nodeIds.Length; i++)
            {
                var node = new MeshNode()
                {
                    Index    = i,
                    Id       = nodeIds[i],
                    X        = x[i],
                    Y        = y[i],
                    Z        = z[i],
                    Code     = code[i],
                    Elements = new List <MeshElement>(),
                };
                meshData.Nodes.Add(node);
            }

            for (int ielmt = 0; ielmt < elementIds.Length; ielmt++)
            {
                var element = new MeshElement()
                {
                    Index       = ielmt,
                    Id          = elementIds[ielmt],
                    ElementType = elementTypes[ielmt],
                    Nodes       = new List <MeshNode>(connectivity[ielmt].Length),
                };
                double xc = 0;
                double yc = 0;
                double zc = 0;

                for (int j = 0; j < connectivity[ielmt].Length; j++)
                {
                    MeshNode meshNode = meshData.Nodes[connectivity[ielmt][j] - 1];
                    element.Nodes.Add(meshNode);
                    meshNode.Elements.Add(element);
                    xc += meshNode.X;
                    yc += meshNode.Y;
                    zc += meshNode.Z;
                }

                element.XCenter = xc / connectivity[ielmt].Length;
                element.YCenter = yc / connectivity[ielmt].Length;
                element.ZCenter = zc / connectivity[ielmt].Length;

                meshData.Elements.Add(element);
            }

            return(meshData);
        }
Beispiel #10
0
 /// <summary>
 /// Create mesh from arrays.
 /// </summary>
 public static SMeshData CreateMesh(SMeshDataBase database, int[] elementTypes, int[][] connectivity, MeshUnit zUnit = MeshUnit.Meter)
 {
     return(new SMeshData(database.Projection, database.NodeIds, database.X, database.Y, database.Z, database.Code, database.ElementIds, elementTypes, connectivity, zUnit));
 }
Beispiel #11
0
 /// <summary>
 /// Create mesh from arrays.
 /// </summary>
 public static SMeshData CreateMesh(
     string projection, double[] x, double[] y, double[] z, int[] code,
     int[][] connectivity, MeshUnit zUnit = MeshUnit.Meter)
 {
     return(new SMeshData(projection, null, x, y, z, code, null, null, connectivity, zUnit));
 }
Beispiel #12
0
 /// <summary>
 /// Set the quantity to use for the mesh Z variable. If not set,
 /// it will use a Bathymetry item type (eumIBathymetry)
 /// with meter unit (eumUmeter).
 /// </summary>
 public void SetZUnit(MeshUnit zUnit)
 {
     _zUnit = zUnit;
 }
Beispiel #13
0
        /// <summary>
        /// Create and return a new <see cref="MeshFile"/> object
        /// </summary>
        public MeshFile CreateMesh()
        {
            Validate(true);

            // Creating default eumQuantity in meters
            _zUnit = MeshUnit.Meter;

            // Creating default node id's, if empty
            if (_nodeIds == null)
            {
                // Setting node ids 1,2,3,...
                _nodeIds = new int[_x.Length];
                for (int i = 0; i < _x.Length; i++)
                {
                    _nodeIds[i] = i + 1;
                }
            }
            // Creating default element id's, if empty
            if (_elementIds == null)
            {
                // Setting element ids 1,2,3,...
                _elementIds = new int[_connectivity.Length];
                for (int i = 0; i < _connectivity.Length; i++)
                {
                    _elementIds[i] = i + 1;
                }
            }

            // Creating additional element information
            int[] elementType   = new int[_connectivity.Length];
            int[] nodesPerElmt  = new int[_connectivity.Length];
            int   nodeElmtCount = 0; // total number of nodes listed in the connectivity table

            for (int i = 0; i < elementType.Length; i++)
            {
                int   elmtTypeNumber;
                int[] elmt = _connectivity[i];
                switch (elmt.Length)
                {
                case 3:
                    elmtTypeNumber = 21;
                    break;

                case 4:
                    elmtTypeNumber = 25;
                    break;

                case 6:
                    elmtTypeNumber = 32;
                    break;

                case 8:
                    elmtTypeNumber = 33;
                    break;

                default:
                    // this should have been caught in the validate phase, but just in case:
                    throw new Exception("Element with invalid number of nodes encountered");
                }
                elementType[i]  = elmtTypeNumber;
                nodesPerElmt[i] = elmt.Length;
                nodeElmtCount  += elmt.Length;
            }

            int[] connectivityArray = new int[nodeElmtCount];
            int   k = 0;

            for (int i = 0; i < elementType.Length; i++)
            {
                int[] elmt = _connectivity[i];
                for (int j = 0; j < elmt.Length; j++)
                {
                    connectivityArray[k++] = elmt[j];
                }
            }

            MeshFile res = MeshFile.Create(_zUnit, _projection, _nodeIds, _x, _y, _z, _code, _elementIds, elementType, _connectivity);

            return(res);
        }