Example #1
0
 def test_invalid_instantiation(self):
     # x_series
     with pytest.raises(ValueError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[0] = [['x', 'y', 'z']]
         for invalid_args in list(itertools.product(*invalid_arg_combos)):
             SSV.create_vis(*invalid_args)
     # x_series_unit
     with pytest.raises(TypeError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[1] = [1, True]
         for invalid_args in itertools.product(*invalid_arg_combos):
             SSV.create_vis(*invalid_args)
     # svg_path
     with pytest.raises(FileNotFoundError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[2] = ['']
         for invalid_args in itertools.product(*invalid_arg_combos):
             SSV.create_vis(*invalid_args)
     # title
     with pytest.raises(TypeError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[3] = [1, True]
         for invalid_args in itertools.product(*invalid_arg_combos):
             SSV.create_vis(*invalid_args)
     # font_size
     with pytest.raises(TypeError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[4] = ['x']
         for invalid_args in itertools.product(*invalid_arg_combos):
             SSV.create_vis(*invalid_args)
Example #2
0
File: tests.py Project: ahd985/ssv
 def test_invalid_instantiation(self):
     # x_series
     with pytest.raises(ValueError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[0] = [['x', 'y', 'z']]
         for invalid_args in list(itertools.product(*invalid_arg_combos)):
             SSV.create_vis(*invalid_args)
     # x_series_unit
     with pytest.raises(TypeError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[1] = [1, True]
         for invalid_args in itertools.product(*invalid_arg_combos):
             SSV.create_vis(*invalid_args)
     # svg_path
     with pytest.raises(FileNotFoundError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[2] = ['']
         for invalid_args in itertools.product(*invalid_arg_combos):
             SSV.create_vis(*invalid_args)
     # title
     with pytest.raises(TypeError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[3] = [1, True]
         for invalid_args in itertools.product(*invalid_arg_combos):
             SSV.create_vis(*invalid_args)
     # font_size
     with pytest.raises(TypeError):
         invalid_arg_combos = [[args[0]] for args in self._valid_inputs]
         invalid_arg_combos[4] = ['x']
         for invalid_args in itertools.product(*invalid_arg_combos):
             SSV.create_vis(*invalid_args)
Example #3
0
def run():
    with open(os.path.join('examples', 'example_5', 'data.json')) as f:
        data = json.load(f)
    ssv_model = SSV.from_json(data)

    ssv_model.save_visualization(
        os.path.join('examples', 'example_5', 'example_5'))

    return True
Example #4
0
def run():
    # Generate fake cutset data
    cutset_data = [['%LDHR','ACB-A-F','ACB-B-F','RCIC-F','HPCI-F'],
                   ['%ATWS','SLC-F','RHR-F'],
                   ['%LOSP','EDG-A-F','EDG-B-F','RCIC-F','HPCI-F'],
                   ['%LDHR','DCB-A-F','DCB-B-F','LPCI-A-F','LPCI-B-F']]

    be_data = {'%LDHR':['Loss of Decay Heat Removal', 1.0E-2],
                        '%LOSP':['Loss of Offsite Power', 1.0E-3],
                        '%ATWS':['Anticipated Transient Without SCRAM', 1.0E-2],
                        'SLC-F':['Failure of Standby Liquid Coolant',1.0E-3],
                        'ACB-A-F':['Failure of AC Bus A',3.0E-3],
                        'ACB-B-F':['Failure of AC Bus B',3.0E-3],
                        'XFMR-F':['Failure of Main Transformer',2.0E-4],
                        'EDG-A-F':['Failure of Emergency Diesel Generator A',1.0E-4],
                        'EDG-B-F':['Failure of Emergency Diesel Generator B',1.0E-4],
                        'DCB-A-F':['Failure of DC Bus A',2.0E-2],
                        'DCB-B-F':['Failure of DC Bus B',2.0E-2],
                        'RHR-F':['Failure of Residual Heat Removal',1.0E-4],
                        'RCIC-F':['Failure of Reactor Core Isolation Cooling',4.0E-3],
                        'LPCI-A-F':['Failure of Low Pressure Coolant Injection A',5.0E-2],
                        'LPCI-B-F':['Failure of Low Pressure Coolant Injection B',5.0E-2],
                        'HPCI-F':['Failure of High Pressure Cooland Injection',1.0E-3]}

    cutset_freqs = [np.prod([be_data[be][1] for be in cutset]) for cutset in cutset_data]

    be_list = be_data.keys()
    be_map = {be:[True if be in cutset else False for cutset in cutset_data] for be in be_list}
    report = [[[i] + be_data[i] for i in cutset] for cutset in cutset_data]


    # Initiate and hook up SSV model
    ssv_model = SSV.create_vis(cutset_freqs, 'per year', os.path.join('examples', 'example_4', 'example_4.svg'),
                    title="Cutset Visualization", font_size=8)

    # Add tablular data
    ssv_model.add_element('table', 'cutset-report', tabular_data=report,
                          headers=['Basic Event', 'Description', 'Probability'])

    # Wire up svg elements
    svg_id = ''
    for eq in be_list:
        if "%" in eq:
            svg_id = eq[1:]
        else:
            svg_id = eq[:-2]

        el = ssv_model.add_element('cell', svg_id.lower())
        el.add_condition('logical', data=be_map[eq], true_color='#F44336', false_color='#FFFFFF')

    ssv_model.save_visualization(os.path.join('examples', 'example_4', 'example_4'))

    return True
Example #5
0
def run():
    # Let's use the freely available CFAST code from NIST to generate data
    # http://www.nist.gov/el/fire_research/cfast.cfm
    # This file is from the sample problem provided with the code

    data_f = os.path.join('examples', 'example_2', 'standard_n.csv')
    data = pd.read_csv(data_f, skiprows=[2], header=[0, 1])
    data.columns = [', '.join(col) if i > 0 else col[0] for i, col in enumerate(data.columns)]

    # Initiate and hook up SSV model
    ssv_model = SSV.create_vis(data['Time'], 'seconds', os.path.join('examples', 'example_2', 'example_2.svg'),
                    title="CFAST Example", font_size=8)

    gas_color_scale = ['#fd8d3c','#fc4e2a','#e31a1c','#bd0026','#800026']
    gas_color_levels = np.linspace(min(data['Upper Layer Temperature, Comp 2']),
                                   max(data['Upper Layer Temperature, Comp 3']), 5)

    # Add nodes
    for i in range(1,4):
        data['Layer Height Upper, Comp %d' % i] = 3.0
        node = ssv_model.add_element('cell', 'node-%d' % i, 'Node %d' % i, cell_report_id='node-%d-report' % i)
        node.add_condition('zonaly', description='Zone Heights', unit='m',
                           data=data[['Layer Height, Comp %d' % i, 'Layer Height Upper, Comp %d' % i]],
                           data_dynamic=data[
                               ['Lower Layer Temperature, Comp %d' % i,
                                'Upper Layer Temperature, Comp %d' % i]],
                           color_scale=gas_color_scale,
                           color_levels=gas_color_levels,
                           max_height=3, description_dynamic='Zone Temperatures', unit_dynamic='C',
                           min_height=0, section_label='Zone')
        node.add_condition('info', data=data[['Pressure, Comp %d' % i]], description='Pressure', unit='Pa')

        if i == 1:
            node.add_condition('info', data=data[['HRR, bunsen']], description='HRR', unit='W')
        elif i == 2:
            node.add_condition('info', data=data[['HRR, Wood_Wall']], description='HRR', unit='W')

    # Add fires
    fire_1 = ssv_model.add_element('toggle', 'fire-1', 'Fire 1')
    fire_1.add_condition('showhide', data=data['HRR, bunsen'])
    fire_2 = ssv_model.add_element('toggle', 'fire-2', 'Fire 2')
    fire_2.add_condition('showhide', data=data['HRR, Wood_Wall'])

    # Show gas color scale
    ssv_model.add_element('legend', 'color-scale', 'Gas Temperature (C)',
                          color_scale=gas_color_scale,
                          color_levels=gas_color_levels)

    ssv_model.save_visualization(os.path.join('examples', 'example_2', 'example_2'))

    return True
Example #6
0
def run():
    # Load steam tables and build interpolation functions for several features
    sat_tables = pd.read_excel(
        os.path.join('examples', 'example_1', 'steam_tables.xls'))
    f_press = interp1d(sat_tables['vg'], sat_tables['Mpa'])
    f_temp = interp1d(sat_tables['vg'], sat_tables['deg C'])
    f_wtr_sp_vol = interp1d(sat_tables['vg'], sat_tables['vf'])
    f_wtr_enthalpy = interp1d(sat_tables['vg'], sat_tables['hf'])
    f_vap_enthalpy = interp1d(sat_tables['vg'], sat_tables['hg'])
    f_lat_heat = interp1d(sat_tables['vg'], sat_tables['hfg'])

    # Function to get properties of saturated water+vapor given vapor density
    def get_props_from_vap_density(density):
        props_out = {}

        sp_vol = 1 / density
        props_out['press'] = float(f_press(sp_vol))
        props_out['temp'] = float(f_temp(sp_vol) + 273.15)
        props_out['wtr_density'] = float(1 / f_wtr_sp_vol(sp_vol))
        props_out['wtr_enthalpy'] = float(f_wtr_enthalpy(sp_vol))
        props_out['vap_enthalpy'] = float(f_vap_enthalpy(sp_vol))
        props_out['lat_heat'] = float(f_lat_heat(sp_vol))

        return props_out

    def th_run(initial_wtr_mass, initial_wtr_level, downstream_height,
               steam_flow, discharge_press, time_step, end_time):
        """
            Simple Thermal-Hydraulic analysis code for water between 2 compartments.
            Assume downstream is water/steam compartment always at saturated conditions.
            Assume upstream is saturated steam environment that discharges to downstream.
            Heat loss to environment and Condensation is assumed to be negligible.  Inputs:

                initial_wtr_mass = initial downstream water mass in kg.
                initial_wtr_level = initial downstream water level in m.  Note that
                    the downstream volume is assumed to increase linearly with height
                    based on this input.
                downstream_height = total height of downstream compartment (m)
                steam_flow = 4 x n array of n occurences of upstream to downstream steam flow.
                    Row 1 is start time of flow in S
                    Row 2 is end time of flow in S
                    Row 3 is specific enthalpy of flow in kJ/kg
                    Row 4 is total mass of flow in kg
                discharge_press = pressure control point of downstream compartment in MPa.
                    Downstream compartment is modeled as instantly opening and relieving
                    conditions down to atmospheric over a single time step.
                time_step = time step of analysis in S.
                end_time = analysis end time is S.

            Returns downstream pressure, temperature, water level, and logical states
            of relief valve and steam discharge as a function of time.
        """

        # Assign initial conditions
        vap_density = 0.59
        wtr_mass = initial_wtr_mass
        wtr_lvl = initial_wtr_level
        wtr_lvl_vol_slope = wtr_lvl / wtr_mass

        # Determine downstream conditions using steam tables - assume saturated conditions
        props = get_props_from_vap_density(vap_density)
        press = props['press']
        temp = props['temp']
        wtr_enthalpy = props['wtr_enthalpy']
        wtr_density = props['wtr_density']
        vap_enthalpy = props['vap_enthalpy']
        lat_heat = props['lat_heat']

        wtr_vol = wtr_mass / wtr_density
        total_vol = wtr_vol * downstream_height / wtr_lvl
        vap_vol = total_vol - wtr_vol
        vap_mass = vap_density * vap_vol
        lvl_vol_slope = wtr_lvl / wtr_vol

        # Cast steam_flow as numpy array
        steam_flow = np.array(steam_flow)

        # Flag for relief valve
        rv_flag = False

        # Record conditons at t=0
        conditions_out = {
            'press': [press],
            'temp': [temp],
            'wtr_lvl': [wtr_lvl],
            'rv': [rv_flag],
            'disch': [False],
            'time': [0]
        }

        # Run through time span, calculating conditions at each step
        for t in np.arange(1, end_time + time_step, time_step):
            # Check if current time span is within or includes any steam_flow entry
            # and calculate integrated enthalpy addition
            time_mask = ((steam_flow[0] >= t) &
                         (steam_flow[0] < t + time_step)) | (
                             (steam_flow[0] < t) & (steam_flow[1] > t))
            start_times = steam_flow[0][time_mask]
            start_times[start_times < t] = t
            end_times = steam_flow[1][time_mask]
            end_times[end_times > t + time_step] = t + time_step
            time_deltas = end_times - start_times
            upstream_enthalpy = steam_flow[2][time_mask]
            flow_mass = steam_flow[3][time_mask] * time_deltas

            # Calculate vaporized water mass
            excess_enthalpy = (upstream_enthalpy - wtr_enthalpy) * flow_mass
            vaporized_wtr_mass = (excess_enthalpy / lat_heat).sum()

            # Update water mass and vapor mass and density
            wtr_mass += flow_mass.sum() - vaporized_wtr_mass
            vap_mass += vaporized_wtr_mass
            vap_density = vap_mass / (total_vol * (1 - wtr_vol / total_vol))

            # If we are at relief pressure reset to saturated conditions and calculate
            # change in water mass
            if press > discharge_press:
                vap_density = 0.59
                props = get_props_from_vap_density(vap_density)
                wtr_enthalpy_new = props['wtr_enthalpy']
                lat_heat = props['lat_heat']
                wtr_mass -= (wtr_enthalpy -
                             wtr_enthalpy_new) * wtr_mass / lat_heat
                rv_flag = True
            else:
                rv_flag = False

            # Calculate new properties
            # Assume water density has negligible change between time steps
            props = get_props_from_vap_density(vap_density)
            press = props['press']
            temp = props['temp']
            wtr_density = props['wtr_density']
            wtr_enthalpy = props['wtr_enthalpy']
            lat_heat = props['lat_heat']
            wtr_lvl = lvl_vol_slope * wtr_mass / wtr_density
            vap_mass = vap_density * (total_vol * (1 - wtr_vol / total_vol))

            # Record new properties
            conditions_out['time'].append(t)
            conditions_out['press'].append(press)
            conditions_out['temp'].append(temp)
            conditions_out['wtr_lvl'].append(wtr_lvl)
            conditions_out['disch'].append(flow_mass.sum())
            conditions_out['rv'].append(rv_flag)

        return conditions_out

    # Run the code
    initial_wtr_mass = 1000000  # kg ~ 2200000 lbm
    initial_wtr_level = 5  # m ~ 16.405 ft
    downstream_height = 10  # m ~ 32.81 ft
    steam_flow = [
        [2, 15, 45, 65],  # S - Steam discharge start
        [10, 40, 60, 90],  # S - Steam discharge end
        [2650, 2650, 2650, 2650],  # kJ/kg - steam at ~2000 psi or 14 MPa
        [50, 100, 150, 150]
    ]  # kg/s - flowrate
    discharge_press = 0.79  # Mpa ~ 100 psig
    time_step = 1  # Seconds
    end_time = 100  # Seconds

    sim_data = th_run(initial_wtr_mass, initial_wtr_level, downstream_height,
                      steam_flow, discharge_press, time_step, end_time)

    # Initiate and hook up SSV model
    ssv_model = SSV.create_vis(sim_data['time'],
                               'seconds',
                               os.path.join('examples', 'example_1',
                                            'example_1.svg'),
                               title="Steam Quench Tank Simulation",
                               font_size=8)

    water_color_scale = ['#0570b0', '#3690c0', '#74a9cf']
    water_color_levels = np.linspace(min(sim_data['temp']),
                                     max(sim_data['temp']),
                                     len(water_color_scale))
    gas_color_scale = ['#fdd49e', '#fdbb84', '#fc8d59']
    gas_color_levels = np.linspace(min(sim_data['temp']),
                                   max(sim_data['temp']), len(gas_color_scale))

    # Wire up svg elements
    tank = ssv_model.add_element('cell',
                                 'tank-1',
                                 'Quench Tank',
                                 report_id='tank-1-report')
    tank.add_condition('background',
                       description='Vapor Temp',
                       unit='K',
                       color_data=sim_data['temp'],
                       color_scale=gas_color_scale,
                       color_levels=gas_color_levels)
    tank.add_condition('dynamiclevel',
                       description='Water Level',
                       unit='m',
                       level_data=sim_data['wtr_lvl'],
                       color_data=sim_data['temp'],
                       color_scale=water_color_scale,
                       color_levels=water_color_levels,
                       max_height=10,
                       color_data_description='Water Temp',
                       color_data_unit='K',
                       overlay='bubbles',
                       min_height=0)
    tank.add_condition('info',
                       data=sim_data['press'],
                       description='Press',
                       unit='MPa')
    tank.add_popover("sparkline", sim_data['wtr_lvl'], label='Tank #1 Wtr Lvl')

    relief_valve = ssv_model.add_element('cell', 'relief-valve',
                                         'Relief Valve')
    relief_valve.add_condition('logical',
                               data=sim_data['rv'],
                               true_color='#4CAF50',
                               false_color='#F44336')

    steam_discharge = ssv_model.add_element('cell',
                                            'steam-discharge',
                                            'Steam Discharge',
                                            report_id='disch-report')
    steam_discharge.add_condition('logical',
                                  description='Flowrate',
                                  data=sim_data['disch'],
                                  true_color='#4CAF50',
                                  false_color='#F44336',
                                  unit='kg/s')

    steam_toggle = ssv_model.add_element('toggle', 'steam-toggle',
                                         'Steam Toggle')
    steam_toggle.add_condition('showhide', data=sim_data['disch'])

    relief_toggle = ssv_model.add_element('toggle', 'relief-toggle',
                                          'Relief Toggle')
    relief_toggle.add_condition('showhide', data=sim_data['rv'])

    water_temp_legend = ssv_model.add_element('legend', 'color-scale-water',
                                              'Water Temperature (F)')
    water_temp_legend.add_condition("colorscale", water_color_scale,
                                    water_color_levels)

    gas_temp_legend = ssv_model.add_element('legend', 'color-scale-gas',
                                            'Gas Temperature (F)')
    gas_temp_legend.add_condition("colorscale", gas_color_scale,
                                  gas_color_levels)

    ssv_model.save_visualization(
        os.path.join('examples', 'example_1', 'example_1'))

    return True
Example #7
0
File: tests.py Project: ahd985/ssv
 def test_bad_svg_(self):
     with pytest.raises(ET.ParseError):
         SSV.create_vis([0], 'Title', os.path.join('tests', 'data', 'bad_svg.svg'))
Example #8
0
def run():
    # Let's build assume our core flux distribution takes the form of:
    #   Φ(r,z) = J0(2.405r/R) cos(πz/H)
    #
    #   Where:
    #     r is the radius from the center of the core
    #     z is the height from the bottom of the core
    #     J0 is the bessel function of the first kind, zero order
    #     R is the total radius of the core
    #     H is the total height of the core
    #
    #   Let's also assume the temperature distribution in the core matches this profile.

    # Build profile function for entire core
    def get_temp(rv, zv, peak_temp):
        # Core height and radius, in m
        core_h = 3.7
        core_r = 1.7
        # Assume there is a ratio of core reflector dimensions to active core dimensions
        refl_ratio = 0.5

        temp = peak_temp * ((special.jv(0, 2.405 * rv / core_r * refl_ratio) *
                             np.cos(np.pi * zv / core_h / 2 * refl_ratio)))

        # Reflect r and z axis to build full core
        # Start with r axis
        temp_reflect = np.fliplr(temp[:, :, :])
        temp = np.append(temp_reflect, temp, 1)
        # Flip z axis
        temp_reflect = np.flipud(temp[:, :, :])
        temp = np.append(temp_reflect, temp, 0)

        return temp

    # Raise peak core temperature from 500 K to 800 K over 24 hours
    # Nodalize core into 5 radial regions x 30 axial regions (15 above center and 15 below center)
    # Take data point every 15 minutes
    r = np.linspace(0, 1.7, 5)
    z = np.linspace(0, 3.7 / 2, 15)
    t = np.linspace(0, 24, 96)
    rv, zv, tz = np.meshgrid(r, z, t, indexing='ij')

    temp_initial = 500
    temp_final = 800
    peak_temp = temp_initial + (temp_final - temp_initial) * (t / t[-1])
    core_temp = get_temp(rv, zv, peak_temp)

    # Transpose data
    core_temp = core_temp.transpose((2, 1, 0))

    # Initiate and hook up SSV model
    ssv_model = SSV.create_vis(t,
                               'hours',
                               os.path.join('examples', 'example_3',
                                            'example_3.svg'),
                               title="Core Heatmap Example",
                               font_size=8)

    core_color_scale = ['#ffffb2', '#fecc5c', '#fd8d3c', '#f03b20', '#bd0026']
    core_color_levels = np.linspace(300, 800, 5)

    node = ssv_model.add_element('heatmap', 'core', 'Core')
    node.add_condition('rect',
                       description='Core Heatmap',
                       unit='K',
                       color_data=core_temp,
                       color_scale=core_color_scale,
                       color_levels=core_color_levels)

    # Use outer vertical rows of heatmap to represent temperature in vessel wall
    walls = ssv_model.add_element('line', ['wall-left', 'wall-right'],
                                  'Vessel Wall')
    walls.add_condition('equaly',
                        description='Vessel Wall Temp',
                        unit='K',
                        color_data=core_temp[:, :, 0],
                        color_scale=core_color_scale,
                        color_levels=core_color_levels)

    # Track average and max core temperature
    core_temp_avg = core_temp.mean(axis=2).mean(axis=1)
    core_temp_max = core_temp.max(axis=2).max(axis=1)
    report = ssv_model.add_element('report', 'report-1', 'Core Metrics')
    report.add_condition('info',
                         description='Avg Temp',
                         unit='F',
                         data=core_temp_avg)
    report.add_condition('info',
                         description='Max Temp',
                         unit='F',
                         data=core_temp_max)

    core_temp_legend = ssv_model.add_element('legend', 'core-color-scale',
                                             'Core Temperature (K)')
    core_temp_legend.add_condition("colorscale", core_color_scale,
                                   core_color_levels)

    ssv_model.save_visualization(
        os.path.join('examples', 'example_3', 'example_3'))

    return True
Example #9
0
 def test_element_id_collision(self):
     with pytest.raises(ValueError):
         vis = SSV.create_vis(*[i[0] for i in self._valid_inputs])
         vis.add_element('cell', 'id_1')
         vis.add_element('heatmap', 'id_1')
Example #10
0
 def test_from_json(self):
     with open('tests/data/data.json') as f:
         data = json.load(f)
     SSV.from_json(data)
Example #11
0
File: tests.py Project: ahd985/ssv
 def test_element_id_collision(self):
     with pytest.raises(ValueError):
         vis = SSV.create_vis(*[i[0] for i in self._valid_inputs])
         vis.add_element('cell', 'id_1')
         vis.add_element('heatmap', 'id_1')
Example #12
0
 def test_bad_svg_(self):
     with pytest.raises(ET.ParseError):
         SSV.create_vis([0], 'Title',
                        os.path.join('tests', 'data', 'bad_svg.svg'))
Example #13
0
 def test_valid_instantiation(self):
     for args in list(itertools.product(*self._valid_inputs)):
         SSV.create_vis(*args)
Example #14
0
File: tests.py Project: ahd985/ssv
 def test_valid_instantiation(self):
     for args in list(itertools.product(*self._valid_inputs)):
         SSV.create_vis(*args)
Example #15
0
def run():
    # Let's build assume our core flux distribution takes the form of:
    #   Φ(r,z) = J0(2.405r/R) cos(πz/H)
    #
    #   Where:
    #     r is the radius from the center of the core
    #     z is the height from the bottom of the core
    #     J0 is the bessel function of the first kind, zero order
    #     R is the total radius of the core
    #     H is the total height of the core
    #
    #   Let's also assume the temperature distribution in the core matches this profile.

    # Build profile function for entire core
    def get_temp(rv, zv, peak_temp):
        # Core height and radius, in m
        core_h = 3.7
        core_r = 1.7
        # Assume there is a ratio of core reflector dimensions to active core dimensions
        refl_ratio = 0.5

        temp = peak_temp * ((special.jv(0, 2.405 * rv / core_r * refl_ratio) *
                            np.cos(np.pi * zv / core_h / 2 * refl_ratio)))

        # Reflect r and z axis to build full core
        # Start with r axis
        temp_reflect = np.fliplr(temp[:,:,:])
        temp = np.append(temp_reflect, temp, 1)
        # Flip z axis
        temp_reflect = np.flipud(temp[:,:,:])
        temp = np.append(temp_reflect, temp, 0)

        return temp

    # Raise peak core temperature from 500 K to 800 K over 24 hours
    # Nodalize core into 5 radial regions x 30 axial regions (15 above center and 15 below center)
    # Take data point every 15 minutes
    r = np.linspace(0, 1.7, 5)
    z = np.linspace(0, 3.7/2, 15)
    t = np.linspace(0,24,96)
    rv,zv,tz = np.meshgrid(r,z,t,indexing='ij')

    temp_initial = 500
    temp_final = 800
    peak_temp = temp_initial + (temp_final - temp_initial) * (t / t[-1])
    core_temp = get_temp(rv, zv, peak_temp)

    # Transpose data
    core_temp = core_temp.transpose((2,1,0))

    # Initiate and hook up SSV model
    ssv_model = SSV.create_vis(t, 'hours', os.path.join('examples', 'example_3', 'example_3.svg'),
                    title="Core Heatmap Example", font_size=8)

    core_color_scale = ['#ffffb2','#fecc5c','#fd8d3c','#f03b20','#bd0026']
    core_color_levels = np.linspace(300,800,5)

    node = ssv_model.add_element('heatmap', 'core', 'Core')
    node.add_condition('rect', description='Core Heatmap', unit='K', data=core_temp,
                       color_scale=core_color_scale, color_levels=core_color_levels)

    # Use outer vertical rows of heatmap to represent temperature in vessel wall
    walls = ssv_model.add_element('line', ['wall-left', 'wall-right'], 'Vessel Wall')
    walls.add_condition('equaly', description='Vessel Wall Temp', unit='K', data=core_temp[:,:,0],
                        color_scale=core_color_scale, color_levels=core_color_levels)

    # Track average and max core temperature
    core_temp_avg = core_temp.mean(axis=2).mean(axis=1)
    core_temp_max = core_temp.max(axis=2).max(axis=1)
    report = ssv_model.add_element('report', 'report-1', 'Core Metrics')
    report.add_condition('info', description='Avg Temp', unit='F', data=core_temp_avg)
    report.add_condition('info', description='Max Temp', unit='F', data=core_temp_max)

    ssv_model.add_element('legend', 'core-color-scale', 'Core Temperature (K)',
                          color_scale=core_color_scale,
                          color_levels=core_color_levels)

    ssv_model.save_visualization(os.path.join('examples', 'example_3', 'example_3'))

    return True
Example #16
0
def run():
    # Let's use the freely available CFAST code from NIST to generate data
    # http://www.nist.gov/el/fire_research/cfast.cfm
    # This file is from the sample problem provided with the code

    data_f = os.path.join('examples', 'example_2', 'standard_n.csv')
    data = pd.read_csv(data_f, skiprows=[2], header=[0, 1])
    data.columns = [
        ', '.join(col) if i > 0 else col[0]
        for i, col in enumerate(data.columns)
    ]

    # Initiate and hook up SSV model
    ssv_model = SSV.create_vis(data['Time'],
                               'seconds',
                               os.path.join('examples', 'example_2',
                                            'example_2.svg'),
                               title="CFAST Example",
                               font_size=8)

    gas_color_scale = ['#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026']
    gas_color_levels = np.linspace(
        min(data['Upper Layer Temperature, Comp 2']),
        max(data['Upper Layer Temperature, Comp 3']), 5)

    # Add nodes
    for i in range(1, 4):
        data['Layer Height Upper, Comp %d' % i] = 3.0
        node = ssv_model.add_element('cell',
                                     'node-%d' % i,
                                     'Node %d' % i,
                                     report_id='node-%d-report' % i)
        node.add_condition('zonaly',
                           description='Zone Heights',
                           unit='m',
                           level_data=data[[
                               'Layer Height, Comp %d' % i,
                               'Layer Height Upper, Comp %d' % i
                           ]],
                           color_data=data[[
                               'Lower Layer Temperature, Comp %d' % i,
                               'Upper Layer Temperature, Comp %d' % i
                           ]],
                           color_scale=gas_color_scale,
                           color_levels=gas_color_levels,
                           max_height=3,
                           color_data_description='Zone Temperatures',
                           color_data_unit='C',
                           min_height=0,
                           section_label='Zone')
        node.add_condition('info',
                           data=data[['Pressure, Comp %d' % i]],
                           description='Pressure',
                           unit='Pa')

        if i == 1:
            node.add_condition('info',
                               data=data[['HRR, bunsen']],
                               description='HRR',
                               unit='W')
        elif i == 2:
            node.add_condition('info',
                               data=data[['HRR, Wood_Wall']],
                               description='HRR',
                               unit='W')

    # Add fires
    fire_1 = ssv_model.add_element('toggle', 'fire-1', 'Fire 1')
    fire_1.add_condition('showhide', data=data['HRR, bunsen'])
    fire_2 = ssv_model.add_element('toggle', 'fire-2', 'Fire 2')
    fire_2.add_condition('showhide', data=data['HRR, Wood_Wall'])

    # Show gas color scale
    gas_temp_legend = ssv_model.add_element('legend', 'color-scale',
                                            'Gas Temperature (C)')
    gas_temp_legend.add_condition("colorscale", gas_color_scale,
                                  gas_color_levels)

    ssv_model.save_visualization(
        os.path.join('examples', 'example_2', 'example_2'))

    return True
Example #17
0
def run():
    # Load steam tables and build interpolation functions for several features
    sat_tables = pd.read_excel(os.path.join('examples', 'example_1', 'steam_tables.xls'))
    f_press = interp1d(sat_tables['vg'], sat_tables['Mpa'])
    f_temp = interp1d(sat_tables['vg'], sat_tables['deg C'])
    f_wtr_sp_vol = interp1d(sat_tables['vg'], sat_tables['vf'])
    f_wtr_enthalpy = interp1d(sat_tables['vg'], sat_tables['hf'])
    f_vap_enthalpy = interp1d(sat_tables['vg'], sat_tables['hg'])
    f_lat_heat = interp1d(sat_tables['vg'], sat_tables['hfg'])

    # Function to get properties of saturated water+vapor given vapor density
    def get_props_from_vap_density(density):
        props_out = {}

        sp_vol = 1 / density
        props_out['press'] = float(f_press(sp_vol))
        props_out['temp'] = float(f_temp(sp_vol) + 273.15)
        props_out['wtr_density'] = float(1 / f_wtr_sp_vol(sp_vol))
        props_out['wtr_enthalpy'] = float(f_wtr_enthalpy(sp_vol))
        props_out['vap_enthalpy'] = float(f_vap_enthalpy(sp_vol))
        props_out['lat_heat'] = float(f_lat_heat(sp_vol))

        return props_out

    def th_run(initial_wtr_mass, initial_wtr_level,
               downstream_height, steam_flow, discharge_press, time_step, end_time):
        """
            Simple Thermal-Hydraulic analysis code for water between 2 compartments.
            Assume downstream is water/steam compartment always at saturated conditions.
            Assume upstream is saturated steam environment that discharges to downstream.
            Heat loss to environment and Condensation is assumed to be negligible.  Inputs:

                initial_wtr_mass = initial downstream water mass in kg.
                initial_wtr_level = initial downstream water level in m.  Note that
                    the downstream volume is assumed to increase linearly with height
                    based on this input.
                downstream_height = total height of downstream compartment (m)
                steam_flow = 4 x n array of n occurences of upstream to downstream steam flow.
                    Row 1 is start time of flow in S
                    Row 2 is end time of flow in S
                    Row 3 is specific enthalpy of flow in kJ/kg
                    Row 4 is total mass of flow in kg
                discharge_press = pressure control point of downstream compartment in MPa.
                    Downstream compartment is modeled as instantly opening and relieving
                    conditions down to atmospheric over a single time step.
                time_step = time step of analysis in S.
                end_time = analysis end time is S.

            Returns downstream pressure, temperature, water level, and logical states
            of relief valve and steam discharge as a function of time.
        """

        # Assign initial conditions
        vap_density = 0.59
        wtr_mass = initial_wtr_mass
        wtr_lvl = initial_wtr_level
        wtr_lvl_vol_slope = wtr_lvl / wtr_mass

        # Determine downstream conditions using steam tables - assume saturated conditions
        props = get_props_from_vap_density(vap_density)
        press = props['press']
        temp = props['temp']
        wtr_enthalpy = props['wtr_enthalpy']
        wtr_density = props['wtr_density']
        vap_enthalpy = props['vap_enthalpy']
        lat_heat = props['lat_heat']

        wtr_vol = wtr_mass / wtr_density
        total_vol = wtr_vol * downstream_height / wtr_lvl
        vap_vol = total_vol - wtr_vol
        vap_mass = vap_density * vap_vol
        lvl_vol_slope = wtr_lvl / wtr_vol

        # Cast steam_flow as numpy array
        steam_flow = np.array(steam_flow)

        # Flag for relief valve
        rv_flag = False

        # Record conditons at t=0
        conditions_out = {'press':[press], 'temp':[temp], 'wtr_lvl':[wtr_lvl],
                          'rv':[rv_flag], 'disch':[False], 'time':[0]}

        # Run through time span, calculating conditions at each step
        for t in np.arange(1, end_time+time_step, time_step):
            # Check if current time span is within or includes any steam_flow entry
            # and calculate integrated enthalpy addition
            time_mask = ((steam_flow[0] >= t) & (steam_flow[0] < t + time_step)) | ((steam_flow[0] < t) & (steam_flow[1] > t))
            start_times = steam_flow[0][time_mask]
            start_times[start_times < t] = t
            end_times = steam_flow[1][time_mask]
            end_times[end_times > t + time_step] = t + time_step
            time_deltas = end_times - start_times
            upstream_enthalpy = steam_flow[2][time_mask]
            flow_mass = steam_flow[3][time_mask] * time_deltas

            # Calculate vaporized water mass
            excess_enthalpy = (upstream_enthalpy - wtr_enthalpy) * flow_mass
            vaporized_wtr_mass = (excess_enthalpy / lat_heat).sum()

            # Update water mass and vapor mass and density
            wtr_mass += flow_mass.sum() - vaporized_wtr_mass
            vap_mass += vaporized_wtr_mass
            vap_density = vap_mass / (total_vol * (1 - wtr_vol/total_vol))

            # If we are at relief pressure reset to saturated conditions and calculate
            # change in water mass
            if press > discharge_press:
                vap_density = 0.59
                props = get_props_from_vap_density(vap_density)
                wtr_enthalpy_new = props['wtr_enthalpy']
                lat_heat = props['lat_heat']
                wtr_mass -= (wtr_enthalpy - wtr_enthalpy_new) * wtr_mass / lat_heat
                rv_flag = True
            else:
                rv_flag = False

            # Calculate new properties
            # Assume water density has negligible change between time steps
            props = get_props_from_vap_density(vap_density)
            press = props['press']
            temp = props['temp']
            wtr_density = props['wtr_density']
            wtr_enthalpy = props['wtr_enthalpy']
            lat_heat = props['lat_heat']
            wtr_lvl = lvl_vol_slope * wtr_mass / wtr_density
            vap_mass = vap_density * (total_vol * (1 - wtr_vol/total_vol))

            # Record new properties
            conditions_out['time'].append(t)
            conditions_out['press'].append(press)
            conditions_out['temp'].append(temp)
            conditions_out['wtr_lvl'].append(wtr_lvl)
            conditions_out['disch'].append(flow_mass.sum())
            conditions_out['rv'].append(rv_flag)

        return conditions_out

    # Run the code
    initial_wtr_mass = 1000000  # kg ~ 2200000 lbm
    initial_wtr_level = 5  # m ~ 16.405 ft
    downstream_height = 10  # m ~ 32.81 ft
    steam_flow = [[2,15,45,65],  # S - Steam discharge start
                    [10,40,60,90],  # S - Steam discharge end
                    [2650,2650,2650,2650],  # kJ/kg - steam at ~2000 psi or 14 MPa
                    [50,100,150,150]]  # kg/s - flowrate
    discharge_press = 0.79  # Mpa ~ 100 psig
    time_step = 1  # Seconds
    end_time = 100  # Seconds

    sim_data = th_run(initial_wtr_mass, initial_wtr_level,
           downstream_height, steam_flow, discharge_press, time_step, end_time)

    # Initiate and hook up SSV model
    ssv_model = SSV.create_vis(sim_data['time'], 'seconds', os.path.join('examples', 'example_1', 'example_1.svg'),
                        title="Steam Quench Tank Simulation", font_size=8)

    water_color_scale = ['#0570b0', '#3690c0', '#74a9cf']
    water_color_levels = np.linspace(min(sim_data['temp']), max(sim_data['temp']), len(water_color_scale))
    gas_color_scale = ['#fdd49e','#fdbb84','#fc8d59']
    gas_color_levels = np.linspace(min(sim_data['temp']), max(sim_data['temp']), len(gas_color_scale))

    # Wire up svg elements
    tank = ssv_model.add_element('cell', 'tank-1', 'Quench Tank', cell_report_id='tank-1-report')
    tank.add_condition('background', description='Vapor Temp', unit='K', data=sim_data['temp'],
                       color_scale=gas_color_scale,
                       color_levels=gas_color_levels)
    tank.add_condition('dynamiclevel', description='Water Level', unit='m', data=sim_data['wtr_lvl'],
                       data_dynamic=sim_data['temp'], color_scale=water_color_scale,
                       color_levels=water_color_levels,
                       max_height=10, description_dynamic='Water Temp', unit_dynamic='K', overlay='bubbles',
                       min_height=0)
    tank.add_condition('info', data=sim_data['press'], description='Press', unit='MPa')
    tank.add_popover("sparkline", sim_data['wtr_lvl'], label='Tank #1 Wtr Lvl')

    relief_valve = ssv_model.add_element('cell', 'relief-valve', 'Relief Valve')
    relief_valve.add_condition('logical', data=sim_data['rv'], true_color='#4CAF50', false_color='#F44336')

    steam_discharge = ssv_model.add_element('cell', 'steam-discharge', 'Steam Discharge', cell_report_id='disch-report')
    steam_discharge.add_condition('logical', description='Flowrate', data=sim_data['disch'], true_color='#4CAF50', false_color='#F44336', unit='kg/s')

    steam_toggle = ssv_model.add_element('toggle', 'steam-toggle', 'Steam Toggle')
    steam_toggle.add_condition('showhide', data=sim_data['disch'])

    relief_toggle = ssv_model.add_element('toggle', 'relief-toggle', 'Relief Toggle')
    relief_toggle.add_condition('showhide', data=sim_data['rv'])

    ssv_model.add_element('legend', 'color-scale-water', 'Water Temperature (F)',
                          color_scale=water_color_scale,
                          color_levels=water_color_levels)

    x = ssv_model.add_element('legend', 'color-scale-gas', 'Gas Temperature (F)',
                          color_scale=gas_color_scale,
                          color_levels=gas_color_levels)

    ssv_model.save_visualization(os.path.join('examples', 'example_1', 'example_1'))

    return True