Example #1
0
    def __init__(self, json_file_path: str) -> None:
        """
        Initialize the plant loop and all components on it.

        :param json_file_path: Path to the JSON input file
        """

        self.start_time = dt.datetime.now()

        # process inputs
        self.ip = InputProcessor(json_file_path)

        try:
            # setup output processor
            self.op = OutputProcessor(
                self.ip.input_dict['simulation']['output-path'],
                self.ip.input_dict['simulation']['output-csv-name'])
        except KeyError:
            # paths were not provided. apply default paths.
            self.op = OutputProcessor(os.getcwd(), 'out.csv')

        # init plant-level variables
        self.demand_inlet_temp = self.ip.input_dict['simulation'][
            'initial-temperature']
        self.demand_outlet_temp = self.ip.input_dict['simulation'][
            'initial-temperature']
        self.supply_inlet_temp = self.ip.input_dict['simulation'][
            'initial-temperature']
        self.supply_outlet_temp = self.ip.input_dict['simulation'][
            'initial-temperature']
        self.end_sim_time = self.ip.input_dict['simulation']['runtime']

        # set the time step
        # can only set the time steps per hour or the time step
        try:
            self.time_step = num_ts_per_hour_to_sec_per_ts(
                self.ip.input_dict['simulation']['time-steps-per-hour'])
        except KeyError:
            try:
                self.time_step = self.ip.input_dict['simulation']['time-step']
            except KeyError:
                raise KeyError(
                    "'simulation' object must contain either 'time-steps-per-hour' or 'time-step' field."
                )

        self.demand_comps = []
        self.supply_comps = []

        # initialize plant loop components
        self.initialize_plant_loop_topology()
Example #2
0
    def add_instance(method):
        fpath = os.path.dirname(os.path.abspath(__file__))
        data_str = '../../../glhe/profiles/external_data/GSHP-GLHE_USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.csv'
        data_path = os.path.normpath(os.path.join(fpath, data_str))
        d = {
            'fluid': {
                'fluid-type': 'water'
            },
            'load-profile': [{
                'load-profile-type': method,
                'value': 10,
                'name': 'my name',
                'path': data_path,
                'start-time': 1,
                'end-time': 10,
                'amplitude': 100,
                'offset': 100,
                'period': 10,
                'synthetic-method': 'symmetric'
            }]
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return make_load_profile(d['load-profile'][0], ip, op)
Example #3
0
    def test_constant_flow(self):
        d = {'flow-profile': [{'flow-profile-type': 'constant', 'name': 'my name', 'value': 1}]}

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        tst = make_flow_profile(d['flow-profile'][0], ip, op)
        self.assertIsInstance(tst, ConstantFlow)
Example #4
0
    def test_fail(self):
        d = {'flow-profile': [{'flow-profile-type': 'constant', 'name': 'my name', 'value': 1}]}

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        with self.assertRaises(ValueError) as _:
            make_flow_profile({'flow-profile-type': 'not-a-type'}, ip, op)
Example #5
0
    def add_instance(path):
        d = {'fluid': {'fluid-type': 'water'},
             'load-profile': [{'load-profile-type': 'external', 'name': 'my name', 'path': path}]}

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return ExternalLoad(d['load-profile'][0], ip, op)
Example #6
0
    def add_instance():
        d = {
            'flow-profile': [{
                'flow-profile-type': 'constant',
                'name': 'my name',
                'value': 0.1
            }]
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return ConstantFlow(d['flow-profile'][0], ip, op)
Example #7
0
    def add_instance():
        d = {
            'fluid': {
                'fluid-type': 'water'
            },
            'soil': {
                "name": "dirt",
                "conductivity": 2.7,
                "density": 2500,
                "specific-heat": 880
            },
            'grout-definitions': [{
                'name': 'standard grout',
                'conductivity': 0.744,
                'density': 1500,
                'specific-heat': 800
            }],
            'pipe-definitions': [{
                'name': '32 mm SDR-11 HDPE',
                'outer-diameter': 0.0334,
                'inner-diameter': 0.0269,
                'conductivity': 0.389,
                'density': 950,
                'specific-heat': 1900
            }]
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')
        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        d_seg = {
            'length': 7.62,
            'diameter': 0.114,
            'segment-name': 0,
            'grout-def-name': 'standard grout',
            'pipe-def-name': '32 mm sdr-11 hdpe'
        }

        return SingleUTubeGroutedSegment(d_seg, ip, op)
Example #8
0
    def add_instance():
        temp_dir = tempfile.mkdtemp()
        temp_data = os.path.join(temp_dir, 'temp_data.csv')

        with open(temp_data, 'w') as f:
            f.write('Date/Time, Meas. Total Power [W], mdot [kg/s], temperature[C]\n'
                    '2018-01-01 00:00:00, 1, 1, 1\n'
                    '2018-01-01 01:00:00, 2, 2, 2\n'
                    '2018-01-01 02:00:00, 3, 3, 3\n'
                    '2018-01-01 03:00:00, 4, 4, 4\n')

        d = {'temperature-profile': [{'temperature-profile-type': 'external', 'name': 'my name', 'path': temp_data}]}
        temp_file = os.path.join(temp_dir, 'temp.json')
        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return ExternalTemps(d['temperature-profile'][0], ip, op)
Example #9
0
    def test_external_flow(self):
        fpath = os.path.dirname(os.path.abspath(__file__))
        rel_path = '../../../glhe/profiles/external_data/GSHP-GLHE_USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.csv'

        d = {
            'flow-profile':
                [{'flow-profile-type': 'external',
                  'name': 'my name',
                  'path': os.path.join(fpath, rel_path)}]}

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        tst = make_flow_profile(d['flow-profile'][0], ip, op)
        self.assertIsInstance(tst, ExternalFlow)
Example #10
0
    def add_instance():
        d = {
            'fluid': {
                'fluid-type': 'water'
            },
            'load-profile': [{
                'load-profile-type': 'constant',
                'name': 'my name',
                'value': 4000
            }]
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return ConstantLoad(d['load-profile'][0], ip, op)
Example #11
0
    def add_instance(method):
        d = {
            'fluid': {
                'fluid-type': 'water'
            },
            'load-profile': [{
                'load-profile-type': 'synthetic',
                'name': 'my name',
                'amplitude': 1000,
                'synthetic-method': method
            }]
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return SyntheticLoad(d['load-profile'][0], ip, op)
Example #12
0
    def add_instance():
        inputs = {'pipe-definitions': [{
            'name': '32 mm sdr-11 hdpe',
            'outer-diameter': 0.0334,
            'inner-diameter': 0.0269,
            'conductivity': 0.4,
            'density': 950,
            'specific-heat': 1900}],
            'fluid': {'fluid-type': 'water'},
            'pipe': [
                {'pipe-def-name': '32 mm sdr-11 hdpe',
                 'name': 'pipe 1',
                 'length': 100}]}

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')
        write_json(temp_file, inputs)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return Pipe(inputs['pipe'][0], ip, op)
Example #13
0
    def add_instance():
        d = {
            'fluid': {
                'fluid-type': 'water'
            },
            'load-profile': [{
                'load-profile-type': 'single-impulse',
                'name': 'my name',
                'value': 1000,
                'start-time': 0,
                'end-time': 200
            }]
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return PulseLoad(d['load-profile'][0], ip, op)
Example #14
0
    def add_instance():
        d = {
            'fluid': {
                'fluid-type': 'water'
            },
            'load-profile': [{
                'load-profile-type': 'sinusoid',
                'name': 'my name',
                'amplitude': 1,
                'offset': 0,
                'period': 2 * pi
            }]
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return SinusoidLoad(d['load-profile'][0], ip, op)
Example #15
0
    def test_fail(self):
        d = {
            'fluid': {
                'fluid-type': 'water'
            },
            'load-profile': [{
                'load-profile-type': 'constant',
                'value': 10,
                'name': 'my name'
            }]
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')

        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        make_load_profile(d['load-profile'][0], ip, op)

        with self.assertRaises(ValueError) as _:
            make_load_profile({'load-profile-type': 'not-a-method'}, ip, op)
    def add_instance():
        f_path = os.path.dirname(os.path.abspath(__file__))
        d = {
            "borehole-definitions": [{
                "borehole-type": "single-grouted",
                "length": 76.2,
                "diameter": 0.114,
                "grout-def-name": "standard grout",
                "name": "borehole type 1",
                "pipe-def-name": "26 mm SDR-11 HDPE",
                "segments": 10,
                "shank-spacing": 0.0469
            }],
            "borehole": [{
                "name": "bh 1",
                "borehole-def-name": "borehole type 1",
                "location": {
                    "x": 0,
                    "y": 0,
                    "z": 0
                }
            }],
            "flow-profile": [{
                "name": "constant 0.3",
                "flow-profile-type": "constant",
                "value": 0.3
            }],
            "fluid": {
                "fluid-type": "water"
            },
            "ground-temperature-model": {
                "ground-temperature-model-type": "constant",
                "temperature": 16.1
            },
            "grout-definitions": [{
                "name": "standard grout",
                "conductivity": 0.85,
                "density": 2500,
                "specific-heat": 1560
            }],
            "load-profile": [{
                "name": "constant 4000",
                "load-profile-type": "constant",
                "value": 4000
            }],
            "ground-heat-exchanger": [{
                "name":
                "GHE 1",
                "simulation-mode":
                "direct",
                "g-function-path":
                os.path.join(f_path, '..', '..', '..', 'validation',
                             'MFRTRT_EWT_g_functions',
                             'EWT_experimental_g_functions.csv'),
                "flow-paths": [{
                    "name":
                    "path 1",
                    "components": [{
                        "comp-type": "borehole",
                        "name": "bh 1"
                    }]
                }],
                "load-aggregation": {
                    "method": "dynamic",
                    "expansion-rate": 1.5,
                    "number-bins-per-level": 9
                }
            }],
            "pipe-definitions": [{
                "name": "26 mm SDR-11 HDPE",
                "outer-diameter": 0.0267,
                "inner-diameter": 0.0218,
                "conductivity": 0.39,
                "density": 950,
                "specific-heat": 1900
            }],
            "simulation": {
                "name": "Basic GLHE",
                "initial-temperature": 16.1,
                "time-step": 30,
                "runtime": 3600
            },
            "topology": {
                "demand-side": [{
                    "comp-type": "flow-profile",
                    "name": "constant 0.3"
                }, {
                    "comp-type": "load-profile",
                    "name": "constant 4000"
                }],
                "supply-side": [{
                    "comp-type": "ground-heat-exchanger",
                    "name": "GHE 1"
                }]
            },
            "soil": {
                "name": "dirt",
                "conductivity": 2.7,
                "density": 2500,
                "specific-heat": 880
            }
        }
        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, 'temp.json')
        write_json(temp_file, d)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(f_path, 'out.csv')
        return GroundHeatExchangerSTS(d['ground-heat-exchanger'][0], ip, op)
Example #17
0
class PlantLoop(object):
    Type = ComponentTypes.PlantLoop

    def __init__(self, json_file_path: str) -> None:
        """
        Initialize the plant loop and all components on it.

        :param json_file_path: Path to the JSON input file
        """

        self.start_time = dt.datetime.now()

        # process inputs
        self.ip = InputProcessor(json_file_path)

        try:
            # setup output processor
            self.op = OutputProcessor(
                self.ip.input_dict['simulation']['output-path'],
                self.ip.input_dict['simulation']['output-csv-name'])
        except KeyError:
            # paths were not provided. apply default paths.
            self.op = OutputProcessor(os.getcwd(), 'out.csv')

        # init plant-level variables
        self.demand_inlet_temp = self.ip.input_dict['simulation'][
            'initial-temperature']
        self.demand_outlet_temp = self.ip.input_dict['simulation'][
            'initial-temperature']
        self.supply_inlet_temp = self.ip.input_dict['simulation'][
            'initial-temperature']
        self.supply_outlet_temp = self.ip.input_dict['simulation'][
            'initial-temperature']
        self.end_sim_time = self.ip.input_dict['simulation']['runtime']

        # set the time step
        # can only set the time steps per hour or the time step
        try:
            self.time_step = num_ts_per_hour_to_sec_per_ts(
                self.ip.input_dict['simulation']['time-steps-per-hour'])
        except KeyError:
            try:
                self.time_step = self.ip.input_dict['simulation']['time-step']
            except KeyError:
                raise KeyError(
                    "'simulation' object must contain either 'time-steps-per-hour' or 'time-step' field."
                )

        self.demand_comps = []
        self.supply_comps = []

        # initialize plant loop components
        self.initialize_plant_loop_topology()

    def initialize_plant_loop_topology(self) -> None:

        for comp in self.ip.input_dict['topology']['demand-side']:
            self.demand_comps.append(
                make_plant_loop_component(comp, self.ip, self.op))

        for comp in self.ip.input_dict['topology']['supply-side']:
            self.supply_comps.append(
                make_plant_loop_component(comp, self.ip, self.op))

    def simulate(self) -> bool:
        """
        Do the entire time stepping simulation of the plant loop
        """

        current_sim_time = 0

        while True:
            self.do_one_time_step(current_sim_time, self.time_step)
            current_sim_time += self.time_step
            self.collect_outputs(current_sim_time)

            if current_sim_time >= self.end_sim_time:
                break

        self.op.write_to_file()

        print('Simulation time: {}'.format(dt.datetime.now() -
                                           self.start_time))

        with open(
                '{}.txt'.format(
                    os.path.join(self.op.output_dir,
                                 self.op.output_file[:-4])), 'w+') as f:
            f.write('Simulation time: {}\n'.format(dt.datetime.now() -
                                                   self.start_time))

        return True

    def do_one_time_step(self, sim_time: Union[int, float],
                         time_step: Union[int, float]):
        """
        Simulate one time step of the entire plant loop
        """

        # update demand inlet node and initial conditions
        self.demand_inlet_temp = self.supply_outlet_temp
        response = SimulationResponse(sim_time, time_step, 0,
                                      self.demand_inlet_temp)

        # simulate demand components flow-wise
        for comp in self.demand_comps:
            response = comp.simulate_time_step(response)

        # update interface nodes
        self.demand_outlet_temp = response.temperature
        self.supply_inlet_temp = response.temperature

        # simulate supply components flow-wise
        for comp in self.supply_comps:
            response = comp.simulate_time_step(response)

        # supply outlet node
        self.supply_outlet_temp = response.temperature

    def report_outputs(self):

        d = {
            '{:s}:{:s}'.format(self.Type, 'Demand Inlet Temp. [C]'):
            self.demand_inlet_temp,
            '{:s}:{:s}'.format(self.Type, 'Demand Outlet Temp. [C]'):
            self.demand_outlet_temp,
            '{:s}:{:s}'.format(self.Type, 'Supply Inlet Temp. [C]'):
            self.supply_inlet_temp,
            '{:s}:{:s}'.format(self.Type, 'Supply Outlet Temp. [C]'):
            self.supply_outlet_temp
        }

        return d

    def collect_outputs(self, sim_time):

        # record current time
        d = {'Elapsed Time [s]': sim_time}

        # report outputs from the PlantLoop object
        d = merge_dicts(d, self.report_outputs())

        # collect reports from demand components
        for comp in self.demand_comps:
            d = merge_dicts(d, comp.report_outputs())

        # collect outputs from the supply components
        for comp in self.supply_comps:
            d = merge_dicts(d, comp.report_outputs())

        # finalize collection by the OutputProcessor
        self.op.collect_output(d)
Example #18
0
    def add_instance():
        temp_dir = tempfile.mkdtemp()

        with open(os.path.join(temp_dir, 'temp.csv'), 'w') as f:
            f.write(
                'Date/Time,Heating Loads (W),Water Heating Loads (W),Outdoor Air Temperature (C)\n'
            )
            f.write('1/1/2019 0:00,751.231087,0,4\n')
            f.write('1/1/2019 1:00,609.682528,60.515364,5.3\n')
            f.write('1/1/2019 2:00,728.634445,41.330207,6.2\n')
            f.write('1/1/2019 3:00,562.383158,42.178469,6.8\n')
            f.write('1/1/2019 4:00,685.067724,63.096246,7.2\n')
            f.write('1/1/2019 5:00,539.127476,43.947185,7.5\n')
            f.write('1/1/2019 6:00,663.467736,44.849591,7.5\n')
            f.write('1/1/2019 7:00,539.08215,165.88032,6.7\n')
            f.write('1/1/2019 8:00,692.252428,26.56684,6\n')
            f.write('1/1/2019 9:00,564.562993,888.906269,5.2\n')
            f.write('1/1/2019 10:00,670.844481,1230.286559,5.2\n')
            f.write('1/1/2019 11:00,453.722975,610.134925,5.2\n')
            f.write('1/1/2019 12:00,538.938447,771.268588,5.2\n')
            f.write('1/1/2019 13:00,460.832251,30.826198,4.6\n')
            f.write('1/1/2019 14:00,674.925154,51.852264,4.1\n')
            f.write('1/1/2019 15:00,583.467315,1515.140121,3.5\n')
            f.write('1/1/2019 16:00,769.103444,10851.59779,3.2\n')
            f.write('1/1/2019 17:00,621.861048,10852.40995,2.9\n')
            f.write('1/1/2019 18:00,807.407677,45000,2.6\n')
            f.write('1/1/2019 19:00,646.501964,1779.03981,2.5\n')
            f.write('1/1/2019 20:00,830.903352,157.21722,2.4\n')
            f.write('1/1/2019 21:00,661.800554,358.381625,2.3\n')
            f.write('1/1/2019 22:00,847.617722,38.695181,2.3\n')
            f.write('1/1/2019 23:00,675.803234,179.849569,2.2\n')

        inputs = {
            'fluid': {
                'fluid-type': 'PG',
                'concentration': 35
            },
            'swedish-heat-pump': [{
                'name':
                'svenska varmmepumpe',
                'max-heating-set-point':
                55,
                'min-heating-set-point':
                30,
                'water-heating-set-point':
                60,
                'outdoor-air-temperature-at-max-heating-set-point':
                -10,
                'outdoor-air-temperature-at-min-heating-set-point':
                20,
                'immersion-heater-capacity':
                7000,
                'load-data-path':
                os.path.join(temp_dir, 'temp.csv'),
                'capacity-coefficients':
                [8.536666667, -0.007266667, -0.00084, 0.263666667],
                'coefficient-of-performance-coefficients':
                [7.641839817, -0.075098454, -0.000208441, 0.109423218],
            }]
        }

        temp_file = os.path.join(temp_dir, 'temp.json')
        write_json(temp_file, inputs)

        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')

        return SwedishHP(inputs['swedish-heat-pump'][0], ip, op)
Example #19
0
    def add_instance():
        d = {
            "borehole-definitions": [{
                "borehole-type": "single-grouted",
                "length": 76.2,
                "diameter": 0.114,
                "grout-def-name": "standard grout",
                "name": "borehole type 1",
                "pipe-def-name": "26 mm SDR-11 HDPE",
                "segments": 10,
                "shank-spacing": 0.0469
            }],
            "borehole": [{
                "name": "bh 1",
                "borehole-def-name": "borehole type 1",
                "location": {
                    "x": 0,
                    "y": 0,
                    "z": 0
                }
            }],
            "fluid": {
                "fluid-type": "water"
            },
            "grout-definitions": [{
                "name": "standard grout",
                "conductivity": 0.85,
                "density": 2500,
                "specific-heat": 1560
            }],
            "ground-heat-exchanger": [{
                "name":
                "GHE 1",
                "simulation-mode":
                "direct",
                "g-function-path":
                "validation/MFRTRT_EWT_g_functions/EWT_experimental_g_functions.csv",
                "flow-paths": [{
                    "name":
                    "path 1",
                    "components": [{
                        "comp-type": "borehole",
                        "name": "bh 1"
                    }]
                }],
                "load-aggregation": {
                    "method": "dynamic",
                    "expansion-rate": 1.5,
                    "number-bins-per-level": 9
                }
            }],
            "pipe-definitions": [{
                "name": "26 mm SDR-11 HDPE",
                "outer-diameter": 0.0267,
                "inner-diameter": 0.0218,
                "conductivity": 0.39,
                "density": 950,
                "specific-heat": 1900
            }],
            "soil": {
                "name": "dirt",
                "conductivity": 2.7,
                "density": 2500,
                "specific-heat": 880
            }
        }

        temp_dir = tempfile.mkdtemp()
        temp_file = norm(join(temp_dir, 'temp.json'))
        write_json(temp_file, d)
        ip = InputProcessor(temp_file)
        op = OutputProcessor(temp_dir, 'out.csv')
        return Path(d['ground-heat-exchanger'][0]['flow-paths'][0], ip, op)