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 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); }
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(); }
static void Main() { // PRACTICAL EXAMPLE: PARAMETRIC STUDY - SENSITIVITY ANALYSIS // In this example, we will analyse how different stiffness values on a support // will affect a bridge (modelled simply as a beam). // This example was last updated 2022-05-03, using the ver. 21.1.0 FEM-Design API. // FILE PATH SETUP // Set the different paths and folders relevant to the example string struxmlPath = "Bridge Model.struxml"; string bscPath = Path.GetFullPath("eigenfreq.bsc"); List <string> bscPaths = new List <string>(); bscPaths.Add(bscPath); // READ MODEL AND GET SUPPORTS Model model = Model.DeserializeFromFilePath(struxmlPath); //Read point support number and its stiffness properties var support1 = model.Entities.Supports.PointSupport.FirstOrDefault(p => p.Name == "S.1"); var support2 = model.Entities.Supports.PointSupport.FirstOrDefault(p => p.Name == "S.2"); double alpha = 0.5; // ITERATION AND ANALYSIS PROCESS // Iterate over model using different stiffness value for the the rotational spring cy int N = 20; for (int i = 1; i <= N; i++) { // Change stiffness of support cy support1.Rotations.YPos = Math.Pow(10, alpha); support1.Rotations.YNeg = Math.Pow(10, alpha); support2.Rotations.YPos = Math.Pow(10, alpha); support2.Rotations.YNeg = Math.Pow(10, alpha); var supports = new List <Supports.PointSupport>() { support1, support2 }; model.AddElements(supports); // Save struxml string outPathIndividual = Path.GetFullPath("Bridge Model_out" + Convert.ToString(alpha, System.Globalization.CultureInfo.InvariantCulture) + ".struxml"); model.SerializeModel(outPathIndividual); // Run analysis var freq = new Calculate.Freq(5, 0, false, false, true, -0.01); Calculate.Analysis analysis = new Calculate.Analysis(null, null, freq, null, true, false, false, false, false, false, true, false, false, false, false, false, false); FemDesign.Calculate.FdScript fdScript = FemDesign.Calculate.FdScript.Analysis(outPathIndividual, analysis, bscPaths, "", true); Calculate.Application app = new Calculate.Application(); app.RunFdScript(fdScript, false, true, true); // Read results from csv file (general method) { Console.WriteLine(""); Console.WriteLine(string.Format("Alpha: {0}", alpha)); string text = System.IO.File.ReadAllText(fdScript.CmdListGen[0].OutFile); Console.WriteLine(text); } alpha = alpha + 0.5; } // ENDING THE PROGRAM Console.WriteLine("\nPress any key to close console."); Console.ReadKey(); }
static void Main() { // PRACTICAL EXAMPLE: PARAMETRIC STUDY - REACTIONS // In this example, we will analyse how different E-modules will result // in different reaction forces in the supports holding a concrete plate. // This example was last updated 2022-05-03, using the ver. 21.1.0 FEM-Design API. // FILE PATH SETUP // Set the different paths and folders relevant to the example string struxmlPath = "sample_slab.struxml"; string outFolder = "output/"; if (!Directory.Exists(outFolder)) { Directory.CreateDirectory(outFolder); } string bscPath = Path.GetFullPath("pointsupportreactions.bsc"); List <string> bscPaths = new List <string>(); bscPaths.Add(bscPath); // READ MODEL Model model = Model.DeserializeFromFilePath(struxmlPath); // READ SLAB TO ANALYSE // In this example, the slab is card-coded to no. 5; if you make any personal applications, // it is probably better to look for a slab with a certain name, eg. P.1, to avoid confusion. Shells.Slab slab = model.Entities.Slabs[4]; Materials.Material material = model.Entities.Slabs[4].Material; double Ecm = Convert.ToDouble(material.Concrete.Ecm); // ITERATION & ANALYSIS PROCESS // Iterate over model using different E-modulus for the slab for (int i = 1; i < 6; i++) { // Change E-modulus double new_Ecm = Math.Round(0.2 * i * Ecm); material.Concrete.Ecm = Convert.ToString(new_Ecm); // Save struxml string outPathIndividual = Path.GetFullPath(outFolder + "sample_slab_out" + Convert.ToString(new_Ecm) + ".struxml"); model.SerializeModel(outPathIndividual); // Run analysis Calculate.Analysis analysis = new Calculate.Analysis(null, null, null, null, calcCase: true, false, false, false, false, false, false, false, false, false, false, false, false); FemDesign.Calculate.FdScript fdScript = FemDesign.Calculate.FdScript.Analysis(outPathIndividual, analysis, bscPaths, "", true); Calculate.Application app = new Calculate.Application(); app.RunFdScript(fdScript, false, true, true); string pointSupportReactionsPath = Path.Combine(outFolder, "pointsupportreactions.csv"); // Reading results (This method is only available for some result types as of now, but more will be added) var results = Results.ResultsReader.Parse(pointSupportReactionsPath); var pointSupportReactions = results.Cast <Results.PointSupportReaction>().ToList(); // Print results Console.WriteLine(); Console.WriteLine($"Emean: {new_Ecm}"); Console.WriteLine("Id | Reaction "); foreach (var reaction in pointSupportReactions) { Console.WriteLine($"{reaction.Id,10} | {reaction.Fz,10}"); } } // ENDING THE PROGRAM Console.WriteLine("\nPress any key to close console."); Console.ReadKey(); }