|
| 1 | +# bluemira is an integrated inter-disciplinary design tool for future fusion |
| 2 | +# reactors. It incorporates several modules, some of which rely on other |
| 3 | +# codes, to carry out a range of typical conceptual fusion reactor design |
| 4 | +# activities. |
| 5 | +# |
| 6 | +# Copyright (C) 2021-2023 M. Coleman, J. Cook, F. Franza, I.A. Maione, S. McIntosh, |
| 7 | +# J. Morris, D. Short |
| 8 | +# |
| 9 | +# bluemira is free software; you can redistribute it and/or |
| 10 | +# modify it under the terms of the GNU Lesser General Public |
| 11 | +# License as published by the Free Software Foundation; either |
| 12 | +# version 2.1 of the License, or (at your option) any later version. |
| 13 | +# |
| 14 | +# bluemira is distributed in the hope that it will be useful, |
| 15 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | +# Lesser General Public License for more details. |
| 18 | +# |
| 19 | +# You should have received a copy of the GNU Lesser General Public |
| 20 | +# License along with bluemira; if not, see <https://www.gnu.org/licenses/>. |
| 21 | + |
| 22 | +""" |
| 23 | +Tools for simple solenoid calculations. |
| 24 | +""" |
| 25 | + |
| 26 | +from typing import Tuple |
| 27 | + |
| 28 | +import numpy as np |
| 29 | + |
| 30 | +from bluemira.magnetostatics.semianalytic_2d import semianalytic_Bx, semianalytic_Bz |
| 31 | + |
| 32 | + |
| 33 | +def calculate_B_max( |
| 34 | + rho_j: float, r_inner: float, r_outer: float, height: float, z_0: float = 0.0 |
| 35 | +) -> float: |
| 36 | + """ |
| 37 | + Calculate the maximum self-field in a solenoid. This is always located |
| 38 | + at (r_inner, z_0) |
| 39 | +
|
| 40 | + Parameters |
| 41 | + ---------- |
| 42 | + rho_j: |
| 43 | + Current density across the solenoid winding pack [A/m^2] |
| 44 | + r_inner: |
| 45 | + Solenoid inner radius [m] |
| 46 | + r_outer: |
| 47 | + Solenoid outer radius [m] |
| 48 | + height: |
| 49 | + Solenoid vertical extent [m] |
| 50 | +
|
| 51 | + Returns |
| 52 | + ------- |
| 53 | + Maximum field in a solenoid [T] |
| 54 | +
|
| 55 | + Notes |
| 56 | + ----- |
| 57 | + Cross-checked graphically with k data from Boom and Livingstone, "Superconducting |
| 58 | + solenoids", 1962, Fig. 6 |
| 59 | + """ |
| 60 | + dxc = 0.5 * (r_outer - r_inner) |
| 61 | + xc = r_inner + dxc |
| 62 | + dzc = 0.5 * height |
| 63 | + x_bmax = r_inner |
| 64 | + current = rho_j * (height * (r_outer - r_inner)) |
| 65 | + Bx_max = current * semianalytic_Bx(xc, z_0, x_bmax, z_0, dxc, dzc) |
| 66 | + Bz_max = current * semianalytic_Bz(xc, z_0, x_bmax, z_0, dxc, dzc) |
| 67 | + return np.hypot(Bx_max, Bz_max) |
| 68 | + |
| 69 | + |
| 70 | +def calculate_hoop_radial_stress( |
| 71 | + B_in: float, |
| 72 | + B_out: float, |
| 73 | + rho_j: float, |
| 74 | + r_inner: float, |
| 75 | + r_outer: float, |
| 76 | + r: float, |
| 77 | + poisson_ratio: float = 0.3, |
| 78 | +) -> Tuple[float]: |
| 79 | + """ |
| 80 | + Calculate the hoop and radial stress at a radial location in a solenoid |
| 81 | +
|
| 82 | + Parameters |
| 83 | + ---------- |
| 84 | + B_in: |
| 85 | + Field at the inside edge of the solenoid [T] |
| 86 | + B_out: |
| 87 | + Field at the outside edge of the solenoid [T] |
| 88 | + rho_j: |
| 89 | + Current density across the solenoid winding pack [A/m^2] |
| 90 | + r_inner: |
| 91 | + Solenoid inner radius [m] |
| 92 | + r_outer: |
| 93 | + Solenoid outer radius [m] |
| 94 | + r: |
| 95 | + Radius at which to calculate [m] |
| 96 | + poisson_ratio: |
| 97 | + Poisson ratio of the material |
| 98 | +
|
| 99 | + Returns |
| 100 | + ------- |
| 101 | + hoop_stress: |
| 102 | + Hoop stress at the radial location [Pa] |
| 103 | + radial_stress: |
| 104 | + Radial stress at the radial location [Pa] |
| 105 | +
|
| 106 | + Notes |
| 107 | + ----- |
| 108 | + Wilson, Superconducting Magnets, 1982, equations 4.10 and 4.11 |
| 109 | + Must still factor in the fraction of load-bearing material |
| 110 | + """ |
| 111 | + alpha = r_outer / r_inner |
| 112 | + eps = r / r_inner |
| 113 | + nu = poisson_ratio |
| 114 | + alpha2 = alpha**2 |
| 115 | + eps2 = eps**2 |
| 116 | + ratio2 = alpha2 / eps2 |
| 117 | + |
| 118 | + K = (alpha * B_in - B_out) * rho_j * r_inner / (alpha - 1) # noqa: N806 |
| 119 | + M = (B_in - B_out) * rho_j * r_inner / (alpha - 1) # noqa: N806 |
| 120 | + a = K * (2 + nu) / (3 * (alpha + 1)) |
| 121 | + c = M * (3 + nu) / 8 |
| 122 | + |
| 123 | + b = alpha2 + alpha + 1 |
| 124 | + b1 = ratio2 - eps * (1 + 2 * nu) * (alpha + 1) / (2 + nu) |
| 125 | + b2 = -ratio2 - eps * (alpha + 1) |
| 126 | + |
| 127 | + d = alpha2 + 1 + ratio2 - eps2 * (1 + 3 * nu) / (3 + nu) |
| 128 | + e = alpha2 + 1 - ratio2 - eps2 |
| 129 | + |
| 130 | + hoop_stress = a * (b + b1) - c * d |
| 131 | + radial_stress = a * (b + b2) - c * e |
| 132 | + |
| 133 | + return hoop_stress, radial_stress |
| 134 | + |
| 135 | + |
| 136 | +def calculate_flux_max(B_max: float, r_inner: float, r_outer: float) -> float: |
| 137 | + """ |
| 138 | + Calculate the maximum flux achievable from a solenoid |
| 139 | +
|
| 140 | + Parameters |
| 141 | + ---------- |
| 142 | + B_max: |
| 143 | + Maximum field in the solenoid [T] |
| 144 | + r_inner: |
| 145 | + Solenoid inner radius [m] |
| 146 | + r_outer: |
| 147 | + Solenoid outer radius [m] |
| 148 | +
|
| 149 | + Returns |
| 150 | + ------- |
| 151 | + Maximum flux achievable from a solenoid [V.s] |
| 152 | + """ |
| 153 | + return np.pi / 3 * B_max * (r_outer**2 + r_inner**2 + r_outer * r_inner) |
0 commit comments