-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
332 additions
and
7 deletions.
There are no files selected for viewing
15 changes: 9 additions & 6 deletions
15
docs/Example/Structural/Dynamics/integrating-preprocessing-with-python.ipynb
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,321 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Validation of Code Section Designations\n", | ||
"\n", | ||
"There is a built-in database of some standard sections used in various design standards.\n", | ||
"\n", | ||
"In this page, we try to validate the section properties of some designations.\n", | ||
"To this end, we mainly use US designations, which are compiled and well documented in the [AISC Shapes Database](https://www.aisc.org/publications/steel-construction-manual-resources/16th-ed-steel-construction-manual/aisc-shapes-database-v16.0/).\n", | ||
"\n", | ||
"## Some Utilities\n", | ||
"\n", | ||
"What we are going to do in the following is to prepare the database." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import pandas\n", | ||
"\n", | ||
"section_table = pandas.read_excel(\n", | ||
" \"https://www.aisc.org/globalassets/aisc/manual/v15.0-shapes-database/aisc-shapes-database-v15.0.xlsx\",\n", | ||
" sheet_name=1,\n", | ||
" storage_options={\"User-Agent\": \"Mozilla/5.0\"},\n", | ||
" usecols=\"A:CF\",\n", | ||
")\n", | ||
"print(section_table.head())" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We define a function to get the area, moment of inertia about the strong and weak axes." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 93, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def get_section(designation: str):\n", | ||
" return section_table[section_table[\"AISC_Manual_Label\"] == designation]\n", | ||
"\n", | ||
"\n", | ||
"def get_properties(designation: str):\n", | ||
" section = get_section(designation)\n", | ||
" return section[\"A\"].values[0], section[\"Ix\"].values[0], section[\"Iy\"].values[0]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The designations that will be validated are the following.\n", | ||
"To save space, a comma separated long string is provided." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 94, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"all_sections = \"W44X335,W44X290,W44X262,W44X230,W40X655,W40X593,W40X503,W40X431,W40X397,W40X372,W40X362,W40X324,W40X297,W40X277,W40X249,W40X215,W40X199,W40X392,W40X331,W40X327,W40X294,W40X278,W40X264,W40X235,W40X211,W40X183,W40X167,W40X149,W36X925,W36X853,W36X802,W36X723,W36X652,W36X529,W36X487,W36X441,W36X395,W36X361,W36X330,W36X302,W36X282,W36X262,W36X247,W36X231,W36X256,W36X232,W36X210,W36X194,W36X182,W36X170,W36X160,W36X150,W36X135,W33X387,W33X354,W33X318,W33X291,W33X263,W33X241,W33X221,W33X201,W33X169,W33X152,W33X141,W33X130,W33X118,W30X391,W30X357,W30X326,W30X292,W30X261,W30X235,W30X211,W30X191,W30X173,W30X148,W30X132,W30X124,W30X116,W30X108,W30X99,W30X90,W27X539,W27X368,W27X336,W27X307,W27X281,W27X258,W27X235,W27X217,W27X194,W27X178,W27X161,W27X146,W27X129,W27X114,W27X102,W27X94,W27X84,W24X370,W24X335,W24X306,W24X279,W24X250,W24X229,W24X207,W24X192,W24X176,W24X162,W24X146,W24X131,W24X117,W24X104,W24X103,W24X94,W24X84,W24X76,W24X68,W24X62,W24X55,W21X275,W21X248,W21X223,W21X201,W21X182,W21X166,W21X147,W21X132,W21X122,W21X111,W21X101,W21X93,W21X83,W21X73,W21X68,W21X62,W21X55,W21X48,W21X57,W21X50,W21X44,W18X311,W18X283,W18X258,W18X234,W18X211,W18X192,W18X175,W18X158,W18X143,W18X130,W18X119,W18X106,W18X97,W18X86,W18X76,W18X71,W18X65,W18X60,W18X55,W18X50,W18X46,W18X40,W18X35,W16X100,W16X89,W16X77,W16X67,W16X57,W16X50,W16X45,W16X40,W16X36,W16X31,W16X26,W14X873,W14X808,W14X730,W14X665,W14X605,W14X550,W14X500,W14X455,W14X426,W14X398,W14X370,W14X342,W14X311,W14X283,W14X257,W14X233,W14X211,W14X193,W14X176,W14X159,W14X145,W14X132,W14X120,W14X109,W14X99,W14X90,W14X82,W14X74,W14X68,W14X61,W14X53,W14X48,W14X43,W14X38,W14X34,W14X30,W14X26,W14X22,W12X336,W12X305,W12X279,W12X252,W12X230,W12X210,W12X190,W12X170,W12X152,W12X136,W12X120,W12X106,W12X96,W12X87,W12X79,W12X72,W12X65,W12X58,W12X53,W12X50,W12X45,W12X40,W12X35,W12X30,W12X26,W12X22,W12X19,W12X16,W12X14,W10X112,W10X100,W10X88,W10X77,W10X68,W10X60,W10X54,W10X49,W10X45,W10X39,W10X33,W10X30,W10X26,W10X22,W10X19,W10X17,W10X15,W10X12,W8X67,W8X58,W8X48,W8X40,W8X35,W8X31,W8X28,W8X24,W8X21,W8X18,W8X15,W8X13,W8X10,W6X25,W6X20,W6X15,W6X16,W6X12,W6X9,W6X8.5,W5X19,W5X16,W4X13,M12.5X12.4,M12.5X11.6,M12X11.8,M12X10.8,M12X10,M10X9,M10X8,M10X7.5,M8X6.5,M8X6.2,M6X4.4,M6X3.7,M5X18.9,M4X6,M4X4.08,M4X3.45,M4X3.2,M3X2.9,S24X121,S24X106,S24X100,S24X90,S24X80,S20X96,S20X86,S20X75,S20X66,S18X70,S18X54.7,S15X50,S15X42.9,S12X50,S12X40.8,S12X35,S12X31.8,S10X35,S10X25.4,S8X23,S8X18.4,S6X17.25,S6X12.5,S5X10,S4X9.5,S4X7.7,S3X7.5,S3X5.7,HP18X204,HP18X181,HP18X157,HP18X135,HP16X183,HP16X162,HP16X141,HP16X121,HP16X101,HP16X88,HP14X117,HP14X102,HP14X89,HP14X73,HP12X89,HP12X84,HP12X74,HP12X63,HP12X53,HP10X57,HP10X42,HP8X36,WT22X167.5,WT22X145,WT22X131,WT22X115,WT20X327.5,WT20X296.5,WT20X251.5,WT20X215.5,WT20X198.5,WT20X186,WT20X181,WT20X162,WT20X148.5,WT20X138.5,WT20X124.5,WT20X107.5,WT20X99.5,WT20X196,WT20X165.5,WT20X163.5,WT20X147,WT20X139,WT20X132,WT20X117.5,WT20X105.5,WT20X91.5,WT20X83.5,WT20X74.5,WT18X462.5,WT18X426.5,WT18X401,WT18X361.5,WT18X326,WT18X264.5,WT18X243.5,WT18X220.5,WT18X197.5,WT18X180.5,WT18X165,WT18X151,WT18X141,WT18X131,WT18X123.5,WT18X115.5,WT18X128,WT18X116,WT18X105,WT18X97,WT18X91,WT18X85,WT18X80,WT18X75,WT18X67.5,WT16.5X193.5,WT16.5X177,WT16.5X159,WT16.5X145.5,WT16.5X131.5,WT16.5X120.5,WT16.5X110.5,WT16.5X100.5,WT16.5X84.5,WT16.5X76,WT16.5X70.5,WT16.5X65,WT16.5X59,WT15X195.5,WT15X178.5,WT15X163,WT15X146,WT15X130.5,WT15X117.5,WT15X105.5,WT15X95.5,WT15X86.5,WT15X74,WT15X66,WT15X62,WT15X58,WT15X54,WT15X49.5,WT15X45,WT13.5X269.5,WT13.5X184,WT13.5X168,WT13.5X153.5,WT13.5X140.5,WT13.5X129,WT13.5X117.5,WT13.5X108.5,WT13.5X97,WT13.5X89,WT13.5X80.5,WT13.5X73,WT13.5X64.5,WT13.5X57,WT13.5X51,WT13.5X47,WT13.5X42,WT12X185,WT12X167.5,WT12X153,WT12X139.5,WT12X125,WT12X114.5,WT12X103.5,WT12X96,WT12X88,WT12X81,WT12X73,WT12X65.5,WT12X58.5,WT12X52,WT12X51.5,WT12X47,WT12X42,WT12X38,WT12X34,WT12X31,WT12X27.5,WT10.5X137.5,WT10.5X124,WT10.5X111.5,WT10.5X100.5,WT10.5X91,WT10.5X83,WT10.5X73.5,WT10.5X66,WT10.5X61,WT10.5X55.5,WT10.5X50.5,WT10.5X46.5,WT10.5X41.5,WT10.5X36.5,WT10.5X34,WT10.5X31,WT10.5X27.5,WT10.5X24,WT10.5X28.5,WT10.5X25,WT10.5X22,WT9X155.5,WT9X141.5,WT9X129,WT9X117,WT9X105.5,WT9X96,WT9X87.5,WT9X79,WT9X71.5,WT9X65,WT9X59.5,WT9X53,WT9X48.5,WT9X43,WT9X38,WT9X35.5,WT9X32.5,WT9X30,WT9X27.5,WT9X25,WT9X23,WT9X20,WT9X17.5,WT8X50,WT8X44.5,WT8X38.5,WT8X33.5,WT8X28.5,WT8X25,WT8X22.5,WT8X20,WT8X18,WT8X15.5,WT8X13,WT7X436.5,WT7X404,WT7X365,WT7X332.5,WT7X302.5,WT7X275,WT7X250,WT7X227.5,WT7X213,WT7X199,WT7X185,WT7X171,WT7X155.5,WT7X141.5,WT7X128.5,WT7X116.5,WT7X105.5,WT7X96.5,WT7X88,WT7X79.5,WT7X72.5,WT7X66,WT7X60,WT7X54.5,WT7X49.5,WT7X45,WT7X41,WT7X37,WT7X34,WT7X30.5,WT7X26.5,WT7X24,WT7X21.5,WT7X19,WT7X17,WT7X15,WT7X13,WT7X11,WT6X168,WT6X152.5,WT6X139.5,WT6X126,WT6X115,WT6X105,WT6X95,WT6X85,WT6X76,WT6X68,WT6X60,WT6X53,WT6X48,WT6X43.5,WT6X39.5,WT6X36,WT6X32.5,WT6X29,WT6X26.5,WT6X25,WT6X22.5,WT6X20,WT6X17.5,WT6X15,WT6X13,WT6X11,WT6X9.5,WT6X8,WT6X7,WT5X56,WT5X50,WT5X44,WT5X38.5,WT5X34,WT5X30,WT5X27,WT5X24.5,WT5X22.5,WT5X19.5,WT5X16.5,WT5X15,WT5X13,WT5X11,WT5X9.5,WT5X8.5,WT5X7.5,WT5X6,WT4X33.5,WT4X29,WT4X24,WT4X20,WT4X17.5,WT4X15.5,WT4X14,WT4X12,WT4X10.5,WT4X9,WT4X7.5,WT4X6.5,WT4X5,WT3X12.5,WT3X10,WT3X7.5,WT3X8,WT3X6,WT3X4.5,WT3X4.25,WT2.5X9.5,WT2.5X8,WT2X6.5,MT6.25X6.2,MT6.25X5.8,MT6X5.9,MT6X5.4,MT6X5,MT5X4.5,MT5X4,MT5X3.75,MT4X3.25,MT4X3.1,MT3X2.2,MT3X1.85,MT2.5X9.45,MT2X3,ST12X60.5,ST12X53,ST12X50,ST12X45,ST12X40,ST10X48,ST10X43,ST10X37.5,ST10X33,ST9X35,ST9X27.35,ST7.5X25,ST7.5X21.45,ST6X25,ST6X20.4,ST6X17.5,ST6X15.9,ST5X17.5,ST5X12.7,ST4X11.5,ST4X9.2,ST3X8.6,ST3X6.25,ST2.5X5,ST2X4.75,ST2X3.85,ST1.5X3.75,ST1.5X2.85\".split(\n", | ||
" \",\"\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"It is possible to get the properties." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"print(get_properties(all_sections[0]))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Next, we define the function to run the analysis and extract the result.\n", | ||
"\n", | ||
"The following is the template model file that will be used.\n", | ||
"A few things to note:\n", | ||
"\n", | ||
"1. The material is assumed to be elastic with unit elastic modulus.\n", | ||
"2. The default integration scheme is used for each designation.\n", | ||
"3. A unit displacement load is applied to axial, strong axis bending and weak axis bending.\n", | ||
"4. The `US3DC` category is used, it automatically recentre the section." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 96, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"template = \"\"\"\n", | ||
"node 1 0 0 0\n", | ||
"\n", | ||
"material Elastic1D 1 1\n", | ||
"\n", | ||
"section US3DC $designation$ 1 1 1\n", | ||
"\n", | ||
"element SingleSection3D 1 1 1\n", | ||
"\n", | ||
"displacement 1 0 1 1 1\n", | ||
"displacement 2 0 1 2 1\n", | ||
"displacement 3 0 1 3 1\n", | ||
"\n", | ||
"step static 1 1\n", | ||
"set ini_step_size 1\n", | ||
"\n", | ||
"analyze\n", | ||
"\n", | ||
"peek node 1\n", | ||
"\n", | ||
"exit\n", | ||
"\"\"\"" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"By using the above settings, the resistances on three DoFs are effectively the area and moments of inertia.\n", | ||
"\n", | ||
"To extract the data, we process the output." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 97, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import subprocess\n", | ||
"\n", | ||
"\n", | ||
"def run_analysis(designation):\n", | ||
" with open(\"analysis.sp\", \"w\") as f:\n", | ||
" f.write(template.replace(\"$designation$\", designation))\n", | ||
"\n", | ||
" result = (\n", | ||
" subprocess.check_output([\"suanpan\", \"-nc\", \"-f\", \"analysis.sp\"])\n", | ||
" .decode(\"utf-8\")\n", | ||
" .splitlines()\n", | ||
" )\n", | ||
" for i, line in enumerate(result):\n", | ||
" if line.startswith(\"Resistance\"):\n", | ||
" return [float(x) for x in result[i + 1].split()]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 98, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"all_results = {}\n", | ||
"\n", | ||
"\n", | ||
"def validate(designation: str):\n", | ||
" fraction = [\n", | ||
" x / y for x, y in zip(run_analysis(designation), get_properties(designation))\n", | ||
" ]\n", | ||
"\n", | ||
" all_results[designation] = fraction" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 99, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"for section in all_sections:\n", | ||
" validate(section)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 100, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import matplotlib.pyplot as plt\n", | ||
"\n", | ||
"\n", | ||
"def plot(title, index):\n", | ||
" values = [x[index] for x in all_results.values()]\n", | ||
" min_value = min(values)\n", | ||
" max_value = max(values)\n", | ||
" colors = [\"red\" if abs(x - 1) > 0.05 else \"green\" for x in values]\n", | ||
" fig = plt.figure(figsize=(100, 6), tight_layout=True)\n", | ||
" ax = fig.add_subplot(111)\n", | ||
" ax.bar(all_results.keys(), values, color=colors)\n", | ||
" ax.set_ylabel(\"Numerical/Analytical\")\n", | ||
" ax.set_xlabel(\"Section\")\n", | ||
" ax.set_ybound(min_value - 0.02, max_value + 0.01)\n", | ||
" ax.set_xlim(-1, len(all_results))\n", | ||
" ax.grid()\n", | ||
"\n", | ||
" for i, v in enumerate(values):\n", | ||
" ax.text(\n", | ||
" i, min_value - 0.01, f\"{v:.3f}\", horizontalalignment=\"center\", rotation=90\n", | ||
" )\n", | ||
"\n", | ||
" plt.title(title)\n", | ||
" plt.xticks(rotation=90)\n", | ||
" plt.savefig(f\"{'-'.join([x.lower() for x in title.split()])}.pdf\")\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Area\n", | ||
"\n", | ||
"In general, the area can be relatively accurately computed.\n", | ||
"However, as all those sections are internally modelled by three flat pieces, the root fillet cannot be accounted for.\n", | ||
"As a result, the numerical area is often smaller than the reference value.\n", | ||
"\n", | ||
"Some very light M shapes cannot be approximated." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"plot(\"Area\", 0)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Strong Axis Bending\n", | ||
"\n", | ||
"Some very heavy T sections tend to have poor strong axis moment of inertia.\n", | ||
"In this shapes, the thickness of flange accounts for a significant portion of the overall depth.\n", | ||
"The normal stress in the flange presents gradient.\n", | ||
"In the meantime, there is only one layer of integration points along the thickness of flange, which is not accurate enough in this case." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"plot(\"Strong Axis Moment of Inertia\", 1)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Weak Axis Bending\n", | ||
"\n", | ||
"The tapered shapes tend to have more material towards the center, as a result, the weak axis moment of inertia is smaller.\n", | ||
"It is modelled by a flat rectangle in numerical models, this overestimate the moment of inertia, mainly for S and ST shapes." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"plot(\"Weak Axis Moment of Inertia\", 2)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The figures can be downloaded: [area](../area.pdf), [strong axis moment of inertia](../strong-axis-moment-of-inertia.pdf), [weak axis moment of inertia](../weak-axis-moment-of-inertia.pdf)." | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": ".venv", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.10.15" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters