using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CaeMesh; using CaeGlobals; using CaeResults; using System.IO; using System.Runtime.Serialization; namespace CaeModel { [Serializable] public class ImportedPressure : VariablePressure, IPreviewable, ISerializable { // Variables private string _fileName; //ISerializable private string _pressureTime; //ISerializable private string _pressureVariableName; //ISerializable private InterpolatorEnum _interpolatorType; //ISerializable private EquationContainer _magnitudeFactor; //ISerializable private EquationContainer _geomScaleFactor; //ISerializable // private FileInfo _oldFileInfo; //ISerializable // [NonSerialized] private ResultsInterpolator _interpolator; // Properties public string FileName { get { return _fileName; } set { _fileName = value; } } public string PressureTime { get { return _pressureTime; } set { _pressureTime = value; } } public string PressureVariableName { get { return _pressureVariableName; } set { _pressureVariableName = value; } } public InterpolatorEnum InterpolatorType { get { return _interpolatorType; } set { _interpolatorType = value; } } public EquationContainer MagnitudeFactor { get { return _magnitudeFactor; } set { SetMagnitudeFactor(value); } } public EquationContainer GeometryScaleFactor { get { return _geomScaleFactor; } set { SetGeomScaleFactor(value); } } // Constructors public ImportedPressure(string name, string surfaceName, RegionTypeEnum regionType, bool twoD, bool complex, double phaseDeg) : base(name, surfaceName, regionType, twoD, complex, phaseDeg) { _fileName = null; _pressureTime = null; _pressureVariableName = null; _interpolatorType = InterpolatorEnum.ClosestNode; MagnitudeFactor = new EquationContainer(typeof(StringDoubleConverter), 1); GeometryScaleFactor = new EquationContainer(typeof(StringDoubleConverter), 1); // _oldFileInfo = null; } public ImportedPressure(SerializationInfo info, StreamingContext context) : base(info, context) { // Compatibility for version v1.4.0 if (_regionType == RegionTypeEnum.PartName) _regionType = RegionTypeEnum.Selection; // foreach (SerializationEntry entry in info) { switch (entry.Name) { case "_fileName": _fileName = (string)entry.Value; break; case "_pressureTime": _pressureTime = (string)entry.Value; break; case "_pressureVariableName": _pressureVariableName = (string)entry.Value; break; case "_interpolatorType": _interpolatorType = (InterpolatorEnum)entry.Value; break; case "_magnitudeFactor": // Compatibility for version v1.4.0 if (entry.Value is double valueMag) MagnitudeFactor = new EquationContainer(typeof(StringDoubleConverter), valueMag); else SetMagnitudeFactor((EquationContainer)entry.Value, false); break; case "_geomScaleFactor": // Compatibility for version v1.4.0 if (entry.Value is double valueSF) GeometryScaleFactor = new EquationContainer(typeof(StringDoubleConverter), valueSF); else SetGeomScaleFactor((EquationContainer)entry.Value, false); break; case "_oldFileInfo": _oldFileInfo = (FileInfo)entry.Value; break; default: break; } } // Compatibility for version v1.4.0 if (_magnitudeFactor == null) MagnitudeFactor = new EquationContainer(typeof(StringDoubleConverter), 1); if (_geomScaleFactor == null) GeometryScaleFactor = new EquationContainer(typeof(StringDoubleConverter), 1); } // Methods private void SetMagnitudeFactor(EquationContainer value, bool checkEquation = true) { EquationContainer.SetAndCheck(ref _magnitudeFactor, value, null, checkEquation); } private void SetGeomScaleFactor(EquationContainer value, bool checkEquation = true) { EquationContainer.SetAndCheck(ref _geomScaleFactor, value, null, checkEquation); } // IContainsEquations public override void CheckEquations() { base.CheckEquations(); // _magnitudeFactor.CheckEquation(); _geomScaleFactor.CheckEquation(); } // public bool IsProperlyDefined(out string error) { error = ""; if (!File.Exists(_fileName)) { error = "The selected file does not exist."; return false; } Dictionary timeResultVariableNames = OpenFoamFileReader.GetTimeResultScalarVariableNames(_fileName); if (timeResultVariableNames.Count == 0) { error = "The selected OpenFOAM folder does not contain results."; return false; } string[] variables; if (timeResultVariableNames.TryGetValue(_pressureTime, out variables)) { if (!variables.Contains(_pressureVariableName)) { error = "The selected OpenFOAM folder does not contain results for variable: " + _pressureVariableName + "."; return false; } } else { error = "The selected OpenFOAM folder does not contain results for time: " + _pressureTime + "."; return false; } // return true; } public bool IsInitialized() { return _interpolator != null; } public void ImportPressure(UnitSystem unitSystem) { bool updateData = false; FileInfo fileInfo = new FileInfo(_fileName); // if (fileInfo.Exists) { if (_interpolator == null) updateData |= true; // each time the load is changed it is Cloned -> _interpolator = null // else if (_oldFileInfo == null) updateData = true; else if (fileInfo.Name != _oldFileInfo.Name) updateData = true; // Files have the same name - check if newer else if (fileInfo.LastWriteTimeUtc < _oldFileInfo.LastWriteTimeUtc) updateData = true; } else { string missingFile = "The file from which the pressure should be imported does not exist."; throw new CaeException(missingFile); } // if (updateData) { _oldFileInfo = fileInfo; // Get results FeResults results = OpenFoamFileReader.Read(_fileName, double.Parse(_pressureTime), _pressureVariableName, unitSystem); if (results == null) throw new CaeException("No pressure was imported."); // Scale geometry if (_geomScaleFactor.Value != 1) results.ScaleAllParts(_geomScaleFactor.Value); // Get pressure field data FieldData[] fieldData = results.GetAllFieldData(); // use GetResults for the first time to check existance Dictionary filedNameComponentNames = results.GetAllFiledNameComponentNames(); if (fieldData == null || fieldData.Length != 1) throw new CaeException("Pressure field could not be found."); // FieldData pressureData = fieldData[0]; // string[] componentNames; filedNameComponentNames.TryGetValue(fieldData[0].Name, out componentNames); if (componentNames.Length != 1) throw new CaeException("Component of the pressure field could not be found."); // pressureData.Component = componentNames[0]; // Initialize interpolator _interpolator = new ResultsInterpolator(results.GetAllNodesCellsAndValues(pressureData)); } } public FeResults GetPreview(FeModel model, string resultName, UnitSystem unitSystem) { FeMesh targetMesh = model.Mesh; ImportPressure(unitSystem); // PartExchangeData allData = new PartExchangeData(); targetMesh.GetAllNodesAndCells(out allData.Nodes.Ids, out allData.Nodes.Coor, out allData.Cells.Ids, out allData.Cells.CellNodeIds, out allData.Cells.Types); // FeSurface surface = targetMesh.Surfaces[_surfaceName]; FeNodeSet nodeSet = targetMesh.NodeSets[surface.NodeSetName]; HashSet nodeIds = new HashSet(nodeSet.Labels); // float[] distancesAll = new float[allData.Nodes.Coor.Length]; float[] distances1 = new float[allData.Nodes.Coor.Length]; float[] distances2 = new float[allData.Nodes.Coor.Length]; float[] distances3 = new float[allData.Nodes.Coor.Length]; float[] values = new float[allData.Nodes.Coor.Length]; // Parallel.For(0, values.Length, i => //for (int i = 0; i < values.Length; i++) { double[] distance; double value; // if (nodeIds.Contains(allData.Nodes.Ids[i])) { GetPressureAndDistanceForPoint(allData.Nodes.Coor[i], out distance, out value); // distances1[i] = (float)distance[0]; distances2[i] = (float)distance[1]; distances3[i] = (float)distance[2]; distancesAll[i] = (float)Math.Sqrt(distance[0] * distance[0] + distance[1] * distance[1] + distance[2] * distance[2]); values[i] = (float)value; } else { distances1[i] = float.NaN; distances2[i] = float.NaN; distances3[i] = float.NaN; distancesAll[i] = float.NaN; values[i] = float.NaN; } } ); // Dictionary nodeIdsLookUp = new Dictionary(); for (int i = 0; i < allData.Nodes.Coor.Length; i++) nodeIdsLookUp.Add(allData.Nodes.Ids[i], i); FeResults results = new FeResults(resultName, unitSystem); results.SetMesh(targetMesh, nodeIdsLookUp); // Add distances FieldData fieldData = new FieldData(FOFieldNames.Distance); fieldData.GlobalIncrementId = 1; fieldData.StepType = StepTypeEnum.Static; fieldData.Time = 1; fieldData.MethodId = 1; fieldData.StepId = 1; fieldData.StepIncrementId = 1; // Distances Field field = new Field(fieldData.Name); field.AddComponent(FOComponentNames.All, distancesAll); field.AddComponent(FOComponentNames.D1, distances1); field.AddComponent(FOComponentNames.D2, distances2); field.AddComponent(FOComponentNames.D3, distances3); results.AddField(fieldData, field); // Add values fieldData = new FieldData(fieldData); fieldData.Name = FOFieldNames.Imported; // field = new Field(fieldData.Name); field.AddComponent(FOComponentNames.PRESS, values); results.AddField(fieldData, field); // return results; } public void GetPressureAndDistanceForPoint(double[] point, out double[] distance, out double value) { _interpolator.InterpolateAt(point, _interpolatorType, out distance, out value); value *= _magnitudeFactor.Value; } // Variable pressure public override double GetPressureForPoint(FeModel model, double[] point) { _interpolator.InterpolateAt(point, _interpolatorType, out double[] distance, out double value); return value * _magnitudeFactor.Value; } public override double[] GetPressuresForPoints(FeModel model, double[][] points) { double[] values = new double[points.Length]; double magnitude = _magnitudeFactor.Value; for (int i = 0; i < points.Length; i++) { _interpolator.InterpolateAt(points[i], _interpolatorType, out _, out values[i]); values[i] *= magnitude; } return values; } // ISerialization public new void GetObjectData(SerializationInfo info, StreamingContext context) { // Using typeof() works also for null fields base.GetObjectData(info, context); // info.AddValue("_fileName", _fileName, typeof(string)); info.AddValue("_pressureTime", _pressureTime, typeof(string)); info.AddValue("_pressureVariableName", _pressureVariableName, typeof(string)); info.AddValue("_interpolatorType", _interpolatorType, typeof(InterpolatorEnum)); info.AddValue("_magnitudeFactor", _magnitudeFactor, typeof(EquationContainer)); info.AddValue("_geomScaleFactor", _geomScaleFactor, typeof(EquationContainer)); info.AddValue("_oldFileInfo", _oldFileInfo, typeof(FileInfo)); } } }