protected override void SolveInstance(IGH_DataAccess DA) { // string filePath = null; List <string> bscPath = new List <string>(); // get data if (!DA.GetData(0, ref filePath)) { return; } if (!DA.GetDataList(1, bscPath)) { // pass } else { if (bscPath.Count == 0) { bscPath = null; } } if (filePath == null) { return; } // FemDesign.Calculate.FdScript fdScript = FemDesign.Calculate.FdScript.ReadStr(filePath, bscPath); FemDesign.Calculate.Application app = new FemDesign.Calculate.Application(); bool hasExited = app.RunFdScript(fdScript, false, true, false); // if (hasExited) { DA.SetData(0, FemDesign.Model.DeserializeFromFilePath(fdScript.StruxmlPath)); DA.SetData(1, hasExited); } else { return; } }
static void Main() { // EXAMPLE 9: READ RESULTS // This example will show you how to model a simple supported beam, // and read some of the results. // This example was last updated 2022-07-01, using the ver. 21.2.0 FEM-Design API. #region DEFINE GEOMETRY // Define geometry var p1 = new Geometry.FdPoint3d(2.0, 2.0, 0); var p2 = new Geometry.FdPoint3d(10, 2.0, 0); var mid = p1 + (p2 - p1) * 0.5; // Create elements var edge = new Geometry.Edge(p1, p2, Geometry.FdVector3d.UnitZ()); Materials.MaterialDatabase materialsDB = Materials.MaterialDatabase.DeserializeStruxml("materials.struxml"); Sections.SectionDatabase sectionsDB = Sections.SectionDatabase.DeserializeStruxml("sections.struxml"); var material = materialsDB.MaterialByName("C35/45"); var section = sectionsDB.SectionByName("Concrete sections, Rectangle, 300x900"); var bar = new Bars.Bar( edge, Bars.BarType.Beam, material, sections: new Sections.Section[] { section }, connectivities: new Bars.Connectivity[] { Bars.Connectivity.GetRigid() }, eccentricities: new Bars.Eccentricity[] { Bars.Eccentricity.GetDefault() }, identifier: "B"); bar.BarPart.LocalY = Geometry.FdVector3d.UnitY(); var elements = new List <GenericClasses.IStructureElement>() { bar }; #endregion #region DEFINE SUPPORTS // Create supports var s1 = new Supports.PointSupport( point: p1, motions: Releases.Motions.RigidPoint(), rotations: Releases.Rotations.Free() ); var s2 = new Supports.PointSupport( point: p2, motions: new Releases.Motions(yNeg: 1e10, yPos: 1e10, zNeg: 1e10, zPos: 1e10), rotations: Releases.Rotations.Free() ); var supports = new List <GenericClasses.ISupportElement>() { s1, s2 }; #endregion #region DEFINE LOAD CASES/COMBINATIONS // Create load cases var deadload = new Loads.LoadCase("Deadload", Loads.LoadCaseType.DeadLoad, Loads.LoadCaseDuration.Permanent); var liveload = new Loads.LoadCase("Liveload", Loads.LoadCaseType.Static, Loads.LoadCaseDuration.Permanent); var loadcases = new List <Loads.LoadCase>() { deadload, liveload }; // Create load combinations var slsFactors = new List <double>() { 1.0, 1.0 }; var SLS = new Loads.LoadCombination("SLS", Loads.LoadCombType.ServiceabilityCharacteristic, loadcases, slsFactors); var ulsFactors = new List <double>() { 1.35, 1.5 }; var ULS = new Loads.LoadCombination("ULS", Loads.LoadCombType.UltimateOrdinary, loadcases, ulsFactors); var loadCombinations = new List <Loads.LoadCombination>() { SLS, ULS }; // Create loads var pointForce = new Loads.PointLoad(mid, new Geometry.FdVector3d(0.0, 0.0, -5.0), liveload, null, Loads.ForceLoadType.Force); var pointMoment = new Loads.PointLoad(p2, new Geometry.FdVector3d(0.0, 5.0, 0.0), liveload, null, Loads.ForceLoadType.Moment); var lineLoadStart = new Geometry.FdVector3d(0.0, 0.0, -2.0); var lineLoadEnd = new Geometry.FdVector3d(0.0, 0.0, -4.0); var lineLoad = new Loads.LineLoad(edge, lineLoadStart, lineLoadEnd, liveload, Loads.ForceLoadType.Force, "", constLoadDir: true, loadProjection: true); var loads = new List <GenericClasses.ILoadElement>() { pointForce, pointMoment, lineLoad }; #endregion #region ASSEMBLE // Add to model Model model = new Model(Country.S); model.AddElements(elements); model.AddSupports(supports); model.AddLoadCases(loadcases); model.AddLoadCombinations(loadCombinations); model.AddLoads(loads); #endregion #region SETTINGS // define the file name string fileName = "SimpleBeam.struxml"; fileName = Path.GetFullPath(fileName); // Define the Units // it is an optional operation and it can be omitted // Default Units can be seen looking at FemDesign.Results.UnitResults.Default() var units = new FemDesign.Results.UnitResults(Results.Length.m, Results.Angle.deg, Results.SectionalData.mm, Results.Force.daN, Results.Mass.kg, Results.Displacement.cm, Results.Stress.MPa); // Select the results to extract var resultTypes = new List <Results.ResultType> { Results.ResultType.PointSupportReaction, Results.ResultType.NodalDisplacement }; var bscPathsFromResultTypes = Calculate.Bsc.BscPathFromResultTypes(resultTypes, fileName, units); #endregion #region ANALYSIS // Running the analysis FemDesign.Calculate.Analysis analysisSettings = new FemDesign.Calculate.Analysis(null, null, null, null, calcCase: true, false, false, calcComb: true, false, false, false, false, false, false, false, false, false); var fdScript = FemDesign.Calculate.FdScript.Analysis(fileName, analysisSettings, bscPathsFromResultTypes, null, true); var app = new FemDesign.Calculate.Application(); app.RunFdScript(fdScript, false, true); model.SerializeModel(fileName); // Read model and results model = Model.DeserializeFromFilePath(fdScript.StruxmlPath); #endregion #region EXTRACT RESULTS IEnumerable <Results.IResult> results = Enumerable.Empty <Results.IResult>(); foreach (var cmd in fdScript.CmdListGen) { string path = cmd.OutFile; var _results = Results.ResultsReader.Parse(path); results = results.Concat(_results); } #endregion #region DO SOMETHING WITH RESULTS // Display Results on Screen // The results are grouped by their type var resultGroups = results.GroupBy(t => t.GetType()).ToList(); foreach (var resultGroup in resultGroups) { Console.WriteLine(resultGroup.Key.Name); Console.WriteLine(); foreach (var result in resultGroup) { Console.WriteLine(result); } Console.WriteLine(); Console.WriteLine(); } // Select a specific result Console.WriteLine("Vertical Reaction Forces"); var zReactions = results.Where(t => t.GetType() == typeof(Results.PointSupportReaction)).Cast <Results.PointSupportReaction>(); foreach (var zReaction in zReactions) { Console.WriteLine($"Node {zReaction.Id}: {zReaction.Fz} {units.Force}"); } #endregion // ENDING THE PROGRAM Console.WriteLine("\nPress any key to close console."); Console.ReadKey(); }
static void Main() { // PRACTICAL EXAMPLE: MESH SIZE CONVERGENCE STUDY // In this example, we will analyse the mesh size convergence for a model, to allow for // an optimal analysis setting. The program will output files to \bin\Debug\Output. // This example was last updated 2022-04-27, using the ver. 21.1.0 FEM-Design API. // INPUTS: // All inputs used in the program. string modelPath = "Model with labelled sections.struxml"; double maxAllowedDeviation = 0.02; string labeledSectionIdentifier = "LS.1"; List <double> meshSizes = new List <double> { 2.0, 1.0, 0.5, 0.25, 0.15, 0.10 }; int forceIdIndex = 2; // The force index stem from the .bsc file made from FEM-Design, where they are ordered like this: // ID Mx' My' Mx'y' Nx' Ny' Nx'y' Tx'z' Ty'z' Comb. // Index [2] [3] [4] [5] [6] [7] [8] [9] [10] // PREPARATIONS: // Some setup necessary to run the analysis and save the results. string fileName = Path.GetFileName(modelPath); FemDesign.Calculate.Analysis analysisSettings = new FemDesign.Calculate.Analysis(null, null, null, null, calcCase: true, false, false, calcComb: true, false, false, false, false, false, false, false, false, false); Model model = Model.DeserializeFromFilePath(modelPath); Dictionary <double, List <double> > allForces = new Dictionary <double, List <double> >() { }; // RUNNING THE ANALYSIS FOR EACH MESH SIZE foreach (double size in meshSizes) { model.Entities.Slabs[0].SlabPart.MeshSize = size; // Serializing new model string currentPath = Path.GetFullPath(Path.Combine(fileName.Replace(".struxml", $"_{size.ToString(System.Globalization.CultureInfo.InvariantCulture)}.struxml"))); model.SerializeModel(currentPath); // Readying the .bsc script string bscPath = Path.Combine(fileName.Replace(".struxml", $" - LabelledSectionsInternalForcesLoadCombination.bsc")); var bsc = new FemDesign.Calculate.Bsc(FemDesign.Calculate.ListProc.LabelledSectionsInternalForcesLoadCombination, bscPath); // Running the analysis FemDesign.Calculate.FdScript fdScript = FemDesign.Calculate.FdScript.Analysis(currentPath, analysisSettings, new List <string> { bsc }, null, true); var app = new FemDesign.Calculate.Application(); app.RunFdScript(fdScript, false, true, true); // Preprarations //string csvPath = bscPath.Replace(".bsc", ".csv"); string csvPath = fdScript.CmdListGen[0].OutFile; List <double> currentForces = new List <double>(); List <string> L = new List <string>(); // Reading results using (var reader = new StreamReader(csvPath)) { while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split('\t'); if (values[0] == labeledSectionIdentifier) { L.Add(values[1]); currentForces.Add(double.Parse(values[forceIdIndex], System.Globalization.CultureInfo.InvariantCulture)); } } } // Printing results Console.WriteLine($"\nMesh size: {size:##0.00}\n" + $"{"x:",6} | {"Mx':",6}"); Console.WriteLine($"{"[m]",6} | {"[kNm/m]",6}"); for (int i = 0; i < currentForces.Count; i++) { Console.WriteLine($"{L[i],6:##0.0} | {currentForces[i]/1000,6:##0.0}"); } allForces.Add(size, currentForces); } // PREPARATIONS // Variables needed for the convergence calculation. int counter = 0; string critMet = "false"; List <double> totalForce = new List <double>(); List <double> previousForces = new List <double>(); List <double> totalDeviation = new List <double>(); List <double> deviationCalculation = new List <double>(); List <double> deviationPercentage = new List <double>(); // Results header Console.WriteLine("\nRESULTS:"); Console.WriteLine($"{"Mesh size", 10} | {"Mx' tot.",10} | {"Dev.tot.",10} | {"Dev %",10} | Meets crit."); Console.WriteLine($"{"[m]",10} | {"[kNm/m]",10} | {"[kNm/m]",10} | {"[-]",10} | {"[-]",10}"); // CONVERGENCE CALCULATION LOOP foreach (var forcesList in allForces) { // Calculate deviation between last and current forces if (counter > 0) { for (int i = 0; i < forcesList.Value.Count; i++) { deviationCalculation.Add(Math.Abs(forcesList.Value[i] - previousForces[i])); } totalDeviation.Add(deviationCalculation.Sum()); deviationCalculation.Clear(); } else { totalDeviation.Add(0.000); } // Calculate the relation between the force and deviation totals totalForce.Add(forcesList.Value.Sum()); deviationPercentage.Add(totalDeviation[counter] / totalForce[counter]); // Check if our criteria is met if (counter > 0 & deviationPercentage[counter] <= maxAllowedDeviation) { critMet = "true"; } // Display results Console.WriteLine($"{forcesList.Key,10} | {totalForce[counter] / 1000,10:##0.0} | {totalDeviation[counter] / 1000,10:##0.0} | {deviationPercentage[counter]*100,10:##0.0} | {critMet, 10}"); // Setup for next loop previousForces.Clear(); previousForces.AddRange(forcesList.Value); counter++; } // ENDING THE PROGRAM Console.WriteLine("\nPress any key to close console."); Console.ReadKey(); }
protected override void SolveInstance(IGH_DataAccess DA) { // Get input string filePath = null; List <string> resultTypes = new List <string>(); Results.FDfea fdFeaModel = null; DA.GetData("StrPath", ref filePath); if (filePath == null) { return; } DA.GetDataList("ResultTypes", resultTypes); bool runNode = true; if (!DA.GetData("RunNode", ref runNode)) { // pass } // Units var units = Results.UnitResults.Default(); DA.GetData("Units", ref units); // RunNode if (runNode) { // It needs to check if model has been runned // Always Return the FeaNode Result resultTypes.Insert(0, "FeaNode"); resultTypes.Insert(1, "FeaBar"); resultTypes.Insert(2, "FeaShell"); var _resultTypes = resultTypes.Select(r => GenericClasses.EnumParser.Parse <Results.ResultType>(r)); // Create Bsc files from resultTypes var bscPathsFromResultTypes = Calculate.Bsc.BscPathFromResultTypes(_resultTypes, filePath, units); // Create FdScript var fdScript = FemDesign.Calculate.FdScript.ReadStr(filePath, bscPathsFromResultTypes); // Run FdScript var app = new FemDesign.Calculate.Application(); bool hasExited = app.RunFdScript(fdScript, false, true, false); // Read model and results var model = Model.DeserializeFromFilePath(fdScript.StruxmlPath); IEnumerable <Results.IResult> results = Enumerable.Empty <Results.IResult>(); List <Results.FeaNode> feaNodeRes = new List <Results.FeaNode>(); List <Results.FeaBar> feaBarRes = new List <Results.FeaBar>(); List <Results.FeaShell> feaShellRes = new List <Results.FeaShell>(); if (resultTypes != null && resultTypes.Any()) { foreach (var cmd in fdScript.CmdListGen) { string path = cmd.OutFile; try { if (path.Contains("FeaNode")) { feaNodeRes = Results.ResultsReader.Parse(path).Cast <Results.FeaNode>().ToList(); } else if (path.Contains("FeaBar")) { feaBarRes = Results.ResultsReader.Parse(path).Cast <Results.FeaBar>().ToList(); } else if (path.Contains("FeaShell")) { feaShellRes = Results.ResultsReader.Parse(path).Cast <Results.FeaShell>().ToList(); } else { var _results = Results.ResultsReader.Parse(path); results = results.Concat(_results); } } catch (Exception e) { throw new Exception(e.InnerException.Message); } } } fdFeaModel = new FemDesign.Results.FDfea(feaNodeRes, feaBarRes, feaShellRes); var resultGroups = results.GroupBy(t => t.GetType()).ToList(); // Convert Data in DataTree structure var resultsTree = new DataTree <object>(); var i = 0; foreach (var resGroup in resultGroups) { resultsTree.AddRange(resGroup.AsEnumerable(), new GH_Path(i)); i++; } // Set output DA.SetData("FdModel", model); DA.SetData("FdFeaModel", fdFeaModel); DA.SetDataTree(2, resultsTree); } else { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "RunNode is set to false!"); } }
public static Dictionary <string, object> ReadStr(string strPath, List <Results.ResultType> resultTypes, Results.UnitResults units) { Results.FDfea fdFeaModel = null; // It needs to check if model has been runned // Always Return the FeaNode Result resultTypes.Insert(0, Results.ResultType.FeaNode); resultTypes.Insert(1, Results.ResultType.FeaBar); resultTypes.Insert(2, Results.ResultType.FeaShell); // Create Bsc files from resultTypes var bscPathsFromResultTypes = Calculate.Bsc.BscPathFromResultTypes(resultTypes, strPath, units); // Create FdScript var fdScript = FemDesign.Calculate.FdScript.ReadStr(strPath, bscPathsFromResultTypes); // Run FdScript var app = new FemDesign.Calculate.Application(); bool hasExited = app.RunFdScript(fdScript, false, true, false); // Read model and results var model = Model.DeserializeFromFilePath(fdScript.StruxmlPath); IEnumerable <Results.IResult> results = Enumerable.Empty <Results.IResult>(); List <Results.FeaNode> feaNodeRes = new List <Results.FeaNode>(); List <Results.FeaBar> feaBarRes = new List <Results.FeaBar>(); List <Results.FeaShell> feaShellRes = new List <Results.FeaShell>(); if (resultTypes != null && resultTypes.Any()) { foreach (var cmd in fdScript.CmdListGen) { string path = cmd.OutFile; try { if (path.Contains("FeaNode")) { feaNodeRes = Results.ResultsReader.Parse(path).Cast <Results.FeaNode>().ToList(); } else if (path.Contains("FeaBar")) { feaBarRes = Results.ResultsReader.Parse(path).Cast <Results.FeaBar>().ToList(); } else if (path.Contains("FeaShell")) { feaShellRes = Results.ResultsReader.Parse(path).Cast <Results.FeaShell>().ToList(); } else { var _results = Results.ResultsReader.Parse(path); results = results.Concat(_results); } } catch (Exception e) { throw new Exception(e.InnerException.Message); } } } fdFeaModel = new FemDesign.Results.FDfea(feaNodeRes, feaBarRes, feaShellRes); var resultGroups = results.GroupBy(t => t.GetType()).ToList(); // Convert Data in DataTree structure var resultsTree = new List <List <Results.IResult> >(); var i = 0; foreach (var resGroup in resultGroups) { resultsTree.Add(resGroup.ToList()); i++; } // Output return(new Dictionary <string, object> { { "Model", model }, { "FdFeaModel", fdFeaModel }, { "Results", results } }); }