using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using CaeMesh; using CaeGlobals; using System.ComponentModel; using System.Globalization; namespace CaeResults { [Serializable] public static class FrdFileReader { static Dictionary componentNameMap = new Dictionary() { { "D1", FOComponentNames.U1}, { "D2", FOComponentNames.U2}, { "D3", FOComponentNames.U3}, // { "SXX", FOComponentNames.S11}, { "SYY", FOComponentNames.S22}, { "SZZ", FOComponentNames.S33}, { "SXY", FOComponentNames.S12}, { "SYZ", FOComponentNames.S23}, { "SZX", FOComponentNames.S13}, // { "MEXX", FOComponentNames.ME11}, { "MEYY", FOComponentNames.ME22}, { "MEZZ", FOComponentNames.ME33}, { "MEXY", FOComponentNames.ME12}, { "MEYZ", FOComponentNames.ME23}, { "MEZX", FOComponentNames.ME13}, // { "EXX", FOComponentNames.E11}, { "EYY", FOComponentNames.E22}, { "EZZ", FOComponentNames.E33}, { "EXY", FOComponentNames.E12}, { "EYZ", FOComponentNames.E23}, { "EZX", FOComponentNames.E13}, // { "TEM(%)", "TEM"}, { "STR(%)", "STR"} }; private static readonly string _materialName = "MATERIAL_"; private static readonly string _gapMaterialName = "MATERIAL_GAP"; private static readonly string _springMaterialName = "MATERIAL_SPRING"; // private static readonly int _gapMaterialId = -1; private static readonly int _springMaterialId = -2; // private static HashSet _bemaNodeIds; // Methods static public FeResults Read(string fileName) { if (fileName != null && File.Exists(fileName)) { if (fileName.ToUpper().Contains("RESULTSFORLASTITERATIONS.FRD")) { CompareIntArray comparer = new CompareIntArray(); _bemaNodeIds = new HashSet(comparer); } // string[] lines = Tools.ReadAllLines(fileName); if (lines == null) return null; // List dataSets = GetDataSets(lines); // string setID; Dictionary nodes = null; Dictionary nodeIdsLookUp = null; Dictionary elements = null; HashSet gapMaterialIds = null; HashSet springMaterialIds = null; Dictionary materialIdMaterialName = null; Dictionary> materialIdElementIds = null; // FeResults result = new FeResults(fileName, null); Field field; FieldData fieldData = null; FieldData prevFieldData = null; // bool constantWidth = true; // foreach (string[] dataSet in dataSets) { setID = dataSet[0]; if (setID.StartsWith(" 1C", StringComparison.Ordinal)) // Data { result.HashName = GetHashName(dataSet); result.DateTime = GetDateTime(dataSet); result.UnitSystem = GetUnitSystem(dataSet); // calls SetConverterUnits on the UnitSystem GetMaterialIdsAndNames(dataSet, out materialIdMaterialName, out gapMaterialIds, out springMaterialIds); } else if (setID.StartsWith(" 2C", StringComparison.Ordinal)) // Nodes { constantWidth = IsConstantWidth(dataSet); nodes = GetNodes(dataSet, constantWidth, out nodeIdsLookUp); } else if (setID.StartsWith(" 3C", StringComparison.Ordinal)) // Elements { elements = GetElements(dataSet, gapMaterialIds, springMaterialIds, out materialIdElementIds); //elements = GetElementsFast(dataSet)); } else if (setID.StartsWith(" 1PSTEP", StringComparison.Ordinal)) // Fields { GetField(dataSet, constantWidth, prevFieldData, nodeIdsLookUp, out fieldData, out field); result.AddField(fieldData, field); prevFieldData = fieldData.DeepClone(); } } // result.Preprocess(); // if (nodes != null && elements != null) { RemoveErrorElements(nodes, ref elements); // FeMesh mesh = new FeMesh(nodes, elements, MeshRepresentation.Results); mesh.ResetPartsColor(); result.SetMesh(mesh, nodeIdsLookUp); // Material element sets FeElementSet elementSet; if (materialIdMaterialName != null && materialIdElementIds != null && materialIdMaterialName.Count <= materialIdElementIds.Count) { foreach (var entry in materialIdMaterialName) { if (materialIdElementIds.ContainsKey(entry.Key)) { elementSet = new FeElementSet(entry.Value, materialIdElementIds[entry.Key].ToArray()); result.Mesh.AddElementSet(elementSet); } } } // Gap element sets BasePart[] modifiedParts; BasePart[] newParts; List partNamesToRemove = new List(); string oldPartName; if (gapMaterialIds.Count > 0 && materialIdElementIds.ContainsKey(_gapMaterialId)) { elementSet = new FeElementSet(_gapMaterialName, materialIdElementIds[_gapMaterialId].ToArray()); result.Mesh.AddElementSet(elementSet); result.Mesh.CreatePartsFromElementSets(new string[] { elementSet.Name }, out modifiedParts, out newParts); // Rename parts if (newParts.Count() == 1) { oldPartName = newParts[0].Name; newParts[0].Name = "Gap_elements"; result.Mesh.Parts.Replace(oldPartName, newParts[0].Name, newParts[0]); } // Get part names to remove foreach (var part in modifiedParts) { if (part.Labels.Length == 0) partNamesToRemove.Add(part.Name); } // Remove parts if (partNamesToRemove.Count > 0) result.Mesh.RemoveParts(partNamesToRemove.ToArray(), out _, false); } // Spring element sets - *SPRING elements are not written into the frd file if (springMaterialIds.Count > 0 && materialIdElementIds.ContainsKey(_springMaterialId)) { elementSet = new FeElementSet(_springMaterialName, materialIdElementIds[_springMaterialId].ToArray()); result.Mesh.AddElementSet(elementSet); } // return result; } } // return null; } static bool IsConstantWidth(string[] lines) { // sample frd lines // ccx 2.12 mkl // -1 1-1.35800E+03-3.18000E+02-9.99201E-13 // -1 1300 7.15000E+02-3.19150E+02 8.66850E+02 // // ccx 2.10 kwip // -1 1-1.35800E+03-3.18000E+02-9.99201E-13 // // ccx 2.12 kwip // -1 1-1.35800E+03-3.18000E+02-9.99201E-13 // -1 1300 7.15000E+02-3.19150E+02 8.66850E+02 // // ccx 2.13 kwip // -1 1-1.35800E+03-3.18000E+02-9.99201E-13 // -1 1300 7.15000E+02-3.19150E+02 8.66850E+02 // // ccx 2.10 CalculiX-GE-OSS-2.10-win-x64 // -1 1-1.35800E+003-3.18000E+002-9.99201E-013 // -1 13007.15000E+002-3.19150E+0028.66850E+002 // -1 160327.95006E+0024.15000E+0021.50000E+002 // // line 0 is the line with the SetID, number of nodes ... // int len = lines[1].Length; for (int i = 2; i < lines.Length; i++) { if (lines[i].Length != len) return false; } return true; int start = 13; string values = lines[1].Substring(start, lines[1].Length - start); if (values.Contains(' ')) return true; if (values[0] == ' ' && values[12] == ' ' && values[24] == ' ') return true; return false; } static private DateTime GetDateTime(string[] lines) { DateTime dateTime = new DateTime(); DateTime time = new DateTime(); string[] tmp; // for (int i = 0; i < lines.Length; i++) { if (lines[i].Contains("1UDATE")) { tmp = lines[i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); dateTime = DateTime.Parse(tmp[1]); } else if (lines[i].Contains("1UTIME")) { tmp = lines[i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); time = DateTime.Parse(tmp[1]); } } // dateTime = dateTime.AddHours(time.Hour); dateTime = dateTime.AddMinutes(time.Minute); dateTime = dateTime.AddSeconds(time.Second); // return dateTime; } static private string GetHashName(string[] lines) { string[] tmp; // for (int i = 0; i < lines.Length; i++) { if (lines[i].ToUpper().Contains("HASH")) { tmp = lines[i].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); foreach (var part in tmp) { if (part.ToUpper().Contains("HASH")) { tmp = part.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries); return tmp[1].Trim(); } } } } // return Tools.GetRandomString(8); } static private UnitSystem GetUnitSystem(string[] lines) { string[] tmp; UnitSystemType unitSystemType = UnitSystemType.Undefined; // for (int i = 0; i < lines.Length; i++) { if (lines[i].ToUpper().Contains("UNIT SYSTEM")) { tmp = lines[i].Split(new string[] { "Unit system:" }, StringSplitOptions.RemoveEmptyEntries); if (tmp.Length == 2) Enum.TryParse(tmp[1], out unitSystemType); } } // return new UnitSystem(unitSystemType); } static private void GetMaterialIdsAndNames(string[] lines, out Dictionary materialIdMaterialName, out HashSet gapMaterialIds, out HashSet springMaterialIds) { // 1UMAT 1S235 // 1UMAT 2SPRING // 1UMAT 3GAP int materialId; string materialName; string[] tmp; materialIdMaterialName = new Dictionary(); gapMaterialIds = new HashSet(); springMaterialIds = new HashSet(); // for (int i = 0; i < lines.Length; i++) { if (lines[i].ToUpper().Contains("1UMAT")) { tmp = lines[i].Split(new string[] { "1UMAT" }, StringSplitOptions.RemoveEmptyEntries); if (tmp.Length == 2) { materialId = int.Parse(tmp[1].Substring(0, 5)); materialName = _materialName + tmp[1].Substring(5, tmp[1].Length - 5).Trim(); // if (materialName == _gapMaterialName) gapMaterialIds.Add(materialId); else if (materialName == _springMaterialName) springMaterialIds.Add(materialId); else materialIdMaterialName.Add(materialId, materialName); } } } } static private List GetDataSets(string[] lines) { List dataSet = new List(); List dataSets = new List(); // for (int i = 0; i < lines.Length; i++) { if (lines[i] == " -3") { dataSets.Add(dataSet.ToArray()); dataSet = new List(); } // Fast check for lines starting with: " 2C" or " 3C" else if (lines[i].Length > 5 && lines[i][5] == 'C' && (lines[i][4] == '2' || lines[i][4] == '3') && lines[i][3] == ' ' && lines[i][2] == ' ' && lines[i][1] == ' ' && lines[i][0] == ' ' && dataSet.Count > 0) { dataSets.Add(dataSet.ToArray()); dataSet = new List() { lines[i] }; } else dataSet.Add(lines[i]); } // return dataSets; } static private Dictionary GetNodes(string[] lines, bool constantWidth, out Dictionary nodeIdsLookUp) { Dictionary nodes = new Dictionary(); nodeIdsLookUp = new Dictionary(); int id; FeNode node; int width; string[] splitter = new string[] { " " }; int start; if (constantWidth) { width = 12; // line 0 is the line with the SetID, number of nodes ... for (int i = 1; i < lines.Length; i++) { start = 3; id = int.Parse(lines[i].Substring(start, 10)); start += 10; node = new FeNode(); node.Id = id; node.X = double.Parse(lines[i].Substring(start, width)); start += width; node.Y = double.Parse(lines[i].Substring(start, width)); start += width; node.Z = double.Parse(lines[i].Substring(start, width)); nodes.Add(id, node); nodeIdsLookUp.Add(id, i - 1); } } else { // line 0 is the line with the SetID, number of nodes ... for (int i = 1; i < lines.Length; i++) { start = 3; id = int.Parse(lines[i].Substring(start, 10)); start += 10; node = new FeNode(); node.Id = id; if (lines[i][start] == '-') width = 13; else width = 12; node.X = double.Parse(lines[i].Substring(start, width)); start += width; if (lines[i][start] == '-') width = 13; else width = 12; node.Y = double.Parse(lines[i].Substring(start, width)); start += width; if (lines[i][start] == '-') width = 13; else width = 12; node.Z = double.Parse(lines[i].Substring(start, width)); nodes.Add(id, node); nodeIdsLookUp.Add(id, i - 1); } } return nodes; } static private Dictionary GetElements(string[] lines, HashSet gapMaterialIds, HashSet springMaterialIds, out Dictionary> materialIdElementIds) { // el.id type ? mat.id // -1 1413 3 0 1 // n1 n1 n3 n4 // -2 483 489 481 482 Dictionary elements = new Dictionary(); List elementIds; materialIdElementIds = new Dictionary>(); int id; FrdFeDescriptorId feDescriptorId; FeElement element; int materialID; int[] nodeIds; string[] record1; string[] record2; string[] splitter = new string[] { " " }; // Line 0 is the line with the SetID, number of elements for (int i = 1; i < lines.Length; i++) { record1 = lines[i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); id = int.Parse(record1[1]); feDescriptorId = (FrdFeDescriptorId)int.Parse(record1[2]); if (record1.Length == 5) materialID = int.Parse(record1[4]); // ResultsForLastIterations has different output else materialID = -1; // if (gapMaterialIds.Contains(materialID)) materialID = _gapMaterialId; else if (springMaterialIds.Contains(materialID)) materialID = _springMaterialId; // if (materialIdElementIds.TryGetValue(materialID, out elementIds)) elementIds.Add(id); else materialIdElementIds.Add(materialID, new List { id }); // switch (feDescriptorId) { // LINEAR ELEMENTS case FrdFeDescriptorId.BeamLinear: // Beam element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); if (TryGetLinearBeamElement(id, record1, out element)) { if (_bemaNodeIds != null) { nodeIds = element.NodeIds; Array.Sort(nodeIds); if (_bemaNodeIds.Contains(nodeIds)) break; else _bemaNodeIds.Add(nodeIds); } elements.Add(id, element); } break; case FrdFeDescriptorId.ShellLinearTriangle: // Triangle element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetLinearTriangleElement(id, record1); elements.Add(id, element); break; case FrdFeDescriptorId.ShellLinearQuadrilateral: // Quadrilateral element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetLinearQuadrilateralElement(id, record1); elements.Add(id, element); break; case FrdFeDescriptorId.SolidLinearTetrahedron: // Tetrahedron element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetLinearTetraElement(id, record1); elements.Add(id, element); break; case FrdFeDescriptorId.SolidLinearWedge: // Wedge element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetLinearWedgeElement(id, record1); elements.Add(id, element); break; case FrdFeDescriptorId.SolidLinearHexahedron: // Hexahedron element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetLinearHexaElement(id, record1); elements.Add(id, element); break; // PARABOLIC ELEMENTS case FrdFeDescriptorId.ShellParabolicTriangle: // Triangle element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetParabolicTriangleElement(id, record1); elements.Add(id, element); break; case FrdFeDescriptorId.ShellParabolicQuadrilateral: // Quadrilateral element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetParabolicQuadrilateralElement(id, record1); elements.Add(id, element); break; case FrdFeDescriptorId.SolidParabolicTetrahedron: // Tetrahedron element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetParabolicTetraElement(id, record1); elements.Add(id, element); break; case FrdFeDescriptorId.SolidParabolicWedge: // Wedge element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); record2 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetParabolicWedgeElement(id, record1, record2); elements.Add(id, element); break; case FrdFeDescriptorId.SolidParabolicHexahedron: // Hexahedron element record1 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); record2 = lines[++i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); element = GetParabolicHexaElement(id, record1, record2); elements.Add(id, element); break; default: throw new Exception("The element type " + feDescriptorId.ToString() + " is not supported."); } } // return elements; } static private void RemoveErrorElements(Dictionary nodes, ref Dictionary elements) { List elementsIdsToRemove = new List(); foreach (var entry in elements) { foreach (var nodeId in entry.Value.NodeIds) { if (!nodes.ContainsKey(nodeId)) { elementsIdsToRemove.Add(entry.Key); break; } } } foreach (var elementId in elementsIdsToRemove) elements.Remove(elementId); } static private void GetField(string[] lines, bool constantWidth, FieldData prevFieldData, Dictionary nodeIdsLookUp, out FieldData fieldData, out Field field) { int lineNum = 0; int numOfVal; List components; // GetFieldHeaderData(lines, ref lineNum, prevFieldData, out fieldData, out numOfVal); float[][] values = GetFieldValuesData(lines, ref lineNum, constantWidth, numOfVal, nodeIdsLookUp, out components); // field = new Field(fieldData.Name); for (int i = 0; i < components.Count; i++) { field.AddComponent(components[i], values[i]); } } static private void GetFieldHeaderData(string[] lines, ref int lineNum, FieldData prevFieldData, out FieldData fieldData, out int numOfVal) { { // STATIC STEP // 1. Record: // Format:(1X,' 100','C',6A1,E12.5,I12,20A1,I2,I5,10A1,I2) // Values: KEY,CODE,SETNAME,VALUE,NUMNOD,TEXT,ICTYPE,NUMSTP,ANALYS, // FORMAT // Where: KEY = 100 // CODE = C // SETNAME= Name (not used) // VALUE = Could be frequency, time or any numerical value // NUMNOD = Number of nodes in this nodal results block // TEXT = Any text // ICTYPE = Analysis type // 0 static // 1 time step // 2 frequency // 3 load step // 4 user named // NUMSTP = Step number // ANALYS = Type of analysis (description) // FORMAT = Format indicator // 0 short format // 1 long format // 2 binary format // field# stepIncrement# step# - COMMENTS // 1PSTEP 25 1 2 // time numOfvalues methodId increment# - COMMENTS // 100CL 107 2.000000000 613 0 7 1 // 1PSTEP 25 1 2 // 100CL 107 2.000000000 613 0 7 1 // -4 DISP 4 1 // -5 D1 1 2 1 0 // -5 D2 1 2 2 0 // -5 D3 1 2 3 0 // -5 ALL 1 2 0 0 1ALL // -1 1-9.27159E-04 1.48271E-04-1.46752E-04 // FREQUENCY STEP // 1PSTEP 5 1 2 // 1PGM 1.000000E+00 // 1PGK 7.155923E+05 // 1PHID -1 // 1PSUBC 0 // 1PMODE 1 - frequency // 100CL 102 1.34633E+02 1329 2 2MODAL 1 // -4 DISP 4 1 // -5 D1 1 2 1 0 // -5 D2 1 2 2 0 // -5 D3 1 2 3 0 // -5 ALL 1 2 0 0 1ALL // BUCKLING STEP // field# stepIncrement# step# - COMMENTS // 1PSTEP 4 1 1 // 100CL 104 93.9434614 1329 4 4 1 // -4 DISP 4 1 // -5 D1 1 2 1 0 // -5 D2 1 2 2 0 // -5 D3 1 2 3 0 // -5 ALL 1 2 0 0 1ALL // STEADY STATE DYNAMICS STEP // 1PSTEP 3 0 2 // 100CL 103 0.00000E+00 21 1 3 1 // -4 DISP 4 1 // -5 D1 1 2 1 0 // -5 D2 1 2 2 0 // -5 D3 1 2 3 0 // -5 ALL 1 2 0 0 1ALL // LAST ITERATIONS // 1PSTEP STP 2INC 12 // iteration# - COMMENTS // 100CL 1051.0000000000 2251 3 5 1 // -4 DISP 4 1 // -5 D1 1 2 1 0 // -5 D2 1 2 2 0 // -5 D3 1 2 3 0 // -5 ALL 1 2 0 0 1ALL // FREQUENCY SENSITIVITY // 1PSTEP 3 1 2 // 100CL 115 0.00000E+00 1393 3 15 1 // -4 SENFREQ 2 1 // -5 DFDN 1 1 1 0 // -5 DFDNFIL 1 1 2 0 } // string line; string[] record; string[] splitter = new string[] { " " }; // string name; int globalIncrementId = -1; StepTypeEnum type = StepTypeEnum.Static; float time; int stepId; int stepIncrementId = -1; int methodId; // record = lines[lineNum++].Split(splitter, StringSplitOptions.RemoveEmptyEntries); // 1PSTEP // Last iterations if (record[2].Contains("INC")) { type = StepTypeEnum.LastIterations; stepId = int.Parse(record[record.Length - 1]); } else { stepIncrementId = int.Parse(record[2]); stepId = int.Parse(record[3]); } // Find 100C line - user field data while (!lines[lineNum].TrimStart().StartsWith("100C", StringComparison.Ordinal)) lineNum++; // line = lines[lineNum++]; int position = line.IndexOf("CL") + 2; // +2 for CL line = line.Insert(position + 5, " "); // +5 for block id line = line.Insert(position, " "); // record = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries); // 100CL globalIncrementId = int.Parse(record[1]) - 100; time = float.Parse(record[2]); numOfVal = int.Parse(record[3]); methodId = int.Parse(record[4]); // Steady state dynamics if (methodId == 1 && stepIncrementId == 0) type = StepTypeEnum.SteadyStateDynamics; // Sensitivity if (type == StepTypeEnum.Static && methodId == 3) // method 3 is also used for last iterations type { if (prevFieldData.StepType == StepTypeEnum.Frequency || prevFieldData.StepType == StepTypeEnum.FrequencySensitivity) type = StepTypeEnum.FrequencySensitivity; } // if (methodId == 4) type = StepTypeEnum.Buckling; // buckling switch // if (type == StepTypeEnum.Buckling) GetStepAndStepIncrementIds(type, 1, globalIncrementId, prevFieldData, out stepId, out stepIncrementId); else if (type == StepTypeEnum.SteadyStateDynamics) GetStepAndStepIncrementIds(type, 1, globalIncrementId, prevFieldData, out stepId, out stepIncrementId); else if (type == StepTypeEnum.FrequencySensitivity) GetStepAndStepIncrementIds(type, 0, globalIncrementId, prevFieldData, out stepId, out stepIncrementId); // Check for modal analysis else if (record.Length > 5 && record[5].Contains("MODAL")) { type = StepTypeEnum.Frequency; record = lines[lineNum - 2].Split(splitter, StringSplitOptions.RemoveEmptyEntries); // 1PMODE int freqNum = int.Parse(record[1]); stepIncrementId = freqNum; } else if (type == StepTypeEnum.LastIterations) { stepIncrementId = int.Parse(record[5]); } // record = lines[lineNum++].Split(splitter, StringSplitOptions.RemoveEmptyEntries); // -4 DISP name = record[1]; // fieldData = new FieldData(name); fieldData.GlobalIncrementId = globalIncrementId; fieldData.StepType = type; fieldData.Time = time; fieldData.MethodId = methodId; fieldData.StepId = stepId; fieldData.StepIncrementId = stepIncrementId; } static private void GetStepAndStepIncrementIds(StepTypeEnum type, int startIncrementId, int globalIncrementId, FieldData prevFieldData, out int stepId, out int stepIncrementId) { if (prevFieldData == null) // this is the first step { stepId = 1; stepIncrementId = startIncrementId; } else if (prevFieldData.StepType != type) // this is the first increment in the new type step { stepId = prevFieldData.StepId + 1; stepIncrementId = startIncrementId; } else if (globalIncrementId != prevFieldData.GlobalIncrementId) // this is the new increment in the new type step { stepId = prevFieldData.StepId; stepIncrementId = prevFieldData.StepIncrementId + 1; } else // this is the same increment { stepId = prevFieldData.StepId; stepIncrementId = prevFieldData.StepIncrementId; } } static private float[][] GetFieldValuesData(string[] lines, ref int lineNum, bool constantWidth, int numOfVal, Dictionary nodeIdsLookUp, out List components) { string[] record; string[] splitter = new string[] { " " }; // -4 DISP 4 1 // -5 D1 1 2 1 0 // -5 D2 1 2 2 0 // -5 D3 1 2 3 0 // -5 ALL 1 2 0 0 1ALL string componentName; string componentRename; components = new List(); while (lineNum < lines.Length) { record = lines[lineNum].Split(splitter, StringSplitOptions.RemoveEmptyEntries); // if (record[0] == "-5") { componentName = record[1]; if (componentNameMap.TryGetValue(componentName, out componentRename)) componentName = componentRename; components.Add(componentName); } else break; // lineNum++; } // Check if the line number equals the number of lines if (lines.Length - lineNum < numOfVal) numOfVal = lines.Length - lineNum; // float[][] values = new float[components.Count][]; for (int i = 0; i < values.Length; i++) values[i] = new float[nodeIdsLookUp.Count]; // bool directIds = nodeIdsLookUp.Count == numOfVal; int width; int lineNumInt = lineNum; int componentsCount = components.Count; // if (constantWidth) { // -1 1-2.70834E-01-1.05325E-01-1.05325E-01 6.25207E-02 1.80015E-08-1.33740E-02 // -1 2-2.80622E-01-9.91633E-02-7.35318E-02-5.78751E-02-1.60376E-03-2.20396E-03 // -1 3 2.28310E-01 8.87877E-02 8.87877E-02 4.85675E-02-3.63429E-08-2.93555E-03 // -1 4 2.24848E-01 8.74410E-02 8.74410E-02-4.91735E-02 3.93390E-08-6.85921E-03 // // -1 1 1.00000E+00 1.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -2 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -2 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -2 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -2 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -1 2 1.00000E+00 1.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -2 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -2 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -2 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // -2 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 0.00000E+00 // Are there multiple data lines for one node int numDataLines = 0; if (numOfVal < lines.Length - lineNumInt) { for (int i = lineNumInt; i < lines.Length; i++) { if (numDataLines == 0 && lines[i].Trim().StartsWith("-1", StringComparison.Ordinal)) numDataLines = 1; else if (numDataLines >= 1 && lines[i].Trim().StartsWith("-2", StringComparison.Ordinal)) numDataLines++; else if (numDataLines >= 1 && lines[i].Trim().StartsWith("-1", StringComparison.Ordinal)) break; } } else numDataLines = 1; // width = 12; // //for (int i = 0; i < numOfVal; i++) Parallel.For(0, numOfVal, i => { int lineId; int nodeId; int nodeValueId; int start; string line; string substring; float value; // lineId = lineNumInt + i * numDataLines; line = lines[lineId]; // Node id if (directIds) nodeValueId = i; else { start = 3; nodeId = int.Parse(line.Substring(start, 10)); if (!nodeIdsLookUp.TryGetValue(nodeId, out nodeValueId)) nodeValueId = -1; } // Values start = 13; for (int j = 0; j < componentsCount; j++) { // Is line to short - do results continue in the next line? if (start + width > line.Length) { if (lines.Length > lineId + 1 && lines[lineId + 1].Trim().StartsWith("-2", StringComparison.Ordinal)) { i++; lineId++; line = lines[lineId]; start = 13; } // No continuation found else continue; } // if (nodeValueId != -1) { substring = line.Substring(start, width); if (!float.TryParse(substring, out value)) value = float.NaN; // Try/catch version is a little faster //try { value = float.Parse(substring); } //catch { value = float.NaN; } // values[j][nodeValueId] = value; } start += width; } } ); } else { // -1 12.55297E-0036.74788E-003-2.86735E-001 // -1 29.68149E-0045.40225E-003-2.82345E-001 // -1 32.35261E-0031.24270E-002-2.97771E-001 // -1 4-9.84216E-0035.62909E-003-2.73047E-001 // -1 53.91981E-0031.22846E-002-2.98849E-001 // -1 6-1.16413E-0027.22403E-003-2.74940E-001 int lineId; int nodeId; int nodeValueId; int start; string line; // for (int i = 0; i < numOfVal; i++) { lineId = i + lineNum; line = lines[lineId]; // Node id if (directIds) nodeValueId = i; else { start = 3; nodeId = int.Parse(line.Substring(start, 10)); if (!nodeIdsLookUp.TryGetValue(nodeId, out nodeValueId)) nodeValueId = -1; } // Values start = 13; for (int j = 0; j < components.Count; j++) { if (start >= line.Length) continue; // if (line[start] == '-') width = 13; else width = 12; // if (start + width > line.Length) continue; // if (nodeValueId != -1) values[j][nodeValueId] = float.Parse(line.Substring(start, width)); start += width; } } } return values; } // LINEAR ELEMENTS static private bool TryGetLinearBeamElement(int id, string[] record, out FeElement element) { element = null; // try { int[] nodes = new int[2]; for (int i = 0; i < nodes.Length; i++) { if (!int.TryParse(record[i + 1], out nodes[i])) return false; } element = new LinearBeamElement(id, nodes); // return true; } catch { return false; } } static private LinearTriangleElement GetLinearTriangleElement(int id, string[] record) { int[] nodes = new int[3]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = int.Parse(record[i + 1]); } return new LinearTriangleElement(id, nodes); } static private LinearQuadrilateralElement GetLinearQuadrilateralElement(int id, string[] record) { int[] nodes = new int[4]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = int.Parse(record[i + 1]); } return new LinearQuadrilateralElement(id, nodes); } static private LinearTetraElement GetLinearTetraElement(int id, string[] record) { int[] nodes = new int[4]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = int.Parse(record[i + 1]); } return new LinearTetraElement(id, nodes); } static private LinearWedgeElement GetLinearWedgeElement(int id, string[] record) { int[] nodes = new int[6]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = int.Parse(record[i + 1]); } return new LinearWedgeElement(id, nodes); } static private LinearHexaElement GetLinearHexaElement(int id, string[] record) { int[] nodes = new int[8]; // nodes[0] = int.Parse(record[1]); nodes[1] = int.Parse(record[2]); nodes[2] = int.Parse(record[3]); nodes[3] = int.Parse(record[4]); nodes[4] = int.Parse(record[5]); nodes[5] = int.Parse(record[6]); nodes[6] = int.Parse(record[7]); nodes[7] = int.Parse(record[8]); // return new LinearHexaElement(id, nodes); } // PARABOLIC ELEMENTS static private ParabolicTriangleElement GetParabolicTriangleElement(int id, string[] record) { int[] nodes = new int[6]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = int.Parse(record[i + 1]); } return new ParabolicTriangleElement(id, nodes); } static private ParabolicQuadrilateralElement GetParabolicQuadrilateralElement(int id, string[] record) { int[] nodes = new int[8]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = int.Parse(record[i + 1]); } return new ParabolicQuadrilateralElement(id, nodes); } static private ParabolicTetraElement GetParabolicTetraElement(int id, string[] record) { int[] nodes = new int[10]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = int.Parse(record[i + 1]); } return new ParabolicTetraElement(id, nodes); } static private ParabolicWedgeElement GetParabolicWedgeElement(int id, string[] record1, string[] record2) { int[] nodes = new int[15]; for (int i = 0; i < 9; i++) // first 9 nodes are OK { nodes[i] = int.Parse(record1[i + 1]); } // Swap last 3 nodes with forelast 3 nodes nodes[9] = int.Parse(record2[3]); nodes[10] = int.Parse(record2[4]); nodes[11] = int.Parse(record2[5]); nodes[12] = int.Parse(record1[10]); nodes[13] = int.Parse(record2[1]); nodes[14] = int.Parse(record2[2]); // return new ParabolicWedgeElement(id, nodes); } static private ParabolicHexaElement GetParabolicHexaElement(int id, string[] record1, string[] record2) { int[] nodes = new int[20]; // First 12 nodes are OK for (int i = 0; i < 10; i++) { nodes[i] = int.Parse(record1[i + 1]); } nodes[10] = int.Parse(record2[1]); nodes[11] = int.Parse(record2[2]); // Swap last 3 nodes with forelast 3 nodes nodes[12] = int.Parse(record2[7]); nodes[13] = int.Parse(record2[8]); nodes[14] = int.Parse(record2[9]); nodes[15] = int.Parse(record2[10]); // nodes[16] = int.Parse(record2[3]); nodes[17] = int.Parse(record2[4]); nodes[18] = int.Parse(record2[5]); nodes[19] = int.Parse(record2[6]); // return new ParabolicHexaElement(id, nodes); } // } }