Skip to content

Commit

Permalink
Add validation page
Browse files Browse the repository at this point in the history
  • Loading branch information
TLCFEM committed Dec 28, 2024
1 parent 8576a33 commit 117f7ce
Show file tree
Hide file tree
Showing 4 changed files with 332 additions and 7 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import pandas
section_table = pandas.read_excel(
'https://www.aisc.org/globalassets/aisc/manual/v15.0-shapes-database/aisc-shapes-database-v15.0.xlsx',
sheet_name=1,
storage_options={'User-Agent': 'Mozilla/5.0'},
usecols='A:CF')
print(section_table.head())
```
Expand Down
321 changes: 321 additions & 0 deletions docs/Library/Section/Code/Validation.ipynb
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
}
2 changes: 1 addition & 1 deletion docs/Library/Section/Eccentricity.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ $$

It can be further verified by applying a moment while restraining the axial displacement.

```text
```text hl_lines="18"
node 1 0 0
node 2 1 0
material Elastic1D 1 1
Expand Down

0 comments on commit 117f7ce

Please sign in to comment.