static void Main() { // EXAMPLE 2: ANALYSING A MODEL // This example will show you how to run an analyse // with a given model from within a C# script. // This example was last updated 2022-05-03, using the ver. 21.1.0 FEM-Design API. // LOADING UP THE MODEL string struxmlPath = "exbeam.struxml"; Model model = Model.DeserializeFromFilePath(struxmlPath); // SETUP BY LOAD CALCULATION SETTINGS // These settings are found in the FEM-Design calculation window. bool NLE = true; bool PL = true; bool NLS = false; bool Cr = false; bool _2nd = false; // SETTING UP LOAD COMBINATIONS // In this example, we use the same settings (CombItem) // for all load combinations, applied with a simple loop. var combItem = new FemDesign.Calculate.CombItem(0, 0, NLE, PL, NLS, Cr, _2nd); int numLoadCombs = model.Entities.Loads.LoadCombinations.Count; var combItems = new List <Calculate.CombItem>(); for (int i = 0; i < numLoadCombs; i++) { combItems.Add(combItem); } Calculate.Comb comb = new Calculate.Comb(); comb.CombItem = combItems.ToList(); // CHOOSING THE ANALYSIS SETTINGS // These dictate which calculations to run. FemDesign.Calculate.Analysis analysis = new FemDesign.Calculate.Analysis( stage: null, comb: comb, freq: null, footfall: null, calcCase: true, calcCStage: false, calcImpf: false, calcComb: true, calcGMax: false, calcStab: false, calcFreq: false, calcSeis: false, calcDesign: false, calcFootfall: false, elemFine: false, diaphragm: false, peakSmoothing: false ); // RUN THE ANALYSIS VIA AN FDSCRIPT var bscPath = new List <string> { @"C:\GitHub\femdesign-api\FemDesign.Examples\C#\Example 2 - Analysing a model\bin\Debug\pointsupportreactions.bsc" }; FemDesign.Calculate.FdScript fdScript = FemDesign.Calculate.FdScript.Analysis(Path.GetFullPath(struxmlPath), analysis, bscPath, "", true); Calculate.Application app = new Calculate.Application(); app.RunFdScript(fdScript, false, true, true); }
protected override void SolveInstance(IGH_DataAccess DA) { // string mode = null; FemDesign.Model model = null; string filePath = null; FemDesign.Calculate.Analysis analysis = null; FemDesign.Calculate.Design design = null; List <string> resultTypes = new List <string>(); string docxTemplatePath = ""; bool endSession = false; bool closeOpenWindows = false; bool runNode = false; // get data if (!DA.GetData(0, ref mode)) { return; } if (!DA.GetData(1, ref model)) { return; } if (!DA.GetData(2, ref filePath)) { return; } if (!DA.GetData(3, ref analysis)) { return; } if (!DA.GetData(4, ref design)) { return; } if (!DA.GetDataList(5, resultTypes)) { // pass } var units = Results.UnitResults.Default(); DA.GetData(6, ref units); if (!DA.GetData(7, ref docxTemplatePath)) { // pass } if (!DA.GetData(8, ref endSession)) { // pass } if (!DA.GetData(9, ref closeOpenWindows)) { // pass } if (!DA.GetData(10, ref runNode)) { // pass } if (mode == null || model == null || filePath == null || analysis == null) { return; } // 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)); var bscPathsFromResultTypes = Calculate.Bsc.BscPathFromResultTypes(_resultTypes, filePath, units); bool rtn = false; var resultsTree = new DataTree <object>(); Results.FDfea fdFeaModel = null; // if (runNode) { model.SerializeModel(filePath); analysis.SetLoadCombinationCalculationParameters(model); rtn = model.FdApp.RunDesign(mode, filePath, analysis, design, bscPathsFromResultTypes, docxTemplatePath, endSession, closeOpenWindows); // Create FdScript var fdScript = FemDesign.Calculate.FdScript.ReadStr(filePath, bscPathsFromResultTypes); 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 i = 0; foreach (var resGroup in resultGroups) { resultsTree.AddRange(resGroup.AsEnumerable(), new GH_Path(i)); i++; } } else { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "RunNode is set to false!"); } // Set output DA.SetData("FdModel", model); DA.SetData("FdFeaModel", fdFeaModel); DA.SetDataTree(2, resultsTree); DA.SetData(3, rtn); }
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(); }
protected override void SolveInstance(IGH_DataAccess DA) { FemDesign.Calculate.Stage stage = FemDesign.Calculate.Stage.Default(); if (!DA.GetData(0, ref stage)) { // pass } FemDesign.Calculate.Comb comb = FemDesign.Calculate.Comb.GetDefault(); if (!DA.GetData(1, ref comb)) { // pass } FemDesign.Calculate.Freq freq = FemDesign.Calculate.Freq.Default(); if (!DA.GetData(2, ref freq)) { // pass } FemDesign.Calculate.Footfall footfall = FemDesign.Calculate.Footfall.Default(); if (!DA.GetData(3, ref footfall)) { // pass } bool calcCase = false; if (!DA.GetData(4, ref calcCase)) { // pass } bool calcCstage = false; if (!DA.GetData(5, ref calcCstage)) { // pass } bool calcImpf = false; if (!DA.GetData(6, ref calcImpf)) { // pass } bool calcComb = false; if (!DA.GetData(7, ref calcComb)) { // pass } bool calcGMax = false; if (!DA.GetData(8, ref calcGMax)) { // pass } bool calcStab = false; if (!DA.GetData(9, ref calcStab)) { // pass } bool calcFreq = false; if (!DA.GetData(10, ref calcFreq)) { // pass } bool calcSeis = false; if (!DA.GetData(11, ref calcSeis)) { // pass } bool calcDesign = false; if (!DA.GetData(12, ref calcDesign)) { // pass } bool calcFootfall = false; if (!DA.GetData(13, ref calcFootfall)) { // pass } bool elemFine = false; if (!DA.GetData(14, ref elemFine)) { // pass } bool diaphragm = false; if (!DA.GetData(15, ref diaphragm)) { // pass } bool peakSmoothing = false; if (!DA.GetData(16, ref peakSmoothing)) { // pass } if (stage == null || comb == null || freq == null) { // pass } // FemDesign.Calculate.Analysis obj = new FemDesign.Calculate.Analysis(stage, comb, freq, footfall, calcCase, calcCstage, calcImpf, calcComb, calcGMax, calcStab, calcFreq, calcSeis, calcDesign, calcFootfall, elemFine, diaphragm, peakSmoothing); // return DA.SetData(0, obj); }
protected override void SolveInstance(IGH_DataAccess DA) { // FemDesign.Model model = null; string filePath = null; FemDesign.Calculate.Analysis analysis = null; List <string> bscPath = new List <string>(); string docxTemplatePath = ""; bool endSession = false; bool closeOpenWindows = false; bool runNode = false; // get data if (!DA.GetData(0, ref model)) { return; } if (!DA.GetData(1, ref filePath)) { return; } if (!DA.GetData(2, ref analysis)) { return; } if (!DA.GetDataList(3, bscPath)) { // pass } if (!DA.GetData(4, ref docxTemplatePath)) { // pass } if (!DA.GetData(5, ref endSession)) { // pass } if (!DA.GetData(6, ref closeOpenWindows)) { // pass } if (!DA.GetData(7, ref runNode)) { // pass } if (model == null || filePath == null || analysis == null) { return; } // if (runNode) { model.SerializeModel(filePath); analysis.SetLoadCombinationCalculationParameters(model); bool rtn = model.FdApp.RunAnalysis(filePath, analysis, bscPath, docxTemplatePath, endSession, closeOpenWindows); DA.SetData(0, rtn); } else { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "RunNode is set to false!"); } }
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(); }