def calc_ts(self): """ Calculates non-dimensional time. """ try: ts = self.borehole.depth**2 / ( 9 * self.borehole.soil.thermal_diffusivity) return ts except: # pragma: no cover PrintClass.fatal_error( message="Error calculating simulation time scale \"ts\"")
def __init__(self, json_data, print_output): BasePropertiesClass.__init__(self, json_data, print_output) try: self.undisturbed_temp = json_data['Temperature'] except: # pragma: no cover PrintClass.my_print("....'Temperature' key not found", 'warn') PrintClass.fatal_error(message="Error initializing SoilClass") self.heat_capacity = self.specific_heat * self.density self.thermal_diffusivity = self.conductivity / \ (self.density * self.specific_heat)
def __init__(self, json_data_pipe, json_data_fluid, initial_temp, print_output): BasePropertiesClass.__init__(self, json_data_pipe, print_output) self.fluid = FluidsClass(json_data_fluid, initial_temp, print_output) try: self.outer_diameter = json_data_pipe['Outside Diameter'] except: # pragma: no cover PrintClass.my_print("....'Outside Diameter' key not found", 'warn') PrintClass.fatal_error(message="Error initializing PipeClass") try: self.thickness = json_data_pipe['Wall Thickness'] except: # pragma: no cover PrintClass.my_print("....'Wall Thickness' key not found", 'warn') PrintClass.fatal_error(message="Error initializing PipeClass") self.outer_radius = self.outer_diameter / 2 self.inner_radius = self.outer_radius - self.thickness self.inner_diameter = self.outer_diameter - 2 * self.thickness self.resist_pipe_convection = None self.resist_pipe_conduction = None self.resist_pipe = None self.calc_pipe_resistance()
def get_sim_config(self, sim_config_path): """ Reads the simulation configuration. If not successful, program exits. :param sim_config_path: path of json file containing the simulation configuration """ errors_found = False # read from JSON file try: with open(sim_config_path) as json_file: self.json_data = json.load(json_file) except: # pragma: no cover PrintClass.fatal_error( message= "Error reading simulation configuration---check file path") try: try: self.aggregation_type = self.json_data[ 'Simulation Configuration']['Aggregation Type'] except: # pragma: no cover PrintClass.my_print("....'Aggregation Type' key not found", "warn") errors_found = True except: # pragma: no cover PrintClass.fatal_error( message="Error reading simulation configuration") if errors_found: # pragma: no cover PrintClass.fatal_error(message="Error loading data")
def __init__(self, json_data, loads_path, output_path, print_output=True): """ Class constructor """ # init base class BaseGHXClass.__init__(self, json_data, loads_path, output_path, print_output) errors_found = False try: self.history_depth = json_data['Simulation Configuration']['History Depth'] except: # pragma: no cover PrintClass.my_print( "....'History Depth' key not found", 'warn') errors_found = True try: self.history_expansion_rate = json_data['Simulation Configuration']['History Expansion Rate'] except: # pragma: no cover PrintClass.my_print("....'History Expansion Rate' key not found", 'warn') errors_found = True # set load aggregation intervals self.set_load_aggregation() # pre-calculate all g-functions for load blocks self.load_g_functions() if not errors_found: # success PrintClass.my_print("Simulation successfully initialized") else: # pragma: no cover PrintClass.fatal_error(message="Error initializing GHXArrayShiftingAggBlocks")
def __init__(self, json_data, loads_path, output_path, print_output=True): """ Constructor for the class. """ PrintClass(print_output, output_path) # init base class BaseGHXClass.__init__(self, json_data, loads_path, output_path, print_output) errors_found = False try: self.min_hourly_history = json_data['Simulation Configuration'][ 'Min Hourly History'] except: # pragma: no cover PrintClass.my_print("....'Min Hourly History' key not found", 'warn') errors_found = True try: self.agg_load_intervals = json_data['Simulation Configuration'][ 'Intervals'] except: # pragma: no cover PrintClass.my_print("....'Intervals' key not found", 'warn') errors_found = True if not errors_found: # success PrintClass.my_print("Simulation successfully initialized") else: # pragma: no cover PrintClass.fatal_error( message="Error initializing GHXArrayFixedAggBlocks") # class data # set load aggregation intervals self.set_load_aggregation() # set first aggregated load, which is zero. Need this for later self.agg_load_objects.append(AggregatedLoadFixed([0], 0, 1, True)) self.g_func_hourly = deque() self.hourly_loads = deque()
def generate_output_reports(self): # pragma: no cover """ Generates output results """ try: PrintClass.my_print("Writing output results") cwd = os.getcwd() path_to_output_dir = os.path.join(cwd, self.output_path) if not os.path.exists(path_to_output_dir): os.makedirs(path_to_output_dir) # open files out_file = open(os.path.join(path_to_output_dir, "GHX.csv"), 'w') # write headers out_file.write("Hour, BH Temp [C], MFT [C]\n") for i in range(len(self.temp_bh)): out_file.write("%d, %0.4f, %0.4f\n" % (i + 1, self.temp_bh[i], self.temp_mft[i])) # close file out_file.close() PrintClass.my_print("....Success") except: # pragma: no cover PrintClass.fatal_error(message="Error writing output results")
def calc_g_func(self): """ Calculate g-functions for given ground heat exchangers. """ try: PrintClass.my_print("Calculating g-functions") self.g_func_present = True PrintClass.my_print("....Success") except: # pragma: no cover PrintClass.fatal_error(message="Error calculating g-functions")
def __init__(self, ghx_input_json_path, loads_path, output_path, print_output=True): """ Class constructor """ PrintClass(print_output, output_path) ConstantClass() self.timer_start = timeit.default_timer() self.ghx_input_json_path = ghx_input_json_path self.json_data = None self.loads_path = loads_path self.output_path = output_path self.print_output = print_output self.aggregation_type = '' self.get_sim_config(self.ghx_input_json_path)
def simulate(self): """ Main simulation routine. Simulates the GHXArray object. More docs to come... """ PrintClass.my_print("Initializing simulation") if self.aggregation_type == "Fixed" or self.aggregation_type == "None": GHXArrayFixedAggBlocks(self.json_data, self.loads_path, self.output_path, self.print_output).simulate() elif self.aggregation_type == "Shifting": GHXArrayShiftingAggBlocks(self.json_data, self.loads_path, self.output_path, self.print_output).simulate() else: PrintClass.my_print( "\tAggregation Type \"%s\" not found" % self.aggregation_type, "warn") PrintClass.fatal_error(message="Error starting program")
def __init__(self, json_data, print_output): try: self.conductivity = json_data['Conductivity'] except: # pragma: no cover PrintClass.my_print("....'Conductivity' key not found", 'warn') PrintClass.fatal_error( message="Error initializing BasePropertiesClass") try: self.specific_heat = json_data['Specific Heat'] except: # pragma: no cover PrintClass.my_print("....'Specific Heat' key not found", 'warn') PrintClass.fatal_error( message="Error initializing BasePropertiesClass") try: self.density = json_data['Density'] except: # pragma: no cover PrintClass.my_print("....'Density' key not found", 'warn') PrintClass.fatal_error( message="Error initializing BasePropertiesClass")
def simulate(self): """ More docs to come... """ PrintClass.my_print("Beginning simulation") # calculate g-functions if not present if not self.g_func_present: PrintClass.my_print("G-functions not present", 'warn') self.calc_g_func() # pre-load hourly g-functions for hour in range(self.agg_load_intervals[0] + self.min_hourly_history): ln_t_ts = np.log((hour + 1) * 3600 / self.ts) self.g_func_hourly.append(self.g_func(ln_t_ts)) # set aggregate load container max length len_hourly_loads = self.min_hourly_history + self.agg_load_intervals[0] self.hourly_loads = deque([0] * len_hourly_loads, maxlen=len_hourly_loads) agg_hour = 0 sim_hour = 0 for year in range(self.sim_years): for month in range(ConstantClass.months_in_year): PrintClass.my_print("....Year/Month: %d/%d" % (year + 1, month + 1)) for hour in range(ConstantClass.hours_in_month): agg_hour += 1 sim_hour += 1 # get raw hourly load and append to hourly list curr_index = month * ConstantClass.hours_in_month + hour self.hourly_loads.append(self.sim_loads[curr_index]) curr_flow_rate = self.total_flow_rate[curr_index] # update borehole flow rate self.borehole.pipe.fluid.update_fluid_state( new_flow_rate=curr_flow_rate) # calculate borehole resistance self.borehole.calc_bh_resistance() # calculate borehole temp # hourly effects temp_bh_hourly = [] temp_mft_hourly = [] start_hourly = len(self.hourly_loads) - 1 end_hourly = start_hourly - agg_hour g_func_index = -1 for i in range(start_hourly, end_hourly, -1): g_func_index += 1 q_curr = self.hourly_loads[i] q_prev = self.hourly_loads[i - 1] g = self.g_func_hourly[g_func_index] # calculate average bh temp delta_q = (q_curr - q_prev) / \ (2 * np.pi * self.borehole.soil.conductivity * self.total_bh_length) temp_bh_hourly.append(delta_q * g) # calculate mean fluid temp g_rb = g + self.borehole.resist_bh if g_rb < 0: g = -self.borehole.resist_bh * 2 * np.pi * self.borehole.soil.conductivity g_rb = g + self.borehole.resist_bh temp_mft_hourly.append(delta_q * g_rb) # aggregated load effects temp_bh_agg = [] temp_mft_agg = [] if self.agg_loads_flag: for i in range(len(self.agg_load_objects)): if i == 0: continue curr_obj = self.agg_load_objects[i] prev_obj = self.agg_load_objects[i - 1] t_agg = sim_hour - curr_obj.time() ln_t_ts = np.log(t_agg * 3600 / self.ts) g = self.g_func(ln_t_ts) # calculate the average borehole temp delta_q = (curr_obj.q - prev_obj.q) / ( 2 * np.pi * self.borehole.soil.conductivity * self.total_bh_length) temp_bh_agg.append(delta_q * g) # calculate the mean fluid temp g_rb = g + self.borehole.resist_bh if g_rb < 0: g = -self.borehole.resist_bh * 2 * np.pi * self.borehole.soil.conductivity g_rb = g + self.borehole.resist_bh temp_mft_agg.append(delta_q * g_rb) # aggregate load if agg_hour == self.agg_load_intervals[ 0] + self.min_hourly_history - 1: # this has one extra value for comparative purposes # need to get rid of it here self.hourly_loads.popleft() # create new aggregated load object self.aggregate_load() # reset aggregation hour to '0' agg_hour -= self.agg_load_intervals[0] # final bh temp self.temp_bh.append(self.borehole.soil.undisturbed_temp + sum(temp_bh_hourly) + sum(temp_bh_agg)) # final mean fluid temp self.temp_mft.append(self.borehole.soil.undisturbed_temp + sum(temp_mft_hourly) + sum(temp_mft_agg)) # update borehole temperature self.borehole.pipe.fluid.update_fluid_state( new_temp=self.temp_mft[-1]) self.generate_output_reports() PrintClass.my_print("Simulation complete", "success") PrintClass.my_print("Simulation time: %0.3f sec" % (timeit.default_timer() - self.timer_start)) PrintClass.write_log_file()
def __init__(self, json_data, loads_path, output_path, print_output=True): """ Class constructor """ self.timer_start = timeit.default_timer() errors_found = False self.output_path = output_path if not os.path.exists(self.output_path): os.makedirs(self.output_path) with open(os.path.join(self.output_path, 'in.json'), 'w') as outfile: json.dump(json_data, outfile, indent=4, sort_keys=True) # load data into data structs PrintClass.my_print("....Loading GHX data") try: self.name = json_data['Name'] except: # pragma: no cover PrintClass.my_print("....'Name' key not found", 'warn') errors_found = True try: self.sim_years = json_data['Simulation Configuration'][ 'Simulation Years'] except: # pragma: no cover PrintClass.my_print("....'Simulation Years' key not found", 'warn') errors_found = True try: self.aggregation_type = json_data['Simulation Configuration'][ 'Aggregation Type'] except: # pragma: no cover PrintClass.my_print("....'Aggregation Type' key not found", 'warn') errors_found = True try: self.g_func_lntts = [] self.g_func_val = [] for pair in json_data['G-func Pairs']: self.g_func_lntts.append(pair[0]) self.g_func_val.append(pair[1]) self.g_func_present = True except: # pragma: no cover PrintClass.my_print("....'G-func Pairs' key not found", 'warn') self.g_func_present = False self.total_bh_length = 0 self.ghx_list = [] ghx_dict_list = [] for json_data_bh in json_data['GHXs']: ghx_dict_list.append(json_data_bh) this_bh = BoreholeClass(json_data_bh, print_output) self.total_bh_length += this_bh.depth self.ghx_list.append(this_bh) self.borehole = BoreholeClass(self.merge_dicts(ghx_dict_list), print_output) try: PrintClass.my_print("....Importing flow rates and loads") load_pairs = np.genfromtxt(loads_path, delimiter=',', skip_header=1) self.sim_hours = [] self.sim_loads = [] self.total_flow_rate = [] for pair in load_pairs: self.sim_hours.append(pair[0]) self.sim_loads.append(pair[1]) self.total_flow_rate.append(pair[2]) except: # pragma: no cover PrintClass.fatal_error(message="Error importing loads") if errors_found: # pragma: no cover PrintClass.fatal_error(message="Error initializing BaseGHXClass") self.ts = self.calc_ts() self.temp_bh = deque() self.temp_mft = deque() self.agg_load_objects = [] self.agg_loads_flag = True
def __init__(self, json_data, print_output): try: self.name = json_data['Name'] except: # pragma: no cover PrintClass.my_print("....'Name' key not found", 'warn') PrintClass.fatal_error(message="Error initializing BoreholeClass") try: self.location = json_data['Location'] except: # pragma: no cover PrintClass.my_print("....'Location' key not found", 'warn') PrintClass.fatal_error(message="Error initializing BoreholeClass") try: self.depth = json_data['Depth'] except: # pragma: no cover PrintClass.my_print("....'Depth' key not found", 'warn') PrintClass.fatal_error(message="Error initializing BoreholeClass") try: self.radius = json_data['Radius'] self.diameter = self.radius * 2 except: # pragma: no cover PrintClass.my_print("....'Radius' key not found", 'warn') PrintClass.fatal_error(message="Error initializing BoreholeClass") try: self.shank_space = json_data['Shank Spacing'] except: # pragma: no cover PrintClass.my_print("....'Shank Spacing' key not found", 'warn') PrintClass.fatal_error(message="Error initializing BoreholeClass") self.soil = SoilClass(json_data['Soil'], print_output) self.grout = BasePropertiesClass(json_data['Grout'], print_output) self.pipe = PipeClass(json_data['Pipe'], json_data['Fluid'], json_data['Soil']['Temperature'], print_output) # validate shank spacing if self.shank_space > (2 * self.radius - self.pipe.outer_diameter) \ or self.shank_space < self.pipe.outer_diameter: # pragma: no cover PrintClass.my_print("Invalid shank spacing", 'warn') PrintClass.my_print( "Check shank spacing, pipe diameter, and borehole radius", 'warn') PrintClass.fatal_error(message="Error initializing BoreholeClass") self.resist_bh_ave = None self.resist_bh_total_internal = None self.resist_bh_grout = None self.resist_bh = None self.theta_1 = self.shank_space / (2 * self.radius) self.theta_2 = self.radius / self.pipe.outer_radius self.theta_3 = 1 / (2 * self.theta_1 * self.theta_2) self.sigma = (self.grout.conductivity - self.soil.conductivity) / \ (self.grout.conductivity + self.soil.conductivity) self.beta = None self.calc_bh_resistance()
def __init__(self, json_data, initial_temp, print_output): try: self.fluid_type = json_data['Type'] except: # pragma: no cover PrintClass.my_print("....'Name' key not found", 'warn') PrintClass.fatal_error(message="Error initializing FluidsClass") try: self.concentration = json_data['Concentration'] except: # pragma: no cover PrintClass.my_print("....'Concentration' key not found", 'warn') PrintClass.fatal_error(message="Error initializing FluidsClass") try: self.flow_rate = json_data['Flow Rate'] self.flow_rate_prev = 0.0 except: # pragma: no cover PrintClass.my_print("....'Flow Rate' key not found", 'warn') PrintClass.fatal_error(message="Error initializing FluidsClass") self.temperature = initial_temp self.temperature_prev = None self.pressure = 101325 self.mass_flow_rate = self.calc_mass_flow_rate() self.dens_val = self.dens() self.cp_val = self.cp() self.visc_val = self.visc() self.cond_val = self.cond() self.pr_val = self.pr() self.heat_capacity_val = self.heat_capacity()
def simulate(self): """ More docs to come... """ PrintClass.my_print("Beginning simulation") sim_hour = 0 sim_hour_old = 0 for year in range(self.sim_years): for month in range(ConstantClass.months_in_year): PrintClass.my_print("....Year/Month: %d/%d" % (year + 1, month + 1)) temp_bh_hourly = [] temp_mft_hourly = [] for hour in range(ConstantClass.hours_in_month): sim_hour += 1 # get raw hourly load and append to hourly list load_index = month * ConstantClass.hours_in_month + hour curr_load = self.sim_loads[load_index] # aggregate energy in load blocks energy = curr_load * (sim_hour - sim_hour_old) * ConstantClass.sec_in_hour self.shift_loads(energy) # get current data curr_index = month * ConstantClass.hours_in_month + hour curr_flow_rate = self.total_flow_rate[curr_index] # update borehole flow rate self.borehole.pipe.fluid.update_fluid_state( new_flow_rate=curr_flow_rate) # calculate borehole resistance self.borehole.calc_bh_resistance() for i, curr_obj in enumerate(self.agg_load_objects): if curr_obj.num_loads == 0: break if i == 0: q_curr = curr_obj.q q_prev = 0 else: prev_obj = self.agg_load_objects[i - 1] q_curr = curr_obj.q q_prev = prev_obj.q # calculate average bh temp delta_q = (q_curr - q_prev) / \ (2 * np.pi * self.borehole.soil.conductivity * self.total_bh_length) g = curr_obj.g_func temp_bh_hourly.append(delta_q * g) # calculate mean fluid temp g_rb = g + self.borehole.resist_bh if g_rb < 0: g = -self.borehole.resist_bh * 2 * np.pi * self.borehole.soil.conductivity g_rb = g + self.borehole.resist_bh temp_mft_hourly.append(delta_q * g_rb) # final bh temp self.temp_bh.append(self.borehole.soil.undisturbed_temp + sum(temp_bh_hourly)) # final mean fluid temp self.temp_mft.append(self.borehole.soil.undisturbed_temp + sum(temp_mft_hourly)) # update borehole temperature self.borehole.pipe.fluid.update_fluid_state(new_temp=self.temp_mft[-1]) sim_hour_old = sim_hour self.generate_output_reports() PrintClass.my_print("Simulation complete", "success") PrintClass.my_print("Simulation time: %0.3f sec" % (timeit.default_timer() - self.timer_start)) PrintClass.write_log_file()