Esempio n. 1
0
 def __init__(self, gzx, gzy, yld, ff, wind, wd, shear, tob=0, dunits='km', wunits='km/h', shearunits='m/s-km', yunits='kT'):
     self.translation = ~Affine.translation(convert_units(gzx, dunits, 'mi'), convert_units(gzy, dunits, 'mi')) # translate coordinates relative to GZ (st. mi)
     self.wd = wd # wind direction in degrees (0=N, 90=E, etc.)
     self.yld = convert_units(yld, yunits, 'MT') # yield (MT)
     self.ff = ff # fission fraction, 0 < ff <= 1.0
     self.wind = convert_units(wind, wunits, 'mph') # wind speed (mi/hr)
     self.shear = convert_units(shear, shearunits, 'mph/kilofoot') # wind shear in mi/hr-kilofoot
     self.tob = tob # time of burst (hrs)
     # FORTRAN is ugly in any language
     # Store these values in the WSEG10 object to avoid recalculating them
     d = np.log(self.yld) + 2.42 # physically meaningless, but occurs twice
     # According to Hanifen, "The cloud is initially formed because the nuclear
     # fireball vaporizes both the surface of the earth at ground zero and the
     # weapon itself. The activity contained in the cloud is both neutron induced
     # and fission. After formation, the fireball rises and begins to cool at its
     # outer edges faster than the center thereby creating the typical torroidal
     # currents associated with the nuclear cloud. WSEG arbitrarily assumes that
     # the cloud will rise to a maximum center height within fifteen minutes and
     # then stabilize." 
     self.H_c =  44 + 6.1 * np.log(yld) - 0.205 * abs(d) * d # cloud center height
     lnyield = np.log(self.yld)
     self.s_0 = np.exp(0.7 + lnyield / 3 - 3.25 / (4.0 + (lnyield + 5.4)**2)) #sigma_0
     self.s_02 = self.s_0**2
     self.s_h = 0.18 * self.H_c # sigma_h
     self.T_c = 1.0573203 * (12 * (self.H_c / 60) - 2.5 * (self.H_c / 60)**2) * (1 - 0.5 * np.exp(-1 * (self.H_c / 25)**2)) # time constant
     self.L_0 = wind * self.T_c # L_0, used by g(x)
     self.L_02 = self.L_0**2
     self.s_x2 = self.s_02 * (self.L_02 + 8 * self.s_02) / (self.L_02 + 2 * self.s_02)
     self.s_x = np.sqrt(self.s_x2) # sigma_x
     self.L_2 = self.L_02 + 2 * self.s_x2
     self.L = np.sqrt(self.L_2) # L
     self.n = (ff * self.L_02 + self.s_x2) / (self.L_02 + 0.5 * self.s_x2) # n
     self.a_1 = 1 / (1 + ((0.001 * self.H_c * wind) / self.s_0)) # alpha_1
Esempio n. 2
0
def r_soviet_overpressure(y,
                          op,
                          h,
                          thermal_layer=True,
                          yunits='kT',
                          dunits='m',
                          opunits='kg/cm^2'):
    """Estimate the radius from the epicenter at which peak static overpressure op 
will be experienced based graphs in the 1987 Soviet military publication _Iadernoe 
oruzhie: Posbie dlia ofitserov_. 

The most interesting feature of this model is that it provides for cases
in which the Mach stem is suppressed by a thermal layer. This phenomenon was 
considered a largely theoretical 'second-order effect' among most US NWE researchers,
but was observed in extreme forms in the USSR's atmospheric nuclear tests, leading
them to conclude it would occur in many real-world military scenarios. To use a 
Soviet model with a Mach stem present, set the parameter thermal_layer to False."""
    yld = convert_units(y, yunits, 'kT')
    height = convert_units(h, dunits, 'm')
    sh = scale_height(yld, height)
    overp = convert_units(op, opunits, 'kg/cm^2')
    if thermal_layer:
        return convert_units(_rsovietnomach(sh, overp), 'm',
                             dunits) * y**0.3333333333333333
    else:
        return convert_units(_rsovietmach(sh, overp), 'm',
                             dunits) * y**0.3333333333333333
Esempio n. 3
0
def brode_overpressure(y, r, h, yunits='kT', dunits='m', opunits='kg/cm^2'):
    """Estimate peak static overpressure at radius r from the epicenter of a burst
with yield y and a burst height of h using the Brode equation."""
    yld = convert_units(y, yunits, 'kT')
    ground_range = convert_units(r, dunits, 'kilofeet')
    height = convert_units(h, dunits, 'kilofeet')
    op = _brodeop(yld, ground_range, height)
    return convert_units(op, 'psi', opunits)
Esempio n. 4
0
 def D_Hplus1(self, x, y, dunits='km', doseunits='Sv'):
     """Returns dose rate at x, y at 1 hour after burst. This value includes dose rate from all activity that WILL be deposited at that location, not just that that has arrived by H+1 hr."""
     rx, ry = self.translation * (convert_units(x, dunits, 'mi'), convert_units(y, dunits, 'mi')) * ~Affine.rotation(-self.wd + 270)
     f_x = self.yld * 2e6 * self.phi(rx) * self.g(rx) * self.ff
     s_y = np.sqrt(self.s_02 + ((8 * abs(rx + 2 * self.s_x) * self.s_02) / self.L) + (2 * (self.s_x * self.T_c * self.s_h * self.shear)**2 / self.L_2) + (((rx + 2 * self.s_x) * self.L_0 * self.T_c * self.s_h * self.shear)**2 / self.L**4))
     a_2 = 1 / (1 + ((0.001 * self.H_c * self.wind) / self.s_0) * (1 - norm.cdf(2 * x / self.wind)))
     f_y = np.exp(-0.5 * (ry / (a_2 * s_y))**2) / (2.5066282746310002 * s_y)
     return convert_units(f_x * f_y, 'Roentgen', doseunits)
Esempio n. 5
0
def brode_overpressure(y, r, h, yunits='kT', dunits='m', opunits='kg/cm^2'):
    """Estimate peak static overpressure at radius r from the epicenter of a burst
with yield y and a burst height of h using the Brode equation."""
    yld = convert_units(y, yunits, 'kT')
    ground_range = convert_units(r, dunits, 'kilofeet')
    height = convert_units(h, dunits, 'kilofeet')
    op = _brodeop(yld, ground_range, height)
    return convert_units(op, 'psi', opunits)
Esempio n. 6
0
def DNA_static_overpressure(y, r, h, yunits='kT', dunits='m', opunits='kg/cm^2'):
    """Estimate peak static overpressure at range r from a burst of yield y using the
the Defense Nuclear Agency 1kT standard free airburst overpressure. This assumes a
thermally ideal surface."""
    yld = convert_units(y, yunits, 'kT')
    gr = convert_units(r, dunits, 'm')
    height = convert_units(h, dunits, 'm')
    op = _DNAairburstpeakop(gr, yld, height)
    return convert_units(op, 'Pa', opunits)
Esempio n. 7
0
 def __init__(self,
              gzx,
              gzy,
              yld,
              ff,
              wind,
              wd,
              shear,
              tob=0,
              dunits='km',
              wunits='km/h',
              shearunits='m/s-km',
              yunits='kT'):
     self.translation = ~Affine.translation(convert_units(
         gzx, dunits, 'mi'), convert_units(
             gzy, dunits,
             'mi'))  # translate coordinates relative to GZ (st. mi)
     self.wd = wd  # wind direction in degrees (0=N, 90=E, etc.)
     self.yld = convert_units(yld, yunits, 'MT')  # yield (MT)
     self.ff = ff  # fission fraction, 0 < ff <= 1.0
     self.wind = convert_units(wind, wunits, 'mph')  # wind speed (mi/hr)
     self.shear = convert_units(
         shear, shearunits, 'mph/kilofoot')  # wind shear in mi/hr-kilofoot
     self.tob = tob  # time of burst (hrs)
     # FORTRAN is ugly in any language
     # Store these values in the WSEG10 object to avoid recalculating them
     d = np.log(self.yld) + 2.42  # physically meaningless, but occurs twice
     # According to Hanifen, "The cloud is initially formed because the nuclear
     # fireball vaporizes both the surface of the earth at ground zero and the
     # weapon itself. The activity contained in the cloud is both neutron induced
     # and fission. After formation, the fireball rises and begins to cool at its
     # outer edges faster than the center thereby creating the typical torroidal
     # currents associated with the nuclear cloud. WSEG arbitrarily assumes that
     # the cloud will rise to a maximum center height within fifteen minutes and
     # then stabilize."
     self.H_c = 44 + 6.1 * np.log(yld) - 0.205 * abs(
         d) * d  # cloud center height
     lnyield = np.log(self.yld)
     self.s_0 = np.exp(0.7 + lnyield / 3 - 3.25 /
                       (4.0 + (lnyield + 5.4)**2))  #sigma_0
     self.s_02 = self.s_0**2
     self.s_h = 0.18 * self.H_c  # sigma_h
     self.T_c = 1.0573203 * (12 * (self.H_c / 60) - 2.5 *
                             (self.H_c / 60)**2) * (
                                 1 - 0.5 * np.exp(-1 * (self.H_c / 25)**2)
                             )  # time constant
     self.L_0 = wind * self.T_c  # L_0, used by g(x)
     self.L_02 = self.L_0**2
     self.s_x2 = self.s_02 * (self.L_02 + 8 * self.s_02) / (self.L_02 +
                                                            2 * self.s_02)
     self.s_x = np.sqrt(self.s_x2)  # sigma_x
     self.L_2 = self.L_02 + 2 * self.s_x2
     self.L = np.sqrt(self.L_2)  # L
     self.n = (ff * self.L_02 + self.s_x2) / (self.L_02 + 0.5 * self.s_x2
                                              )  # n
     self.a_1 = 1 / (1 + ((0.001 * self.H_c * wind) / self.s_0))  # alpha_1
Esempio n. 8
0
def DNA_dynamic_pressure(y, r, h, yunits='kT', dunits='m', opunits='kg/cm^2'):
    """Estimate peak pynamic overpressure at range r from a burst of yield y using the
the Defense Nuclear Agency 1kT standard free airburst overpressure, assuming an ideal
surface. Many real-world surfaces are not ideal (most, in the opinion of Soviet 
analysts), meaning that this function has only limited predictove capability."""
    yld = convert_units(y, yunits, 'kT')
    gr = convert_units(r, dunits, 'm')
    height = convert_units(h, dunits, 'm')
    dyn = _DNAairburstpeakdyn(gr, yld, height)
    return convert_units(dyn, 'Pa', opunits)
Esempio n. 9
0
def r_soviet_ground_thermal(y, fluence, h, visibility, yunits='kT', dunits='m'):
    """Estimate the range from a ground burst of yield y at which fluence will occur
using the methodology described in _Iadernoe oruzhie_ 4th ed. (1987).

visibility is given as International Visibility Code (IVC) numbers (1=thick fog,
9=clear)."""
    yld = convert_units(y, yunits, 'kT')
    v = _ivc_to_model_input(visibility, yld, h)
    sr = _reverse_soviet_ground_thermal(fluence, yld, v)
    return convert_units(sr, 'km', dunits)
Esempio n. 10
0
def DNA_dynamic_pressure(y, r, h, yunits='kT', dunits='m', opunits='kg/cm^2'):
    """Estimate peak pynamic overpressure at range r from a burst of yield y using the
the Defense Nuclear Agency 1kT standard free airburst overpressure, assuming an ideal
surface. Many real-world surfaces are not ideal (most, in the opinion of Soviet 
analysts), meaning that this function has only limited predictove capability."""
    yld = convert_units(y, yunits, 'kT')
    gr = convert_units(r, dunits, 'm')
    height = convert_units(h, dunits, 'm')
    dyn = _DNAairburstpeakdyn(gr, yld, height)
    return convert_units(dyn, 'Pa', opunits)
Esempio n. 11
0
def soviet_ground_thermal(y, r, h, visibility, yunits='kT', dunits='m'):
    """Estimate thermal fluence at range r from a ground burst of yield y using the 
methodology described in _Iadernoe oruzhie_ 4th ed. (1987).

visibility is given as International Visibility Code (IVC) numbers (1=thick fog,
9=clear)."""
    slant_range = convert_units(r, dunits, 'km')
    yld = convert_units(y, yunits, 'kT')
    # height only used to determine visibility code
    v = _ivc_to_model_input(visibility, yld, h)
    fluence = _soviet_ground_thermal(slant_range, yld, v)
    return fluence
Esempio n. 12
0
def DNA_static_overpressure(y,
                            r,
                            h,
                            yunits='kT',
                            dunits='m',
                            opunits='kg/cm^2'):
    """Estimate peak static overpressure at range r from a burst of yield y using the
the Defense Nuclear Agency 1kT standard free airburst overpressure. This assumes a
thermally ideal surface."""
    yld = convert_units(y, yunits, 'kT')
    gr = convert_units(r, dunits, 'm')
    height = convert_units(h, dunits, 'm')
    op = _DNAairburstpeakop(gr, yld, height)
    return convert_units(op, 'Pa', opunits)
Esempio n. 13
0
 def D_Hplus1(self, x, y, dunits='km', doseunits='Sv'):
     """Returns dose rate at x, y at 1 hour after burst. This value includes dose rate from all activity that WILL be deposited at that location, not just that that has arrived by H+1 hr."""
     rx, ry = self.translation * (convert_units(
         x, dunits, 'mi'), convert_units(
             y, dunits, 'mi')) * ~Affine.rotation(-self.wd + 270)
     f_x = self.yld * 2e6 * self.phi(rx) * self.g(rx) * self.ff
     s_y = np.sqrt(self.s_02 +
                   ((8 * abs(rx + 2 * self.s_x) * self.s_02) / self.L) +
                   (2 * (self.s_x * self.T_c * self.s_h * self.shear)**2 /
                    self.L_2) +
                   (((rx + 2 * self.s_x) * self.L_0 * self.T_c * self.s_h *
                     self.shear)**2 / self.L**4))
     a_2 = 1 / (1 + ((0.001 * self.H_c * self.wind) / self.s_0) *
                (1 - norm.cdf(2 * x / self.wind)))
     f_y = np.exp(-0.5 * (ry / (a_2 * s_y))**2) / (2.5066282746310002 * s_y)
     return convert_units(f_x * f_y, 'Roentgen', doseunits)
Esempio n. 14
0
    def dose(self, x, y, dunits='km', doseunits='Sv'):
        """Estimate of total "Equivalent Residual Dose" (ERD) at location x, y from time of fallout arrival to 30 days, including a 90% recovery factor. 

"""
        rx, _ = self.translation * (convert_units(x, dunits, 'mi'), convert_units(y, dunits, 'mi')) * ~Affine.rotation(-self.wd + 270)
        t_a = self.fallouttoa(rx)
        # To obtain a measure of dose to humans, "Biological Dose" was defined as the
        # product of the DH+1 and a conversion factor, called Bio. Bio is an
        # empirical function depending on fallout arrival time and length of
        # exposure. Ten percent of the dose received is assumed irreparable and
        # ninety percent is assumed reparable with a thirty day time constant. This
        # was solved numerically and plotted as Dose vs. Time. Bio was then estimated
        # as Bio = (t / 19)**0.33, so that the dose at some time after activity
        # arrival is defined as Dose = DH+1 * Bio. Further refinements in the model
        # resulted in a second order approximation for Bio used here:
        bio = np.exp(-(0.287 + 0.52 * np.log(t_a / 31.6) + 0.04475 * np.log((t_a / 31.6)**2)))
        return self.D_Hplus1(x, y, dunits=dunits, doseunits=doseunits) * bio
Esempio n. 15
0
def r_soviet_overpressure(y, op, h, thermal_layer=True, yunits='kT', dunits='m', opunits='kg/cm^2'):
    """Estimate the radius from the epicenter at which peak static overpressure op 
will be experienced based graphs in the 1987 Soviet military publication _Iadernoe 
oruzhie: Posbie dlia ofitserov_. 

The most interesting feature of this model is that it provides for cases
in which the Mach stem is suppressed by a thermal layer. This phenomenon was 
considered a largely theoretical 'second-order effect' among most US NWE researchers,
but was observed in extreme forms in the USSR's atmospheric nuclear tests, leading
them to conclude it would occur in many real-world military scenarios. To use a 
Soviet model with a Mach stem present, set the parameter thermal_layer to False."""
    yld = convert_units(y, yunits, 'kT')
    height = convert_units(h, dunits, 'm')
    sh = scale_height(yld, height)
    overp = convert_units(op, opunits, 'kg/cm^2')
    if thermal_layer:
        return convert_units(_rsovietnomach(sh, overp), 'm', dunits) * y**0.3333333333333333
    else:
        return convert_units(_rsovietmach(sh, overp), 'm', dunits) * y**0.3333333333333333
Esempio n. 16
0
    def dose(self, x, y, dunits='km', doseunits='Sv'):
        """Estimate of total "Equivalent Residual Dose" (ERD) at location x, y from time of fallout arrival to 30 days, including a 90% recovery factor. 

"""
        rx, _ = self.translation * (convert_units(
            x, dunits, 'mi'), convert_units(
                y, dunits, 'mi')) * ~Affine.rotation(-self.wd + 270)
        t_a = self.fallouttoa(rx)
        # To obtain a measure of dose to humans, "Biological Dose" was defined as the
        # product of the DH+1 and a conversion factor, called Bio. Bio is an
        # empirical function depending on fallout arrival time and length of
        # exposure. Ten percent of the dose received is assumed irreparable and
        # ninety percent is assumed reparable with a thirty day time constant. This
        # was solved numerically and plotted as Dose vs. Time. Bio was then estimated
        # as Bio = (t / 19)**0.33, so that the dose at some time after activity
        # arrival is defined as Dose = DH+1 * Bio. Further refinements in the model
        # resulted in a second order approximation for Bio used here:
        bio = np.exp(-(0.287 + 0.52 * np.log(t_a / 31.6) +
                       0.04475 * np.log((t_a / 31.6)**2)))
        return self.D_Hplus1(x, y, dunits=dunits, doseunits=doseunits) * bio