Skip to content

Writing case files from Python

The JSON case files used by the command line can also be read, modified and written from Python with pyflange.io. This is convenient for running variants of a case and for collecting the results of many cases in one table.

Download the full script: case_file.py. Run it in a folder that contains fatigue-case.json.

1. Load a case

from pyflange.io import load_inputfile, create_fatiguecase

case = load_inputfile("fatigue-case.json")      # a plain Python dictionary
fcase = create_fatiguecase(case)                # a BoltFatigueAnalysis object
print(f"Damage of the example case: {fcase.damage:.3f}")
Damage of the example case: 0.501

load_inputfile returns the content of the file as a dictionary, with the same structure as the JSON file. create_fatiguecase builds the BoltFatigueAnalysis from it. To do both in one step, use load_fatiguecase.

2. Write variants of the case

Change the dictionary and save it with dict_to_json. Here we create one case per design gap angle, with the AMD1 design gap height of each angle:

import copy
from pyflange.io import dict_to_json
from pyflange.stats import gap_height_distribution

D = 2 * case["FlangeSegment"]["R"]          # tower outer diameter
u_tol = 0.0014                              # flatness tolerance, 1.4 mm/m

for angle_deg in (30, 60, 90, 120):
    angle = angle_deg * deg
    variant = copy.deepcopy(case)
    variant["CaseID"] = f"Example, {angle_deg} deg gap"
    variant["FlangeSegment"]["gap"]["angle"] = angle
    variant["FlangeSegment"]["gap"]["height"] = gap_height_distribution(D, u_tol, angle * D/2).ppf(0.95)
    dict_to_json(variant, f"case-gap{angle_deg}.json")
    print(f"Written case-gap{angle_deg}.json")

Since the example case has "k_shell": "interp", the shell stiffness is interpolated for the new gap angle when the case is loaded.

3. Export a case with its results

fatiguecase_to_dict converts an analysis back to the JSON format. With verbose=True it adds the results and the intermediate quantities of the model, like the output of pyflange determ:

from pyflange.io import fatiguecase_to_dict

result = fatiguecase_to_dict(fcase, verbose=True)   # input + results + report
dict_to_json(result, "case-res.json")
print(f"Fatigue life: {result['FatigueLife']:.1f} years")

The same function works for an analysis built in Python, for example the fatigue object of the L-flange tutorial: this is the way to create a case file from a Python model.

from pyflange.io import fatiguecase_to_dict, dict_to_json
dict_to_json(fatiguecase_to_dict(fatigue), "my-case.json")

Note

The JSON format currently supports L-flange segments only.

4. Run a batch

import glob
import pandas as pd
from pyflange.io import load_fatiguecase

rows = []
for path in sorted(glob.glob("case-gap*.json")):
    fc = load_fatiguecase(path)
    rows.append({"case": path,
                 "gap angle [deg]": fc.fseg.gap.angle / deg,
                 "damage": fc.damage,
                 "fatigue life [years]": fc.fatigue_life})

table = pd.DataFrame(rows)
print(table.to_string(index=False))
table.to_excel("results.xlsx", index=False)
            case  gap angle [deg]   damage  fatigue life [years]
case-gap120.json            120.0 1.080555             27.763512
 case-gap30.json             30.0 0.503086             59.632003
 case-gap60.json             60.0 0.763320             39.302010
 case-gap90.json             90.0 1.169948             25.642169

The table is also saved to results.xlsx. To add a Monte Carlo simulation of each case, use sample_fatiguecase, which returns the same table as the sample command.