diff --git a/docs/0.1.1/build/build.svg b/docs/0.1.1/build/build.svg new file mode 100644 index 0000000..9cd2a24 --- /dev/null +++ b/docs/0.1.1/build/build.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + build + build + + + passing + passing + + diff --git a/docs/0.1.1/coverage/.gitignore b/docs/0.1.1/coverage/.gitignore new file mode 100644 index 0000000..ccccf14 --- /dev/null +++ b/docs/0.1.1/coverage/.gitignore @@ -0,0 +1,2 @@ +# Created by coverage.py +* diff --git a/docs/0.1.1/coverage/badge.svg b/docs/0.1.1/coverage/badge.svg new file mode 100644 index 0000000..5d787db --- /dev/null +++ b/docs/0.1.1/coverage/badge.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + coverage + coverage + 58% + 58% + + diff --git a/docs/0.1.1/coverage/coverage_html.js b/docs/0.1.1/coverage/coverage_html.js new file mode 100644 index 0000000..5934882 --- /dev/null +++ b/docs/0.1.1/coverage/coverage_html.js @@ -0,0 +1,624 @@ +// Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 +// For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt + +// Coverage.py HTML report browser code. +/*jslint browser: true, sloppy: true, vars: true, plusplus: true, maxerr: 50, indent: 4 */ +/*global coverage: true, document, window, $ */ + +coverage = {}; + +// General helpers +function debounce(callback, wait) { + let timeoutId = null; + return function(...args) { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + callback.apply(this, args); + }, wait); + }; +}; + +function checkVisible(element) { + const rect = element.getBoundingClientRect(); + const viewBottom = Math.max(document.documentElement.clientHeight, window.innerHeight); + const viewTop = 30; + return !(rect.bottom < viewTop || rect.top >= viewBottom); +} + +function on_click(sel, fn) { + const elt = document.querySelector(sel); + if (elt) { + elt.addEventListener("click", fn); + } +} + +// Helpers for table sorting +function getCellValue(row, column = 0) { + const cell = row.cells[column] // nosemgrep: eslint.detect-object-injection + if (cell.childElementCount == 1) { + const child = cell.firstElementChild + if (child instanceof HTMLTimeElement && child.dateTime) { + return child.dateTime + } else if (child instanceof HTMLDataElement && child.value) { + return child.value + } + } + return cell.innerText || cell.textContent; +} + +function rowComparator(rowA, rowB, column = 0) { + let valueA = getCellValue(rowA, column); + let valueB = getCellValue(rowB, column); + if (!isNaN(valueA) && !isNaN(valueB)) { + return valueA - valueB + } + return valueA.localeCompare(valueB, undefined, {numeric: true}); +} + +function sortColumn(th) { + // Get the current sorting direction of the selected header, + // clear state on other headers and then set the new sorting direction + const currentSortOrder = th.getAttribute("aria-sort"); + [...th.parentElement.cells].forEach(header => header.setAttribute("aria-sort", "none")); + if (currentSortOrder === "none") { + th.setAttribute("aria-sort", th.dataset.defaultSortOrder || "ascending"); + } else { + th.setAttribute("aria-sort", currentSortOrder === "ascending" ? "descending" : "ascending"); + } + + const column = [...th.parentElement.cells].indexOf(th) + + // Sort all rows and afterwards append them in order to move them in the DOM + Array.from(th.closest("table").querySelectorAll("tbody tr")) + .sort((rowA, rowB) => rowComparator(rowA, rowB, column) * (th.getAttribute("aria-sort") === "ascending" ? 1 : -1)) + .forEach(tr => tr.parentElement.appendChild(tr) ); +} + +// Find all the elements with data-shortcut attribute, and use them to assign a shortcut key. +coverage.assign_shortkeys = function () { + document.querySelectorAll("[data-shortcut]").forEach(element => { + document.addEventListener("keypress", event => { + if (event.target.tagName.toLowerCase() === "input") { + return; // ignore keypress from search filter + } + if (event.key === element.dataset.shortcut) { + element.click(); + } + }); + }); +}; + +// Create the events for the filter box. +coverage.wire_up_filter = function () { + // Cache elements. + const table = document.querySelector("table.index"); + const table_body_rows = table.querySelectorAll("tbody tr"); + const no_rows = document.getElementById("no_rows"); + + // Observe filter keyevents. + document.getElementById("filter").addEventListener("input", debounce(event => { + // Keep running total of each metric, first index contains number of shown rows + const totals = new Array(table.rows[0].cells.length).fill(0); + // Accumulate the percentage as fraction + totals[totals.length - 1] = { "numer": 0, "denom": 0 }; // nosemgrep: eslint.detect-object-injection + + // Hide / show elements. + table_body_rows.forEach(row => { + if (!row.cells[0].textContent.includes(event.target.value)) { + // hide + row.classList.add("hidden"); + return; + } + + // show + row.classList.remove("hidden"); + totals[0]++; + + for (let column = 1; column < totals.length; column++) { + // Accumulate dynamic totals + cell = row.cells[column] // nosemgrep: eslint.detect-object-injection + if (column === totals.length - 1) { + // Last column contains percentage + const [numer, denom] = cell.dataset.ratio.split(" "); + totals[column]["numer"] += parseInt(numer, 10); // nosemgrep: eslint.detect-object-injection + totals[column]["denom"] += parseInt(denom, 10); // nosemgrep: eslint.detect-object-injection + } else { + totals[column] += parseInt(cell.textContent, 10); // nosemgrep: eslint.detect-object-injection + } + } + }); + + // Show placeholder if no rows will be displayed. + if (!totals[0]) { + // Show placeholder, hide table. + no_rows.style.display = "block"; + table.style.display = "none"; + return; + } + + // Hide placeholder, show table. + no_rows.style.display = null; + table.style.display = null; + + const footer = table.tFoot.rows[0]; + // Calculate new dynamic sum values based on visible rows. + for (let column = 1; column < totals.length; column++) { + // Get footer cell element. + const cell = footer.cells[column]; // nosemgrep: eslint.detect-object-injection + + // Set value into dynamic footer cell element. + if (column === totals.length - 1) { + // Percentage column uses the numerator and denominator, + // and adapts to the number of decimal places. + const match = /\.([0-9]+)/.exec(cell.textContent); + const places = match ? match[1].length : 0; + const { numer, denom } = totals[column]; // nosemgrep: eslint.detect-object-injection + cell.dataset.ratio = `${numer} ${denom}`; + // Check denom to prevent NaN if filtered files contain no statements + cell.textContent = denom + ? `${(numer * 100 / denom).toFixed(places)}%` + : `${(100).toFixed(places)}%`; + } else { + cell.textContent = totals[column]; // nosemgrep: eslint.detect-object-injection + } + } + })); + + // Trigger change event on setup, to force filter on page refresh + // (filter value may still be present). + document.getElementById("filter").dispatchEvent(new Event("input")); +}; + +coverage.INDEX_SORT_STORAGE = "COVERAGE_INDEX_SORT_2"; + +// Loaded on index.html +coverage.index_ready = function () { + coverage.assign_shortkeys(); + coverage.wire_up_filter(); + document.querySelectorAll("[data-sortable] th[aria-sort]").forEach( + th => th.addEventListener("click", e => sortColumn(e.target)) + ); + + // Look for a localStorage item containing previous sort settings: + const stored_list = localStorage.getItem(coverage.INDEX_SORT_STORAGE); + + if (stored_list) { + const {column, direction} = JSON.parse(stored_list); + const th = document.querySelector("[data-sortable]").tHead.rows[0].cells[column]; // nosemgrep: eslint.detect-object-injection + th.setAttribute("aria-sort", direction === "ascending" ? "descending" : "ascending"); + th.click() + } + + // Watch for page unload events so we can save the final sort settings: + window.addEventListener("unload", function () { + const th = document.querySelector('[data-sortable] th[aria-sort="ascending"], [data-sortable] [aria-sort="descending"]'); + if (!th) { + return; + } + localStorage.setItem(coverage.INDEX_SORT_STORAGE, JSON.stringify({ + column: [...th.parentElement.cells].indexOf(th), + direction: th.getAttribute("aria-sort"), + })); + }); + + on_click(".button_prev_file", coverage.to_prev_file); + on_click(".button_next_file", coverage.to_next_file); + + on_click(".button_show_hide_help", coverage.show_hide_help); +}; + +// -- pyfile stuff -- + +coverage.LINE_FILTERS_STORAGE = "COVERAGE_LINE_FILTERS"; + +coverage.pyfile_ready = function () { + // If we're directed to a particular line number, highlight the line. + var frag = location.hash; + if (frag.length > 2 && frag[1] === "t") { + document.querySelector(frag).closest(".n").classList.add("highlight"); + coverage.set_sel(parseInt(frag.substr(2), 10)); + } else { + coverage.set_sel(0); + } + + on_click(".button_toggle_run", coverage.toggle_lines); + on_click(".button_toggle_mis", coverage.toggle_lines); + on_click(".button_toggle_exc", coverage.toggle_lines); + on_click(".button_toggle_par", coverage.toggle_lines); + + on_click(".button_next_chunk", coverage.to_next_chunk_nicely); + on_click(".button_prev_chunk", coverage.to_prev_chunk_nicely); + on_click(".button_top_of_page", coverage.to_top); + on_click(".button_first_chunk", coverage.to_first_chunk); + + on_click(".button_prev_file", coverage.to_prev_file); + on_click(".button_next_file", coverage.to_next_file); + on_click(".button_to_index", coverage.to_index); + + on_click(".button_show_hide_help", coverage.show_hide_help); + + coverage.filters = undefined; + try { + coverage.filters = localStorage.getItem(coverage.LINE_FILTERS_STORAGE); + } catch(err) {} + + if (coverage.filters) { + coverage.filters = JSON.parse(coverage.filters); + } + else { + coverage.filters = {run: false, exc: true, mis: true, par: true}; + } + + for (cls in coverage.filters) { + coverage.set_line_visibilty(cls, coverage.filters[cls]); // nosemgrep: eslint.detect-object-injection + } + + coverage.assign_shortkeys(); + coverage.init_scroll_markers(); + coverage.wire_up_sticky_header(); + + document.querySelectorAll("[id^=ctxs]").forEach( + cbox => cbox.addEventListener("click", coverage.expand_contexts) + ); + + // Rebuild scroll markers when the window height changes. + window.addEventListener("resize", coverage.build_scroll_markers); +}; + +coverage.toggle_lines = function (event) { + const btn = event.target.closest("button"); + const category = btn.value + const show = !btn.classList.contains("show_" + category); + coverage.set_line_visibilty(category, show); + coverage.build_scroll_markers(); + coverage.filters[category] = show; + try { + localStorage.setItem(coverage.LINE_FILTERS_STORAGE, JSON.stringify(coverage.filters)); + } catch(err) {} +}; + +coverage.set_line_visibilty = function (category, should_show) { + const cls = "show_" + category; + const btn = document.querySelector(".button_toggle_" + category); + if (btn) { + if (should_show) { + document.querySelectorAll("#source ." + category).forEach(e => e.classList.add(cls)); + btn.classList.add(cls); + } + else { + document.querySelectorAll("#source ." + category).forEach(e => e.classList.remove(cls)); + btn.classList.remove(cls); + } + } +}; + +// Return the nth line div. +coverage.line_elt = function (n) { + return document.getElementById("t" + n)?.closest("p"); +}; + +// Set the selection. b and e are line numbers. +coverage.set_sel = function (b, e) { + // The first line selected. + coverage.sel_begin = b; + // The next line not selected. + coverage.sel_end = (e === undefined) ? b+1 : e; +}; + +coverage.to_top = function () { + coverage.set_sel(0, 1); + coverage.scroll_window(0); +}; + +coverage.to_first_chunk = function () { + coverage.set_sel(0, 1); + coverage.to_next_chunk(); +}; + +coverage.to_prev_file = function () { + window.location = document.getElementById("prevFileLink").href; +} + +coverage.to_next_file = function () { + window.location = document.getElementById("nextFileLink").href; +} + +coverage.to_index = function () { + location.href = document.getElementById("indexLink").href; +} + +coverage.show_hide_help = function () { + const helpCheck = document.getElementById("help_panel_state") + helpCheck.checked = !helpCheck.checked; +} + +// Return a string indicating what kind of chunk this line belongs to, +// or null if not a chunk. +coverage.chunk_indicator = function (line_elt) { + const classes = line_elt?.className; + if (!classes) { + return null; + } + const match = classes.match(/\bshow_\w+\b/); + if (!match) { + return null; + } + return match[0]; +}; + +coverage.to_next_chunk = function () { + const c = coverage; + + // Find the start of the next colored chunk. + var probe = c.sel_end; + var chunk_indicator, probe_line; + while (true) { + probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + chunk_indicator = c.chunk_indicator(probe_line); + if (chunk_indicator) { + break; + } + probe++; + } + + // There's a next chunk, `probe` points to it. + var begin = probe; + + // Find the end of this chunk. + var next_indicator = chunk_indicator; + while (next_indicator === chunk_indicator) { + probe++; + probe_line = c.line_elt(probe); + next_indicator = c.chunk_indicator(probe_line); + } + c.set_sel(begin, probe); + c.show_selection(); +}; + +coverage.to_prev_chunk = function () { + const c = coverage; + + // Find the end of the prev colored chunk. + var probe = c.sel_begin-1; + var probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + var chunk_indicator = c.chunk_indicator(probe_line); + while (probe > 1 && !chunk_indicator) { + probe--; + probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + chunk_indicator = c.chunk_indicator(probe_line); + } + + // There's a prev chunk, `probe` points to its last line. + var end = probe+1; + + // Find the beginning of this chunk. + var prev_indicator = chunk_indicator; + while (prev_indicator === chunk_indicator) { + probe--; + if (probe <= 0) { + return; + } + probe_line = c.line_elt(probe); + prev_indicator = c.chunk_indicator(probe_line); + } + c.set_sel(probe+1, end); + c.show_selection(); +}; + +// Returns 0, 1, or 2: how many of the two ends of the selection are on +// the screen right now? +coverage.selection_ends_on_screen = function () { + if (coverage.sel_begin === 0) { + return 0; + } + + const begin = coverage.line_elt(coverage.sel_begin); + const end = coverage.line_elt(coverage.sel_end-1); + + return ( + (checkVisible(begin) ? 1 : 0) + + (checkVisible(end) ? 1 : 0) + ); +}; + +coverage.to_next_chunk_nicely = function () { + if (coverage.selection_ends_on_screen() === 0) { + // The selection is entirely off the screen: + // Set the top line on the screen as selection. + + // This will select the top-left of the viewport + // As this is most likely the span with the line number we take the parent + const line = document.elementFromPoint(0, 0).parentElement; + if (line.parentElement !== document.getElementById("source")) { + // The element is not a source line but the header or similar + coverage.select_line_or_chunk(1); + } else { + // We extract the line number from the id + coverage.select_line_or_chunk(parseInt(line.id.substring(1), 10)); + } + } + coverage.to_next_chunk(); +}; + +coverage.to_prev_chunk_nicely = function () { + if (coverage.selection_ends_on_screen() === 0) { + // The selection is entirely off the screen: + // Set the lowest line on the screen as selection. + + // This will select the bottom-left of the viewport + // As this is most likely the span with the line number we take the parent + const line = document.elementFromPoint(document.documentElement.clientHeight-1, 0).parentElement; + if (line.parentElement !== document.getElementById("source")) { + // The element is not a source line but the header or similar + coverage.select_line_or_chunk(coverage.lines_len); + } else { + // We extract the line number from the id + coverage.select_line_or_chunk(parseInt(line.id.substring(1), 10)); + } + } + coverage.to_prev_chunk(); +}; + +// Select line number lineno, or if it is in a colored chunk, select the +// entire chunk +coverage.select_line_or_chunk = function (lineno) { + var c = coverage; + var probe_line = c.line_elt(lineno); + if (!probe_line) { + return; + } + var the_indicator = c.chunk_indicator(probe_line); + if (the_indicator) { + // The line is in a highlighted chunk. + // Search backward for the first line. + var probe = lineno; + var indicator = the_indicator; + while (probe > 0 && indicator === the_indicator) { + probe--; + probe_line = c.line_elt(probe); + if (!probe_line) { + break; + } + indicator = c.chunk_indicator(probe_line); + } + var begin = probe + 1; + + // Search forward for the last line. + probe = lineno; + indicator = the_indicator; + while (indicator === the_indicator) { + probe++; + probe_line = c.line_elt(probe); + indicator = c.chunk_indicator(probe_line); + } + + coverage.set_sel(begin, probe); + } + else { + coverage.set_sel(lineno); + } +}; + +coverage.show_selection = function () { + // Highlight the lines in the chunk + document.querySelectorAll("#source .highlight").forEach(e => e.classList.remove("highlight")); + for (let probe = coverage.sel_begin; probe < coverage.sel_end; probe++) { + coverage.line_elt(probe).querySelector(".n").classList.add("highlight"); + } + + coverage.scroll_to_selection(); +}; + +coverage.scroll_to_selection = function () { + // Scroll the page if the chunk isn't fully visible. + if (coverage.selection_ends_on_screen() < 2) { + const element = coverage.line_elt(coverage.sel_begin); + coverage.scroll_window(element.offsetTop - 60); + } +}; + +coverage.scroll_window = function (to_pos) { + window.scroll({top: to_pos, behavior: "smooth"}); +}; + +coverage.init_scroll_markers = function () { + // Init some variables + coverage.lines_len = document.querySelectorAll("#source > p").length; + + // Build html + coverage.build_scroll_markers(); +}; + +coverage.build_scroll_markers = function () { + const temp_scroll_marker = document.getElementById("scroll_marker") + if (temp_scroll_marker) temp_scroll_marker.remove(); + // Don't build markers if the window has no scroll bar. + if (document.body.scrollHeight <= window.innerHeight) { + return; + } + + const marker_scale = window.innerHeight / document.body.scrollHeight; + const line_height = Math.min(Math.max(3, window.innerHeight / coverage.lines_len), 10); + + let previous_line = -99, last_mark, last_top; + + const scroll_marker = document.createElement("div"); + scroll_marker.id = "scroll_marker"; + document.getElementById("source").querySelectorAll( + "p.show_run, p.show_mis, p.show_exc, p.show_exc, p.show_par" + ).forEach(element => { + const line_top = Math.floor(element.offsetTop * marker_scale); + const line_number = parseInt(element.querySelector(".n a").id.substr(1)); + + if (line_number === previous_line + 1) { + // If this solid missed block just make previous mark higher. + last_mark.style.height = `${line_top + line_height - last_top}px`; + } else { + // Add colored line in scroll_marker block. + last_mark = document.createElement("div"); + last_mark.id = `m${line_number}`; + last_mark.classList.add("marker"); + last_mark.style.height = `${line_height}px`; + last_mark.style.top = `${line_top}px`; + scroll_marker.append(last_mark); + last_top = line_top; + } + + previous_line = line_number; + }); + + // Append last to prevent layout calculation + document.body.append(scroll_marker); +}; + +coverage.wire_up_sticky_header = function () { + const header = document.querySelector("header"); + const header_bottom = ( + header.querySelector(".content h2").getBoundingClientRect().top - + header.getBoundingClientRect().top + ); + + function updateHeader() { + if (window.scrollY > header_bottom) { + header.classList.add("sticky"); + } else { + header.classList.remove("sticky"); + } + } + + window.addEventListener("scroll", updateHeader); + updateHeader(); +}; + +coverage.expand_contexts = function (e) { + var ctxs = e.target.parentNode.querySelector(".ctxs"); + + if (!ctxs.classList.contains("expanded")) { + var ctxs_text = ctxs.textContent; + var width = Number(ctxs_text[0]); + ctxs.textContent = ""; + for (var i = 1; i < ctxs_text.length; i += width) { + key = ctxs_text.substring(i, i + width).trim(); + ctxs.appendChild(document.createTextNode(contexts[key])); + ctxs.appendChild(document.createElement("br")); + } + ctxs.classList.add("expanded"); + } +}; + +document.addEventListener("DOMContentLoaded", () => { + if (document.body.classList.contains("indexfile")) { + coverage.index_ready(); + } else { + coverage.pyfile_ready(); + } +}); diff --git a/docs/0.1.1/coverage/d_35fc0e049e81dfd6___init___py.html b/docs/0.1.1/coverage/d_35fc0e049e81dfd6___init___py.html new file mode 100644 index 0000000..cfa34e4 --- /dev/null +++ b/docs/0.1.1/coverage/d_35fc0e049e81dfd6___init___py.html @@ -0,0 +1,99 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/__init__.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/__init__.py: + 100% +

+ +

+ 2 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from .heat_exchanger import HeatExchanger 

+

2from .moving_boundary_ntu import MovingBoundaryNTUCondenser, MovingBoundaryNTUEvaporator 

+
+ + + diff --git a/docs/0.1.1/coverage/d_35fc0e049e81dfd6_economizer_py.html b/docs/0.1.1/coverage/d_35fc0e049e81dfd6_economizer_py.html new file mode 100644 index 0000000..8a0a4d6 --- /dev/null +++ b/docs/0.1.1/coverage/d_35fc0e049e81dfd6_economizer_py.html @@ -0,0 +1,169 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/economizer.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/economizer.py: + 100% +

+ +

+ 32 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import logging 

+

2 

+

3from vclibpy.components.heat_exchangers.ntu import BasicNTU 

+

4from vclibpy.media import ThermodynamicState 

+

5 

+

6logger = logging.getLogger(__name__) 

+

7 

+

8 

+

9class VaporInjectionEconomizerNTU(BasicNTU): 

+

10 """ 

+

11 Economizer heat exchanger which is NTU based. 

+

12 Used only for vapor injection cycles, as 

+

13 calculations are purely based for two-phase 

+

14 and liquid estimations. 

+

15 

+

16 See parent class for more arguments. 

+

17 

+

18 Assumptions: 

+

19 

+

20 - Default `flow_type` is counter_flow. 

+

21 - Default `ratio_outer_to_inner_area` is 1, as 

+

22 - pipes are nearly same diameter and length 

+

23 - Secondary heat transfer for alpha is disabled; gas, 

+

24 liquid and two-phase models are used for both sides. 

+

25 """ 

+

26 

+

27 def __init__(self, **kwargs): 

+

28 kwargs.pop("secondary_heat_transfer", None) 

+

29 kwargs.pop("secondary_medium", None) 

+

30 self._state_two_phase_outlet = None 

+

31 self._state_two_phase_inlet = None 

+

32 super().__init__( 

+

33 flow_type=kwargs.pop("flow_type", "counter"), 

+

34 secondary_heat_transfer="None", 

+

35 secondary_medium="None", 

+

36 ratio_outer_to_inner_area=kwargs.pop("ratio_outer_to_inner_area", 1), 

+

37 **kwargs) 

+

38 

+

39 @property 

+

40 def state_two_phase_inlet(self) -> ThermodynamicState: 

+

41 return self._state_two_phase_inlet 

+

42 

+

43 @state_two_phase_inlet.setter 

+

44 def state_two_phase_inlet(self, state_inlet: ThermodynamicState): 

+

45 self._state_two_phase_inlet = state_inlet 

+

46 

+

47 @property 

+

48 def state_two_phase_outlet(self) -> ThermodynamicState: 

+

49 return self._state_two_phase_outlet 

+

50 

+

51 @state_two_phase_outlet.setter 

+

52 def state_two_phase_outlet(self, state_outlet: ThermodynamicState): 

+

53 self._state_two_phase_outlet = state_outlet 

+

54 

+

55 def calc(self, inputs, fs_state) -> (float, float): 

+

56 raise NotImplementedError("Could be moved from VaporInjectionEconomizer") 

+

57 

+

58 def set_secondary_cp(self, cp: float): 

+

59 """Set primary m_flow_cp""" 

+

60 self._secondary_cp = cp 

+

61 

+

62 def start_secondary_med_prop(self): 

+

63 self.med_prop_sec = self.med_prop 

+

64 

+

65 def terminate_secondary_med_prop(self): 

+

66 pass # Not required as it is the central med_prop class 

+

67 

+

68 def calc_alpha_secondary(self, transport_properties): 

+

69 raise NotImplementedError("Economizer does not use secondary heat transfer model.") 

+

70 

+

71 def calc_transport_properties_secondary_medium(self, T, p=None): 

+

72 raise NotImplementedError("Economizer does not use this method") 

+
+ + + diff --git a/docs/0.1.1/coverage/d_35fc0e049e81dfd6_heat_exchanger_py.html b/docs/0.1.1/coverage/d_35fc0e049e81dfd6_heat_exchanger_py.html new file mode 100644 index 0000000..b7a6a60 --- /dev/null +++ b/docs/0.1.1/coverage/d_35fc0e049e81dfd6_heat_exchanger_py.html @@ -0,0 +1,336 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/heat_exchanger.py: 97% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/heat_exchanger.py: + 97% +

+ +

+ 70 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import abc 

+

2 

+

3from typing import Tuple 

+

4 

+

5from vclibpy import media 

+

6from vclibpy.datamodels import FlowsheetState, Inputs 

+

7from vclibpy.components.component import BaseComponent 

+

8from vclibpy.components.heat_exchangers.heat_transfer.heat_transfer import HeatTransfer, TwoPhaseHeatTransfer 

+

9 

+

10 

+

11class HeatExchanger(BaseComponent, abc.ABC): 

+

12 """ 

+

13 Class for a heat exchanger. 

+

14 

+

15 Args: 

+

16 A (float): 

+

17 Area of HE in m^2 for NTU calculation 

+

18 secondary_medium (str): 

+

19 Name for secondary medium, e.g. `water` or `air` 

+

20 wall_heat_transfer (HeatTransfer): 

+

21 Model for heat transfer inside wall 

+

22 secondary_heat_transfer (HeatTransfer): 

+

23 Model for heat transfer from secondary medium to wall 

+

24 gas_heat_transfer (HeatTransfer): 

+

25 Model for heat transfer from refrigerant gas to wall 

+

26 liquid_heat_transfer (HeatTransfer): 

+

27 Model for heat transfer from refrigerant liquid to wall 

+

28 two_phase_heat_transfer (TwoPhaseHeatTransfer): 

+

29 Model for heat transfer from refrigerant two phase to wall 

+

30 """ 

+

31 

+

32 def __init__( 

+

33 self, 

+

34 A: float, 

+

35 wall_heat_transfer: HeatTransfer, 

+

36 secondary_heat_transfer: HeatTransfer, 

+

37 gas_heat_transfer: HeatTransfer, 

+

38 liquid_heat_transfer: HeatTransfer, 

+

39 two_phase_heat_transfer: TwoPhaseHeatTransfer, 

+

40 secondary_medium: str 

+

41 ): 

+

42 super().__init__() 

+

43 self.A = A 

+

44 self.secondary_medium = secondary_medium.lower() 

+

45 

+

46 self._wall_heat_transfer = wall_heat_transfer 

+

47 self._secondary_heat_transfer = secondary_heat_transfer 

+

48 self._gas_heat_transfer = gas_heat_transfer 

+

49 self._liquid_heat_transfer = liquid_heat_transfer 

+

50 self._two_phase_heat_transfer = two_phase_heat_transfer 

+

51 

+

52 self.med_prop_sec = None # Later start in start_secondary_med_prop 

+

53 self._m_flow_secondary = None 

+

54 self._secondary_cp = 0 # Allow initial calculation of _m_flow_secondary_cp if cp is not set 

+

55 self._m_flow_secondary_cp = 0 

+

56 

+

57 def start_secondary_med_prop(self): 

+

58 """ 

+

59 Set up the wrapper for the secondary medium's media properties. 

+

60 """ 

+

61 # Set up the secondary_medium wrapper: 

+

62 med_prop_class, med_prop_kwargs = media.get_global_med_prop_and_kwargs() 

+

63 if self.secondary_medium == "air" and med_prop_class == media.RefProp: 

+

64 fluid_name = "AIR.PPF" 

+

65 else: 

+

66 fluid_name = self.secondary_medium 

+

67 if self.med_prop_sec is not None: 

+

68 if self.med_prop_sec.fluid_name == fluid_name: 

+

69 return 

+

70 self.med_prop_sec.terminate() 

+

71 self.med_prop_sec = med_prop_class(fluid_name=self.secondary_medium, **med_prop_kwargs) 

+

72 

+

73 def terminate_secondary_med_prop(self): 

+

74 if self.med_prop_sec is not None: 

+

75 self.med_prop_sec.terminate() 

+

76 

+

77 @abc.abstractmethod 

+

78 def calc(self, inputs: Inputs, fs_state: FlowsheetState) -> Tuple[float, float]: 

+

79 """ 

+

80 Calculate the heat exchanger based on the given inputs. 

+

81 

+

82 The flowsheet state can be used to save important variables 

+

83 during calculation for later analysis. 

+

84 

+

85 Both return values are used to check if the heat transfer is valid or not. 

+

86 

+

87 Args: 

+

88 inputs (Inputs): The inputs for the calculation. 

+

89 fs_state (FlowsheetState): The flowsheet state to save important variables. 

+

90 

+

91 Returns: 

+

92 Tuple[float, float]: 

+

93 error: Error in percentage between the required and calculated heat flow rates. 

+

94 dT_min: Minimal temperature difference (can be negative). 

+

95 """ 

+

96 raise NotImplementedError 

+

97 

+

98 def calc_alpha_two_phase(self, state_q0, state_q1, inputs: Inputs, fs_state: FlowsheetState) -> float: 

+

99 """ 

+

100 Calculate the two-phase heat transfer coefficient. 

+

101 

+

102 Args: 

+

103 state_q0: State at vapor quality 0. 

+

104 state_q1: State at vapor quality 1. 

+

105 inputs (Inputs): The inputs for the calculation. 

+

106 fs_state (FlowsheetState): The flowsheet state to save important variables. 

+

107 

+

108 Returns: 

+

109 float: The two-phase heat transfer coefficient. 

+

110 """ 

+

111 return self._two_phase_heat_transfer.calc( 

+

112 state_q0=state_q0, 

+

113 state_q1=state_q1, 

+

114 inputs=inputs, 

+

115 fs_state=fs_state, 

+

116 m_flow=self.m_flow, 

+

117 med_prop=self.med_prop, 

+

118 state_inlet=self.state_inlet, 

+

119 state_outlet=self.state_outlet 

+

120 ) 

+

121 

+

122 def calc_alpha_liquid(self, transport_properties) -> float: 

+

123 """ 

+

124 Calculate the liquid-phase heat transfer coefficient. 

+

125 

+

126 Args: 

+

127 transport_properties: Transport properties for the liquid phase. 

+

128 

+

129 Returns: 

+

130 float: The liquid-phase heat transfer coefficient. 

+

131 """ 

+

132 return self._liquid_heat_transfer.calc( 

+

133 transport_properties=transport_properties, 

+

134 m_flow=self.m_flow 

+

135 ) 

+

136 

+

137 def calc_alpha_gas(self, transport_properties) -> float: 

+

138 """ 

+

139 Calculate the gas-phase heat transfer coefficient. 

+

140 

+

141 Args: 

+

142 transport_properties: Transport properties for the gas phase. 

+

143 

+

144 Returns: 

+

145 float: The gas-phase heat transfer coefficient. 

+

146 """ 

+

147 return self._gas_heat_transfer.calc( 

+

148 transport_properties=transport_properties, 

+

149 m_flow=self.m_flow 

+

150 ) 

+

151 

+

152 def calc_alpha_secondary(self, transport_properties) -> float: 

+

153 """ 

+

154 Calculate the secondary-medium heat transfer coefficient. 

+

155 

+

156 Args: 

+

157 transport_properties: Transport properties for the secondary medium. 

+

158 

+

159 Returns: 

+

160 float: The secondary-medium heat transfer coefficient. 

+

161 """ 

+

162 return self._secondary_heat_transfer.calc( 

+

163 transport_properties=transport_properties, 

+

164 m_flow=self.m_flow_secondary 

+

165 ) 

+

166 

+

167 def calc_wall_heat_transfer(self) -> float: 

+

168 """ 

+

169 Calculate the heat transfer coefficient inside the wall. 

+

170 

+

171 Returns: 

+

172 float: The wall heat transfer coefficient. 

+

173 """ 

+

174 # Arguments are not required 

+

175 return self._wall_heat_transfer.calc( 

+

176 transport_properties=media.TransportProperties(), 

+

177 m_flow=0 

+

178 ) 

+

179 

+

180 @property 

+

181 def m_flow_secondary(self) -> float: 

+

182 return self._m_flow_secondary 

+

183 

+

184 @m_flow_secondary.setter 

+

185 def m_flow_secondary(self, m_flow: float): 

+

186 self._m_flow_secondary = m_flow 

+

187 self._m_flow_secondary_cp = self._m_flow_secondary * self._secondary_cp 

+

188 

+

189 @property 

+

190 def m_flow_secondary_cp(self): 

+

191 return self._m_flow_secondary_cp 

+

192 

+

193 def calc_secondary_cp(self, T: float, p=None): 

+

194 """ 

+

195 Calculate and set the heat capacity rate m_flow_cp of the secondary medium. 

+

196 

+

197 Args: 

+

198 T (float): Temperature of the secondary medium. 

+

199 p (float, optional): Pressure of the secondary medium. Defaults to None. 

+

200 """ 

+

201 self._secondary_cp = self.calc_transport_properties_secondary_medium(T=T, p=p).cp 

+

202 self._m_flow_secondary_cp = self.m_flow_secondary * self._secondary_cp 

+

203 

+

204 def calc_secondary_Q_flow(self, Q_flow: float) -> float: 

+

205 return Q_flow 

+

206 

+

207 def calc_Q_flow(self) -> float: 

+

208 """ 

+

209 Calculate the total heat flow rate. 

+

210 

+

211 Returns: 

+

212 float: The total heat flow rate. 

+

213 """ 

+

214 return self.m_flow * abs(self.state_inlet.h - self.state_outlet.h) 

+

215 

+

216 def calc_transport_properties_secondary_medium(self, T, p=None) -> media.TransportProperties: 

+

217 """ 

+

218 Calculate the transport properties for the selected secondary_medium. 

+

219 

+

220 Args: 

+

221 T (float): Temperature in K. 

+

222 p (float, optional): Pressure to use. Defaults to None. 

+

223 

+

224 Returns: 

+

225 media.TransportProperties: The calculated transport properties. 

+

226 """ 

+

227 if p is None: 

+

228 if self.secondary_medium == "water": 

+

229 p = 2e5 # 2 bar (default hydraulic pressure) 

+

230 elif self.secondary_medium == "air": 

+

231 p = 101325 # 1 atm 

+

232 else: 

+

233 raise NotImplementedError( 

+

234 "Default pressures for secondary_mediums aside from water and air are not supported yet." 

+

235 ) 

+

236 # Calc state 

+

237 state = self.med_prop_sec.calc_state("PT", p, T) 

+

238 # Return properties 

+

239 return self.med_prop_sec.calc_transport_properties(state) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_35fc0e049e81dfd6_moving_boundary_ntu_py.html b/docs/0.1.1/coverage/d_35fc0e049e81dfd6_moving_boundary_ntu_py.html new file mode 100644 index 0000000..2ed2bb3 --- /dev/null +++ b/docs/0.1.1/coverage/d_35fc0e049e81dfd6_moving_boundary_ntu_py.html @@ -0,0 +1,463 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/moving_boundary_ntu.py: 95% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/moving_boundary_ntu.py: + 95% +

+ +

+ 133 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import abc 

+

2import logging 

+

3 

+

4import numpy as np 

+

5from vclibpy.datamodels import FlowsheetState, Inputs 

+

6from vclibpy.components.heat_exchangers.ntu import BasicNTU 

+

7from vclibpy.media import ThermodynamicState 

+

8 

+

9logger = logging.getLogger(__name__) 

+

10 

+

11 

+

12class MovingBoundaryNTU(BasicNTU, abc.ABC): 

+

13 """ 

+

14 Moving boundary NTU based heat exchanger. 

+

15 

+

16 See parent classe for arguments. 

+

17 """ 

+

18 

+

19 def separate_phases(self, state_max: ThermodynamicState, state_min: ThermodynamicState, p: float): 

+

20 """ 

+

21 Separates a flow with possible phase changes into three parts: 

+

22 subcooling (sc), latent phase change (lat), and superheating (sh) 

+

23 at the given pressure. 

+

24 

+

25 Args: 

+

26 state_max (ThermodynamicState): State with higher enthalpy. 

+

27 state_min (ThermodynamicState): State with lower enthalpy. 

+

28 p (float): Pressure of phase change. 

+

29 

+

30 Returns: 

+

31 Tuple[float, float, float, ThermodynamicState, ThermodynamicState]: 

+

32 Q_sc: Heat for subcooling. 

+

33 Q_lat: Heat for latent phase change. 

+

34 Q_sh: Heat for superheating. 

+

35 state_q0: State at vapor quality 0 and the given pressure. 

+

36 state_q1: State at vapor quality 1 and the given pressure. 

+

37 """ 

+

38 # Get relevant states: 

+

39 state_q0 = self.med_prop.calc_state("PQ", p, 0) 

+

40 state_q1 = self.med_prop.calc_state("PQ", p, 1) 

+

41 Q_sc = max(0.0, 

+

42 min((state_q0.h - state_min.h), 

+

43 (state_max.h - state_min.h))) * self.m_flow 

+

44 Q_lat = max(0.0, 

+

45 (min(state_max.h, state_q1.h) - 

+

46 max(state_min.h, state_q0.h))) * self.m_flow 

+

47 Q_sh = max(0.0, 

+

48 min((state_max.h - state_q1.h), 

+

49 (state_max.h - state_min.h))) * self.m_flow 

+

50 return Q_sc, Q_lat, Q_sh, state_q0, state_q1 

+

51 

+

52 def iterate_area(self, dT_max, alpha_pri, alpha_sec, Q) -> float: 

+

53 """ 

+

54 Iteratively calculates the required area for the heat exchange. 

+

55 

+

56 Args: 

+

57 dT_max (float): Maximum temperature differential. 

+

58 alpha_pri (float): Heat transfer coefficient for the primary medium. 

+

59 alpha_sec (float): Heat transfer coefficient for the secondary medium. 

+

60 Q (float): Heat flow rate. 

+

61 

+

62 Returns: 

+

63 float: Required area for heat exchange. 

+

64 """ 

+

65 _accuracy = 1e-6 # square mm 

+

66 _step = 1.0 

+

67 R = self.calc_R() 

+

68 k = self.calc_k(alpha_pri, alpha_sec) 

+

69 m_flow_cp_min = self.calc_m_flow_cp_min() 

+

70 # First check if point is feasible at all 

+

71 if dT_max <= 0: 

+

72 return self.A 

+

73 eps_necessary = Q / (m_flow_cp_min * dT_max) 

+

74 

+

75 # Special cases: 

+

76 # --------------- 

+

77 # eps is equal or higher than 1, an infinite amount of area would be necessary. 

+

78 if eps_necessary >= 1: 

+

79 return self.A 

+

80 # eps is lower or equal to zero: No Area required (Q<=0) 

+

81 if eps_necessary <= 0: 

+

82 return 0 

+

83 

+

84 area = 0.0 

+

85 while True: 

+

86 NTU = self.calc_NTU(area, k, m_flow_cp_min) 

+

87 eps = self.calc_eps(R, NTU) 

+

88 if eps >= eps_necessary: 

+

89 if _step <= _accuracy: 

+

90 break 

+

91 else: 

+

92 # Go back 

+

93 area -= _step 

+

94 _step /= 10 

+

95 continue 

+

96 if _step < _accuracy and area > self.A: 

+

97 break 

+

98 area += _step 

+

99 

+

100 return min(area, self.A) 

+

101 

+

102 

+

103class MovingBoundaryNTUCondenser(MovingBoundaryNTU): 

+

104 """ 

+

105 Condenser class which implements the actual `calc` method. 

+

106 

+

107 Assumptions: 

+

108 - No phase changes in secondary medium 

+

109 - cp of secondary medium is constant over heat-exchanger 

+

110 

+

111 See parent classes for arguments. 

+

112 """ 

+

113 

+

114 def calc(self, inputs: Inputs, fs_state: FlowsheetState) -> (float, float): 

+

115 """ 

+

116 Calculate the heat exchanger with the NTU-Method based on the given inputs. 

+

117 

+

118 The flowsheet state can be used to save important variables 

+

119 during calculation for later analysis. 

+

120 

+

121 Both return values are used to check if the heat transfer is valid or not. 

+

122 

+

123 Args: 

+

124 inputs (Inputs): The inputs for the calculation. 

+

125 fs_state (FlowsheetState): The flowsheet state to save important variables. 

+

126 

+

127 Returns: 

+

128 Tuple[float, float]: 

+

129 error: Error in percentage between the required and calculated heat flow rates. 

+

130 dT_min: Minimal temperature difference (can be negative). 

+

131 """ 

+

132 self.m_flow_secondary = inputs.m_flow_con # [kg/s] 

+

133 self.calc_secondary_cp(T=inputs.T_con_in) 

+

134 

+

135 # First we separate the flow: 

+

136 Q_sc, Q_lat, Q_sh, state_q0, state_q1 = self.separate_phases( 

+

137 self.state_inlet, 

+

138 self.state_outlet, 

+

139 self.state_inlet.p 

+

140 ) 

+

141 Q = Q_sc + Q_lat + Q_sh 

+

142 

+

143 # Note: As Q_con_ntu has to converge to Q_con (m_ref*delta_h), we can safely 

+

144 # calculate the output temperature. 

+

145 

+

146 T_mean = inputs.T_con_in + self.calc_secondary_Q_flow(Q) / (self.m_flow_secondary_cp * 2) 

+

147 tra_prop_med = self.calc_transport_properties_secondary_medium(T_mean) 

+

148 alpha_med_wall = self.calc_alpha_secondary(tra_prop_med) 

+

149 

+

150 # Calculate secondary_medium side temperatures: 

+

151 # Assumption loss is the same correlation for each regime 

+

152 T_sc = inputs.T_con_in + self.calc_secondary_Q_flow(Q_sc) / self.m_flow_secondary_cp 

+

153 T_sh = T_sc + self.calc_secondary_Q_flow(Q_lat) / self.m_flow_secondary_cp 

+

154 T_out = T_sh + self.calc_secondary_Q_flow(Q_sh) / self.m_flow_secondary_cp 

+

155 

+

156 # 1. Regime: Subcooling 

+

157 Q_sc_ntu, A_sc = 0, 0 

+

158 if Q_sc > 0 and (state_q0.T != self.state_outlet.T): 

+

159 self.set_primary_cp((state_q0.h - self.state_outlet.h) / (state_q0.T - self.state_outlet.T)) 

+

160 # Get transport properties: 

+

161 tra_prop_ref_con = self.med_prop.calc_mean_transport_properties(state_q0, self.state_outlet) 

+

162 alpha_ref_wall = self.calc_alpha_liquid(tra_prop_ref_con) 

+

163 

+

164 # Only use still available area: 

+

165 A_sc = self.iterate_area(dT_max=(state_q0.T - inputs.T_con_in), 

+

166 alpha_pri=alpha_ref_wall, 

+

167 alpha_sec=alpha_med_wall, 

+

168 Q=Q_sc) 

+

169 A_sc = min(self.A, A_sc) 

+

170 

+

171 Q_sc_ntu, k_sc = self.calc_Q_ntu(dT_max=(state_q0.T - inputs.T_con_in), 

+

172 alpha_pri=alpha_ref_wall, 

+

173 alpha_sec=alpha_med_wall, 

+

174 A=A_sc) 

+

175 

+

176 # 2. Regime: Latent heat exchange 

+

177 Q_lat_ntu, A_lat = 0, 0 

+

178 if Q_lat > 0: 

+

179 self.set_primary_cp(np.inf) 

+

180 # Get transport properties: 

+

181 alpha_ref_wall = self.calc_alpha_two_phase( 

+

182 state_q0=state_q0, 

+

183 state_q1=state_q1, 

+

184 fs_state=fs_state, 

+

185 inputs=inputs 

+

186 ) 

+

187 

+

188 A_lat = self.iterate_area(dT_max=(state_q1.T - T_sc), 

+

189 alpha_pri=alpha_ref_wall, 

+

190 alpha_sec=alpha_med_wall, 

+

191 Q=Q_lat) 

+

192 # Only use still available area: 

+

193 A_lat = min(self.A - A_sc, A_lat) 

+

194 

+

195 Q_lat_ntu, k_lat = self.calc_Q_ntu(dT_max=(state_q1.T - T_sc), 

+

196 alpha_pri=alpha_ref_wall, 

+

197 alpha_sec=alpha_med_wall, 

+

198 A=A_lat) 

+

199 logger.debug(f"con_lat: pri: {round(alpha_ref_wall, 2)} sec: {round(alpha_med_wall, 2)}") 

+

200 

+

201 # 3. Regime: Superheat heat exchange 

+

202 Q_sh_ntu, A_sh = 0, 0 

+

203 if Q_sh and (self.state_inlet.T != state_q1.T): 

+

204 self.set_primary_cp((self.state_inlet.h - state_q1.h) / (self.state_inlet.T - state_q1.T)) 

+

205 # Get transport properties: 

+

206 tra_prop_ref_con = self.med_prop.calc_mean_transport_properties(self.state_inlet, state_q1) 

+

207 alpha_ref_wall = self.calc_alpha_gas(tra_prop_ref_con) 

+

208 

+

209 # Only use still available area: 

+

210 A_sh = self.A - A_sc - A_lat 

+

211 

+

212 Q_sh_ntu, k_sh = self.calc_Q_ntu(dT_max=(self.state_inlet.T - T_sh), 

+

213 alpha_pri=alpha_ref_wall, 

+

214 alpha_sec=alpha_med_wall, 

+

215 A=A_sh) 

+

216 logger.debug(f"con_sh: pri: {round(alpha_ref_wall, 2)} sec: {round(alpha_med_wall, 2)}") 

+

217 

+

218 Q_ntu = Q_sh_ntu + Q_sc_ntu + Q_lat_ntu 

+

219 error = (Q_ntu / Q - 1) * 100 

+

220 # Get possible dT_min: 

+

221 dT_min_in = self.state_outlet.T - inputs.T_con_in 

+

222 dT_min_out = self.state_inlet.T - T_out 

+

223 dT_min_LatSH = state_q1.T - T_sh 

+

224 

+

225 fs_state.set(name="A_con_sh", value=A_sh, unit="m2", description="Area for superheat heat exchange in condenser") 

+

226 fs_state.set(name="A_con_lat", value=A_lat, unit="m2", description="Area for latent heat exchange in condenser") 

+

227 fs_state.set(name="A_con_sc", value=A_sc, unit="m2", description="Area for subcooling heat exchange in condenser") 

+

228 

+

229 return error, min(dT_min_in, 

+

230 dT_min_LatSH, 

+

231 dT_min_out) 

+

232 

+

233 

+

234class MovingBoundaryNTUEvaporator(MovingBoundaryNTU): 

+

235 """ 

+

236 Evaporator class which implements the actual `calc` method. 

+

237 

+

238 Assumptions: 

+

239 - No phase changes in secondary medium 

+

240 - cp of secondary medium is constant over heat-exchanger 

+

241 

+

242 See parent classes for arguments. 

+

243 """ 

+

244 

+

245 def calc(self, inputs: Inputs, fs_state: FlowsheetState) -> (float, float): 

+

246 """ 

+

247 Calculate the heat exchanger with the NTU-Method based on the given inputs. 

+

248 

+

249 The flowsheet state can be used to save important variables 

+

250 during calculation for later analysis. 

+

251 

+

252 Both return values are used to check if the heat transfer is valid or not. 

+

253 

+

254 Args: 

+

255 inputs (Inputs): The inputs for the calculation. 

+

256 fs_state (FlowsheetState): The flowsheet state to save important variables. 

+

257 

+

258 Returns: 

+

259 Tuple[float, float]: 

+

260 error: Error in percentage between the required and calculated heat flow rates. 

+

261 dT_min: Minimal temperature difference (can be negative). 

+

262 """ 

+

263 self.m_flow_secondary = inputs.m_flow_eva # [kg/s] 

+

264 self.calc_secondary_cp(T=inputs.T_eva_in) 

+

265 

+

266 # First we separate the flow: 

+

267 Q_sc, Q_lat, Q_sh, state_q0, state_q1 = self.separate_phases( 

+

268 self.state_outlet, 

+

269 self.state_inlet, 

+

270 self.state_inlet.p 

+

271 ) 

+

272 

+

273 Q = Q_sc + Q_lat + Q_sh 

+

274 

+

275 # Note: As Q_eva_ntu has to converge to Q_eva (m_ref*delta_h), we can safely 

+

276 # calculate the output temperature. 

+

277 T_mean = inputs.T_eva_in - Q / (self.m_flow_secondary_cp * 2) 

+

278 tra_prop_med = self.calc_transport_properties_secondary_medium(T_mean) 

+

279 alpha_med_wall = self.calc_alpha_secondary(tra_prop_med) 

+

280 

+

281 # Calculate secondary_medium side temperatures: 

+

282 T_sh = inputs.T_eva_in - Q_sh / self.m_flow_secondary_cp 

+

283 T_sc = T_sh - Q_lat / self.m_flow_secondary_cp 

+

284 T_out = T_sc - Q_sc / self.m_flow_secondary_cp 

+

285 

+

286 # 1. Regime: Superheating 

+

287 Q_sh_ntu, A_sh = 0, 0 

+

288 if Q_sh and (self.state_outlet.T != state_q1.T): 

+

289 self.set_primary_cp((self.state_outlet.h - state_q1.h) / (self.state_outlet.T - state_q1.T)) 

+

290 # Get transport properties: 

+

291 tra_prop_ref_eva = self.med_prop.calc_mean_transport_properties(self.state_outlet, state_q1) 

+

292 alpha_ref_wall = self.calc_alpha_gas(tra_prop_ref_eva) 

+

293 

+

294 if Q_lat > 0: 

+

295 A_sh = self.iterate_area(dT_max=(inputs.T_eva_in - state_q1.T), 

+

296 alpha_pri=alpha_ref_wall, 

+

297 alpha_sec=alpha_med_wall, 

+

298 Q=Q_sh) 

+

299 else: 

+

300 # if only sh is present --> full area: 

+

301 A_sh = self.A 

+

302 

+

303 # Only use still available area 

+

304 A_sh = min(self.A, A_sh) 

+

305 

+

306 Q_sh_ntu, k_sh = self.calc_Q_ntu(dT_max=(inputs.T_eva_in - state_q1.T), 

+

307 alpha_pri=alpha_ref_wall, 

+

308 alpha_sec=alpha_med_wall, 

+

309 A=A_sh) 

+

310 

+

311 logger.debug(f"eva_sh: pri: {round(alpha_ref_wall, 2)} sec: {round(alpha_med_wall, 2)}") 

+

312 

+

313 # 2. Regime: Latent heat exchange 

+

314 Q_lat_ntu, A_lat = 0, 0 

+

315 if Q_lat > 0: 

+

316 self.set_primary_cp(np.inf) 

+

317 

+

318 alpha_ref_wall = self.calc_alpha_two_phase( 

+

319 state_q0=state_q0, 

+

320 state_q1=state_q1, 

+

321 fs_state=fs_state, 

+

322 inputs=inputs 

+

323 ) 

+

324 

+

325 if Q_sc > 0: 

+

326 A_lat = self.iterate_area(dT_max=(T_sh - self.state_inlet.T), 

+

327 alpha_pri=alpha_ref_wall, 

+

328 alpha_sec=alpha_med_wall, 

+

329 Q=Q_lat) 

+

330 else: 

+

331 A_lat = self.A - A_sh 

+

332 

+

333 # Only use still available area: 

+

334 A_lat = min(self.A - A_sh, A_lat) 

+

335 Q_lat_ntu, k_lat = self.calc_Q_ntu(dT_max=(T_sh - self.state_inlet.T), 

+

336 alpha_pri=alpha_ref_wall, 

+

337 alpha_sec=alpha_med_wall, 

+

338 A=A_lat) 

+

339 logger.debug(f"eva_lat: pri: {round(alpha_ref_wall, 2)} sec: {round(alpha_med_wall, 2)}") 

+

340 

+

341 # 3. Regime: Subcooling 

+

342 Q_sc_ntu, A_sc = 0, 0 

+

343 if Q_sc > 0 and (state_q0.T != self.state_inlet.T): 

+

344 self.set_primary_cp((state_q0.h - self.state_inlet.h) / (state_q0.T - self.state_inlet.T)) 

+

345 # Get transport properties: 

+

346 tra_prop_ref_eva = self.med_prop.calc_mean_transport_properties(state_q0, self.state_inlet) 

+

347 alpha_ref_wall = self.calc_alpha_liquid(tra_prop_ref_eva) 

+

348 

+

349 # Only use still available area: 

+

350 A_sc = self.A - A_sh - A_lat 

+

351 

+

352 Q_sc_ntu, k_sc = self.calc_Q_ntu(dT_max=(T_sc - self.state_inlet.T), 

+

353 alpha_pri=alpha_ref_wall, 

+

354 alpha_sec=alpha_med_wall, 

+

355 A=A_sc) 

+

356 

+

357 Q_ntu = Q_sh_ntu + Q_sc_ntu + Q_lat_ntu 

+

358 error = (Q_ntu / Q - 1) * 100 

+

359 # Get dT_min 

+

360 dT_min_in = inputs.T_eva_in - self.state_outlet.T 

+

361 dT_min_out = T_out - self.state_inlet.T 

+

362 

+

363 fs_state.set(name="A_eva_sh", value=A_sh, unit="m2", description="Area for superheat heat exchange in evaporator") 

+

364 fs_state.set(name="A_eva_lat", value=A_lat, unit="m2", description="Area for latent heat exchange in evaporator") 

+

365 

+

366 return error, min(dT_min_out, dT_min_in) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_35fc0e049e81dfd6_ntu_py.html b/docs/0.1.1/coverage/d_35fc0e049e81dfd6_ntu_py.html new file mode 100644 index 0000000..d3447b5 --- /dev/null +++ b/docs/0.1.1/coverage/d_35fc0e049e81dfd6_ntu_py.html @@ -0,0 +1,270 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/ntu.py: 82% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/ntu.py: + 82% +

+ +

+ 50 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import logging 

+

2import abc 

+

3 

+

4import numpy as np 

+

5from vclibpy.components.heat_exchangers.heat_exchanger import HeatExchanger 

+

6 

+

7 

+

8logger = logging.getLogger(__name__) 

+

9 

+

10 

+

11class BasicNTU(HeatExchanger, abc.ABC): 

+

12 """ 

+

13 Moving boundary NTU based heat exchanger. 

+

14 

+

15 See parent class for more arguments. 

+

16 

+

17 Args: 

+

18 flow_type (str): 

+

19 Counter, Cross or parallel flow 

+

20 ratio_outer_to_inner_area (float): 

+

21 The NTU method uses the overall heat transfer coefficient `k` 

+

22 and multiplies it with the outer area `A` (area of the secondary side). 

+

23 However, depending on the heat exchanger type, the areas may 

+

24 differ drastically. For instance in an air-to-water heat exchanger. 

+

25 The VDI-Atlas proposes the ratio of outer area to inner pipe area 

+

26 to account for this mismatch in sizes. 

+

27 The calculation follows the code in the function `calc_k`. 

+

28 Typical values are around 20-30. 

+

29 """ 

+

30 

+

31 def __init__(self, flow_type: str, ratio_outer_to_inner_area: float, **kwargs): 

+

32 """ 

+

33 Initializes BasicNTU. 

+

34 

+

35 Args: 

+

36 flow_type (str): Type of flow: Counter, Cross, or Parallel. 

+

37 ratio_outer_to_inner_area (float): 

+

38 The NTU method uses the overall heat transfer coefficient `k` 

+

39 and multiplies it with the overall area `A`. 

+

40 However, depending on the heat exchanger type, the areas may 

+

41 differ drastically. For instance in an air-to-water heat exchanger. 

+

42 The VDI-Atlas proposes the ratio of outer area to inner pipe area 

+

43 to account for this mismatch in sizes. 

+

44 The calculation follows the code in the function `calc_k`. 

+

45 **kwargs: Additional keyword arguments passed to the parent class. 

+

46 """ 

+

47 super().__init__(**kwargs) 

+

48 self.ratio_outer_to_inner_area = ratio_outer_to_inner_area 

+

49 

+

50 # Set primary cp: 

+

51 self._primary_cp = None 

+

52 

+

53 # Type of HE: 

+

54 self.flow_type = flow_type.lower() 

+

55 if self.flow_type not in ["counter", "cross", "parallel"]: 

+

56 raise TypeError("Given flow_type is not supported") 

+

57 

+

58 def set_primary_cp(self, cp: float): 

+

59 """ 

+

60 Set the specific heat (cp) for the primary medium. 

+

61 

+

62 Args: 

+

63 cp (float): Specific heat for the primary medium. 

+

64 """ 

+

65 self._primary_cp = cp 

+

66 

+

67 def calc_eps(self, R: float, NTU: float) -> float: 

+

68 """ 

+

69 Calculate the effectiveness (eps) of the heat exchanger based on NTU. 

+

70 

+

71 Source of implementation: EBC Lecture SimModelle. 

+

72 

+

73 Args: 

+

74 R (float): Ratio of heat capacity rates (m_flow*cp) of the primary to secondary medium. 

+

75 NTU (float): Number of Transfer Units. 

+

76 

+

77 Returns: 

+

78 float: Effectiveness (eps) of the heat exchanger. 

+

79 """ 

+

80 if R in (0, 1): 

+

81 return NTU / (NTU + 1) 

+

82 if self.flow_type == "counter": 

+

83 return (1 - np.exp(-NTU * (1 - R))) / (1 - R * np.exp(-NTU * (1 - R))) 

+

84 if self.flow_type == "cross": 

+

85 if NTU == 0: 

+

86 return 0 

+

87 eta = NTU ** -0.22 

+

88 return 1 - np.exp((np.exp(- NTU * R * eta) - 1) / (R * eta)) 

+

89 if self.flow_type == "parallel": 

+

90 return (1 - np.exp(-NTU * (1 + R))) / (1 + R) 

+

91 raise TypeError(f"Flow type {self.flow_type} not supported") 

+

92 

+

93 def calc_R(self) -> float: 

+

94 """ 

+

95 Calculate the R value, which is the ratio of heat capacity rates (m_flow*cp) of the primary to secondary medium. 

+

96 

+

97 Returns: 

+

98 float: R value. 

+

99 """ 

+

100 m_flow_pri_cp = self.m_flow * self._primary_cp 

+

101 if m_flow_pri_cp > self.m_flow_secondary_cp: 

+

102 return self.m_flow_secondary_cp / m_flow_pri_cp 

+

103 return m_flow_pri_cp / self.m_flow_secondary_cp 

+

104 

+

105 def calc_k(self, alpha_pri: float, alpha_sec: float) -> float: 

+

106 """ 

+

107 Calculate the overall heat transfer coefficient (k) of the heat exchanger. 

+

108 

+

109 Args: 

+

110 alpha_pri (float): Heat transfer coefficient for the primary medium. 

+

111 alpha_sec (float): Heat transfer coefficient for the secondary medium. 

+

112 

+

113 Returns: 

+

114 float: Overall heat transfer coefficient (k). 

+

115 """ 

+

116 k_wall = self.calc_wall_heat_transfer() 

+

117 k = (1 / ( 

+

118 (1 / alpha_pri) * self.ratio_outer_to_inner_area + 

+

119 (1 / k_wall) * self.ratio_outer_to_inner_area + 

+

120 (1 / alpha_sec) 

+

121 ) 

+

122 ) 

+

123 return k 

+

124 

+

125 @staticmethod 

+

126 def calc_NTU(A: float, k: float, m_flow_cp: float) -> float: 

+

127 """ 

+

128 Calculate the Number of Transfer Units (NTU) for the heat exchanger. 

+

129 

+

130 Args: 

+

131 A (float): Area of the heat exchanger. 

+

132 k (float): Overall heat transfer coefficient. 

+

133 m_flow_cp (float): Minimal heat capacity rates (m_flow*cp) between primary and secondary side. 

+

134 

+

135 Returns: 

+

136 float: Number of Transfer Units (NTU). 

+

137 """ 

+

138 return k * A / m_flow_cp 

+

139 

+

140 def calc_m_flow_cp_min(self) -> float: 

+

141 """ 

+

142 Calculate the minimum value between the heat capacity rates (m_flow*cp) for the primary and secondary mediums. 

+

143 

+

144 Returns: 

+

145 float: Minimum value. 

+

146 """ 

+

147 return min( 

+

148 self.m_flow * self._primary_cp, 

+

149 self.m_flow_secondary_cp 

+

150 ) 

+

151 

+

152 def calc_Q_ntu(self, dT_max: float, alpha_pri: float, alpha_sec: float, A: float) -> (float, float): 

+

153 """ 

+

154 Calculate the heat transfer and overall heat transfer coefficient for the heat exchanger based on NTU. 

+

155 

+

156 Args: 

+

157 dT_max (float): Maximum temperature differential. 

+

158 alpha_pri (float): Heat transfer coefficient for the primary medium. 

+

159 alpha_sec (float): Heat transfer coefficient for the secondary medium. 

+

160 A (float): Area of the heat exchanger. 

+

161 

+

162 Returns: 

+

163 Tuple[float, float]: Heat transfer and overall heat transfer coefficient. 

+

164 """ 

+

165 R = self.calc_R() 

+

166 k = self.calc_k(alpha_pri, alpha_sec) 

+

167 m_flow_cp_min = self.calc_m_flow_cp_min() 

+

168 NTU = self.calc_NTU(A, k, m_flow_cp_min) 

+

169 eps = self.calc_eps(R, NTU) 

+

170 

+

171 # Get the maximal allowed heat flow 

+

172 Q_max = m_flow_cp_min * dT_max 

+

173 return Q_max * eps, k 

+
+ + + diff --git a/docs/0.1.1/coverage/d_38531a0795c587f9___init___py.html b/docs/0.1.1/coverage/d_38531a0795c587f9___init___py.html new file mode 100644 index 0000000..7a88ee4 --- /dev/null +++ b/docs/0.1.1/coverage/d_38531a0795c587f9___init___py.html @@ -0,0 +1,99 @@ + + + + + Coverage for vclibpy/components/expansion_valves/__init__.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/expansion_valves/__init__.py: + 100% +

+ +

+ 2 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from .expansion_valve import ExpansionValve 

+

2from .bernoulli import Bernoulli 

+
+ + + diff --git a/docs/0.1.1/coverage/d_38531a0795c587f9_bernoulli_py.html b/docs/0.1.1/coverage/d_38531a0795c587f9_bernoulli_py.html new file mode 100644 index 0000000..b118b29 --- /dev/null +++ b/docs/0.1.1/coverage/d_38531a0795c587f9_bernoulli_py.html @@ -0,0 +1,119 @@ + + + + + Coverage for vclibpy/components/expansion_valves/bernoulli.py: 83% + + + + + +
+
+

+ Coverage for vclibpy/components/expansion_valves/bernoulli.py: + 83% +

+ +

+ 6 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module with simple bernoulli expansion valve 

+

3""" 

+

4from vclibpy.components.expansion_valves import ExpansionValve 

+

5 

+

6 

+

7class Bernoulli(ExpansionValve): 

+

8 """ 

+

9 Simple Bernoulli model. 

+

10 

+

11 Args: 

+

12 A (float): Cross-sectional area of the expansion valve. 

+

13 """ 

+

14 

+

15 def calc_m_flow_at_opening(self, opening): 

+

16 return opening * self.A * (2 * self.state_inlet.d * (self.state_inlet.p - self.state_outlet.p)) ** 0.5 

+

17 

+

18 def calc_opening_at_m_flow(self, m_flow, **kwargs): 

+

19 return ( 

+

20 m_flow / 

+

21 (self.A * (2 * self.state_inlet.d * (self.state_inlet.p - self.state_outlet.p)) ** 0.5) 

+

22 ) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_38531a0795c587f9_expansion_valve_py.html b/docs/0.1.1/coverage/d_38531a0795c587f9_expansion_valve_py.html new file mode 100644 index 0000000..b75fc97 --- /dev/null +++ b/docs/0.1.1/coverage/d_38531a0795c587f9_expansion_valve_py.html @@ -0,0 +1,153 @@ + + + + + Coverage for vclibpy/components/expansion_valves/expansion_valve.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/expansion_valves/expansion_valve.py: + 100% +

+ +

+ 12 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module with classes for EV models. 

+

3They are not used for the calculation. 

+

4They may be used to see if the output is correct. 

+

5""" 

+

6import abc 

+

7 

+

8from vclibpy.components.component import BaseComponent 

+

9 

+

10 

+

11class ExpansionValve(BaseComponent, abc.ABC): 

+

12 """Base class for an expansion valve. 

+

13 

+

14 Args: 

+

15 A (float): Cross-sectional area of the expansion valve. 

+

16 """ 

+

17 

+

18 def __init__(self, A): 

+

19 super().__init__() 

+

20 self.A = A # Cross-sectional area of the expansion valve 

+

21 

+

22 @abc.abstractmethod 

+

23 def calc_m_flow_at_opening(self, opening) -> float: 

+

24 """ 

+

25 Calculate the mass flow rate for the given opening. 

+

26 

+

27 Args: 

+

28 opening (float): Opening of valve between 0 and 1 

+

29 

+

30 Returns: 

+

31 float: Mass flow rate in kg/s 

+

32 """ 

+

33 raise NotImplementedError 

+

34 

+

35 @abc.abstractmethod 

+

36 def calc_opening_at_m_flow(self, m_flow, **kwargs) -> float: 

+

37 """ 

+

38 Calculate the opening for the given mass flow rate 

+

39 

+

40 Args: 

+

41 m_flow (float): Mass flow rate in kg/s 

+

42 **kwargs: Possible keyword arguments for child classes 

+

43 

+

44 Returns: 

+

45 float: Opening 

+

46 """ 

+

47 raise NotImplementedError 

+

48 

+

49 def calc_outlet(self, p_outlet: float): 

+

50 """ 

+

51 Calculate isenthalpic expansion valve. 

+

52 

+

53 Args: 

+

54 p_outlet (float): Outlet pressure level 

+

55 """ 

+

56 self.state_outlet = self.med_prop.calc_state("PH", p_outlet, self.state_inlet.h) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_3aa0e56d51a2f798___init___py.html b/docs/0.1.1/coverage/d_3aa0e56d51a2f798___init___py.html new file mode 100644 index 0000000..db872a6 --- /dev/null +++ b/docs/0.1.1/coverage/d_3aa0e56d51a2f798___init___py.html @@ -0,0 +1,104 @@ + + + + + Coverage for vclibpy/__init__.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/__init__.py: + 100% +

+ +

+ 2 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Package for stationary vapor compression models and their analysis 

+

3""" 

+

4 

+

5from vclibpy.datamodels import FlowsheetState, Inputs 

+

6 

+

7__version__ = "0.1.1" 

+
+ + + diff --git a/docs/0.1.1/coverage/d_3aa0e56d51a2f798_datamodels_py.html b/docs/0.1.1/coverage/d_3aa0e56d51a2f798_datamodels_py.html new file mode 100644 index 0000000..db5663e --- /dev/null +++ b/docs/0.1.1/coverage/d_3aa0e56d51a2f798_datamodels_py.html @@ -0,0 +1,338 @@ + + + + + Coverage for vclibpy/datamodels.py: 98% + + + + + +
+
+

+ Coverage for vclibpy/datamodels.py: + 98% +

+ +

+ 52 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module which contains datamodels which are used in this library. 

+

3""" 

+

4 

+

5from dataclasses import dataclass 

+

6from typing import Dict, Any 

+

7from copy import deepcopy 

+

8 

+

9 

+

10@dataclass 

+

11class Variable: 

+

12 """ 

+

13 Class for a variable used in analysis. 

+

14 

+

15 Args: 

+

16 name (str): The name of the variable. 

+

17 value (float): The numerical value of the variable. 

+

18 unit (str): The unit of measurement for the variable (optional). 

+

19 description (str): A description of the variable (optional). 

+

20 """ 

+

21 name: str 

+

22 value: float 

+

23 unit: str = None 

+

24 description: str = None 

+

25 

+

26 

+

27class VariableContainer: 

+

28 """ 

+

29 Class which holds Variables to be used anywhere in the models. 

+

30 

+

31 This class enables dynamic addition of Variables. 

+

32 """ 

+

33 def __init__(self): 

+

34 self._variables: Dict[str, Variable] = {} 

+

35 

+

36 def __str__(self): 

+

37 return f"{self.__class__.__name__}:\n" + "\n".join( 

+

38 [f"{var.name}={var.value} {var.unit} ({var.description})" 

+

39 for var in self._variables.values()] 

+

40 ) 

+

41 

+

42 def set(self, name: str, value: float, unit: str = None, description: str = None): 

+

43 """ 

+

44 Add or update a Variable in the container. 

+

45 

+

46 Args: 

+

47 name (str): The name of the variable. 

+

48 value (float): The numerical value of the variable. 

+

49 unit (str): The unit of measurement for the variable (optional). 

+

50 description (str): A description of the variable (optional). 

+

51 """ 

+

52 if name in self._variables: 

+

53 self._variables[name].value = value 

+

54 else: 

+

55 self._variables[name] = Variable( 

+

56 name=name, value=value, unit=unit, description=description 

+

57 ) 

+

58 

+

59 def __getattr__(self, item): 

+

60 """ 

+

61 Overwrite the dunder method to enable usage of e.g. 

+

62 fs_state.COP 

+

63 """ 

+

64 if item in {'__getstate__', '__setstate__'}: 

+

65 return super().__getattr__(self, item) 

+

66 if item in self._variables: 

+

67 return self._variables.get(item).value 

+

68 raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'") 

+

69 

+

70 def get_variable_names(self) -> list: 

+

71 """ 

+

72 Get the names of all variables in the container. 

+

73 

+

74 Returns: 

+

75 list: A list of variable names. 

+

76 """ 

+

77 return list(self._variables.keys()) 

+

78 

+

79 def get_variables(self): 

+

80 """ 

+

81 Get all variables in the container. 

+

82 

+

83 Returns: 

+

84 Dict[str, Variable]: A dictionary of variable names and Variable objects. 

+

85 """ 

+

86 return self._variables 

+

87 

+

88 def items(self): 

+

89 """ 

+

90 Get items from the container. 

+

91 

+

92 Returns: 

+

93 Dict[str, Variable]: A dictionary of variable names and Variable objects. 

+

94 """ 

+

95 return self._variables.items() 

+

96 

+

97 def get(self, name: str, default: Any = None): 

+

98 """ 

+

99 Get the Variable with the specified name. 

+

100 

+

101 Args: 

+

102 name (str): The name of the variable. 

+

103 default (Any): Default value to return if the variable is not found. 

+

104 

+

105 Returns: 

+

106 Variable: The Variable object. 

+

107 

+

108 """ 

+

109 return self._variables.get(name, default) 

+

110 

+

111 def copy(self): 

+

112 """ 

+

113 Return a deepcopy of the instance as the variable dict is mutable. 

+

114 

+

115 Returns: 

+

116 VariableContainer: A deepcopy of the VariableContainer instance. 

+

117 """ 

+

118 return deepcopy(self) 

+

119 

+

120 def convert_to_str_value_format(self, with_unit_and_description: bool) -> Dict[str, float]: 

+

121 """ 

+

122 Returns a dictionary with a str: float format which is handy when storing results 

+

123 in files like .csv or .xlsx. 

+

124 

+

125 Args: 

+

126 with_unit_and_description (bool): When False, only the name is in the string. 

+

127 

+

128 Returns: 

+

129 dict: Containing all variables and values. 

+

130 """ 

+

131 if with_unit_and_description: 

+

132 return {f"{k} in {v.unit} ({v.description})": v.value for k, v in self.items()} 

+

133 return {k: v.value for k, v in self.items()} 

+

134 

+

135 

+

136class FlowsheetState(VariableContainer): 

+

137 """ 

+

138 This class is used to define the unique states of the flowsheet 

+

139 in the heat pump. 

+

140 

+

141 The class is dynamic in the sense that attributes may be 

+

142 added during calculation of new flowsheet. This enables 

+

143 the easy adding of custom values to analyze the whole flowsheet 

+

144 and not restrict to a certain naming convention. 

+

145 """ 

+

146 

+

147 

+

148class Inputs(VariableContainer): 

+

149 """ 

+

150 Class defining inputs to calculate the FlowsheetState. 

+

151 

+

152 While the inputs are pre-defined, you may add further ones 

+

153 using the `set` method. 

+

154 

+

155 Args: 

+

156 n (float): Relative compressor speed between 0 and 1. 

+

157 T_eva_in (float): Secondary side evaporator inlet temperature. 

+

158 T_con_in (float): Secondary side condenser inlet temperature. 

+

159 m_flow_eva (float): Secondary side evaporator mass flow rate. 

+

160 m_flow_con (float): Secondary side condenser mass flow rate. 

+

161 dT_eva_superheating (float): Super-heating after evaporator. 

+

162 dT_con_subcooling (float): Subcooling after condenser. 

+

163 T_ambient (float): Ambient temperature of the machine. 

+

164 """ 

+

165 

+

166 def __init__( 

+

167 self, 

+

168 n: float = None, 

+

169 T_eva_in: float = None, 

+

170 T_con_in: float = None, 

+

171 m_flow_eva: float = None, 

+

172 m_flow_con: float = None, 

+

173 dT_eva_superheating: float = None, 

+

174 dT_con_subcooling: float = None, 

+

175 T_ambient: float = None 

+

176 ): 

+

177 """ 

+

178 Initializes an Inputs object with parameters representing external conditions 

+

179 for the vapor compression cycle. 

+

180 

+

181 Args: 

+

182 n (float): Relative compressor speed between 0 and 1 (unit: -). 

+

183 T_eva_in (float): Secondary side evaporator inlet temperature (unit: K). 

+

184 T_con_in (float): Secondary side condenser inlet temperature (unit: K). 

+

185 m_flow_eva (float): Secondary side evaporator mass flow rate (unit: kg/s). 

+

186 m_flow_con (float): Secondary side condenser mass flow rate (unit: kg/s). 

+

187 dT_eva_superheating (float): Super-heating after evaporator (unit: K). 

+

188 dT_con_subcooling (float): Subcooling after condenser (unit: K). 

+

189 T_ambient (float): Ambient temperature of the machine (unit: K). 

+

190 """ 

+

191 super().__init__() 

+

192 self.set( 

+

193 name="n", 

+

194 value=n, 

+

195 unit="-", 

+

196 description="Relative compressor speed" 

+

197 ) 

+

198 self.set( 

+

199 name="T_eva_in", 

+

200 value=T_eva_in, 

+

201 unit="K", 

+

202 description="Secondary side evaporator inlet temperature" 

+

203 ) 

+

204 self.set( 

+

205 name="T_con_in", 

+

206 value=T_con_in, 

+

207 unit="K", 

+

208 description="Secondary side condenser inlet temperature" 

+

209 ) 

+

210 self.set( 

+

211 name="m_flow_con", 

+

212 value=m_flow_con, 

+

213 unit="kg/s", 

+

214 description="Secondary side condenser mass flow rate" 

+

215 ) 

+

216 self.set( 

+

217 name="m_flow_eva", 

+

218 value=m_flow_eva, 

+

219 unit="kg/s", 

+

220 description="Secondary side evaporator mass flow rate" 

+

221 ) 

+

222 self.set( 

+

223 name="dT_eva_superheating", 

+

224 value=dT_eva_superheating, 

+

225 unit="K", 

+

226 description="Super-heating after evaporator" 

+

227 ) 

+

228 self.set( 

+

229 name="dT_con_subcooling", 

+

230 value=dT_con_subcooling, 

+

231 unit="K", 

+

232 description="Subcooling after condenser" 

+

233 ) 

+

234 if T_ambient is None: 

+

235 T_ambient = T_eva_in 

+

236 self.set( 

+

237 name="T_ambient", 

+

238 value=T_ambient, 

+

239 unit="K", 

+

240 description="Ambient temperature of machine" 

+

241 ) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_4deeb89b86ecce82___init___py.html b/docs/0.1.1/coverage/d_4deeb89b86ecce82___init___py.html new file mode 100644 index 0000000..a88af25 --- /dev/null +++ b/docs/0.1.1/coverage/d_4deeb89b86ecce82___init___py.html @@ -0,0 +1,100 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/heat_transfer/__init__.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/heat_transfer/__init__.py: + 100% +

+ +

+ 3 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from .heat_transfer import TwoPhaseHeatTransfer, HeatTransfer, calc_reynolds_pipe 

+

2from vclibpy.components.heat_exchangers.heat_transfer import constant 

+

3from vclibpy.components.heat_exchangers.heat_transfer import wall 

+
+ + + diff --git a/docs/0.1.1/coverage/d_4deeb89b86ecce82_air_to_wall_py.html b/docs/0.1.1/coverage/d_4deeb89b86ecce82_air_to_wall_py.html new file mode 100644 index 0000000..b7511c2 --- /dev/null +++ b/docs/0.1.1/coverage/d_4deeb89b86ecce82_air_to_wall_py.html @@ -0,0 +1,208 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py: 0% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py: + 0% +

+ +

+ 31 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import abc 

+

2import logging 

+

3 

+

4from .heat_transfer import HeatTransfer 

+

5from vclibpy.media import TransportProperties 

+

6 

+

7 

+

8logger = logging.getLogger(__name__) 

+

9 

+

10 

+

11class AirToWallTransfer(HeatTransfer, abc.ABC): 

+

12 """ 

+

13 Heat transfer model for air to wall. 

+

14 

+

15 Args: 

+

16 A_cross (float): 

+

17 Cross-section area in m2. 

+

18 characteristic_length (float): 

+

19 Length in m to calculate the similitude approach for the 

+

20 heat transfer from secondary_medium -> wall. 

+

21 """ 

+

22 

+

23 def __init__(self, A_cross: float, characteristic_length: float): 

+

24 self.A_cross = A_cross 

+

25 self.characteristic_length = characteristic_length 

+

26 

+

27 def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: 

+

28 """ 

+

29 Heat transfer coefficient from air to the wall of the heat exchanger. 

+

30 The flow is assumed to be always laminar. 

+

31 

+

32 Returns: 

+

33 float: Heat transfer coefficient in W/(m^2*K). 

+

34 """ 

+

35 Re = self.calc_reynolds(dynamic_viscosity=transport_properties.dyn_vis, m_flow=m_flow) 

+

36 alpha_sec = self.calc_laminar_area_nusselt(Re, transport_properties.Pr, lambda_=transport_properties.lam) 

+

37 return alpha_sec 

+

38 

+

39 @abc.abstractmethod 

+

40 def calc_reynolds(self, dynamic_viscosity: float, m_flow: float): 

+

41 """ 

+

42 Calculate the reynolds number of the given flow rate. 

+

43 

+

44 Args: 

+

45 dynamic_viscosity (float): Dynamic viscosity. 

+

46 m_flow (float): Mass flow rate. 

+

47 

+

48 Returns: 

+

49 float: Reynolds number 

+

50 """ 

+

51 raise NotImplementedError 

+

52 

+

53 @abc.abstractmethod 

+

54 def calc_laminar_area_nusselt(self, Re, Pr, lambda_): 

+

55 """ 

+

56 Calculate the Nusselt number for laminar heat transfer 

+

57 on an area (Used for Air->Wall in the evaporator). 

+

58 

+

59 Args: 

+

60 Re (float): Reynolds number 

+

61 Pr (float): Prandlt number 

+

62 lambda_ (float): Lambda of air 

+

63 

+

64 Returns: 

+

65 float: Nusselt number 

+

66 """ 

+

67 raise NotImplementedError 

+

68 

+

69 

+

70class WSUAirToWall(AirToWallTransfer): 

+

71 """ 

+

72 Class to implement the heat transfer calculations 

+

73 based on the WSÜ-Script at the RWTH. 

+

74 """ 

+

75 

+

76 def calc_reynolds(self, dynamic_viscosity: float, m_flow: float) -> float: 

+

77 """ 

+

78 Calculate the Reynolds number on air side. 

+

79 

+

80 Args: 

+

81 dynamic_viscosity (float): Dynamic viscosity of air. 

+

82 m_flow (float): Mass flow rate of air. 

+

83 

+

84 Returns: 

+

85 float: Reynolds number. 

+

86 """ 

+

87 velocity_times_dens = m_flow / self.A_cross 

+

88 return (velocity_times_dens * self.characteristic_length) / dynamic_viscosity 

+

89 

+

90 def calc_laminar_area_nusselt(self, Re, Pr, lambda_) -> float: 

+

91 """ 

+

92 Calculate the Nusselt number for laminar heat transfer 

+

93 on an area (Used for Air->Wall in the evaporator). 

+

94 

+

95 Args: 

+

96 Re (float): Reynolds number of air. 

+

97 Pr (float): Prandtl number of air. 

+

98 lambda_ (float): Lambda of air. 

+

99 

+

100 Returns: 

+

101 float: Nusselt number of air. 

+

102 """ 

+

103 const_fac = 0.664 

+

104 exp_rey = 0.5 

+

105 exp_pra = 1 / 3 

+

106 if Re > 2e5: 

+

107 raise ValueError(f"Given Re {Re} is outside of allowed bounds for WSÜ-Script") 

+

108 if Pr > 10 or Pr < 0.6: 

+

109 raise ValueError(f"Given Pr {Pr} is outside of allowed bounds for WSÜ-Script") 

+

110 Nu = const_fac * Re ** exp_rey * Pr ** exp_pra 

+

111 return Nu * lambda_ / self.characteristic_length 

+
+ + + diff --git a/docs/0.1.1/coverage/d_4deeb89b86ecce82_constant_py.html b/docs/0.1.1/coverage/d_4deeb89b86ecce82_constant_py.html new file mode 100644 index 0000000..415209a --- /dev/null +++ b/docs/0.1.1/coverage/d_4deeb89b86ecce82_constant_py.html @@ -0,0 +1,156 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/heat_transfer/constant.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/heat_transfer/constant.py: + 100% +

+ +

+ 12 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module with constant heat transfer assumptions 

+

3""" 

+

4import abc 

+

5 

+

6from vclibpy.media import TransportProperties 

+

7 

+

8 

+

9class ConstantHeatTransfer(abc.ABC): 

+

10 """ 

+

11 Constant heat transfer assumption 

+

12 

+

13 Args: 

+

14 alpha (float): 

+

15 Constant heat transfer coefficient in W/(m2*K) 

+

16 """ 

+

17 

+

18 def __init__(self, alpha: float): 

+

19 self.alpha = alpha 

+

20 

+

21 def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: 

+

22 """ 

+

23 Calculate constant heat transfer coefficient. 

+

24 

+

25 Args: 

+

26 transport_properties (TransportProperties): Transport properties of the medium (not used). 

+

27 m_flow (float): Mass flow rate (not used). 

+

28 

+

29 Returns: 

+

30 float: Constant heat transfer coefficient in W/(m2*K). 

+

31 

+

32 """ 

+

33 return self.alpha 

+

34 

+

35 

+

36class ConstantTwoPhaseHeatTransfer(abc.ABC): 

+

37 """ 

+

38 Constant heat transfer assumption. 

+

39 

+

40 Args: 

+

41 alpha (float): 

+

42 Constant heat transfer coefficient in W/(m2*K). 

+

43 """ 

+

44 

+

45 def __init__(self, alpha: float): 

+

46 self.alpha = alpha 

+

47 

+

48 def calc(self, **kwargs) -> float: 

+

49 """ 

+

50 Calculate constant two-phase heat transfer coefficient. 

+

51 

+

52 Args: 

+

53 **kwargs: Allows to set arguments for different heat transfer classes which are not used here. 

+

54 

+

55 Returns: 

+

56 float: Constant two-phase heat transfer coefficient in W/(m2*K). 

+

57 

+

58 """ 

+

59 return self.alpha 

+
+ + + diff --git a/docs/0.1.1/coverage/d_4deeb89b86ecce82_heat_transfer_py.html b/docs/0.1.1/coverage/d_4deeb89b86ecce82_heat_transfer_py.html new file mode 100644 index 0000000..77fc0cf --- /dev/null +++ b/docs/0.1.1/coverage/d_4deeb89b86ecce82_heat_transfer_py.html @@ -0,0 +1,189 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py: 92% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py: + 92% +

+ +

+ 12 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module with basic functions to calculate heat transfer coefficients. 

+

3""" 

+

4import abc 

+

5 

+

6import numpy as np 

+

7 

+

8from vclibpy.media import TransportProperties, ThermodynamicState, MedProp 

+

9from vclibpy.datamodels import FlowsheetState, Inputs 

+

10 

+

11 

+

12class HeatTransfer(abc.ABC): 

+

13 """ 

+

14 Base class to implement possible heat transfer models. 

+

15 

+

16 Methods: 

+

17 calc(transport_properties: TransportProperties, m_flow: float) -> float: 

+

18 Abstract method to calculate heat transfer. 

+

19 

+

20 """ 

+

21 

+

22 @abc.abstractmethod 

+

23 def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: 

+

24 """ 

+

25 Calculate heat transfer. 

+

26 

+

27 Args: 

+

28 transport_properties (TransportProperties): Transport properties of the medium. 

+

29 m_flow (float): Mass flow rate. 

+

30 

+

31 Returns: 

+

32 float: Calculated heat transfer coefficient. 

+

33 

+

34 Raises: 

+

35 NotImplementedError: If the method is not implemented in the subclass. 

+

36 """ 

+

37 raise NotImplementedError 

+

38 

+

39 

+

40class TwoPhaseHeatTransfer(abc.ABC): 

+

41 """ 

+

42 Base class to implement possible heat transfer models 

+

43 """ 

+

44 

+

45 @abc.abstractmethod 

+

46 def calc( 

+

47 self, 

+

48 state_q0: ThermodynamicState, 

+

49 state_q1: ThermodynamicState, 

+

50 state_inlet: ThermodynamicState, 

+

51 state_outlet: ThermodynamicState, 

+

52 med_prop: MedProp, 

+

53 inputs: Inputs, 

+

54 fs_state: FlowsheetState, 

+

55 m_flow: float 

+

56 ) -> float: 

+

57 """ 

+

58 Calculate two-phase heat transfer. 

+

59 

+

60 Args: 

+

61 state_q0 (ThermodynamicState): Thermodynamic state at the beginning of the two-phase region. 

+

62 state_q1 (ThermodynamicState): Thermodynamic state at the end of the two-phase region. 

+

63 state_inlet (ThermodynamicState): Inlet thermodynamic state. 

+

64 state_outlet (ThermodynamicState): Outlet thermodynamic state. 

+

65 med_prop (MedProp): Medium properties class. 

+

66 inputs (Inputs): Input parameters. 

+

67 fs_state (FlowsheetState): Flowsheet state. 

+

68 m_flow (float): Mass flow rate. 

+

69 

+

70 Returns: 

+

71 float: Calculated two-phase heat transfer coefficient. 

+

72 

+

73 Raises: 

+

74 NotImplementedError: If the method is not implemented in the subclass. 

+

75 """ 

+

76 raise NotImplementedError 

+

77 

+

78 

+

79def calc_reynolds_pipe(dynamic_viscosity: float, m_flow: float, characteristic_length: float) -> float: 

+

80 """ 

+

81 Calculate Reynolds number for flow inside a pipe. 

+

82 

+

83 Args: 

+

84 dynamic_viscosity (float): Dynamic viscosity of the fluid. 

+

85 m_flow (float): Mass flow rate. 

+

86 characteristic_length (float): Characteristic length (e.g., diameter) of the pipe. 

+

87 

+

88 Returns: 

+

89 float: Reynolds number. 

+

90 

+

91 """ 

+

92 return 4 * m_flow / (np.pi * characteristic_length * dynamic_viscosity) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_4deeb89b86ecce82_pipe_to_wall_py.html b/docs/0.1.1/coverage/d_4deeb89b86ecce82_pipe_to_wall_py.html new file mode 100644 index 0000000..bfe01a8 --- /dev/null +++ b/docs/0.1.1/coverage/d_4deeb89b86ecce82_pipe_to_wall_py.html @@ -0,0 +1,196 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py: 0% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py: + 0% +

+ +

+ 36 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module with models for pipe-to-wall heat transfer. 

+

3""" 

+

4 

+

5from .heat_transfer import HeatTransfer, calc_reynolds_pipe 

+

6from vclibpy.media import TransportProperties 

+

7 

+

8 

+

9class TurbulentFluidInPipeToWallTransfer(HeatTransfer): 

+

10 """ 

+

11 Class to model turbulent heat exchange in a pipe. 

+

12 

+

13 Args: 

+

14 method (str): 

+

15 Equation to calc the nusselt number of turbulent flow for 

+

16 a given Re and Pr number. 

+

17 Note: Just for one-phase heat transfer!! 

+

18 Implemented Options are: 

+

19 

+

20 - Taler2016 

+

21 - Domanski1989_sp_smooth 

+

22 - Amalfi2016 

+

23 - ScriptWSÜ. For turbulent regimes, eta_by_eta_w is assumed to be one. 

+

24 

+

25 Refer to the paper / documents or the function in this class for more 

+

26 info on numbers and assumptions 

+

27 characteristic_length (float): 

+

28 Length to calculate the similitude approach for the 

+

29 heat transfer from ref -> wall. For heat pumps this is 

+

30 always the Diameter of the HE in m 

+

31 """ 

+

32 

+

33 def __init__(self, method: str, characteristic_length: float): 

+

34 self.method = method 

+

35 self.characteristic_length = characteristic_length 

+

36 

+

37 def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: 

+

38 """ 

+

39 Calculate heat transfer coefficient from refrigerant to the wall of the heat exchanger. 

+

40 

+

41 The flow is assumed to be always turbulent and is based on a calibrated 

+

42 Nusselt correlation. 

+

43 

+

44 Args: 

+

45 transport_properties (TransportProperties): Transport properties of the fluid. 

+

46 m_flow (float): Mass flow rate of the fluid. 

+

47 

+

48 Returns: 

+

49 float: Heat transfer coefficient from refrigerant to HE in W/(m^2*K). 

+

50 """ 

+

51 Re = calc_reynolds_pipe( 

+

52 characteristic_length=self.characteristic_length, 

+

53 dynamic_viscosity=transport_properties.dyn_vis, 

+

54 m_flow=m_flow 

+

55 ) 

+

56 Nu = self.calc_turbulent_tube_nusselt(Re, transport_properties.Pr) 

+

57 return Nu * transport_properties.lam / self.characteristic_length 

+

58 

+

59 def calc_turbulent_tube_nusselt(self, Re, Pr) -> float: 

+

60 """ 

+

61 Calculate the Nuseelt number for turbulent heat transfer 

+

62 in a tube (used for ref/water->Wall in the evaporator and condernser). 

+

63 

+

64 Args: 

+

65 Re (float): Reynolds number. 

+

66 Pr (float): Prandtl number. 

+

67 

+

68 Returns: 

+

69 float: Nusselt number. 

+

70 """ 

+

71 if self.method == "Taler2016": 

+

72 if Re < 3e3 or Re > 1e6: 

+

73 raise ValueError(f"Given Re {Re} is outside of allowed bounds for method {self.method}") 

+

74 if 0.1 <= Pr <= 1: 

+

75 return 0.02155 * Re ** 0.8018 * Pr ** 0.7095 

+

76 elif 1 < Pr <= 3: 

+

77 return 0.02155 * Re ** 0.8018 * Pr ** 0.7095 

+

78 elif 3 < Pr <= 1000: 

+

79 return 0.02155 * Re ** 0.8018 * Pr ** 0.7095 

+

80 else: 

+

81 raise ValueError(f"Given Pr {Pr} is outside of allowed bounds for method {self.method}") 

+

82 elif self.method == "ScriptWSÜ": 

+

83 if Re < 3000 or Re > 1e5: 

+

84 raise ValueError(f"Given Re {Re} is outside of allowed bounds for method {self.method}") 

+

85 eta_by_eta_w = 1 

+

86 return 0.027 * Re ** 0.8 ** Pr ** (1 / 3) * eta_by_eta_w ** 0.14 

+

87 elif self.method == "Amalfi2016": 

+

88 if Re <= 700: 

+

89 Nu = (0.0295 * Pr - 0.115) * Re ** 0.954 

+

90 else: 

+

91 Nu = (1.760 * Pr - 5.391) * Re ** 0.262 

+

92 if Nu < 0: 

+

93 raise ValueError(f"Given Pr {Pr} is outside of allowed bounds for method {self.method}") 

+

94 return Nu 

+

95 elif self.method == "Domanski1989_sp_smooth": 

+

96 # According to Domanski 1989 for singular phase and smooth surfaces 

+

97 return 0.023 * Re ** 0.8 * Pr ** 0.4 

+

98 else: 

+

99 raise TypeError(f"Method {self.method} not supported!") 

+
+ + + diff --git a/docs/0.1.1/coverage/d_4deeb89b86ecce82_vdi_atlas_air_to_wall_py.html b/docs/0.1.1/coverage/d_4deeb89b86ecce82_vdi_atlas_air_to_wall_py.html new file mode 100644 index 0000000..e1544dc --- /dev/null +++ b/docs/0.1.1/coverage/d_4deeb89b86ecce82_vdi_atlas_air_to_wall_py.html @@ -0,0 +1,265 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py: 0% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py: + 0% +

+ +

+ 72 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import logging 

+

2from dataclasses import dataclass 

+

3 

+

4import numpy as np 

+

5 

+

6from .air_to_wall import AirToWallTransfer 

+

7 

+

8logger = logging.getLogger(__name__) 

+

9 

+

10 

+

11@dataclass 

+

12class AirSourceHeatExchangerGeometry: 

+

13 """ 

+

14 Geometry of a fin and tube heat exchanger with two rows of pipes in a shifted arrangement. 

+

15 

+

16 Source: VDI-Wärmeatlas, Berechnungsblätter für den Wärmeübergang, 11. Auflage, S.1461 

+

17 

+

18 As the source is in German, the names are kept in German as well. 

+

19 """ 

+

20 t_l: float # Achsabstand der Rohre in Luftrichtung in m 

+

21 t_q: float # Achsabstand der Rohre quer zur Luftrichtung in m 

+

22 tiefe: float # Tiefe der Rippe gesamt 

+

23 d_a: float # Äußerer Rohrdurchmesser 

+

24 d_i: float # Innener Rohrdurchmesser 

+

25 lambda_R: float # Wärmeleitfähigkeit Material der Wand 

+

26 n_Rohre: int = 50 

+

27 n_Rippen: int = 500 

+

28 a: float = 1.95e-3 

+

29 dicke_rippe: float = 0.05e-3 

+

30 laenge: float = 1.040 

+

31 hoehe: float = 0.64 

+

32 

+

33 @property 

+

34 def char_length(self) -> float: 

+

35 """Return the characteristic length d_a.""" 

+

36 return self.d_a 

+

37 

+

38 @property 

+

39 def A_Rippen(self) -> float: 

+

40 """Return the total surface area of the fins.""" 

+

41 return 2 * self.n_Rippen * (self.tiefe * self.hoehe - self.n_Rohre * np.pi * 0.25 * self.d_a ** 2) 

+

42 

+

43 @property 

+

44 def A(self) -> float: 

+

45 """Total air side heat transfer area.""" 

+

46 return self.A_Rippen + self.A_FreieOberflaecheRohr 

+

47 

+

48 @property 

+

49 def A_FreieOberflaecheRohr(self) -> float: 

+

50 """Free air side area of the tubes.""" 

+

51 return self.n_Rippen * np.pi * self.d_a * self.a * self.n_Rohre 

+

52 

+

53 @property 

+

54 def A_RohrInnen(self) -> float: 

+

55 """Total refrigerant heat transfer area.""" 

+

56 return self.laenge * self.d_i * np.pi * self.n_Rohre 

+

57 

+

58 @property 

+

59 def A_RohrUnberippt(self) -> float: 

+

60 """Total outside area of the tubes without fins""" 

+

61 return self.laenge * self.d_a * np.pi * self.n_Rohre 

+

62 

+

63 @property 

+

64 def verjuengungsfaktor(self) -> float: 

+

65 """Reduction factor A_cross_free/A_cross_smallest""" 

+

66 return ((self.hoehe * self.laenge) / 

+

67 (self.hoehe * self.laenge - 

+

68 self.hoehe * self.n_Rippen * self.dicke_rippe - 

+

69 self.d_a * self.n_Rohre / 2 * (self.laenge - self.n_Rippen * self.dicke_rippe))) 

+

70 

+

71 @property 

+

72 def phi(self) -> float: 

+

73 """Auxiliary variable for fin efficiency""" 

+

74 if self.t_l >= 0.5 * self.t_q: 

+

75 b_r = self.t_q 

+

76 else: 

+

77 b_r = 2 * self.t_l 

+

78 l_r = np.sqrt(self.t_l **2 + self.t_q **2 / 4) 

+

79 phi_strich = 1.27 * b_r / self.d_a * np.sqrt(l_r / b_r - 0.3) 

+

80 return (phi_strich - 1) * (1 + 0.35 * np.log(phi_strich)) 

+

81 

+

82 def eta_R(self, alpha_R) -> float: 

+

83 """ 

+

84 Calculate fin efficiency. 

+

85 

+

86 Args: 

+

87 alpha_R (float): Average heat transfer coefficient for tube and fin. 

+

88 

+

89 Returns: 

+

90 float: Fin efficiency. 

+

91 """ 

+

92 X = self.phi * self.d_a / 2 * np.sqrt(2 * alpha_R / (self.lambda_R * self.dicke_rippe)) 

+

93 return 1 / X * (np.exp(X) - np.exp(-X)) / (np.exp(X) + np.exp(-X)) 

+

94 

+

95 def alpha_S(self, alpha_R) -> float: 

+

96 """ 

+

97 Calculate apparent heat transfer coefficient. 

+

98 

+

99 Args: 

+

100 alpha_R (float): Average heat transfer coefficient for tube and fin. 

+

101 

+

102 Returns: 

+

103 float: Apparent heat transfer coefficient. 

+

104 """ 

+

105 A_R_to_A = self.A_Rippen / self.A 

+

106 return alpha_R * (1 - (1 - self.eta_R(alpha_R)) * A_R_to_A) 

+

107 

+

108 

+

109class VDIAtlasAirToWallTransfer(AirToWallTransfer): 

+

110 """ 

+

111 VDI-Atlas based heat transfer estimation. 

+

112 Check `AirToWallTransfer` for further argument options. 

+

113 

+

114 This class assumes two pipes with a shifted arrangement. 

+

115 

+

116 Args: 

+

117 A_cross (float): Free cross-sectional area. 

+

118 characteristic_length (float): Characteristic length d_a. 

+

119 geometry_parameters (AirSourceHeatExchangerGeometry): 

+

120 Geometry parameters for heat exchanger according to VDI-Atlas 

+

121 """ 

+

122 

+

123 def __init__(self, 

+

124 A_cross: float, characteristic_length: float, 

+

125 geometry_parameters: AirSourceHeatExchangerGeometry): 

+

126 super().__init__(A_cross=A_cross, characteristic_length=characteristic_length) 

+

127 self.geometry_parameters = geometry_parameters 

+

128 

+

129 def calc_reynolds(self, dynamic_viscosity: float, m_flow: float) -> float: 

+

130 """ 

+

131 Calculate Reynolds number. 

+

132 

+

133 Args: 

+

134 dynamic_viscosity (float): Dynamic viscosity of the fluid. 

+

135 m_flow (float): Mass flow rate. 

+

136 

+

137 Returns: 

+

138 float: Reynolds number. 

+

139 """ 

+

140 velocity_times_dens = m_flow / self.A_cross * self.geometry_parameters.verjuengungsfaktor 

+

141 return (velocity_times_dens * self.characteristic_length) / dynamic_viscosity 

+

142 

+

143 def calc_laminar_area_nusselt(self, Re: float, Pr: float, lambda_: float) -> float: 

+

144 """ 

+

145 Calculate apparent heat transfer coefficient based on Nusselt correlation. 

+

146 

+

147 Args: 

+

148 Re (float): Reynolds number. 

+

149 Pr (float): Prandtl number. 

+

150 lambda_ (float): Thermal conductivity of air. 

+

151 

+

152 Returns: 

+

153 float: Apparent heat transfer coefficient. 

+

154 """ 

+

155 C = 0.33 # Versetzte Anordnung, zwei Rohre 

+

156 if Re < 1e3 or Re > 1e5: 

+

157 logger.debug("Given Re %s is outside of allowed bounds for VDI-Atlas", Re) 

+

158 A_div_A_0 = self.geometry_parameters.A / self.geometry_parameters.A_RohrUnberippt 

+

159 if A_div_A_0 < 5 or A_div_A_0 > 30: 

+

160 logger.debug("Given A/A0 is outside of bounds for method VDI-Atlas") 

+

161 Nu = ( 

+

162 C * Re ** 0.6 * 

+

163 A_div_A_0 ** (-0.15) * 

+

164 Pr ** (1 / 3) 

+

165 ) 

+

166 alpha_R = Nu * lambda_ / self.characteristic_length 

+

167 alpha_S = self.geometry_parameters.alpha_S(alpha_R=alpha_R) 

+

168 return alpha_S 

+
+ + + diff --git a/docs/0.1.1/coverage/d_4deeb89b86ecce82_wall_py.html b/docs/0.1.1/coverage/d_4deeb89b86ecce82_wall_py.html new file mode 100644 index 0000000..d64cbeb --- /dev/null +++ b/docs/0.1.1/coverage/d_4deeb89b86ecce82_wall_py.html @@ -0,0 +1,128 @@ + + + + + Coverage for vclibpy/components/heat_exchangers/heat_transfer/wall.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/heat_exchangers/heat_transfer/wall.py: + 100% +

+ +

+ 10 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import logging 

+

2 

+

3from .heat_transfer import HeatTransfer 

+

4from vclibpy.media import TransportProperties 

+

5 

+

6 

+

7logger = logging.getLogger(__name__) 

+

8 

+

9 

+

10class WallTransfer(HeatTransfer): 

+

11 """ 

+

12 Simple wall heat transfer 

+

13 

+

14 Args: 

+

15 lambda_ (float): 

+

16 Heat conductivity of wall material in W/Km 

+

17 thickness (float): 

+

18 Thickness of wall in m^2 

+

19 """ 

+

20 def __init__(self, lambda_: float, thickness: float): 

+

21 self.thickness = thickness 

+

22 self.lambda_ = lambda_ 

+

23 

+

24 def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: 

+

25 """ 

+

26 Heat transfer coefficient inside wall 

+

27 

+

28 Returns: 

+

29 float: Heat transfer coefficient in W/(m^2*K) 

+

30 """ 

+

31 return self.lambda_ / self.thickness 

+
+ + + diff --git a/docs/0.1.1/coverage/d_57d6adb9ba5af1cf___init___py.html b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf___init___py.html new file mode 100644 index 0000000..96e0138 --- /dev/null +++ b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf___init___py.html @@ -0,0 +1,99 @@ + + + + + Coverage for vclibpy/utils/__init__.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/utils/__init__.py: + 100% +

+ +

+ 2 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from .automation import full_factorial_map_generation, calc_multiple_states 

+

2from .sdf_ import save_to_sdf 

+
+ + + diff --git a/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_automation_py.html b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_automation_py.html new file mode 100644 index 0000000..d5a8bda --- /dev/null +++ b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_automation_py.html @@ -0,0 +1,317 @@ + + + + + Coverage for vclibpy/utils/automation.py: 78% + + + + + +
+
+

+ Coverage for vclibpy/utils/automation.py: + 78% +

+ +

+ 99 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Functions to generate HP Maps automatically 

+

3""" 

+

4import logging 

+

5import pathlib 

+

6import os 

+

7from typing import List, Union 

+

8import multiprocessing 

+

9import numpy as np 

+

10import pandas as pd 

+

11from vclibpy.datamodels import FlowsheetState, Inputs 

+

12from vclibpy.flowsheets import BaseCycle 

+

13from vclibpy import utils 

+

14 

+

15logger = logging.getLogger(__name__) 

+

16 

+

17 

+

18def calc_multiple_states( 

+

19 save_path: pathlib.Path, 

+

20 heat_pump: BaseCycle, 

+

21 inputs: List[Inputs], 

+

22 **kwargs): 

+

23 """ 

+

24 Function to calculate the flowsheet states for all given inputs. 

+

25 All results are stored as a .xlsx file in the given save-path 

+

26 

+

27 Args: 

+

28 save_path (pathlib.Path): Location where to save the results as xlsx. 

+

29 heat_pump (BaseCycle): A valid flowsheet 

+

30 inputs (List[Inputs]): A list with all inputs to simulate 

+

31 **kwargs: Solver settings for the flowsheet 

+

32 """ 

+

33 rel_infos = [] 

+

34 for i, single_inputs in enumerate(inputs): 

+

35 fs_state = None 

+

36 logger.info(f"Running combination {i+1}/{len(inputs)}.") 

+

37 try: 

+

38 fs_state = heat_pump.calc_steady_state(inputs=single_inputs, 

+

39 **kwargs) 

+

40 except Exception as e: 

+

41 # Avoid loss of data if un-excepted errors occur. 

+

42 logger.error(f"An error occurred: {e}") 

+

43 if fs_state is None: 

+

44 fs_state = FlowsheetState() 

+

45 hp_state_dic = { 

+

46 **single_inputs.convert_to_str_value_format(with_unit_and_description=True), 

+

47 **fs_state.convert_to_str_value_format(with_unit_and_description=True) 

+

48 } 

+

49 rel_infos.append(hp_state_dic) 

+

50 df = pd.DataFrame(rel_infos) 

+

51 df.index.name = "State Number" 

+

52 df.to_excel(save_path.joinpath(f"{heat_pump}_{heat_pump.fluid}.xlsx"), sheet_name="HP_states", float_format="%.5f") 

+

53 

+

54 

+

55def full_factorial_map_generation( 

+

56 heat_pump: BaseCycle, 

+

57 T_eva_in_ar: Union[list, np.ndarray], 

+

58 T_con_in_ar: Union[list, np.ndarray], 

+

59 n_ar: Union[list, np.ndarray], 

+

60 m_flow_con: float, 

+

61 m_flow_eva: float, 

+

62 save_path: Union[pathlib.Path, str], 

+

63 dT_eva_superheating=5, 

+

64 dT_con_subcooling=0, 

+

65 use_multiprocessing: bool = False, 

+

66 save_plots: bool = False, 

+

67 **kwargs 

+

68) -> (pathlib.Path, pathlib.Path): 

+

69 """ 

+

70 Run a full-factorial simulation to create performance maps 

+

71 used in other simulation tools like Modelica or to analyze 

+

72 the off-design of the flowsheet. 

+

73 The results are stored and returned as .sdf and .csv files. 

+

74 Currently, only varying T_eva_in, T_con_in, and n is implemented. 

+

75 However, changing this to more dimensions or other variables 

+

76 is not much work. In this case, please raise an issue. 

+

77 

+

78 Args: 

+

79 heat_pump (BaseCycle): The flowsheet to use 

+

80 T_eva_in_ar: Array with inputs for T_eva_in 

+

81 T_con_in_ar: Array with inputs for T_con_in 

+

82 n_ar: Array with inputs for n_ar 

+

83 m_flow_con: Condenser mass flow rate 

+

84 m_flow_eva: Evaporator mass flow rate 

+

85 save_path: Where to save all results. 

+

86 dT_eva_superheating: Evaporator superheating 

+

87 dT_con_subcooling: Condenser subcooling 

+

88 use_multiprocessing: 

+

89 True to use multiprocessing. May speed up the calculation. Default is False 

+

90 save_plots: 

+

91 True to save plots of each steady state point. Default is False 

+

92 **kwargs: Solver settings for the flowsheet 

+

93 

+

94 Returns: 

+

95 tuple (pathlib.Path, pathlib.Path): 

+

96 Path to the created .sdf file and to the .csv file 

+

97 """ 

+

98 if isinstance(save_path, str): 

+

99 save_path = pathlib.Path(save_path) 

+

100 if save_plots: 

+

101 kwargs["save_path_plots"] = pathlib.Path(save_path).joinpath(f"plots_{heat_pump.flowsheet_name}_{heat_pump.fluid}") 

+

102 os.makedirs(kwargs["save_path_plots"], exist_ok=True) 

+

103 

+

104 list_mp_inputs = [] 

+

105 list_inputs = [] 

+

106 idx_for_access_later = [] 

+

107 for i_T_eva_in, T_eva_in in enumerate(T_eva_in_ar): 

+

108 for i_n, n in enumerate(n_ar): 

+

109 for i_T_con_in, T_con_in in enumerate(T_con_in_ar): 

+

110 idx_for_access_later.append([i_n, i_T_con_in, i_T_eva_in]) 

+

111 inputs = Inputs(n=n, 

+

112 T_eva_in=T_eva_in, 

+

113 T_con_in=T_con_in, 

+

114 m_flow_eva=m_flow_eva, 

+

115 m_flow_con=m_flow_con, 

+

116 dT_eva_superheating=dT_eva_superheating, 

+

117 dT_con_subcooling=dT_con_subcooling) 

+

118 list_mp_inputs.append([heat_pump, inputs, kwargs]) 

+

119 list_inputs.append(inputs) 

+

120 fs_states = [] 

+

121 i = 0 

+

122 if use_multiprocessing: 

+

123 pool = multiprocessing.Pool(processes=multiprocessing.cpu_count()) 

+

124 for fs_state in pool.imap(_calc_single_hp_state, list_mp_inputs): 

+

125 fs_states.append(fs_state) 

+

126 i += 1 

+

127 logger.info(f"Ran {i} of {len(list_mp_inputs)} points") 

+

128 else: 

+

129 for inputs in list_inputs: 

+

130 fs_state = _calc_single_hp_state([heat_pump, inputs, kwargs]) 

+

131 fs_states.append(fs_state) 

+

132 i += 1 

+

133 logger.info(f"Ran {i} of {len(list_mp_inputs)} points") 

+

134 

+

135 # Save to sdf 

+

136 result_shape = (len(n_ar), len(T_con_in_ar), len(T_eva_in_ar)) 

+

137 _dummy = np.zeros(result_shape) # Use a copy to avoid overwriting of values of any sort. 

+

138 _dummy[:] = np.nan 

+

139 # Get all possible values: 

+

140 all_variables = {} 

+

141 all_variables_info = {} 

+

142 variables_to_excel = [] 

+

143 for fs_state, inputs in zip(fs_states, list_inputs): 

+

144 all_variables.update({var: _dummy.copy() for var in fs_state.get_variable_names()}) 

+

145 all_variables_info.update({var: variable for var, variable in fs_state.get_variables().items()}) 

+

146 variables_to_excel.append({ 

+

147 **inputs.convert_to_str_value_format(with_unit_and_description=True), 

+

148 **fs_state.convert_to_str_value_format(with_unit_and_description=True), 

+

149 }) 

+

150 

+

151 # Save to excel 

+

152 save_path_sdf = save_path.joinpath(f"{heat_pump.flowsheet_name}_{heat_pump.fluid}.sdf") 

+

153 save_path_csv = save_path.joinpath(f"{heat_pump.flowsheet_name}_{heat_pump.fluid}.csv") 

+

154 pd.DataFrame(variables_to_excel).to_csv( 

+

155 save_path_csv 

+

156 ) 

+

157 

+

158 for fs_state, idx_triple in zip(fs_states, idx_for_access_later): 

+

159 i_n, i_T_con_in, i_T_eva_in = idx_triple 

+

160 for variable_name, variable in fs_state.get_variables().items(): 

+

161 all_variables[variable_name][i_n][i_T_con_in][i_T_eva_in] = variable.value 

+

162 

+

163 _nd_data = {} 

+

164 for variable, nd_data in all_variables.items(): 

+

165 _nd_data.update({ 

+

166 variable: { 

+

167 "data": nd_data, 

+

168 "unit": all_variables_info[variable].unit, 

+

169 "comment": all_variables_info[variable].description} 

+

170 }) 

+

171 

+

172 _scale_values = { 

+

173 "n": n_ar, 

+

174 "T_con_in": T_con_in_ar, 

+

175 "T_eva_in": T_eva_in_ar 

+

176 } 

+

177 inputs: Inputs = list_inputs[0] 

+

178 _parameters = {} 

+

179 for name, variable in inputs.items(): 

+

180 if name not in _scale_values: 

+

181 _parameters[name] = { 

+

182 "data": variable.value, 

+

183 "unit": variable.unit, 

+

184 "comment": variable.description 

+

185 } 

+

186 _scales = {} 

+

187 for name, data in _scale_values.items(): 

+

188 _scales[name] = { 

+

189 "data": data, 

+

190 "unit": inputs.get(name).unit, 

+

191 "comment": inputs.get(name).description 

+

192 } 

+

193 

+

194 sdf_data = { 

+

195 heat_pump.flowsheet_name: 

+

196 { 

+

197 heat_pump.fluid: (_scales, _nd_data, _parameters) 

+

198 } 

+

199 } 

+

200 utils.save_to_sdf(data=sdf_data, save_path=save_path_sdf) 

+

201 

+

202 # Terminate heat pump med-props: 

+

203 heat_pump.terminate() 

+

204 

+

205 return save_path_sdf, save_path_csv 

+

206 

+

207 

+

208def _calc_single_hp_state(data): 

+

209 """Helper function for a single state to enable multiprocessing""" 

+

210 heat_pump, inputs, kwargs = data 

+

211 fs_state = None 

+

212 try: 

+

213 fs_state = heat_pump.calc_steady_state(inputs=inputs, 

+

214 **kwargs) 

+

215 except Exception as e: 

+

216 logger.error(f"An error occurred for input: {inputs.__dict__}: {e}") 

+

217 if fs_state is None: 

+

218 fs_state = FlowsheetState() 

+

219 # Append the data to the dataframe 

+

220 return fs_state 

+
+ + + diff --git a/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_nominal_design_py.html b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_nominal_design_py.html new file mode 100644 index 0000000..598d051 --- /dev/null +++ b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_nominal_design_py.html @@ -0,0 +1,183 @@ + + + + + Coverage for vclibpy/utils/nominal_design.py: 0% + + + + + +
+
+

+ Coverage for vclibpy/utils/nominal_design.py: + 0% +

+ +

+ 34 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import time 

+

2import logging 

+

3 

+

4from vclibpy import Inputs 

+

5from vclibpy.flowsheets import BaseCycle 

+

6 

+

7logger = logging.getLogger(__name__) 

+

8 

+

9 

+

10def nominal_hp_design( 

+

11 heat_pump: BaseCycle, 

+

12 inputs: Inputs, 

+

13 fluid: str, 

+

14 dT_con: float = None, 

+

15 dT_eva: float = None, 

+

16 **kwargs) -> dict: 

+

17 """ 

+

18 Function to calculate the heat pump design 

+

19 at a given nominal point.  

+

20 Args: 

+

21 heat_pump (BaseCycle): A supported flowsheet 

+

22 inputs (Inputs): 

+

23 The input values at the nominal point. 

+

24 If the mass flow rates are not given, you 

+

25 can use dT_con and dT_eva to iteratively calculate 

+

26 the mass flow rates in order to achieve the required 

+

27 temperature differences at the nominal point. 

+

28 dT_con (float): 

+

29 Condenser temperature difference to calculate mass flow rate 

+

30 dT_eva (float): 

+

31 Evaporator temperature difference to calculate mass flow rate 

+

32 fluid (str): Fluid to be used. 

+

33 **kwargs:  

+

34 m_flow_eva_start: Guess start-value for iteration. Default 0.2 

+

35 m_flow_con_start: Guess start-value for iteration. Default 1 

+

36 accuracy: Minimal accuracy for mass flow rate iteration (in kg/s).  

+

37 Default 0.001 kg/s 

+

38  

+

39 Returns: 

+

40 dict: A dictionary with all flowsheet states and inputs containing 

+

41 information about the nominal design. 

+

42 """ 

+

43 t0 = time.time() 

+

44 # Define nominal values: 

+

45 m_flow_con_start = kwargs.get("m_flow_con_start", 0.2) 

+

46 m_flow_eva_start = kwargs.get("m_flow_eva_start", 1) 

+

47 accuracy = kwargs.get("accuracy", 0.001) 

+

48 calculate_m_flow = dT_eva is not None and dT_con is not None 

+

49 if calculate_m_flow: 

+

50 # Get nominal value: 

+

51 fs_state = heat_pump.calc_steady_state(fluid=fluid, inputs=inputs) 

+

52 if fs_state is None: 

+

53 raise ValueError("Given configuration is infeasible at nominal point.") 

+

54 

+

55 else: 

+

56 # We have to iterate to match the m_flows to the Q_cons: 

+

57 m_flow_eva_next = m_flow_eva_start 

+

58 m_flow_con_next = m_flow_con_start 

+

59 while True: 

+

60 # Set values 

+

61 m_flow_eva = m_flow_eva_next 

+

62 m_flow_con = m_flow_con_next 

+

63 inputs.set("m_flow_con", m_flow_con) 

+

64 inputs.set("m_flow_eva", m_flow_eva) 

+

65 # Get nominal value: 

+

66 fs_state = heat_pump.calc_steady_state(fluid=fluid, inputs=inputs) 

+

67 if fs_state is None: 

+

68 raise ValueError("Given configuration is infeasible at nominal point.") 

+

69 cp_eva = heat_pump.evaporator._secondary_cp 

+

70 cp_con = heat_pump.condenser._secondary_cp 

+

71 m_flow_con_next = fs_state.get("Q_con") / (dT_con * cp_con) 

+

72 m_flow_eva_next = (fs_state.get("Q_con") * (1 - 1 / fs_state.get("COP"))) / (dT_eva * cp_eva) 

+

73 # Check convergence: 

+

74 if abs(m_flow_eva_next - m_flow_eva) < accuracy and abs(m_flow_con-m_flow_con_next) < accuracy: 

+

75 break 

+

76 

+

77 nominal_design_info = { 

+

78 **inputs.convert_to_str_value_format(with_unit_and_description=False), 

+

79 **fs_state.convert_to_str_value_format(with_unit_and_description=False), 

+

80 "dT_con": dT_con, 

+

81 "dT_eva": dT_eva 

+

82 } 

+

83 logger.info("Auto-generation of nominal values took %s seconds", time.time()-t0) 

+

84 logger.info('Nominal values: %s', nominal_design_info) 

+

85 

+

86 return nominal_design_info 

+
+ + + diff --git a/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_plotting_py.html b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_plotting_py.html new file mode 100644 index 0000000..0c41363 --- /dev/null +++ b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_plotting_py.html @@ -0,0 +1,396 @@ + + + + + Coverage for vclibpy/utils/plotting.py: 57% + + + + + +
+
+

+ Coverage for vclibpy/utils/plotting.py: + 57% +

+ +

+ 169 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import pathlib 

+

2from typing import List 

+

3 

+

4import numpy as np 

+

5import matplotlib.pyplot as plt 

+

6import sdf 

+

7 

+

8from vclibpy.media import ThermodynamicState, MedProp 

+

9 

+

10 

+

11def plot_cycle( 

+

12 med_prop: MedProp, 

+

13 states: List[ThermodynamicState], 

+

14 save_path: pathlib.Path = None, 

+

15 show: bool = False 

+

16): 

+

17 """ 

+

18 Creates T-h and p-h diagrams for a thermodynamic cycle. 

+

19 

+

20 Args: 

+

21 med_prop (MedProp): 

+

22 Object containing the medium properties and two-phase limits. 

+

23 states (List[ThermodynamicState]): 

+

24 List of thermodynamic states defining the cycle points. Each state 

+

25 should contain T, p, and h properties. 

+

26 save_path (pathlib.Path, optional): 

+

27 Path where the plot should be saved. If None, returns the figure 

+

28 and axes objects instead. Defaults to None. 

+

29 show (bool): 

+

30 If True, plots are displayed. Default is False. 

+

31 

+

32 Returns: 

+

33 tuple(matplotlib.figure.Figure, numpy.ndarray) or None: 

+

34 If save_path is provided, saves the plot and returns None. 

+

35 If show is True, shows the plot. 

+

36 """ 

+

37 states.append(states[0]) # Plot full cycle 

+

38 # Unpack state var: 

+

39 h_T = np.array([state.h for state in states]) / 1000 

+

40 T = [state.T - 273.15 for state in states] 

+

41 p = np.array([state.p / 1e5 for state in states]) 

+

42 h_p = h_T 

+

43 

+

44 fig, ax = plt.subplots(2, 1, sharex=True) 

+

45 ax[0].set_ylabel("$T$ in °C") 

+

46 ax[1].set_xlabel("$h$ in kJ/kgK") 

+

47 # Two phase limits 

+

48 ax[0].plot( 

+

49 med_prop.get_two_phase_limits("h") / 1000, 

+

50 med_prop.get_two_phase_limits("T") - 273.15, color="black" 

+

51 ) 

+

52 

+

53 ax[0].plot(h_T, T, color="r", marker="s") 

+

54 ax[1].set_yscale('log') # Set y-axis to logarithmic scale 

+

55 ax[1].plot(h_p, p, marker="s", color="r") 

+

56 # Two phase limits 

+

57 ax[1].plot( 

+

58 med_prop.get_two_phase_limits("h") / 1000, 

+

59 med_prop.get_two_phase_limits("p") / 1e5, 

+

60 color="black" 

+

61 ) 

+

62 ax[1].set_ylabel("$log(p)$ in bar") 

+

63 ax[1].set_ylim([np.min(p) * 0.9, np.max(p) * 1.1]) 

+

64 ax[0].set_ylim([np.min(T) - 5, np.max(T) + 5]) 

+

65 ax[1].set_xlim([np.min(h_T) * 0.9, np.max(h_T) * 1.1]) 

+

66 ax[0].set_xlim([np.min(h_T) * 0.9, np.max(h_T) * 1.1]) 

+

67 if show: 

+

68 plt.show() 

+

69 if save_path is not None: 

+

70 fig.tight_layout() 

+

71 fig.savefig(save_path) 

+

72 plt.close(fig) 

+

73 return 

+

74 return fig, ax 

+

75 

+

76 

+

77def plot_sdf_map( 

+

78 filepath_sdf: pathlib.Path, 

+

79 nd_data: str, 

+

80 first_dimension: str, 

+

81 second_dimension: str, 

+

82 fluids: List[str] = None, 

+

83 flowsheets: List[str] = None, 

+

84 violin_plot_variable: str = None, 

+

85 third_dimension: str = None 

+

86): 

+

87 """ 

+

88 Generate and display visualizations based on data from an SDF (Structured Data File) dataset. 

+

89 This function generates various types of visualizations based on the provided parameters, 

+

90 including 3D scatter plots, 3D surface plots, and violin plots, and displays them using Matplotlib. 

+

91 

+

92 Args: 

+

93 filepath_sdf (pathlib.Path): 

+

94 The path to the SDF dataset file. 

+

95 nd_data (str): 

+

96 The name of the primary data to be plotted. 

+

97 first_dimension (str): 

+

98 The name of the first dimension for the visualization. 

+

99 second_dimension (str): 

+

100 The name of the second dimension for the visualization. 

+

101 fluids (List[str], optional): 

+

102 List of specific fluids to include in the visualization. 

+

103 Default is None, which includes all fluids. 

+

104 flowsheets (List[str], optional): 

+

105 List of specific flowsheets to include in the visualization. 

+

106 Default is None, which includes all flowsheets. 

+

107 violin_plot_variable (str, optional): 

+

108 The variable to be used for creating violin plots. 

+

109 Default is None, which disables violin plots. 

+

110 third_dimension (str, optional): 

+

111 The name of the third dimension for 4D visualizations. 

+

112 Default is None, which disables 4D plotting. 

+

113 

+

114 Raises: 

+

115 KeyError: If the specified data or dimensions are not found in the dataset. 

+

116 

+

117 Examples: 

+

118 >>> FILEPATH_SDF = r"HeatPumpMaps.sdf" 

+

119 >>> plot_sdf_map( 

+

120 >>> filepath_sdf=FILEPATH_SDF, 

+

121 >>> nd_data="COP", 

+

122 >>> first_dimension="T_eva_in", 

+

123 >>> second_dimension="n", 

+

124 >>> fluids=["R410A"], 

+

125 >>> flowsheets=["OptiHorn"], 

+

126 >>> ) 

+

127 

+

128 """ 

+

129 if fluids is None: 

+

130 fluids = [] 

+

131 if flowsheets is None: 

+

132 flowsheets = [] 

+

133 if "T_" in second_dimension: 

+

134 offset_sec = -273.15 

+

135 else: 

+

136 offset_sec = 0 

+

137 if "T_" in first_dimension: 

+

138 offset_pri = -273.15 

+

139 else: 

+

140 offset_pri = 0 

+

141 offset_thi = 0 

+

142 plot_4D = False 

+

143 if third_dimension is not None: 

+

144 plot_4D = True 

+

145 if "T_" in third_dimension: 

+

146 offset_thi = -273.15 

+

147 

+

148 dataset = sdf.load(str(filepath_sdf)) 

+

149 plot_violin = True 

+

150 if violin_plot_variable is None: 

+

151 plot_violin = False 

+

152 violin_plot_variable = "" 

+

153 if plot_violin: 

+

154 if flowsheets: 

+

155 n_rows = len(flowsheets) 

+

156 else: 

+

157 n_rows = len(dataset.groups) 

+

158 fig_v, ax_v = plt.subplots(nrows=n_rows, ncols=1, sharex=True, 

+

159 squeeze=False) 

+

160 fig_v.suptitle(violin_plot_variable) 

+

161 i_fs = 0 

+

162 nd_str_plot = nd_data 

+

163 fac = 1 

+

164 if nd_data == "dT_eva_min": 

+

165 nd_data = "T_1" 

+

166 sub_str = "T_eva_in" 

+

167 fac = - 1 

+

168 elif nd_data == "dT_con": 

+

169 nd_data = "T_3" 

+

170 sub_str = "T_con_in" 

+

171 elif nd_data == "dT_sh": 

+

172 nd_data = "T_1" 

+

173 sub_str = "T_4" 

+

174 else: 

+

175 sub_str = "" 

+

176 

+

177 if nd_str_plot.startswith("T_"): 

+

178 offset_nd = -273.15 

+

179 else: 

+

180 offset_nd = 0 

+

181 

+

182 for flowsheet in dataset.groups: 

+

183 violin_data = {} 

+

184 if flowsheet.name not in flowsheets and len(flowsheets) > 0: 

+

185 continue 

+

186 for fluid in flowsheet.groups: 

+

187 if fluid.name not in fluids and len(fluids) > 0: 

+

188 continue 

+

189 nd, fd, sd, sub_data, td = None, None, None, None, None 

+

190 _other_scale = {} 

+

191 for ds in fluid.datasets: 

+

192 if ds.name == nd_data: 

+

193 nd = ds 

+

194 elif ds.name == first_dimension: 

+

195 fd = ds.data 

+

196 elif ds.name == second_dimension: 

+

197 sd = ds.data 

+

198 if ds.name == sub_str: 

+

199 sub_data = ds.data 

+

200 if ds.name == violin_plot_variable: 

+

201 data = ds.data.flatten() 

+

202 violin_data[fluid.name] = data[~np.isnan(data)] 

+

203 if plot_4D and ds.name == third_dimension: 

+

204 td = ds.data 

+

205 

+

206 if nd is None: 

+

207 raise KeyError("nd-String not found in dataset") 

+

208 

+

209 if sub_data is None: 

+

210 sub_data = np.zeros(nd.data.shape) 

+

211 

+

212 # Check other scales: 

+

213 for i, scale in enumerate(nd.scales): 

+

214 if scale.name not in [first_dimension, second_dimension]: 

+

215 _other_scale[i] = scale 

+

216 

+

217 if fd is None or sd is None or not _other_scale or (plot_4D and td is None): 

+

218 raise KeyError("One of the given strings was not found in dataset") 

+

219 

+

220 if plot_4D: 

+

221 fig = plt.figure() 

+

222 figtitle = f"{flowsheet.name}_{fluid.name}_{nd_str_plot}" 

+

223 fig.suptitle(figtitle) 

+

224 ax = fig.add_subplot(111, projection='3d') 

+

225 ax.set_xlabel(first_dimension) 

+

226 ax.set_ylabel(second_dimension) 

+

227 ax.set_zlabel(third_dimension) 

+

228 fourth_dim = (nd.data - sub_data) * fac + offset_nd 

+

229 # Scale values for better sizes of circles: 

+

230 bounds = [fourth_dim.min(), fourth_dim.max()] 

+

231 _max_circle_size = 30 

+

232 fourth_dim_scaled = (fourth_dim - bounds[0]) / (bounds[1] - bounds[0]) * _max_circle_size 

+

233 inp = [fd + offset_pri, sd + offset_sec, td + offset_thi] 

+

234 import itertools 

+

235 scattergrid = np.array([c for c in itertools.product(*inp)]) 

+

236 ax.scatter(scattergrid[:, 0], 

+

237 scattergrid[:, 1], 

+

238 scattergrid[:, 2], 

+

239 c=fourth_dim_scaled, 

+

240 s=fourth_dim_scaled) 

+

241 else: 

+

242 for index, scale in _other_scale.items(): 

+

243 for idx_data, value in enumerate(scale.data): 

+

244 if index==0: 

+

245 Z = nd.data[idx_data, :, :] 

+

246 if sub_str in ["T_4", ""]: 

+

247 sub_data_use = sub_data[idx_data, :, :] 

+

248 else: 

+

249 sub_data_use = sub_data 

+

250 elif index == 1: 

+

251 Z = nd.data[:, idx_data, :] 

+

252 if sub_str in ["T_4", ""]: 

+

253 sub_data_use = sub_data[:, idx_data, :] 

+

254 else: 

+

255 sub_data_use = sub_data 

+

256 else: 

+

257 Z = nd.data[:, :, idx_data] 

+

258 if sub_str in ["T_4", ""]: 

+

259 sub_data_use = sub_data[:, :, idx_data] 

+

260 else: 

+

261 sub_data_use = sub_data 

+

262 if not plot_violin: 

+

263 fig = plt.figure() 

+

264 figtitle = f"{flowsheet.name}_{fluid.name}_{nd_str_plot}_{scale.name}={round(value, 3)}" 

+

265 fig.suptitle(figtitle) 

+

266 ax = fig.add_subplot(111, projection='3d') 

+

267 ax.set_xlabel(first_dimension) 

+

268 ax.set_ylabel(second_dimension) 

+

269 X, Y = np.meshgrid(fd, sd) 

+

270 ax.plot_surface(X + offset_pri, Y + offset_sec, (Z - sub_data_use)*fac + offset_nd) 

+

271 

+

272 if plot_violin: 

+

273 for key, value in violin_data.items(): 

+

274 print(f"{violin_plot_variable}: {flowsheet.name}_{key}") 

+

275 print(f"Min: {np.min(value)}") 

+

276 print(f"Max: {np.max(value)}") 

+

277 print(f"Mean: {np.mean(value)}") 

+

278 print(f"Median: {np.median(value)}\n") 

+

279 ax_v[i_fs][0].violinplot( 

+

280 list(violin_data.values()), 

+

281 showextrema=True, 

+

282 showmeans=True, 

+

283 showmedians=True 

+

284 ) 

+

285 set_axis_style(ax_v[i_fs][0], list(violin_data.keys())) 

+

286 ax_v[i_fs][0].set_ylabel(flowsheet.name.replace("Flowsheet", "")) 

+

287 i_fs += 1 

+

288 plt.show() 

+

289 

+

290 

+

291def set_axis_style(ax, labels): 

+

292 """ 

+

293 From: https://matplotlib.org/3.1.1/gallery/statistics/customized_violin.html#sphx-glr-gallery-statistics-customized-violin-py 

+

294 """ 

+

295 ax.get_xaxis().set_tick_params(direction='out') 

+

296 ax.xaxis.set_ticks_position('bottom') 

+

297 ax.set_xticks(np.arange(1, len(labels) + 1)) 

+

298 ax.set_xticklabels(labels) 

+

299 ax.set_xlim(0.25, len(labels) + 0.75) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_printing_py.html b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_printing_py.html new file mode 100644 index 0000000..162cbb7 --- /dev/null +++ b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_printing_py.html @@ -0,0 +1,143 @@ + + + + + Coverage for vclibpy/utils/printing.py: 0% + + + + + +
+
+

+ Coverage for vclibpy/utils/printing.py: + 0% +

+ +

+ 13 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1# -*- coding: utf-8 -*- 

+

2""" 

+

3Created on 24.04.2023 

+

4 

+

5@author: Christoph Hoeges 

+

6 

+

7Last Update: 24.04.2023 

+

8""" 

+

9import pandas as pd 

+

10 

+

11 

+

12def print_states(**kwargs): 

+

13 """ 

+

14 Transforms given states to DataFrame and prints table layout. 

+

15 Declaration of state must start with 'state' 

+

16 

+

17 Returns: 

+

18 :return pandas.DataFrame df_states: 

+

19 DataFrame with states 

+

20 """ 

+

21 # Remove keys in given data that are not label as "state" 

+

22 for key in kwargs.keys(): 

+

23 if not key.startswith("state"): 

+

24 print( 

+

25 f"Given value {key} is removed from data transformation! " 

+

26 f"Value must be declared as 'state'" 

+

27 ) 

+

28 kwargs.pop(key, None) 

+

29 

+

30 # Extract data from ThermodynamicStates 

+

31 data_states = {key: {"state": key[5:], "T": data.T, "p": data.p, "h": data.h, "s": data.s, "d": data.d} 

+

32 for key, data in kwargs.items()} 

+

33 df_states = pd.DataFrame.from_dict(data=data_states) 

+

34 

+

35 # Similar to previous results - now with rounded data 

+

36 data_states_rounded = {key: {"State": key[5:], 

+

37 "T in °C": round(data.T - 273.15, 2), 

+

38 "p in bar": round(data.p * 1e-5, 3), 

+

39 "h in kJ/kg": round(data.h * 1e-3, 3), 

+

40 "s in kJ/kg": round(data.s * 1e-3, 3), 

+

41 "d in kg/m3": round(data.d, 3)} 

+

42 for key, data in kwargs.items()} 

+

43 df_states_rounded = pd.DataFrame.from_dict(data=data_states_rounded) 

+

44 print(df_states_rounded.T) 

+

45 

+

46 return df_states 

+
+ + + diff --git a/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_sdf__py.html b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_sdf__py.html new file mode 100644 index 0000000..bf2288a --- /dev/null +++ b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_sdf__py.html @@ -0,0 +1,260 @@ + + + + + Coverage for vclibpy/utils/sdf_.py: 42% + + + + + +
+
+

+ Coverage for vclibpy/utils/sdf_.py: + 42% +

+ +

+ 73 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import itertools 

+

2import pathlib 

+

3 

+

4import pandas as pd 

+

5import sdf 

+

6 

+

7 

+

8def save_to_sdf(data: dict, save_path: pathlib.Path): 

+

9 """ 

+

10 Save given input dictionary to a sdf file in the given save_path 

+

11 

+

12 Args: 

+

13 data (dict): 

+

14 A dictionary with the following structure: 

+

15 Keys: Flowsheet_name 

+

16 Values: A dictionary with the following structure: 

+

17 

+

18 - Keys: Fluids 

+

19 - Values: Data dictionaries with the following structure: 

+

20 A tuple with three values, in that order: 

+

21 

+

22 - scales: Of the given nd_data, e.g. T_Amb, n 

+

23 - nd_data: More-dimensional data, e.g. COP 

+

24 - parameters: Scalar values, like m_flow_con or similar 

+

25 

+

26 save_path (pathlib.Path): Where to store the data 

+

27 flowsheet_name (str): Name of the flowsheet. This is the top level group 

+

28 :return: 

+

29 """ 

+

30 if isinstance(save_path, str): 

+

31 save_path = pathlib.Path(save_path) 

+

32 _all_groups = [] 

+

33 

+

34 for flowsheet_name, fluid_dict in data.items(): 

+

35 _all_fluids = [] 

+

36 for fluid, fluid_data in fluid_dict.items(): 

+

37 # First write scales 

+

38 _scales = [] 

+

39 for scale_name, scale_values in fluid_data[0].items(): 

+

40 _scales.append(sdf.Dataset(scale_name, 

+

41 data=scale_values["data"], 

+

42 unit=scale_values["unit"], 

+

43 is_scale=True, 

+

44 display_name=scale_name, 

+

45 comment=scale_values.get("comment", ""))) 

+

46 # Now the ND-Data: 

+

47 _nd_data = [] 

+

48 for data_name, data_values in fluid_data[1].items(): 

+

49 _nd_data.append(sdf.Dataset(data_name, 

+

50 data=data_values["data"], 

+

51 unit=data_values["unit"], 

+

52 scales=_scales, 

+

53 comment=data_values.get("comment", ""))) 

+

54 # Now the constant parameters 

+

55 _paras = [] 

+

56 for para_name, para_value in fluid_data[2].items(): 

+

57 _paras.append(sdf.Dataset(para_name, 

+

58 data=para_value["data"], 

+

59 unit=para_value["unit"], 

+

60 comment=para_value.get("comment", ""))) 

+

61 

+

62 # Save everything 

+

63 fluid_group = sdf.Group(fluid, comment="Values for fluid", datasets=_scales + _nd_data + _paras) 

+

64 _all_fluids.append(fluid_group) 

+

65 

+

66 flowsheet_group = sdf.Group(flowsheet_name, 

+

67 comment="Multiple fluids for the flowsheet", 

+

68 groups=_all_fluids) 

+

69 _all_groups.append(flowsheet_group) 

+

70 

+

71 parent_group = sdf.Group("/", comment="Generated with VCLibPy", groups=_all_groups) 

+

72 sdf.save(save_path, group=parent_group) 

+

73 return save_path 

+

74 

+

75 

+

76def merge_sdfs(filepaths, save_path): 

+

77 """ 

+

78 Merge given files and return a merged file. 

+

79 Be careful if both files contain the same combination. 

+

80 Then, the latter element of the list will overwrite the first one. 

+

81 

+

82 Args: 

+

83 filepaths (list): List with paths to the files 

+

84 save_path (str): Save path for the new file 

+

85 """ 

+

86 _all_flowsheets = {} 

+

87 # Merge to structure 

+

88 for fpath in filepaths: 

+

89 dataset = sdf.load(fpath) 

+

90 for flowsheet in dataset.groups: 

+

91 fluid_data = {fluid.name: fluid for fluid in flowsheet.groups} 

+

92 if flowsheet.name not in _all_flowsheets: 

+

93 _all_flowsheets.update({flowsheet.name: fluid_data}) 

+

94 else: 

+

95 _all_flowsheets[flowsheet.name].update(fluid_data) 

+

96 

+

97 # Write structure 

+

98 _all_groups = [] 

+

99 for flowsheet_name, fluid_dict in _all_flowsheets.items(): 

+

100 _all_fluids = [] 

+

101 for fluid, data in fluid_dict.items(): 

+

102 _all_fluids.append(data) 

+

103 flowsheet_group = sdf.Group(flowsheet_name, 

+

104 comment="Multiple fluids for the flowsheet", 

+

105 groups=_all_fluids) 

+

106 _all_groups.append(flowsheet_group) 

+

107 

+

108 parent_group = sdf.Group("/", comment="Generated with python script", groups=_all_groups) 

+

109 sdf.save(save_path, group=parent_group) 

+

110 return save_path 

+

111 

+

112 

+

113def sdf_to_csv(filepath: pathlib.Path, save_path: pathlib.Path): 

+

114 """ 

+

115 Convert a given .sdf file to multiple excel files, 

+

116 for each combination of flowsheet and refrigerant one file. 

+

117 

+

118 Args: 

+

119 filepath (pathlib.Path): sdf file 

+

120 save_path (pathlib.Path): Directory where to store the csv files. 

+

121 """ 

+

122 dataset = sdf.load(str(filepath)) 

+

123 for flowsheet in dataset.groups: 

+

124 for fluid in flowsheet.groups: 

+

125 dfs = [] 

+

126 for data in fluid.datasets: 

+

127 if _is_nd(data): 

+

128 dfs.append(_unpack_nd_data(data)) 

+

129 df = pd.concat(dfs, axis=1) 

+

130 df = df.loc[:, ~df.columns.duplicated()] 

+

131 df.to_csv(save_path.joinpath(f"{flowsheet.name}_{fluid.name}.csv")) 

+

132 

+

133 

+

134def _get_name(data): 

+

135 return f"{data.name} in {data.unit} ({data.comment})" 

+

136 

+

137 

+

138def _is_nd(data): 

+

139 if data.scales == [None]: 

+

140 return False 

+

141 return True 

+

142 

+

143 

+

144def _unpack_nd_data(data): 

+

145 column_name = _get_name(data) 

+

146 scale_names = [_get_name(scale) for scale in data.scales] 

+

147 scales_with_idx = [[(idx, value) for idx, value in enumerate(scale.data)] for scale in data.scales] 

+

148 all_data = [] 

+

149 for scales in itertools.product(*scales_with_idx): 

+

150 indexer = tuple([scale[0] for scale in scales]) 

+

151 values = [scale[1] for scale in scales] 

+

152 all_data.append({ 

+

153 column_name: data.data[indexer], 

+

154 **{name: value for name, value in zip(scale_names, values)} 

+

155 }) 

+

156 return pd.DataFrame(all_data) 

+

157 

+

158 

+

159if __name__ == '__main__': 

+

160 sdf_to_csv( 

+

161 filepath=pathlib.Path(r"D:\00_temp\calibration_jmo\Optihorst_3D_vclibpy.sdf"), 

+

162 save_path=pathlib.Path(r"D:\04_git\vclibpy\tests\regression_data") 

+

163 ) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_ten_coefficient_compressor_reqression_py.html b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_ten_coefficient_compressor_reqression_py.html new file mode 100644 index 0000000..3056a90 --- /dev/null +++ b/docs/0.1.1/coverage/d_57d6adb9ba5af1cf_ten_coefficient_compressor_reqression_py.html @@ -0,0 +1,278 @@ + + + + + Coverage for vclibpy/utils/ten_coefficient_compressor_reqression.py: 0% + + + + + +
+
+

+ Coverage for vclibpy/utils/ten_coefficient_compressor_reqression.py: + 0% +

+ +

+ 64 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from typing import List 

+

2import csv 

+

3import pandas as pd 

+

4 

+

5from vclibpy.components.compressors import TenCoefficientCompressor 

+

6from vclibpy import media, Inputs 

+

7 

+

8try: 

+

9 from sklearn.linear_model import LinearRegression 

+

10 from sklearn.preprocessing import PolynomialFeatures 

+

11 from xlsxwriter.workbook import Workbook 

+

12except ImportError as err: 

+

13 raise ImportError("You have to install xlsxwriter and " 

+

14 "sklearn to use this regression tool") 

+

15 

+

16 

+

17def create_regression_data( 

+

18 variables: List[str], 

+

19 T_con: List[float], T_eva: List[float], n: List[float], 

+

20 T_sh: float, T_sc: float, n_max: int, V_h: float, fluid: str, datasheet: str, 

+

21 capacity_definition: str, assumed_eta_mech: int, 

+

22 folder_path: str): 

+

23 """ 

+

24 Performs multidimensional linear regression to create compressor learning data. 

+

25 

+

26 Args: 

+

27 variables: (List[str]): 

+

28 Variable names to create regressions for. 

+

29 Options are: eta_s, lambda_h, and eta_mech 

+

30 T_con (List[float]): Condensing temperatures in K 

+

31 T_eva (List[float]): Evaporation temperatures in K 

+

32 n (List[float]): Compressor speeds from 0 to 1 

+

33 T_sh (float): Superheat temperature. 

+

34 T_sc (float): Subcooling temperature. 

+

35 n_max (int): Maximum compressor speed. 

+

36 V_h (float): Compressor volume. 

+

37 fluid (str): Type of refrigerant. 

+

38 datasheet (str): Path to the modified datasheet. 

+

39 capacity_definition (str): Definition of compressor capacity (e.g., "cooling"). 

+

40 assumed_eta_mech (int): Assumed mechanical efficiency. 

+

41 folder_path (str): Path to the folder where the newly created table will be saved. 

+

42 

+

43 Returns: 

+

44 List[float]: A list containing the regression parameters [P0, P1, ..., P9]. 

+

45 

+

46 Raises: 

+

47 ValueError: If any specified variable column is not present in the DataFrame. 

+

48 

+

49 Example: 

+

50 >>> create_regression_data(11.1, 8.3, 120, 20.9e-6, "PROPANE", "path/to/datasheet.xlsx", 

+

51 ... "cooling", 1, 6, 5, 5, 5, 303.15, 243.15, "path/to/save", 3) 

+

52 [intercept, P1, P2, P3, P4, P5, P6, P7, P8, P9] 

+

53 """ 

+

54 # create RefProp, fluid & compressor instance 

+

55 med_prop = media.CoolProp(fluid) 

+

56 

+

57 compressor = TenCoefficientCompressor( 

+

58 N_max=n_max, V_h=V_h, T_sc=T_sc, T_sh=T_sh, 

+

59 capacity_definition=capacity_definition, 

+

60 assumed_eta_mech=assumed_eta_mech, 

+

61 datasheet=datasheet 

+

62 ) 

+

63 

+

64 compressor.med_prop = med_prop 

+

65 keywords = { 

+

66 "eta_s": "Isentropic Efficiency(-)", 

+

67 "lambda_h": "Volumentric Efficiency(-)", 

+

68 "eta_mech": "Mechanical Efficiency(-)" 

+

69 } 

+

70 

+

71 tuples_for_cols = [("", "n")] 

+

72 for _variable in variables: 

+

73 for _n in n: 

+

74 tuples_for_cols.append((keywords[_variable], compressor.get_n_absolute(_n))) 

+

75 # tuples_for_cols: 

+

76 # eta_s eta_s eta_s lambda_h lambda_h lambda_h eta_mech ... 

+

77 # n 30 60 90 30 60 90 30 ... 

+

78 cols = pd.MultiIndex.from_tuples(tuples_for_cols) 

+

79 final_df = pd.DataFrame( 

+

80 data={cols[0]: ["P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10"]}, 

+

81 columns=cols 

+

82 ) 

+

83 # final_df: column names are tuples (tuples_for_cols). 

+

84 # First column is filled with P1, P2, ... 

+

85 

+

86 # for-loop for multiple types(eta_s, eta_mech, etc) 

+

87 for m, _variable in enumerate(variables): 

+

88 for k, _n in enumerate(n): # for-loop for multiple rotation speeds 

+

89 T_eva_list = [] 

+

90 T_con_list = [] 

+

91 result_list = [] 

+

92 # for-loop for multiple evaporating temperatures 

+

93 for i in range(len(T_eva)): 

+

94 # for-loop for multiple condensing temperatures 

+

95 for j in range(len(T_con)): 

+

96 if T_eva[i] < T_con[j]: 

+

97 p1 = med_prop.calc_state("TQ", T_eva[i], 1).p 

+

98 state_1 = med_prop.calc_state("PT", p1, (T_eva[i] + T_sh)) 

+

99 compressor.state_inlet = state_1 

+

100 p2 = med_prop.calc_state("TQ", T_con[j], 1).p 

+

101 # The enthalpy and entropy of the outlet 

+

102 # state do not matter, only the pressure: 

+

103 # TODO: Enable calculation of get_lambda_h etc. with p2 only 

+

104 state_2 = med_prop.calc_state("PS", p2, state_1.s) 

+

105 compressor.state_outlet = state_2 

+

106 T_eva_list.append(T_eva[i]) 

+

107 T_con_list.append(T_con[j]) 

+

108 inputs = Inputs(n=_n) 

+

109 

+

110 if _variable == "eta_s": 

+

111 result_list.append(compressor.get_eta_isentropic( 

+

112 p_outlet=p2, inputs=inputs) 

+

113 ) 

+

114 elif _variable == "lambda_h": 

+

115 result_list.append(compressor.get_lambda_h(inputs=inputs)) 

+

116 elif _variable == "eta_mech": 

+

117 result_list.append(compressor.get_eta_mech(inputs=inputs)) 

+

118 

+

119 df = pd.DataFrame( 

+

120 data={"T_eva": T_eva_list, 

+

121 "T_con": T_con_list, 

+

122 _variable: result_list} 

+

123 ) 

+

124 

+

125 final_df[cols[m * len(n) + k + 1]] = create_regression_parameters(df, _variable) 

+

126 

+

127 # dataframes with a double column header can't be saved as a 

+

128 # .xlsx yet, if index = False (NotImplementedError). 

+

129 # .xlsx format is necessary, because TenCoefficientCompressor.get_parameter() 

+

130 # expects a .xlsx as an input 

+

131 # --> workaround: save the dataframe as a .csv, read it again and save it as a .xlsx 

+

132 # TODO: Revert once this feature is in pandas. 

+

133 final_df.to_csv(folder_path + r"\regressions.csv", index=False) 

+

134 

+

135 workbook = Workbook(folder_path + r"\regressions.xlsx") 

+

136 worksheet = workbook.add_worksheet() 

+

137 with open(folder_path + r"\regressions.csv", 'rt', encoding='utf8') as f: 

+

138 reader = csv.reader(f) 

+

139 for r, row in enumerate(reader): 

+

140 for c, col in enumerate(row): 

+

141 worksheet.write(r, c, col) 

+

142 workbook.close() 

+

143 

+

144 

+

145def create_regression_parameters(df: pd.DataFrame, variable: str): 

+

146 """ 

+

147 Performs multidimensional linear regression to calculate 

+

148 ten coefficient regression parameters. 

+

149 

+

150 Args: 

+

151 df (pd.DataFrame): The input DataFrame containing the necessary columns. 

+

152 variable (str): The column name for the dependent variable. 

+

153 

+

154 Returns: 

+

155 List[float]: A list containing the ten regression parameters. 

+

156 

+

157 Raises: 

+

158 ValueError: If the specified variable column is not present in the DataFrame. 

+

159 

+

160 Example: 

+

161 >>> df = pd.DataFrame({'T_eva': [1, 2, 3], 'T_con': [4, 5, 6], 'X': [7, 8, 9]}) 

+

162 >>> create_regression_parameters(df, 'X') 

+

163 [intercept, P1, P2, P3, P4, P5, P6, P7, P8, P9] 

+

164 """ 

+

165 # extract the columns x, y und z 

+

166 x = df['T_eva'].values 

+

167 y = df['T_con'].values 

+

168 z = df[variable].values 

+

169 

+

170 # define the features (x, y, x^2, xy, y^2, x^3, x^2y, xy^2, y^3) 

+

171 features = PolynomialFeatures(degree=3, include_bias=False) 

+

172 X = features.fit_transform(pd.concat([pd.DataFrame(x), pd.DataFrame(y)], axis=1)) 

+

173 

+

174 # Execute the multidimensional linear regression 

+

175 model = LinearRegression().fit(X, z) 

+

176 

+

177 output = [model.intercept_, model.coef_[0], model.coef_[1], model.coef_[2], 

+

178 model.coef_[3], model.coef_[4], 

+

179 model.coef_[5], model.coef_[6], model.coef_[7], model.coef_[8]] 

+

180 # output = P1-P10 

+

181 return output 

+
+ + + diff --git a/docs/0.1.1/coverage/d_c048ebee450da2af___init___py.html b/docs/0.1.1/coverage/d_c048ebee450da2af___init___py.html new file mode 100644 index 0000000..1beed55 --- /dev/null +++ b/docs/0.1.1/coverage/d_c048ebee450da2af___init___py.html @@ -0,0 +1,136 @@ + + + + + Coverage for vclibpy/media/__init__.py: 90% + + + + + +
+
+

+ Coverage for vclibpy/media/__init__.py: + 90% +

+ +

+ 10 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from .states import ThermodynamicState, TransportProperties 

+

2from .media import get_two_phase_limits, MedProp 

+

3from .cool_prop import CoolProp 

+

4from .ref_prop import RefProp 

+

5 

+

6 

+

7__all__ = ['ThermodynamicState', 

+

8 'TransportProperties', 

+

9 'MedProp', 

+

10 'CoolProp', 

+

11 'RefProp'] 

+

12 

+

13USED_MED_PROP = (CoolProp, {}) 

+

14 

+

15 

+

16def set_global_media_properties(med_prop_class: object, **kwargs): 

+

17 """ 

+

18 Set the globally used MedProp class. 

+

19 

+

20 Args: 

+

21 med_prop_class (object): 

+

22 Available MedProp children class. 

+

23 kwargs (dict): 

+

24 Additional settings for the MedProp class, 

+

25 e.g. {"use_high_level_api": True} for CoolProp. 

+

26 """ 

+

27 global USED_MED_PROP 

+

28 USED_MED_PROP = (med_prop_class, kwargs) 

+

29 

+

30 

+

31def get_global_med_prop_and_kwargs(): 

+

32 """ 

+

33 Get the global MedProp class used 

+

34 for all calculations. 

+

35 Returns: 

+

36 MedProp: The class 

+

37 """ 

+

38 global USED_MED_PROP 

+

39 return USED_MED_PROP[0], USED_MED_PROP[1] 

+
+ + + diff --git a/docs/0.1.1/coverage/d_c048ebee450da2af_cool_prop_py.html b/docs/0.1.1/coverage/d_c048ebee450da2af_cool_prop_py.html new file mode 100644 index 0000000..c83653a --- /dev/null +++ b/docs/0.1.1/coverage/d_c048ebee450da2af_cool_prop_py.html @@ -0,0 +1,239 @@ + + + + + Coverage for vclibpy/media/cool_prop.py: 67% + + + + + +
+
+

+ Coverage for vclibpy/media/cool_prop.py: + 67% +

+ +

+ 57 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module with cool prop wrapper. 

+

3""" 

+

4import logging 

+

5 

+

6import CoolProp.CoolProp as CoolPropInternal 

+

7 

+

8from vclibpy.media.media import MedProp 

+

9from vclibpy.media.states import ThermodynamicState, TransportProperties 

+

10 

+

11logger = logging.getLogger(__name__) 

+

12 

+

13 

+

14class CoolProp(MedProp): 

+

15 """ 

+

16 Class using the open-source CoolProp package 

+

17 to access the properties. 

+

18 

+

19 Args: 

+

20 use_high_level_api (bool): 

+

21 True to use the high-level api, which is much slower, 

+

22 but you can use all modes in calc_state. 

+

23 Default is False. 

+

24 """ 

+

25 

+

26 _mode_map = { 

+

27 "PT": (CoolPropInternal.PT_INPUTS, True), 

+

28 "TQ": (CoolPropInternal.QT_INPUTS, False), 

+

29 "PS": (CoolPropInternal.PSmass_INPUTS, True), 

+

30 "PH": (CoolPropInternal.HmassP_INPUTS, False), 

+

31 "PQ": (CoolPropInternal.PQ_INPUTS, True) 

+

32 } 

+

33 

+

34 def __init__(self, fluid_name, use_high_level_api: bool = False): 

+

35 super().__init__(fluid_name=fluid_name) 

+

36 # Set molar mass and trigger a possible fluid-name error 

+

37 # if the fluid is not supported. 

+

38 self._helmholtz_equation_of_state = CoolPropInternal.AbstractState("HEOS", self.fluid_name) 

+

39 self.M = self._helmholtz_equation_of_state.molar_mass() 

+

40 self.use_high_level_api = use_high_level_api 

+

41 

+

42 def calc_state(self, mode: str, var1: float, var2: float): 

+

43 super().calc_state(mode=mode, var1=var1, var2=var2) 

+

44 

+

45 if self.use_high_level_api: 

+

46 _var1_str, _var2_str = mode[0], mode[1] 

+

47 # CoolProp returns Pa 

+

48 p = CoolPropInternal.PropsSI('P', _var1_str, var1, _var2_str, var2, self.fluid_name) 

+

49 # CoolProp returns kg/m^3 

+

50 d = CoolPropInternal.PropsSI('D', _var1_str, var1, _var2_str, var2, self.fluid_name) 

+

51 # CoolProp returns K 

+

52 T = CoolPropInternal.PropsSI('T', _var1_str, var1, _var2_str, var2, self.fluid_name) 

+

53 # CoolProp returns J/kg 

+

54 u = CoolPropInternal.PropsSI('U', _var1_str, var1, _var2_str, var2, self.fluid_name) 

+

55 # CoolProp returns J/kg 

+

56 h = CoolPropInternal.PropsSI('H', _var1_str, var1, _var2_str, var2, self.fluid_name) 

+

57 # CoolProp returns J/kg/K 

+

58 s = CoolPropInternal.PropsSI('S', _var1_str, var1, _var2_str, var2, self.fluid_name) 

+

59 # CoolProp returns mol/mol 

+

60 q = CoolPropInternal.PropsSI('Q', _var1_str, var1, _var2_str, var2, self.fluid_name) 

+

61 # Return new state 

+

62 return ThermodynamicState(p=p, T=T, u=u, h=h, s=s, d=d, q=q) 

+

63 

+

64 self._update_coolprop_heos(mode=mode, var1=var1, var2=var2) 

+

65 # Return new state 

+

66 return ThermodynamicState( 

+

67 p=self._helmholtz_equation_of_state.p(), 

+

68 T=self._helmholtz_equation_of_state.T(), 

+

69 u=self._helmholtz_equation_of_state.umass(), 

+

70 h=self._helmholtz_equation_of_state.hmass(), 

+

71 s=self._helmholtz_equation_of_state.smass(), 

+

72 d=self._helmholtz_equation_of_state.rhomass(), 

+

73 q=self._helmholtz_equation_of_state.Q() 

+

74 ) 

+

75 

+

76 def calc_transport_properties(self, state: ThermodynamicState): 

+

77 if 0 <= state.q <= 1: 

+

78 mode = "PQ" 

+

79 var1, var2 = state.p, state.q 

+

80 else: 

+

81 # Get using p and T 

+

82 mode = "PT" 

+

83 var1, var2 = state.p, state.T 

+

84 

+

85 if self.use_high_level_api: 

+

86 args = [mode[0], var1, mode[1], var2, self.fluid_name] 

+

87 # CoolProp returns - 

+

88 pr = CoolPropInternal.PropsSI('PRANDTL', *args) 

+

89 # CoolProp returns J/kg/K 

+

90 cp = CoolPropInternal.PropsSI('C', *args) 

+

91 # CoolProp returns J/kg/K 

+

92 cv = CoolPropInternal.PropsSI('CVMASS', *args) 

+

93 # CoolProp returns W/m/K 

+

94 lam = CoolPropInternal.PropsSI('CONDUCTIVITY', *args) 

+

95 # CoolProp returns Pa*s 

+

96 dyn_vis = CoolPropInternal.PropsSI('VISCOSITY', *args) 

+

97 # Internal calculation as kinematic vis is ration of dyn_vis to density 

+

98 # In m^2/s 

+

99 kin_vis = dyn_vis / state.d 

+

100 

+

101 # Create transport properties instance 

+

102 return TransportProperties(lam=lam, dyn_vis=dyn_vis, kin_vis=kin_vis, 

+

103 pr=pr, cp=cp, cv=cv, state=state) 

+

104 # Low-level API 

+

105 self._update_coolprop_heos(mode=mode, var1=var1, var2=var2) 

+

106 # Create transport properties instance 

+

107 return TransportProperties( 

+

108 lam=self._helmholtz_equation_of_state.conductivity(), 

+

109 dyn_vis=self._helmholtz_equation_of_state.viscosity(), 

+

110 kin_vis=self._helmholtz_equation_of_state.viscosity() / state.d, 

+

111 pr=self._helmholtz_equation_of_state.Prandtl(), 

+

112 cp=self._helmholtz_equation_of_state.cpmass(), 

+

113 cv=self._helmholtz_equation_of_state.cvmass(), 

+

114 state=state 

+

115 ) 

+

116 

+

117 def _update_coolprop_heos(self, mode, var1, var2): 

+

118 if mode not in self._mode_map: 

+

119 raise KeyError( 

+

120 f"Given mode '{mode}' is currently not supported with the " 

+

121 f"faster low-level API to cool-prop. " 

+

122 f"Either use the high-level API or raise an issue. " 

+

123 f"Supported modes: {', '.join(self._mode_map.keys())}" 

+

124 ) 

+

125 i_input, not_reverse_variables = self._mode_map[mode] 

+

126 if not_reverse_variables: 

+

127 self._helmholtz_equation_of_state.update(i_input, var1, var2) 

+

128 else: 

+

129 self._helmholtz_equation_of_state.update(i_input, var2, var1) 

+

130 

+

131 def get_critical_point(self): 

+

132 Tc = CoolPropInternal.PropsSI("TCRIT", self.fluid_name) 

+

133 pc = CoolPropInternal.PropsSI("PCRIT", self.fluid_name) 

+

134 dc = CoolPropInternal.PropsSI("RHOCRIT", self.fluid_name) 

+

135 return Tc, pc, dc 

+

136 

+

137 def get_molar_mass(self): 

+

138 return self.M 

+

139 

+

140 

+

141if __name__ == '__main__': 

+

142 CoolProp("Propan") 

+
+ + + diff --git a/docs/0.1.1/coverage/d_c048ebee450da2af_media_py.html b/docs/0.1.1/coverage/d_c048ebee450da2af_media_py.html new file mode 100644 index 0000000..1d9446b --- /dev/null +++ b/docs/0.1.1/coverage/d_c048ebee450da2af_media_py.html @@ -0,0 +1,333 @@ + + + + + Coverage for vclibpy/media/media.py: 85% + + + + + +
+
+

+ Coverage for vclibpy/media/media.py: + 85% +

+ +

+ 53 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1"""Module with wrappers to access and handle media property databases. 

+

2 

+

3This module provides interfaces to load media properties using various wrappers and 

+

4handle calculations related to media properties. 

+

5 

+

6Classes: 

+

7 MedProp: Base class for all media property interfaces. 

+

8 

+

9Functions: 

+

10 get_two_phase_limits: Return the states of the boundaries of the two-phase section for a given fluid. 

+

11 

+

12""" 

+

13import abc 

+

14import logging 

+

15import warnings 

+

16from typing import List 

+

17import numpy as np 

+

18 

+

19from vclibpy.media import ThermodynamicState, TransportProperties 

+

20 

+

21 

+

22logger = logging.getLogger(__name__) 

+

23 

+

24 

+

25class MedProp(abc.ABC): 

+

26 """Base class for all media property interfaces. 

+

27 

+

28 This class serves as the base for defining interfaces to access and compute media properties. 

+

29 

+

30 Methods: 

+

31 calc_state: Calculate the thermodynamic state based on mode and state variables. 

+

32 calc_transport_properties: Calculate transport properties for a given state. 

+

33 get_critical_point: Retrieve critical point information. 

+

34 get_molar_mass: Retrieve molar mass information. 

+

35 get_two_phase_limits: Retrieve the two-phase limits for plotting. 

+

36 calc_mean_transport_properties: Calculate the average transport properties for given states. 

+

37 """ 

+

38 _fluid_mapper = {} 

+

39 

+

40 def __init__(self, fluid_name): 

+

41 """Initialize the MedProp class instance. 

+

42 

+

43 Args: 

+

44 fluid_name (str): The name of the fluid. 

+

45 """ 

+

46 # Check if better internal names exist (e.g. air is modelled as air.ppf) 

+

47 self.fluid_name = self._fluid_mapper.get(fluid_name, fluid_name) 

+

48 self._two_phase_limits: dict = None 

+

49 

+

50 def calc_state(self, mode: str, var1: float, var2: float): 

+

51 """Calculate the thermodynamic state based on the specified mode and state variables. 

+

52 

+

53 This function calculates the thermodynamic state based on the chosen mode and provided state variables. 

+

54 The input state variables need to be in SI units. 

+

55 

+

56 Notes: 

+

57 - PT does not work when the state might fall within the two-phase region. 

+

58 - Only functions for density are implemented. In cases where you know the specific volume, use the density 

+

59 functions with the inverse value. 

+

60 - Quality (q) may have values outside the 'physical' scope: 

+

61 - q = -998: Subcooled liquid 

+

62 - q = 998: Superheated vapor 

+

63 - q = 999: Supercritical state 

+

64 

+

65 Possible modes include: 

+

66 - "PD": Pressure, Density 

+

67 - "PH": Pressure, Enthalpy 

+

68 - "PQ": Pressure, Quality 

+

69 - "PS": Pressure, Entropy 

+

70 - "PT": Pressure, Temperature 

+

71 - "PU": Pressure, Internal Energy 

+

72 - "TD": Temperature, Density 

+

73 - "TH": Temperature, Enthalpy 

+

74 - "TQ": Temperature, Quality 

+

75 - "TS": Temperature, Entropy 

+

76 - "TU": Temperature, Internal Energy 

+

77 - "DH": Density, Enthalpy 

+

78 - "DS": Density, Entropy 

+

79 - "DU": Density, Internal Energy 

+

80 

+

81 Args: 

+

82 mode (str): Defines the given input state variables (see possible modes above). 

+

83 var1 (float): Value of the first state variable (as specified in the mode) in SI units. 

+

84 var2 (float): Value of the second state variable (as specified in the mode) in SI units. 

+

85 

+

86 Returns: 

+

87 ThermodynamicState: A ThermodynamicState instance with state variables. 

+

88 

+

89 Raises: 

+

90 AssertionError: If the given mode is not within the available options. 

+

91 """ 

+

92 available_options = ['PD', 'PH', 'PQ', 'PS', 'PT', 

+

93 'PU', 'TD', 'TH', 'TQ', 'TS', 

+

94 'TU', 'DH', 'DS', 'DU', ] 

+

95 assert mode in available_options, f'Given mode {mode} is not in available options' 

+

96 

+

97 def terminate(self): 

+

98 """ 

+

99 Terminate the class. 

+

100 Default behaviour does nothing. 

+

101 """ 

+

102 pass 

+

103 

+

104 @abc.abstractmethod 

+

105 def calc_transport_properties(self, state: ThermodynamicState): 

+

106 """Calculate the transport properties for the given state. 

+

107 

+

108 Args: 

+

109 state (ThermodynamicState): The current thermodynamic state. 

+

110 

+

111 Returns: 

+

112 TransportProperties: An instance of TransportProperties. 

+

113 """ 

+

114 pass 

+

115 

+

116 @abc.abstractmethod 

+

117 def get_critical_point(self): 

+

118 """Retrieve critical point information for the fluid. 

+

119 

+

120 Returns: 

+

121 Tuple[float, float, float]: A tuple containing critical point information 

+

122 (Temperature Tc [K], Pressure pc [Pa], Density dc [kg/m^3]). 

+

123 """ 

+

124 pass 

+

125 

+

126 @abc.abstractmethod 

+

127 def get_molar_mass(self): 

+

128 """Retrieve the molar mass of the current fluid. 

+

129 

+

130 Returns: 

+

131 float: The molar mass M of the current fluid in kg/mol. 

+

132 """ 

+

133 pass 

+

134 

+

135 def get_two_phase_limits(self, quantity: str, p_min: int = 100000, p_step: int = 5000): 

+

136 """ 

+

137 Retrieve the two-phase limits for plotting a specified quantity. 

+

138 

+

139 This method returns the two-phase limits for a specified quantity (T, h, s, or p) in an array used for 

+

140 plotting purposes. It calculates the limits within the pressure range from p_min and quality (q) 0 to the 

+

141 critical pressure (pc), and then from the critical pressure to the pressure p_min and quality 1. 

+

142 

+

143 Args: 

+

144 quantity (str): The specified quantity (T, h, s, or p). 

+

145 p_min (int, optional): The minimum pressure value to start iteration. Default is 100000 Pa. 

+

146 p_step (int, optional): The step size for pressure variation. Default is 5000 Pa. 

+

147 

+

148 Returns: 

+

149 numpy.ndarray: An array containing the two-phase limits for the specified quantity. 

+

150 

+

151 Raises: 

+

152 ValueError: If the given quantity is not supported (T, h, s, or p). 

+

153 """ 

+

154 if self._two_phase_limits is not None: 

+

155 # Check existing two-phase limits 

+

156 p_min_old = self._two_phase_limits['p'][0] 

+

157 p_step_old = self._two_phase_limits['p'][1] - p_min_old 

+

158 if not np.isclose(p_min_old, p_min, 0, 10) or not np.isclose(p_step_old, p_step, 0, 10): 

+

159 warnings.warn(f"Overwriting previously calculated two-phase limits with " 

+

160 f"p_min={p_min_old} and p_step={p_step_old}. This might take a few seconds.\n" 

+

161 f"The quantity might not match with the previously calculated quantities.") 

+

162 self._two_phase_limits = None 

+

163 

+

164 if self._two_phase_limits is None: 

+

165 # Calculate new two-phase limits for plotting 

+

166 _two_phase_limits = get_two_phase_limits(self, p_step=p_step, p_min=p_min) 

+

167 self._two_phase_limits = { 

+

168 "T": np.array([state.T for state in _two_phase_limits]), 

+

169 "h": np.array([state.h for state in _two_phase_limits]), 

+

170 "s": np.array([state.s for state in _two_phase_limits]), 

+

171 "p": np.array([state.p for state in _two_phase_limits]), 

+

172 } 

+

173 

+

174 if quantity not in self._two_phase_limits: 

+

175 raise ValueError("The given quantity is not supported. T, h, s, or p are supported.") 

+

176 return self._two_phase_limits[quantity] 

+

177 

+

178 def calc_mean_transport_properties(self, state_in, state_out): 

+

179 """ 

+

180 Calculate the average transport properties for the given states. 

+

181 

+

182 Args: 

+

183 state_in (ThermodynamicState): First state 

+

184 state_out (ThermodynamicState): Second state 

+

185 

+

186 Returns: 

+

187 TransportProperties: Average transport properties 

+

188 

+

189 Notes: 

+

190 The TransportProperties does not contain a state, as an average 

+

191 state is not possible to calculate. 

+

192 """ 

+

193 tr_pr_in = self.calc_transport_properties(state_in) 

+

194 tr_pr_out = self.calc_transport_properties(state_out) 

+

195 

+

196 return TransportProperties( 

+

197 lam=0.5 * (tr_pr_in.lam + tr_pr_out.lam), 

+

198 dyn_vis=0.5 * (tr_pr_in.dyn_vis + tr_pr_out.dyn_vis), 

+

199 kin_vis=0.5 * (tr_pr_in.kin_vis + tr_pr_out.kin_vis), 

+

200 pr=0.5 * (tr_pr_in.Pr + tr_pr_out.Pr), 

+

201 cp=0.5 * (tr_pr_in.cp + tr_pr_out.cp), 

+

202 cv=0.5 * (tr_pr_in.cv + tr_pr_out.cv), 

+

203 state=None) 

+

204 

+

205 

+

206def get_two_phase_limits(med_prop: MedProp, p_step: int = 1000, p_min: int = int(1e3)) -> List[ThermodynamicState]: 

+

207 """ 

+

208 Return the states representing the boundaries of the two-phase section for the given fluid. 

+

209 

+

210 This function is primarily used for visualizing the two-phase section and validating the accuracy of calculations. 

+

211 

+

212 Args: 

+

213 med_prop (MedProp): An instance of a valid MedProp-Class. 

+

214 p_step (int): The step size for pressure variation in Pa. Default is 1000 Pa. 

+

215 p_min (int): The minimum pressure in Pa from where to start calculation. Default is 1000 Pa. 

+

216 

+

217 Returns: 

+

218 List[ThermodynamicState]: A list of ThermodynamicState instances representing the two-phase limits. 

+

219 

+

220 Notes: 

+

221 The two-phase limits are computed by iterating over a range of pressures from the minimum pressure up to the 

+

222 critical point pressure (exclusive) with a specified step size. States at quality 0 (saturated liquid) 

+

223 and quality 1 (saturated vapor) are appended to form the two-phase boundary. The list is reversed to 

+

224 maintain the correct order for visualization purposes. 

+

225 """ 

+

226 _, _p_max, _ = med_prop.get_critical_point() 

+

227 q0, q1 = [], [] 

+

228 for _p in range(p_min, int(_p_max), p_step): 

+

229 try: 

+

230 q0.append(med_prop.calc_state("PQ", _p, 0)) 

+

231 q1.append(med_prop.calc_state("PQ", _p, 1)) 

+

232 except ValueError as err: 

+

233 logger.info("Could not calculate two-phase limits for p=%s: %s", 

+

234 _p, err) 

+

235 # Reverse list for correct order 

+

236 return q0 + q1[::-1] 

+
+ + + diff --git a/docs/0.1.1/coverage/d_c048ebee450da2af_ref_prop_py.html b/docs/0.1.1/coverage/d_c048ebee450da2af_ref_prop_py.html new file mode 100644 index 0000000..24592c3 --- /dev/null +++ b/docs/0.1.1/coverage/d_c048ebee450da2af_ref_prop_py.html @@ -0,0 +1,1328 @@ + + + + + Coverage for vclibpy/media/ref_prop.py: 12% + + + + + +
+
+

+ Coverage for vclibpy/media/ref_prop.py: + 12% +

+ +

+ 429 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1# -*- coding: utf-8 -*- 

+

2""" 

+

3Created on 21.04.2020 

+

4 

+

5@author: Christoph Hoeges, Fabian Wuellhorst, Jona Brach 

+

6 

+

7To test: 

+

8- Transport properties are not fully tested (Status: 11.06.2020) 

+

9- Error raising is not implemented at all refprop calls 

+

10 - Additional change might be that not all errors and warning are excluded when 'use_error_check' is set to false but 

+

11 only warnings or errors? 

+

12""" 

+

13import logging 

+

14import os 

+

15import warnings 

+

16import shutil 

+

17import atexit 

+

18 

+

19from ctREFPROP.ctREFPROP import REFPROPFunctionLibrary 

+

20 

+

21from vclibpy.media import ThermodynamicState, TransportProperties, MedProp 

+

22 

+

23 

+

24logger = logging.getLogger(__name__) 

+

25 

+

26 

+

27class RefProp(MedProp): 

+

28 """ 

+

29 Class to connect to refProp package. 

+

30 

+

31 Args: 

+

32 :param string fluid_name: 

+

33 Fluid name for RefProp use 

+

34 :param list or None z: 

+

35 Fluid composition. Should only be used, when a self-design mixture shall be used. Further information 

+

36 see notes. 

+

37 When you want to use a self-design mixture to as follows: 

+

38 - Fluid-name needs to contain all component names within mixture: "R32.FLD|R125.FLD" 

+

39 - z needs to be a list with molar fractions: [0.697, 0.303] 

+

40 - Used example would be similar to R410A 

+

41 

+

42 :param string dll_path: 

+

43 Specifier for the dll path used for RefProp, 

+

44 e.g. dll_path='C:\\path_to_dll\\RefProp64.dll'. 

+

45 If None, the `ref_prop_path` and function `get_dll_path` are 

+

46 used to determine the dll path 

+

47 :param boolean use_error_check: 

+

48 Specifier whether errors and warnings shall be checked when calling RefProp or not 

+

49 :param boolean use_warnings: 

+

50 Specifier whether warnings shall be used 

+

51 :param str ref_prop_path: 

+

52 Path to RefProp package. Default is the ENV variable `RPPREFIX`. 

+

53 :param bool copy_dll: 

+

54 If True (not the default), a copy of the dll is created to enable simultaneous use of 

+

55 multiple fluids in multiprocessing. 

+

56 :param str copy_dll_directory: 

+

57 If `copy_dll` is True, the DLL is copied to this directory. 

+

58 If None (default), the current working directory is used. 

+

59 

+

60 Note: 

+

61 - You need to install package ctREFPROP Package 

+

62 https://github.com/usnistgov/REFPROP-wrappers/tree/master/wrappers/python 

+

63 - In case you use a self-defined mixture: Entropy reference state might deviate from GUI!! 

+

64 

+

65 Functionality: 

+

66 - It does not work to have multiple instances simultaneously. When calculating values the last fluid name 

+

67 somehow will be used even though instance includes "new" name. Need to be fixed at some point. 

+

68 

+

69 

+

70 How to use RefProp-Wrapper: 

+

71 --------------------------- 

+

72 1.) Create RefProp instance: rp = RefProp("R32") 

+

73 2.) In case you want to calculate fluid properties (state variables) for a specific state: Use calc_state() function 

+

74 Multiple inputs can be given (but you need to now two in order to define the values). For further 

+

75 information see function header. 

+

76 3.) Further get-Functions implemented 

+

77 - get_gwp(): Global warming potential 

+

78 - get_odp(): Ozone depletion potential 

+

79 - get_safety(): Safety class 

+

80 - get_mass_fraction(): Mass fractions of pure substances in fluid 

+

81 - get_molar_mass(): Molar mass of fluid 

+

82 - get_mol_fraction(): Mol fractions of pure substances in fluid 

+

83 - get_comp_names(): Pure substances names in fluid 

+

84 - get_longname(): Long name of fluid within RefProp 

+

85 - get_critical_point(): Crit. Temperature and Pressure 

+

86 - get_version(): Version of wrapper and of RefProp dll 

+

87 

+

88 

+

89 Version notes: 

+

90 -------------- 

+

91 0.1.0 (21.04.2020, Christoph Hoeges): 

+

92 First implementation 

+

93 - Contains multiple functions to call RefProp instance 

+

94 - Can calculate state, crit, GWP, ODP, Safety class, molar mass etc. of fluid 

+

95 - Mixtures might work but it wasn't fully testet - R455A e.g. still deviates slightly 

+

96 

+

97 0.1.1 (25.04.2020, Christoph Hoeges): 

+

98 Multiple changes, added functionality. Commands are still the same though 

+

99 - Self designed mixtures are possible now as well (see instructions in init 

+

100 - Added composition input to __init__ function 

+

101 - Added modes in calc_state function and removed bug in PH calculation 

+

102 - Additional protected functions due to different input 

+

103 - Adjusted _call_refprop function (z is not mass frac but mol fraction) 

+

104 - Added documentation / instruction 

+

105 

+

106 0.1.2 (08.05.2020, Christoph Hoeges): 

+

107 Multiple adjustments 

+

108 - Added function to call ABFLSHdll function in refprop (high level function) 

+

109 - Changed function calls in calc_state function to ABFLSH and adjusted conversion 

+

110 - Change init-function so user can choose which dll shall be used 

+

111 - Add function to get version of this current wrapper as well as RefProp-dll version 

+

112 

+

113 0.1.3 (12.05.2020, Christoph Hoeges): 

+

114 Multiple changes 

+

115 - Added function to get all files in MIXTURE and FLUIDS directory to check available fluids 

+

116 - Added error function in order to return errors when RefProp-Functions are called. 

+

117 NOTE: Not all instances where refprop is called are checked for errors. Currently, it is only used in 

+

118 init and calc_state 

+

119 

+

120 0.1.4 (19.05.2020, Christoph Hoeges): 

+

121 Multiple changes: 

+

122 - Debugged fluid properties calculation for predefined mixtures 

+

123 - Fixed option of self-defined mixtures 

+

124 

+

125 0.1.5 (22.05.2020, Christoph Hoeges): 

+

126 Include transport properties calculation into wrapper 

+

127 

+

128 0.1.6 (10.06.2020, Fabian Wuellhorst): 

+

129 Add option to use a custom dll path. This necessary to use multiple instances with possible 

+

130 different fluids at the same time. 

+

131 """ 

+

132 # General information 

+

133 # 

+

134 __version__ = "0.1.6" 

+

135 __author__ = "Christoph Hoeges" 

+

136 

+

137 _fluid_mapper = {'air': 'air.ppf'} 

+

138 

+

139 def __init__(self, 

+

140 fluid_name, 

+

141 z=None, 

+

142 dll_path: str = None, 

+

143 use_error_check: bool = True, 

+

144 use_warnings: bool = True, 

+

145 ref_prop_path: str = None, 

+

146 copy_dll: bool = True, 

+

147 copy_dll_directory: str = None 

+

148 ): 

+

149 if ref_prop_path is None: 

+

150 # Get environment variable for path to dll 

+

151 ref_prop_path = os.environ["RPPREFIX"] 

+

152 if dll_path is None: 

+

153 path_to_dll = self.get_dll_path(ref_prop_path) 

+

154 else: 

+

155 path_to_dll = dll_path 

+

156 

+

157 if copy_dll: 

+

158 if copy_dll_directory is None: 

+

159 copy_dll_directory = os.getcwd() 

+

160 try: 

+

161 self._delete_dll_path = os.path.join( 

+

162 copy_dll_directory, 

+

163 f"med_prop_{fluid_name}_REFPRP64.dll" 

+

164 ) 

+

165 shutil.copyfile(path_to_dll, self._delete_dll_path) 

+

166 atexit.register(self.terminate) 

+

167 path_to_dll = self._delete_dll_path 

+

168 except (PermissionError, FileExistsError) as err: 

+

169 logger.error("Can't copy file to new path: %s", err) 

+

170 else: 

+

171 self._delete_dll_path = None 

+

172 logger.info("Using dll: %s", path_to_dll) 

+

173 

+

174 super().__init__(fluid_name=fluid_name) 

+

175 

+

176 self._flag_check_errors = use_error_check 

+

177 self._flag_warnings = use_warnings 

+

178 # Set path to RefProp package 

+

179 self._ref_prop_path = ref_prop_path 

+

180 self.rp = REFPROPFunctionLibrary(path_to_dll) 

+

181 self.rp.SETPATHdll(ref_prop_path) 

+

182 self.molar_base_si = self.rp.GETENUMdll(0, "MOLAR BASE SI").iEnum 

+

183 # Set fluid name 

+

184 self.fluid_name = fluid_name 

+

185 # Get mass and mol fraction and number of components 

+

186 self._get_comp_frac(z) 

+

187 # Get component names 

+

188 self._comp_names = self._get_comp_names() 

+

189 # Mixture flag 

+

190 if self._n_comp > 1: 

+

191 self._mix_flag = True 

+

192 else: 

+

193 self._mix_flag = False 

+

194 

+

195 # Setup 

+

196 self._setup_rp() 

+

197 # Calculate molar mass in kg/mol 

+

198 # self.M = self._call_refprop_allprop("M").Output[0] 

+

199 self.M = self._call_refprop(inp_name="", out_name="M").Output[0] # kg/mol 

+

200 

+

201 self._nbp = None 

+

202 

+

203 def terminate(self): 

+

204 if self._delete_dll_path is not None: 

+

205 self._delete_dll() 

+

206 

+

207 def _delete_dll(self): 

+

208 try: 

+

209 # Taken from here: https://stackoverflow.com/questions/21770419/free-the-opened-ctypes-library-in-python 

+

210 import _ctypes 

+

211 import sys 

+

212 _handle = self.rp.dll._handle 

+

213 if sys.platform.startswith('win'): 

+

214 _ctypes.FreeLibrary(_handle) 

+

215 else: 

+

216 _ctypes.dlclose(_handle) 

+

217 os.remove(self._delete_dll_path) 

+

218 self._delete_dll_path = None 

+

219 except (FileNotFoundError, PermissionError) as err: 

+

220 logger.error( 

+

221 "Could not automatically delete the copied RefProp dll at %s. " 

+

222 "Delete it yourself! Error message: %s", self._delete_dll_path, err 

+

223 ) 

+

224 

+

225 def _call_refprop_abflsh(self, 

+

226 inp_name, 

+

227 value_a, 

+

228 value_b, 

+

229 i_flag=1): 

+

230 """ Call RefProp via ABFLSHdll method 

+

231 You can define multiple inputs but only "specific ones" where no input values are needed for 

+

232 e.g. M, Tcrit, pcrit 

+

233 

+

234 Parameters: 

+

235 ----------- 

+

236 :param string inp_name: 

+

237 Input commands: "PQ" 

+

238 :param float value_a: 

+

239 Value of parameter b defined in inp_name. In case of None 0 will be used. 

+

240 :param float value_b: 

+

241 Value of parameter b defined in inp_name. In case of None 0 will be used. 

+

242 :param int i_flag: 

+

243 Flag 

+

244 Return: 

+

245 ------- 

+

246 :return ABFLSHdlloutput tmp: 

+

247 Returns ABFLSH output 

+

248 

+

249 """ 

+

250 # TODO 

+

251 tmp = self.rp.ABFLSHdll(inp_name, value_a, value_b, self._mol_frac, i_flag) 

+

252 

+

253 return tmp 

+

254 

+

255 def _call_refprop_allprop(self, 

+

256 out_name, 

+

257 T_val=None, 

+

258 d_val=None, 

+

259 i_mass=0, 

+

260 i_flag=1): 

+

261 """ Call RefProp via ALLPROPSdll-method 

+

262 

+

263 Parameters: 

+

264 ----------- 

+

265 :param string out_name: 

+

266 Variables you want to calculate. Multiple outputs are possible: 

+

267 - Single: "M" 

+

268 - Multiple: "M,TC,PC" 

+

269 :param float T_val: 

+

270 Temperature in current state in K. 

+

271 Note: In case you want to get general fluid parameters such as M, Tcrit, .. Stick to default value! 

+

272 :param float d_val: 

+

273 Density in current state (unit depending on i_mass flag - either mol/m^3 or kg/m^3) 

+

274 Note: In case you want to get general fluid parameters such as M, Tcrit, .. Stick to default value! 

+

275 :param int i_mass: 

+

276 Specifies which units the inputs are given in. 

+

277 - 0: Molar based 

+

278 - 1: Mass based 

+

279 Note: In current version (10.0.0.72) Ian Bell says in multiple Git-Issues that you should stick to molar 

+

280 base! 

+

281 :param int i_flag: 

+

282 In current version (10.0.0.72) i_flag is used to define whether a string containing the units is written in 

+

283 'hUnits'. 

+

284 - 0: Deactivated (increases the calculation speed) 

+

285 - 1: activated 

+

286 Return: 

+

287 ------- 

+

288 :return ALLPROPSdlloutput result: 

+

289 List with values for parameters 

+

290 

+

291 """ 

+

292 # Check values of T and d 

+

293 if T_val is None: 

+

294 T_val = 0 

+

295 if d_val is None: 

+

296 d_val = 0 

+

297 # Define fraction used depending on i_mass flag 

+

298 if i_mass == 0: 

+

299 frac = self._mol_frac 

+

300 elif i_mass == 1: 

+

301 frac = self._mass_frac 

+

302 else: 

+

303 raise ValueError("Chosen i_mass flag '{}' is not possible in ALLPROPSdll function!".format(i_mass)) 

+

304 

+

305 # Call RefProp 

+

306 res = self.rp.ALLPROPSdll(out_name, self.molar_base_si, i_mass, i_flag, T_val, d_val, frac) 

+

307 

+

308 return res 

+

309 

+

310 def _call_refprop(self, 

+

311 inp_name, 

+

312 out_name, 

+

313 value_a=None, 

+

314 value_b=None, 

+

315 i_mass=0, 

+

316 i_flag=1, 

+

317 frac=None, 

+

318 fluid=None): 

+

319 """ Call general refProp function and calculate values 

+

320 

+

321 Parameters: 

+

322 ----------- 

+

323 :param string fluid: 

+

324 Fluid name - in case default value None is used, stored fluid name will be used for command 

+

325 :param string inp_name: 

+

326 Input parameter specification 

+

327 :param string out_name: 

+

328 Output string name 

+

329 :param float value_a: 

+

330 Value of parameter b defined in inp_name. In case of None 0 will be used. 

+

331 :param float value_b: 

+

332 Value of parameter b defined in inp_name. In case of None 0 will be used. 

+

333 :param integer i_flag: 

+

334 Defines further settings (see documentation) 

+

335 :param int i_mass: 

+

336 Specifies which units the inputs are given in. # TODO: WRONG! iMass determines composition, iUnits determines properties (except q) 

+

337 - 0: Molar based 

+

338 - 1: Mass based 

+

339 Note: In current version (10.0.0.72) Ian Bell says in multiple Git-Issues that you should stick to molar 

+

340 base! 

+

341 :param list frac: 

+

342 List with either mol or mass fraction of pure substances in current fluid 

+

343 (in case of single pure substance: [1]). 

+

344 

+

345 Return: 

+

346 ------- 

+

347 :return REFPROPdlloutput output: 

+

348 Command of refprop 

+

349 """ 

+

350 # Check inputs 

+

351 if value_a is None: 

+

352 value_a = 0 

+

353 if value_b is None: 

+

354 value_b = 0 

+

355 

+

356 if fluid is None: 

+

357 if self._predefined: 

+

358 fluid = self.fluid_name # TODO: in general not necessary, decreases performance 

+

359 else: 

+

360 fluid = "" 

+

361 if frac is None: 

+

362 if self._predefined: 

+

363 frac = "" 

+

364 else: 

+

365 if i_mass == 0: 

+

366 frac = self._mol_frac 

+

367 elif i_mass == 1: 

+

368 frac = self._mass_frac 

+

369 else: 

+

370 raise ValueError("Variable i_mass has invalid input '{}'".format(i_mass)) 

+

371 

+

372 # Call refprop function 

+

373 tmp = self.rp.REFPROPdll(fluid, 

+

374 inp_name, 

+

375 out_name, 

+

376 self.molar_base_si, 

+

377 i_mass, 

+

378 i_flag, 

+

379 value_a, 

+

380 value_b, 

+

381 frac) 

+

382 

+

383 return tmp 

+

384 

+

385 def _check_error(self, 

+

386 err_num, 

+

387 err_msg, 

+

388 func_name=""): 

+

389 """ Check error code and raise error in case it is critical 

+

390 

+

391 Parameters: 

+

392 ----------- 

+

393 :param integer err_num: 

+

394 Error return code 

+

395 :param string err_msg: 

+

396 Error message given in RefProp call 

+

397 :param string func_name: 

+

398 Name of function error needs to be checked in 

+

399 """ 

+

400 # All fine in case error number is 0 

+

401 # Throw warning in case error number different than 0 and smaller than 100 is given 

+

402 # Throw error in case error number higher than 100 is given 

+

403 if err_num: 

+

404 if err_num < 100: 

+

405 if self._flag_warnings: 

+

406 warnings.warn("[WARNING] Error number {} was given in function '{}'. No critical error but " 

+

407 "something went wrong maybe. \n Error message is: '{}'".format(str(err_num), 

+

408 func_name, err_msg)) 

+

409 else: 

+

410 if self._flag_check_errors: 

+

411 raise TypeError("[ERROR] When calling RefProp in function '{}' error number {} was " 

+

412 "returned. \n Error message is: '{}'".format(func_name, str(err_num), err_msg)) 

+

413 

+

414 def _get_comp_names(self): 

+

415 """ Get component names. In case current fluid is mixture, only component names will be returned. 

+

416 In case fluid is a pure substance, substance name is returned. 

+

417 

+

418 Return: 

+

419 ------- 

+

420 :return list comp_names: 

+

421 List with pure substances in current refrigerant 

+

422 """ 

+

423 comp_names = [] 

+

424 if self._predefined: 

+

425 # Note: While trying it was possible to get fluid name as well, therefore n_comp+1 is used. 

+

426 if self._n_comp > 1: 

+

427 for i in range(1, self._n_comp + 3): 

+

428 test = self.rp.NAMEdll(i) 

+

429 tmp = test.hn80.replace(".FLD", "") 

+

430 if not tmp == "": 

+

431 comp_names.append(tmp) 

+

432 else: 

+

433 for i in range(self._n_comp + 3): 

+

434 tmp = self.rp.NAMEdll(i).hnam 

+

435 if not tmp == "": 

+

436 comp_names.append(tmp) 

+

437 

+

438 else: 

+

439 # Self-defined 

+

440 tmp_str = self.fluid_name.split("|") 

+

441 for i in tmp_str: 

+

442 i = i.replace(".FLD", "") 

+

443 i = i.replace(".MIX", "") 

+

444 if len(i) < 2: 

+

445 continue 

+

446 else: 

+

447 comp_names.append(i) 

+

448 

+

449 # Replace Carbon Dioxide for CO2 

+

450 for i, tmp in enumerate(comp_names): 

+

451 if "Carbon dio" in tmp: 

+

452 comp_names[i] = "CO2" 

+

453 

+

454 return comp_names 

+

455 

+

456 def _get_comp_frac(self, z): 

+

457 """ Get mass/mol fraction and number of components of current fluid 

+

458 

+

459 Parameters: 

+

460 ----------- 

+

461 :param list z: 

+

462 Contains predefined molar fractions in case one is given. Otherwise, z will be None 

+

463 """ 

+

464 # Check if predefined or not 

+

465 # Predefined 

+

466 if z is None: 

+

467 self._predefined = True 

+

468 # Pure substance 

+

469 elif len(z) == 1: 

+

470 self._predefined = True 

+

471 # Self-designed mixture 

+

472 else: 

+

473 self._predefined = False 

+

474 

+

475 # In case predefined mixture or pure substance is used 

+

476 if self._predefined: 

+

477 # Dummy function to get values for z in order to specify number of components 

+

478 tmp_mol = self.rp.REFPROPdll(self.fluid_name, "PQ", "H", self.molar_base_si, 0, 0, 101325, 0, [1]) 

+

479 tmp_mass = self.rp.REFPROPdll(self.fluid_name, "PQ", "H", self.molar_base_si, 1, 0, 101325, 0, []) 

+

480 # Check for errors 

+

481 self._check_error(tmp_mol.ierr, tmp_mol.herr, self._get_comp_frac.__name__) 

+

482 self._check_error(tmp_mass.ierr, tmp_mass.herr, self._get_comp_frac.__name__) 

+

483 # Mass and molar fractions of components 

+

484 self._mol_frac = [zi for zi in tmp_mol.z if zi > 0] 

+

485 self._mass_frac = [zi for zi in tmp_mass.z if zi > 0] 

+

486 # Get number of components 

+

487 self._n_comp = len(self._mol_frac) 

+

488 # Check, whether error occurred 

+

489 if self._n_comp < 1: 

+

490 # It might be possible that z value bugs when calling RefProp. In case of a pure substance this does not 

+

491 # matter so an additional filter is included 

+

492 if len(self._mass_frac) == 1: 

+

493 self._n_comp = 1 

+

494 self._mol_frac = [1] 

+

495 else: 

+

496 raise ValueError("Number of components for current fluid '{}' is less than " 

+

497 "one!".format(self.fluid_name)) 

+

498 

+

499 # Get mol fraction 

+

500 # self._mol_frac = self._transform_to_molfraction(self._mass_frac) 

+

501 else: 

+

502 # Mol fraction 

+

503 self._mol_frac = z 

+

504 self._mass_frac = [] 

+

505 # Get number of components 

+

506 self._n_comp = len(self._mol_frac) 

+

507 

+

508 def _setup_rp(self): 

+

509 """ Setup for RefProp """ 

+

510 # Errors can occur in case REFPROP is initalizated multiple time with same fluid - thus a pre setup is used here 

+

511 self.rp.SETUPdll(1, "N2", "HMX.BNC", "DEF") 

+

512 # In case of pure substance 

+

513 if self._n_comp == 1: 

+

514 self.rp.SETUPdll(self._n_comp, self.fluid_name, "HMX.BNC", "DEF") 

+

515 # In case of mixtures 

+

516 else: 

+

517 # Check if mixture is predefined 

+

518 if self._predefined: 

+

519 # Pre defined mixture - different baseline operating point is used 

+

520 mode = 2 

+

521 mixture = "|".join([f+".FLD" for f in self._comp_names]) 

+

522 n_comp = self._n_comp 

+

523 else: 

+

524 # Self defined mixture 

+

525 mode = 1 

+

526 n_comp = self._n_comp 

+

527 # Define mixtures name 

+

528 # TODO: Ending is not necessary to create mixtures.... 

+

529 mixture = "|".join([f+".FLD" for f in self._comp_names]) 

+

530 

+

531 # Setup for mixture 

+

532 setup = self.rp.SETUPdll(n_comp, mixture, 'HMX.BNC', 'DEF') 

+

533 setref = self.rp.SETREFdll("DEF", mode, self._mol_frac, 0, 0, 0, 0) 

+

534 # z = self._mol_frac 

+

535 # Get mass fraction 

+

536 self._mass_frac = self._transform_to_massfraction(self._mol_frac) 

+

537 

+

538 # Check whether mixing rules are available 

+

539 if setup.ierr == 117: 

+

540 if self._flag_check_errors: 

+

541 raise ValueError( 

+

542 "[MIXING ERROR] Mixing rules for mixture '{}' do not exist!".format(self._comp_names)) 

+

543 else: 

+

544 print( 

+

545 "[MIXING ERROR] Mixing rules for mixture '{}' do not exist!".format(self._comp_names)) 

+

546 elif setup.ierr == -117: 

+

547 if self._flag_warnings: 

+

548 warnings.warn( 

+

549 "[MIXING ERROR] Mixing rules for mixture '{}' are estimated!".format(self._comp_names)) 

+

550 else: 

+

551 print( 

+

552 "[MIXING WARNING] Mixing rules for mixture '{}' are estimated!".format(self._comp_names)) 

+

553 

+

554 def _transform_to_massfraction(self, 

+

555 mol_frac): 

+

556 """ Transforms mol fraction to mass fraction 

+

557 

+

558 Parameters: 

+

559 ----------- 

+

560 :param list mol_frac: 

+

561 List containing floats for mol fraction 

+

562 

+

563 Return: 

+

564 ------- 

+

565 :return list mass_frac: 

+

566 List containing floats for mass fraction 

+

567 """ 

+

568 tmp = self.rp.XMASSdll(mol_frac) 

+

569 mass_frac = [yi for yi in tmp.xkg if yi > 0] 

+

570 return mass_frac 

+

571 

+

572 def _transform_to_molfraction(self, 

+

573 mass_frac): 

+

574 """ Transforms mass fraction to mol fraction 

+

575 

+

576 Parameters: 

+

577 ----------- 

+

578 :param list mass_frac: 

+

579 List containing floats for mass fraction 

+

580 

+

581 Return: 

+

582 ------- 

+

583 :return list frac: 

+

584 List containing floats for mol fraction 

+

585 """ 

+

586 tmp = self.rp.XMOLEdll(mass_frac) 

+

587 mol_frac = [xi for xi in tmp.xmol if xi > 0] 

+

588 return mol_frac 

+

589 

+

590 def calc_state(self, mode: str, var1: float, var2: float, kr=1): 

+

591 """ Calculate state. Depending on mode, different function will be chosen. Input state variables need to be in 

+

592 SI units! 

+

593 

+

594 Notes: 

+

595 ------ 

+

596 1.) PT does not work when state might be within the two-phase region! 

+

597 2.) Only functions for density are implemented. In case you know the specific volume instead use density 

+

598 functions with inverse value! 

+

599 3.) Quality can have values outside of 'physical' scope: 

+

600 q = -998: Subcooled liquid 

+

601 q = 998: Superheated vapor 

+

602 q = 999: Supercritical state 

+

603 

+

604 Possible modes are currently: 

+

605 - "PD": Pressure, Density 

+

606 - "PH": Pressure, Enthalpy 

+

607 - "PQ": Pressure, Quality 

+

608 - "PS": Pressure, Entropy 

+

609 - "PT": Pressure, Temperature 

+

610 - "PU": Pressure, Internal Energy 

+

611 - "TD": Temperature, Density 

+

612 - "TH": Temperature, Enthalpy 

+

613 - "TQ": Temperature, Quality 

+

614 - "TS": Temperature, Entropy 

+

615 - "TU": Temperature, Internal Energy 

+

616 - "DH": Density, Enthalpy 

+

617 - "DS": Density, Entropy 

+

618 - "DU": Density, Internal Energy 

+

619 - "HS": Enthalpy, Entropy 

+

620 

+

621 Parameters: 

+

622 ----------- 

+

623 :param string mode: 

+

624 Defines which input state variables are given (see possible modes above) 

+

625 :param float var1: 

+

626 Value of state variable 1 (first one in name) - use SI units! 

+

627 :param float var2: 

+

628 Value of state variable 2 (second one in name) - use SI units! 

+

629 :param int kr: 

+

630 phase flag (kr=1: lower density, kr=2: higher density) 

+

631 relevant for "TH", "TS", "TU" 

+

632 

+

633 Return: 

+

634 ------- 

+

635 :return ThermodynamicState state: 

+

636 Thermodynamic state with state variables 

+

637 """ 

+

638 # Multiplier for pressure since kPa is used in RefProp 

+

639 p_multi = 1e-3 

+

640 # Multiplier for energy 

+

641 e_multi = self.M 

+

642 # Multiplier for density 

+

643 d_multi = 1 / self.M / 1000 

+

644 

+

645 # Init all parameters 

+

646 p = None 

+

647 d = None 

+

648 T = None 

+

649 u = None 

+

650 h = None 

+

651 s = None 

+

652 q = None 

+

653 

+

654 # Check modi 

+

655 

+

656 # Pressure and density 

+

657 if mode == "PD": 

+

658 p = var1 

+

659 d = var2 

+

660 var1 = var1 * p_multi 

+

661 var2 = var2 * d_multi 

+

662 tmp = self.rp.PDFLSHdll(var1, var2, self._mol_frac) 

+

663 # Pressure and enthalpy 

+

664 elif mode == "PH": 

+

665 p = var1 

+

666 var1 = var1 * p_multi 

+

667 h = var2 

+

668 var2 = var2 * e_multi 

+

669 tmp = self.rp.PHFLSHdll(var1, var2, self._mol_frac) 

+

670 # Pressure and quality 

+

671 elif mode == "PQ": 

+

672 p = var1 

+

673 var1 = var1 * p_multi 

+

674 q = var2 

+

675 # In case current fluid is mixture you need to transform Q to molar base for RefProp-function 

+

676 if self._mix_flag: 

+

677 var2 = self._call_refprop("PQMASS", "QMOLE", p, q, i_mass=1).Output[0] 

+

678 tmp = self.rp.PQFLSHdll(var1, var2, self._mol_frac, 0) 

+

679 # Pressure and entropy 

+

680 elif mode == "PS": 

+

681 p = var1 

+

682 var1 = var1 * p_multi 

+

683 s = var2 

+

684 var2 = var2 * e_multi 

+

685 tmp = self.rp.PSFLSHdll(var1, var2, self._mol_frac) 

+

686 # Pressure and Temperature 

+

687 elif mode == "PT": 

+

688 p = var1 

+

689 var1 = var1 * p_multi 

+

690 T = var2 

+

691 tmp = self.rp.TPFLSHdll(var2, var1, self._mol_frac) 

+

692 # Pressure and internal energy 

+

693 elif mode == "PU": 

+

694 p = var1 

+

695 var1 = var1 * p_multi 

+

696 u = var2 

+

697 var2 = var2 * e_multi 

+

698 # mode = "PE" 

+

699 tmp = self.rp.PEFLSHdll(var1, var2, self._mol_frac) 

+

700 # Temperature and density 

+

701 elif mode == "TD": 

+

702 T = var1 

+

703 d = var2 

+

704 var2 = var2 * d_multi 

+

705 tmp = self.rp.TDFLSHdll(var1, var2, self._mol_frac) 

+

706 # Temperature and enthalpy 

+

707 elif mode == "TH": 

+

708 T = var1 

+

709 h = var2 

+

710 var2 = var2 * e_multi 

+

711 tmp = self.rp.THFLSHdll(T, var2, self._mol_frac, kr) 

+

712 # Temperature and quality 

+

713 elif mode == "TQ": 

+

714 T = var1 

+

715 q = var2 

+

716 # In case current fluid is mixture you need to transform Q to molar base for RefProp-function 

+

717 if self._mix_flag: 

+

718 var2 = self._call_refprop("TQMASS", "QMOLE", T, q, i_mass=1).Output[0] 

+

719 tmp = self.rp.TQFLSHdll(T, var2, self._mol_frac, 1) 

+

720 # Temperature and entropy 

+

721 elif mode == "TS": 

+

722 T = var1 

+

723 s = var2 

+

724 var2 = var2 * e_multi 

+

725 tmp = self.rp.TSFLSHdll(T, var2, self._mol_frac, kr) 

+

726 # Temperature and internal energy 

+

727 elif mode == "TU": 

+

728 T = var1 

+

729 u = var2 

+

730 var2 = var2 * e_multi 

+

731 # mode = "TE" 

+

732 tmp = self.rp.TEFLSHdll(T, var2, self._mol_frac, kr) 

+

733 # Density and enthalpy 

+

734 elif mode == "DH": 

+

735 d = var1 

+

736 var1 = var1 * d_multi 

+

737 h = var2 

+

738 var2 = var2 * e_multi 

+

739 tmp = self.rp.DHFLSHdll(var1, var2, self._mol_frac) 

+

740 # Density and entropy 

+

741 elif mode == "DS": 

+

742 d = var1 

+

743 var1 = var1 * d_multi 

+

744 s = var2 

+

745 var2 = var2 * e_multi 

+

746 tmp = self.rp.DSFLSHdll(var1, var2, self._mol_frac) 

+

747 # Density and inner energy 

+

748 elif mode == "DU": 

+

749 d = var1 

+

750 var1 = var1 * d_multi 

+

751 u = var2 

+

752 var2 = var2 * e_multi 

+

753 # mode = "DE" 

+

754 tmp = self.rp.DEFLSHdll(var1, var2, self._mol_frac) 

+

755 elif mode == "HS": 

+

756 h = var1 

+

757 var1 = var1 * e_multi 

+

758 s = var2 

+

759 var2 = var2 * e_multi 

+

760 tmp = self.rp.HSFLSHdll(var1, var2, self._mol_frac) 

+

761 else: 

+

762 raise ValueError("Chosen mode is not available in refprop calc_state function!") 

+

763 

+

764 # Check for errors 

+

765 self._check_error(tmp.ierr, tmp.herr, self.calc_state.__name__) 

+

766 

+

767 # Get all state variables 

+

768 if p is None: 

+

769 p = tmp.P / p_multi 

+

770 if T is None: 

+

771 T = tmp.T 

+

772 if u is None: 

+

773 u = tmp.e / e_multi 

+

774 if h is None: 

+

775 h = tmp.h / e_multi 

+

776 if s is None: 

+

777 s = tmp.s / e_multi 

+

778 if d is None: 

+

779 d = tmp.D / d_multi 

+

780 if q is None: 

+

781 if self._mix_flag: 

+

782 # Transform current q (molar) to mass based quality 

+

783 tmp2 = self._call_refprop("PH", "QMASS", p, h * e_multi, i_mass=1) 

+

784 if tmp2.Output[0] < 0: 

+

785 q_mass = tmp2.ierr 

+

786 else: 

+

787 q_mass = tmp2.Output[0] 

+

788 q = q_mass 

+

789 else: 

+

790 q = tmp.q 

+

791 

+

792 # # In case not in two phase region reset q to -1 

+

793 # if q > 1 or q < 0: 

+

794 # q = -1 

+

795 

+

796 # Define state 

+

797 state = ThermodynamicState(p=p, T=T, u=u, h=h, s=s, d=d, q=q) 

+

798 return state 

+

799 

+

800 def calc_satliq_state(self, s): 

+

801 """s in kJ/kgK""" 

+

802 s = s * self.M * 1000 # kJ/kgK -> J/molK 

+

803 tmp = self.rp.SATSdll(s=s, z="", kph=1) 

+

804 self._check_error(tmp.ierr, tmp.herr, self.calc_satliq_state.__name__) 

+

805 if tmp.k1 != 1: 

+

806 raise TypeError 

+

807 p = tmp.P1 * 1000 # kPa -> Pa 

+

808 d = tmp.D1 * self.M * 1000 # mol/l -> kg/mol 

+

809 return self.calc_state("PD", p, d) 

+

810 

+

811 def calc_transport_properties(self, state: ThermodynamicState): 

+

812 """ Calculate transport properties of RefProp fluid at given state 

+

813 

+

814 Parameters: 

+

815 ----------- 

+

816 :param ThermodynamicState state: 

+

817 Current thermodynamic state 

+

818 Return: 

+

819 ------- 

+

820 :return TransportProperties props: 

+

821 Instance of TransportProperties 

+

822 """ 

+

823 # Get properties 

+

824 tmp = self._call_refprop_allprop("PRANDTL,VIS,TCX,KV,CV,CP,BETA,STN,ACF", state.T, state.d / self.M, i_mass=0) 

+

825 # Create transport properties instance 

+

826 props = TransportProperties(lam=tmp.Output[2], 

+

827 dyn_vis=tmp.Output[1], 

+

828 kin_vis=tmp.Output[3], 

+

829 pr=tmp.Output[0], 

+

830 cp=tmp.Output[5] / self.M, 

+

831 cv=tmp.Output[4] / self.M, 

+

832 beta=tmp.Output[6], 

+

833 sur_ten=tmp.Output[7], 

+

834 ace_fac=tmp.Output[8], 

+

835 state=state) 

+

836 # Return props 

+

837 return props 

+

838 

+

839 def get_available_substances(self, 

+

840 mode="all", 

+

841 include_ending=False, 

+

842 save_txt=False): 

+

843 """ Get all available RefProp fluids (mixtures and / or pure substances depending on mode) 

+

844 

+

845 Parameters: 

+

846 ----------- 

+

847 :param string mode: 

+

848 Mode defining which kind of fluids you want to have: 'pure': pure substances, 'mix': mixtures, 'all': all 

+

849 :param boolean include_ending: 

+

850 Defines, whether file ending shall be returned as well or not 

+

851 :param boolean save_txt: 

+

852 Defines, whether a text file with names shall be created in current working directory 

+

853 Return: 

+

854 ------- 

+

855 :return list names: 

+

856 String list containing names of available fluids (depending on defined mode) 

+

857 """ 

+

858 # Possible endings 

+

859 _endings = ["MIX", "FLD", "PPF"] 

+

860 

+

861 # Folders where fluid data is located 

+

862 folders = [r"FLUIDS", r"MIXTURES"] 

+

863 

+

864 # Define paths by mode 

+

865 if mode == "pure": 

+

866 paths = [os.path.join(self._ref_prop_path, folders[0])] 

+

867 elif mode == "mix": 

+

868 paths = [os.path.join(self._ref_prop_path, folders[1])] 

+

869 elif mode == "all": 

+

870 paths = [os.path.join(self._ref_prop_path, folders[0]), 

+

871 os.path.join(self._ref_prop_path, folders[1])] 

+

872 else: 

+

873 raise ValueError("Chosen mode '{}' is not possible!".format(mode)) 

+

874 

+

875 # Get files in folders, remove ending and append to names 

+

876 names = [] 

+

877 for p in paths: 

+

878 # Get all files in directory 

+

879 files = [f for f in os.listdir(p) if os.path.isfile(os.path.join(p, f))] 

+

880 # Remove ending 

+

881 if include_ending: 

+

882 tmp = [path for path in files if path.split(".")[1] in _endings] 

+

883 else: 

+

884 tmp = [path.split(".")[0] for path in files if path.split(".")[1] in _endings] 

+

885 # Append names to names list 

+

886 names.extend(tmp) 

+

887 

+

888 # In case names shall be stored 

+

889 if save_txt: 

+

890 with open("available_fluids.txt", "w") as output: 

+

891 for i in names: 

+

892 output.write("{} \n".format(i)) 

+

893 

+

894 if not names: 

+

895 raise ValueError("No fluids are in current RefProp directory. Check path '{}'!".format(self._ref_prop_path)) 

+

896 

+

897 # Return names 

+

898 return names 

+

899 

+

900 def get_comp_names(self): 

+

901 """ Get name of components within current fluid" 

+

902 

+

903 Return: 

+

904 ------- 

+

905 :return list comp_names: 

+

906 String names of components within current fluid 

+

907 """ 

+

908 return self._comp_names 

+

909 

+

910 def get_nbp(self): 

+

911 """ Get normal boiling point (T @ q=0 and 1 bar) 

+

912 

+

913 Return: 

+

914 ------- 

+

915 :return float nbp: 

+

916 Normal boiling point of refrigerant in °C 

+

917 """ 

+

918 if not self._nbp: 

+

919 self._nbp = self.calc_state("PQ", 1e5, 0.0).T - 273.15 

+

920 

+

921 return self._nbp 

+

922 

+

923 def get_molar_composition(self, state: ThermodynamicState, z_molar=None): 

+

924 """ Get composition on molar base. Liquid phase, vapor phase and total. 

+

925 

+

926 :param ThermodynamicState state: the state whose compositions will be returned 

+

927 :param list z_molar: molar composition of fluid. In case of None, default value _mol_frac is used 

+

928 :return: 

+

929 - list x: 

+

930 composition of liquid phase 

+

931 - list y: 

+

932 composition of vapor phase 

+

933 - list z: 

+

934 composition in total 

+

935 """ 

+

936 if z_molar is None: 

+

937 z = self._mol_frac 

+

938 M = self.M 

+

939 else: 

+

940 z = z_molar 

+

941 M = self.rp.REFPROPdll(hFld="", 

+

942 hIn="", 

+

943 hOut="M", 

+

944 iUnits=self.molar_base_si, 

+

945 iMass=0, 

+

946 iFlag=1, 

+

947 a=0, 

+

948 b=0, 

+

949 z=z_molar).Output[0] 

+

950 num_components = len(z) 

+

951 

+

952 tmp = self.rp.TDFLSHdll(T=state.T, 

+

953 D=state.d / M / 1000, 

+

954 z=z) 

+

955 # TDFLSHdll is deprecated, use the following in future: 

+

956 # tmp = self.rp.ABFLSHdll(ab="TD", 

+

957 # a=state.T, 

+

958 # b=state.d / self.M / 1000, 

+

959 # z=self._mol_frac, 

+

960 # iFlag=0) # molar units 

+

961 

+

962 x = list(tmp.x[:num_components]) 

+

963 y = list(tmp.y[:num_components]) 

+

964 

+

965 return x, y, z 

+

966 

+

967 def get_critical_point(self): 

+

968 """ Get T and p of critical point 

+

969 

+

970 Return: 

+

971 ------- 

+

972 :return float Tc: 

+

973 Temperature at critical point in K 

+

974 :return float pc: 

+

975 Pressure at critical point in Pa 

+

976 :return float dc: 

+

977 Density at critical point in kg/m^3 

+

978 """ 

+

979 mode = 2 

+

980 if mode == 1: 

+

981 tmp = self._call_refprop("CRIT", "T,P,D", i_mass=1) 

+

982 Tc = tmp.Output[0] 

+

983 pc = tmp.Output[1] 

+

984 dc = tmp.Output[2] * self.M 

+

985 else: 

+

986 res = self._call_refprop_allprop("TC,PC,DC") 

+

987 Tc = res.Output[0] 

+

988 pc = res.Output[1] 

+

989 dc = res.Output[2] * self.M 

+

990 return Tc, pc, dc 

+

991 

+

992 # 

+

993 # 

+

994 def get_def_limits(self): 

+

995 """ Get limits of current ref prop fluid 

+

996 Limits contain Tmin, Tmax, Dmax and Pmax (Temperatures, density, pressure) 

+

997 

+

998 :return dict limits: 

+

999 Dictionary with definition limits in RefProp. Contains min/max temperature, max density, max pressure. 

+

1000 """ 

+

1001 tmp = self._call_refprop_allprop("TMIN,TMAX,DMAX,PMAX") 

+

1002 limits = {"Tmin": tmp.Output[0], 

+

1003 "Tmax": tmp.Output[1], 

+

1004 "Dmax": tmp.Output[2] * self.M, 

+

1005 "Pmax": tmp.Output[3]} 

+

1006 return limits 

+

1007 

+

1008 @staticmethod 

+

1009 def get_dll_path(ref_prop_path: str): 

+

1010 """ 

+

1011 Return the location of the dll 

+

1012 

+

1013 Return: 

+

1014 :return: string path_to_dll: 

+

1015 Path of a valid dll 

+

1016 """ 

+

1017 path_to_dll = os.path.join(ref_prop_path, r"REFPRP64.DLL") 

+

1018 

+

1019 # Check if dll actually exists: 

+

1020 if not os.path.exists(path_to_dll): 

+

1021 raise FileNotFoundError("Selected dll not found automatically. " 

+

1022 "Please alter the local attribute or search for yourself.") 

+

1023 

+

1024 return path_to_dll 

+

1025 

+

1026 def get_fluid_name(self): 

+

1027 """ Get fluid name. 

+

1028 

+

1029 Return: 

+

1030 ------- 

+

1031 :return string fluid_name: 

+

1032 Fluid name 

+

1033 """ 

+

1034 return self.fluid_name 

+

1035 

+

1036 def get_gwp(self): 

+

1037 """ Get gwp of current fluid from refProp 

+

1038 

+

1039 Return: 

+

1040 ------- 

+

1041 :return float gwp: 

+

1042 Global warming potential of fluid. In case calculation failed, None will be returned. 

+

1043 """ 

+

1044 # Call refProp 

+

1045 tmp = self._call_refprop("", 

+

1046 "GWP", 

+

1047 i_mass=1) 

+

1048 # Calculate gwp 

+

1049 gwp = round(sum(max(tmp.Output[i], 0) * self._mass_frac[i] for i in range(self._n_comp)), 2) 

+

1050 # In case GWP cannot be calculated 

+

1051 if gwp < 0: 

+

1052 gwp = 0 

+

1053 return gwp 

+

1054 

+

1055 def get_longname(self): 

+

1056 """ Get longname of fluid 

+

1057 

+

1058 Return: 

+

1059 ------- 

+

1060 :return string longname: 

+

1061 Name of current fluid in refprop - provides mass fractions and components as well (in case of mixture) 

+

1062 """ 

+

1063 longname = self._call_refprop("", "LONGNAME(0)").hUnits 

+

1064 return longname 

+

1065 

+

1066 def get_mass_fraction(self, use_round=True): 

+

1067 """ Get mass fractions of pure substances in current fluid 

+

1068 

+

1069 Parameters: 

+

1070 :param boolean use_round: 

+

1071 Flag to define, whether the exact values or rounded values (by the fourth number) shall be used 

+

1072 Return: 

+

1073 ------- 

+

1074 :return list mass_frac: 

+

1075 List of component mass fractions 

+

1076 """ 

+

1077 if use_round: 

+

1078 mass_frac = [round(i, 4) for i in self._mass_frac] 

+

1079 else: 

+

1080 mass_frac = self._mass_frac 

+

1081 return mass_frac 

+

1082 

+

1083 def get_molar_mass(self): 

+

1084 """ Get molar mass of current fluid 

+

1085 

+

1086 Return: 

+

1087 ------- 

+

1088 :return float M: 

+

1089 Molar mass of current fluid in kg/mol 

+

1090 """ 

+

1091 return self.M 

+

1092 

+

1093 def get_mol_fraction(self, use_round=True): 

+

1094 """ Get mol fractions of pure substances in current fluid 

+

1095 

+

1096 Parameters: 

+

1097 :param boolean use_round: 

+

1098 Flag to define, whether the exact values or rounded values (by the fourth number) shall be used 

+

1099 Return: 

+

1100 ------- 

+

1101 :return list frac: 

+

1102 List of component mol fractions 

+

1103 """ 

+

1104 if use_round: 

+

1105 mol_frac = [round(i, 4) for i in self._mol_frac] 

+

1106 else: 

+

1107 mol_frac = self._mol_frac 

+

1108 return mol_frac 

+

1109 

+

1110 def get_odp(self): 

+

1111 """ Calculate ozone depletion potential 

+

1112 In case of mixtures: Maximum value of pure substances will be used 

+

1113 

+

1114 Return: 

+

1115 ------- 

+

1116 :return float odp: 

+

1117 ODP of fluid. In case calculation failed, None will be returned. 

+

1118 """ 

+

1119 # Call refProp 

+

1120 tmp = self._call_refprop("", 

+

1121 "ODP", 

+

1122 i_mass=1) 

+

1123 # Calculate odp 

+

1124 odp = max(max(tmp.Output), 0) 

+

1125 # In case some error occured 

+

1126 if odp < 0: 

+

1127 odp = 0 

+

1128 return odp 

+

1129 

+

1130 def get_safety(self): 

+

1131 """ Calculate safety class of refrigerant 

+

1132 

+

1133 Return: 

+

1134 ------- 

+

1135 :return string safety: 

+

1136 Safety class of fluid. 

+

1137 """ 

+

1138 # Call refProp 

+

1139 tmp = self._call_refprop("", 

+

1140 "SAFETY", 

+

1141 i_mass=1) 

+

1142 # Get safety class 

+

1143 safety = tmp.hUnits 

+

1144 # Return safety 

+

1145 return safety 

+

1146 

+

1147 def get_sat_vap_pressure(self, T_sat): 

+

1148 """ Get pressure of saturated vapor for defined temperature 

+

1149 

+

1150 Note: 

+

1151 - works for vapor, liquid and solid 

+

1152 - returns equilibrium pressure at defined line (q=1) 

+

1153 

+

1154 Parameters: 

+

1155 :param float T_sat: 

+

1156 Temperature in K 

+

1157 Return: 

+

1158 :return float p_sat: 

+

1159 Vapor pressure in Pa 

+

1160 """ 

+

1161 trip = self.get_triple_point() 

+

1162 if trip[0] <= T_sat: 

+

1163 p_sat = self.calc_state("TQ", T_sat, 1.0).p 

+

1164 else: 

+

1165 tmp = self.rp.REFPROPdll("", "TSUBL", "P", self.molar_base_si, 0, 0, T_sat, 0.0, self._mol_frac) 

+

1166 p_sat = tmp.Output[0] 

+

1167 return p_sat 

+

1168 

+

1169 def get_triple_point(self): 

+

1170 """ Get temperature and pressure at triple point of current fluid 

+

1171 

+

1172 Note: Works fine for pure substances, mixtures might not work properly 

+

1173 

+

1174 Return: 

+

1175 :return float T_tpl: 

+

1176 Temperature at triple point in K 

+

1177 :return float p_tpl: 

+

1178 Pressure at triple point in Pa 

+

1179 """ 

+

1180 # Call Refprop 

+

1181 tmp = self._call_refprop("TRIP", "T;P") 

+

1182 return tmp.Output[0], tmp.Output[1] 

+

1183 

+

1184 def get_version(self): 

+

1185 """ Get version of wrapper and used RefProp dll 

+

1186 

+

1187 Return: 

+

1188 :return string wrapper_version: 

+

1189 Refprop wrapper version 

+

1190 :return string refprop_version: 

+

1191 Version of used RefProp dll 

+

1192 """ 

+

1193 return self.__version__, self.rp.RPVersion() 

+

1194 

+

1195 def is_mixture(self): 

+

1196 """ Find out if fluid is mixture or not. 

+

1197 In case current fluid is mixture, true is returned. 

+

1198 In case current fluid is pure substance, false is returned. 

+

1199 

+

1200 Return: 

+

1201 ------- 

+

1202 :return boolean _mix_flag: 

+

1203 Boolean for mixture (True), pure substance (False) 

+

1204 """ 

+

1205 return self._mix_flag 

+

1206 

+

1207 def set_error_flag(self, flag): 

+

1208 """ Set error flag 

+

1209 

+

1210 Parameters: 

+

1211 :param boolean flag: 

+

1212 New error flag 

+

1213 Return: 

+

1214 :return int err: 

+

1215 Notifier for error code - in case everything went fine, 0 is returned 

+

1216 """ 

+

1217 self._flag_check_errors = flag 

+

1218 return 0 

+

1219 

+

1220 def set_warning_flag(self, flag): 

+

1221 """ Set warning flag 

+

1222 

+

1223 Parameters: 

+

1224 :param boolean flag: 

+

1225 New warning flag 

+

1226 Return: 

+

1227 :return int err: 

+

1228 Notifier for error code - in case everything went fine, 0 is returned 

+

1229 """ 

+

1230 self._flag_warnings = flag 

+

1231 return 0 

+
+ + + diff --git a/docs/0.1.1/coverage/d_c048ebee450da2af_states_py.html b/docs/0.1.1/coverage/d_c048ebee450da2af_states_py.html new file mode 100644 index 0000000..b25d10b --- /dev/null +++ b/docs/0.1.1/coverage/d_c048ebee450da2af_states_py.html @@ -0,0 +1,279 @@ + + + + + Coverage for vclibpy/media/states.py: 92% + + + + + +
+
+

+ Coverage for vclibpy/media/states.py: + 92% +

+ +

+ 60 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module containing classes for thermodynamic state and transport properties. 

+

3""" 

+

4from vclibpy.datamodels import VariableContainer 

+

5 

+

6 

+

7__all__ = [ 

+

8 'ThermodynamicState', 

+

9 'TransportProperties', 

+

10] 

+

11 

+

12 

+

13class ThermodynamicState: 

+

14 """ 

+

15 Represents a thermodynamic state within a cycle. 

+

16 

+

17 Notes: 

+

18 Does not necessarily need to have all state variables defined! 

+

19 

+

20 Args: 

+

21 p (float): Pressure at the state in Pa. 

+

22 T (float): Temperature at the state in K. 

+

23 u (float): Inner energy at the state in J/kg. 

+

24 h (float): Enthalpy at the state in J/kg. 

+

25 s (float): Entropy at the state in J/(kg * K). 

+

26 v (float): Specific volume at the state in m^3/kg. 

+

27 q (float): Quality at the state (between 0 and 1). 

+

28 d (float): Density at the state in kg/m^3. 

+

29 

+

30 Methods: 

+

31 __init__: Initializes the state class. 

+

32 __str__: Provides a string representation of the state. 

+

33 get_pretty_print: Formats the state with names, units, and descriptions. 

+

34 """ 

+

35 

+

36 def __init__(self, 

+

37 p=None, 

+

38 T=None, 

+

39 u=None, 

+

40 h=None, 

+

41 s=None, 

+

42 v=None, 

+

43 q=None, 

+

44 d=None): 

+

45 """ 

+

46 Initializes a thermodynamic state. 

+

47 

+

48 Args: 

+

49 p (float): Pressure at the state in Pa. 

+

50 T (float): Temperature at the state in K. 

+

51 u (float): Inner energy at the state in J/kg. 

+

52 h (float): Enthalpy at the state in J/kg. 

+

53 s (float): Entropy at the state in J/(kg * K). 

+

54 v (float): Specific volume at the state in m^3/kg. 

+

55 q (float): Quality at the state (between 0 and 1). 

+

56 d (float): Density at the state in kg/m^3. 

+

57 

+

58 Notes: 

+

59 If only v or d is provided, the other attribute will be calculated. If both are given and they are similar, 

+

60 an error will be raised. 

+

61 """ 

+

62 self.p = p 

+

63 self.T = T 

+

64 self.u = u 

+

65 self.h = h 

+

66 self.s = s 

+

67 self.v = v 

+

68 self.q = q 

+

69 self.d = d 

+

70 # Define density 

+

71 if v and d: 

+

72 if not round(1/v, 4) == round(d, 4): 

+

73 raise ValueError("At current state d and v do not match", d, v) 

+

74 elif v: 

+

75 self.d = 1/v 

+

76 elif d: 

+

77 self.v = 1/d 

+

78 

+

79 def __str__(self): 

+

80 """ 

+

81 Returns a string representation of the state. 

+

82 """ 

+

83 return ";".join([f"{k}={v}" for k, v in self.__dict__.items()]) 

+

84 

+

85 def get_pretty_print(self): 

+

86 """ 

+

87 Provides a formatted representation of the state with names, units, and descriptions. 

+

88 """ 

+

89 _container = VariableContainer() 

+

90 _container.__class__.__name__ = self.__class__.__name__ 

+

91 _container.set(name="p", value=self.p, unit="Pa", description="Pressure") 

+

92 _container.set(name="T", value=self.T, unit="K", description="Temperature") 

+

93 _container.set(name="u", value=self.u, unit="J/kg", description="Inner energy") 

+

94 _container.set(name="h", value=self.h, unit="J/kg", description="Enthalpy") 

+

95 _container.set(name="s", value=self.s, unit="J/(kg*K)", description="Entropy") 

+

96 _container.set(name="v", value=self.v, unit="m^3/kg", description="Specific volume") 

+

97 _container.set(name="q", value=self.q, unit="-", description="Quality") 

+

98 _container.set(name="d", value=self.d, unit="kg/m^3", description="Density") 

+

99 return str(_container) 

+

100 

+

101 

+

102class TransportProperties: 

+

103 """ 

+

104 Represents transport properties at a specific thermodynamic state. 

+

105 

+

106 Args: 

+

107 lam (float): Thermal conductivity in W/(m*K). 

+

108 dyn_vis (float): Dynamic viscosity in Pa*s. 

+

109 kin_vis (float): Kinematic viscosity in m^2/s. 

+

110 Pr (float): Prandtl number. 

+

111 cp (float): Isobaric specific heat capacity in J/(kg*K). 

+

112 cv (float): Isochoric specific heat capacity in J/(kg*K). 

+

113 beta (float): Thermal expansion coefficient in 1/K. 

+

114 sur_ten (float): Surface tension in N/m. 

+

115 ace_fac (float): Acentric factor. 

+

116 state (ThermodynamicState): The state the transport properties belong to. 

+

117 

+

118 Methods: 

+

119 __init__: Initializes the transport properties class. 

+

120 __str__: Provides a string representation of the transport properties. 

+

121 get_pretty_print: Formats the properties with names, units, and descriptions. 

+

122 """ 

+

123 

+

124 def __init__(self, 

+

125 lam=None, 

+

126 dyn_vis=None, 

+

127 kin_vis=None, 

+

128 pr=None, 

+

129 cp=None, 

+

130 cv=None, 

+

131 beta=None, 

+

132 sur_ten=None, 

+

133 ace_fac=None, 

+

134 state=None): 

+

135 """ 

+

136 Initializes transport properties. 

+

137 

+

138 Args: 

+

139 lam (float): Thermal conductivity in W/(m*K). 

+

140 dyn_vis (float): Dynamic viscosity in Pa*s. 

+

141 kin_vis (float): Kinematic viscosity in m^2/s. 

+

142 pr (float): Prandtl number. 

+

143 cp (float): Isobaric specific heat capacity in J/(kg*K). 

+

144 cv (float): Isochoric specific heat capacity in J/(kg*K). 

+

145 beta (float): Thermal expansion coefficient in 1/K. 

+

146 sur_ten (float): Surface tension in N/m. 

+

147 ace_fac (float): Acentric factor. 

+

148 state (ThermodynamicState): The state the transport properties belong to. 

+

149 """ 

+

150 self.lam = lam 

+

151 self.dyn_vis = dyn_vis 

+

152 self.kin_vis = kin_vis 

+

153 self.Pr = pr 

+

154 self.cp = cp 

+

155 self.cv = cv 

+

156 self.beta = beta 

+

157 self.sur_ten = sur_ten 

+

158 self.ace_fac = ace_fac 

+

159 self.state = state 

+

160 

+

161 def __str__(self): 

+

162 """ 

+

163 Returns a string representation of the transport properties. 

+

164 """ 

+

165 return ";".join([f"{k}={v}" for k, v in self.__dict__.items()]) 

+

166 

+

167 def get_pretty_print(self): 

+

168 """ 

+

169 Provides a formatted representation of the properties with names, units, and descriptions. 

+

170 """ 

+

171 _container = VariableContainer() 

+

172 _container.__class__.__name__ = self.__class__.__name__ 

+

173 _container.set(name="lam", value=self.lam, unit="W/(m*K)", description="Thermal conductivity") 

+

174 _container.set(name="dyn_vis", value=self.dyn_vis, unit="Pa*s", description="Dynamic viscosity") 

+

175 _container.set(name="kin_vis", value=self.kin_vis, unit="m^2/s", description="Kinematic viscosity") 

+

176 _container.set(name="pr", value=self.Pr, unit="-", description="Prandtl number") 

+

177 _container.set(name="cp", value=self.cp, unit="J/(kg*K)", description="Isobaric specific heat capacity") 

+

178 _container.set(name="cv", value=self.cv, unit="J/(kg*K)", description="Isochoric specific heat capacity") 

+

179 _container.set(name="beta", value=self.beta, unit="1/K", description="Thermal expansion coefficient") 

+

180 _container.set(name="sur_ten", value=self.sur_ten, unit="N/m", description="Surface tension") 

+

181 _container.set(name="ace_fac", value=self.ace_fac, unit="-", description="Acentric factor") 

+

182 return str(_container) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_d45aa4312ad3649a___init___py.html b/docs/0.1.1/coverage/d_d45aa4312ad3649a___init___py.html new file mode 100644 index 0000000..e8d8636 --- /dev/null +++ b/docs/0.1.1/coverage/d_d45aa4312ad3649a___init___py.html @@ -0,0 +1,101 @@ + + + + + Coverage for vclibpy/components/compressors/__init__.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/compressors/__init__.py: + 100% +

+ +

+ 4 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from .compressor import Compressor 

+

2from .rotary import RotaryCompressor 

+

3from .ten_coefficient import TenCoefficientCompressor, DataSheetCompressor 

+

4from .constant_effectivness import ConstantEffectivenessCompressor 

+
+ + + diff --git a/docs/0.1.1/coverage/d_d45aa4312ad3649a_compressor_py.html b/docs/0.1.1/coverage/d_d45aa4312ad3649a_compressor_py.html new file mode 100644 index 0000000..112ba24 --- /dev/null +++ b/docs/0.1.1/coverage/d_d45aa4312ad3649a_compressor_py.html @@ -0,0 +1,270 @@ + + + + + Coverage for vclibpy/components/compressors/compressor.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/compressors/compressor.py: + 100% +

+ +

+ 35 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module for different compressor models 

+

3""" 

+

4 

+

5from vclibpy.components.component import BaseComponent 

+

6from vclibpy.datamodels import Inputs, FlowsheetState 

+

7 

+

8 

+

9class Compressor(BaseComponent): 

+

10 """ 

+

11 Base compressor class to be extended for specific compressor models. 

+

12 

+

13 Args: 

+

14 N_max (float): Maximal rotations per second of the compressor. 

+

15 V_h (float): Volume of the compressor in m^3. 

+

16 

+

17 Methods: 

+

18 get_lambda_h(inputs: Inputs) -> float: 

+

19 Get the volumetric efficiency. 

+

20 

+

21 get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float: 

+

22 Get the isentropic efficiency. 

+

23 

+

24 get_eta_mech(inputs: Inputs) -> float: 

+

25 Get the mechanical efficiency. 

+

26 

+

27 get_p_outlet() -> float: 

+

28 Get the outlet pressure. 

+

29 

+

30 get_n_absolute(n: float) -> float: 

+

31 Return the absolute compressor frequency based on the relative speed. 

+

32 

+

33 calc_state_outlet(p_outlet: float, inputs: Inputs, fs_state: FlowsheetState): 

+

34 Calculate the outlet state based on the high pressure level and provided inputs. 

+

35 

+

36 calc_m_flow(inputs: Inputs, fs_state: FlowsheetState) -> float: 

+

37 Calculate the refrigerant mass flow rate. 

+

38 

+

39 calc_electrical_power(inputs: Inputs, fs_state: FlowsheetState) -> float: 

+

40 Calculate the electrical power consumed by the compressor based on an adiabatic energy balance. 

+

41 """ 

+

42 

+

43 def __init__(self, N_max: float, V_h: float): 

+

44 """ 

+

45 Initialize the compressor. 

+

46 

+

47 Args: 

+

48 N_max (float): Maximal rotations per second of the compressor. 

+

49 V_h (float): Volume of the compressor in m^3. 

+

50 """ 

+

51 super().__init__() 

+

52 self.N_max = N_max 

+

53 self.V_h = V_h 

+

54 

+

55 def get_lambda_h(self, inputs: Inputs) -> float: 

+

56 """ 

+

57 Get the volumetric efficiency. 

+

58 

+

59 Args: 

+

60 inputs (Inputs): Inputs for the calculation. 

+

61 

+

62 Returns: 

+

63 float: Volumetric efficiency. 

+

64 """ 

+

65 raise NotImplementedError("Re-implement this function to use it") 

+

66 

+

67 def get_eta_isentropic(self, p_outlet: float, inputs: Inputs) -> float: 

+

68 """ 

+

69 Get the isentropic efficiency. 

+

70 

+

71 Args: 

+

72 p_outlet (float): High pressure value. 

+

73 inputs (Inputs): Inputs for the calculation. 

+

74 

+

75 Returns: 

+

76 float: Isentropic efficiency. 

+

77 """ 

+

78 raise NotImplementedError("Re-implement this function to use it") 

+

79 

+

80 def get_eta_mech(self, inputs: Inputs) -> float: 

+

81 """ 

+

82 Get the mechanical efficiency including motor and inverter efficiencies. 

+

83 

+

84 Args: 

+

85 inputs (Inputs): Inputs for the calculation. 

+

86 

+

87 Returns: 

+

88 float: Mechanical efficiency including motor and inverter efficiencies. 

+

89 """ 

+

90 raise NotImplementedError("Re-implement this function to use it") 

+

91 

+

92 def get_p_outlet(self) -> float: 

+

93 """ 

+

94 Get the outlet pressure. 

+

95 

+

96 Returns: 

+

97 float: Outlet pressure. 

+

98 """ 

+

99 assert self.state_outlet is not None, "You have to calculate the outlet state first." 

+

100 return self.state_outlet.p 

+

101 

+

102 def get_n_absolute(self, n: float) -> float: 

+

103 """ 

+

104 Return given relative n as absolute rounds/sec based on self.N_max. 

+

105 

+

106 Args: 

+

107 n (float): Relative compressor speed between 0 and 1. 

+

108 

+

109 Returns: 

+

110 float: Absolute compressor frequency in rounds/sec. 

+

111 """ 

+

112 return self.N_max * n 

+

113 

+

114 def calc_state_outlet(self, p_outlet: float, inputs: Inputs, fs_state: FlowsheetState): 

+

115 """ 

+

116 Calculate the output state based on the high pressure level and the provided inputs. 

+

117 The state is automatically set as the outlet state of this component. 

+

118 

+

119 Args: 

+

120 p_outlet (float): High pressure value. 

+

121 inputs (Inputs): Inputs for calculation. 

+

122 fs_state (FlowsheetState): Flowsheet state. 

+

123 """ 

+

124 state_outlet_isentropic = self.med_prop.calc_state("PS", p_outlet, self.state_inlet.s) 

+

125 eta_is = self.get_eta_isentropic(p_outlet=p_outlet, inputs=inputs) 

+

126 h_outlet = ( 

+

127 self.state_inlet.h + (state_outlet_isentropic.h - self.state_inlet.h) / 

+

128 eta_is 

+

129 ) 

+

130 fs_state.set(name="eta_is", value=eta_is, unit="%", description="Isentropic efficiency") 

+

131 self.state_outlet = self.med_prop.calc_state("PH", p_outlet, h_outlet) 

+

132 

+

133 def calc_m_flow(self, inputs: Inputs, fs_state: FlowsheetState) -> float: 

+

134 """ 

+

135 Calculate the refrigerant mass flow rate. 

+

136 

+

137 Args: 

+

138 inputs (Inputs): Inputs for the calculation. 

+

139 fs_state (FlowsheetState): Flowsheet state. 

+

140 

+

141 Returns: 

+

142 float: Refrigerant mass flow rate. 

+

143 """ 

+

144 lambda_h = self.get_lambda_h(inputs=inputs) 

+

145 V_flow_ref = ( 

+

146 lambda_h * 

+

147 self.V_h * 

+

148 self.get_n_absolute(inputs.n) 

+

149 ) 

+

150 self.m_flow = self.state_inlet.d * V_flow_ref 

+

151 fs_state.set(name="lambda_h", value=lambda_h, unit="%", description="Volumetric efficiency") 

+

152 fs_state.set(name="V_flow_ref", value=V_flow_ref, unit="m3/s", description="Refrigerant volume flow rate") 

+

153 fs_state.set(name="m_flow_ref", value=self.m_flow, unit="kg/s", description="Refrigerant mass flow rate") 

+

154 return self.m_flow 

+

155 

+

156 def calc_electrical_power(self, inputs: Inputs, fs_state: FlowsheetState) -> float: 

+

157 """ 

+

158 Calculate the electrical power consumed by the compressor based on an adiabatic energy balance. 

+

159 

+

160 Args: 

+

161 inputs (Inputs): Inputs for the calculation. 

+

162 fs_state (FlowsheetState): Flowsheet state. 

+

163 

+

164 Returns: 

+

165 float: Electrical power consumed. 

+

166 """ 

+

167 # Heat flow in the compressor 

+

168 P_t = self.m_flow * (self.state_outlet.h - self.state_inlet.h) 

+

169 # Electrical power consumed 

+

170 eta_mech = self.get_eta_mech(inputs=inputs) 

+

171 P_el = P_t / eta_mech 

+

172 fs_state.set(name="eta_mech", value=eta_mech, unit="-", description="Mechanical efficiency") 

+

173 return P_el 

+
+ + + diff --git a/docs/0.1.1/coverage/d_d45aa4312ad3649a_constant_effectivness_py.html b/docs/0.1.1/coverage/d_d45aa4312ad3649a_constant_effectivness_py.html new file mode 100644 index 0000000..814ffc8 --- /dev/null +++ b/docs/0.1.1/coverage/d_d45aa4312ad3649a_constant_effectivness_py.html @@ -0,0 +1,195 @@ + + + + + Coverage for vclibpy/components/compressors/constant_effectivness.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/compressors/constant_effectivness.py: + 100% +

+ +

+ 14 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from vclibpy.components.compressors.compressor import Compressor 

+

2from vclibpy.datamodels import Inputs 

+

3 

+

4 

+

5class ConstantEffectivenessCompressor(Compressor): 

+

6 """ 

+

7 Compressor model with constant efficiencies. 

+

8 

+

9 Inherits from the Compressor class, which defines the basic properties and behavior of a compressor in a vapor 

+

10 compression cycle. 

+

11 

+

12 Parameters: 

+

13 N_max (float): Maximal rotations per second of the compressor. 

+

14 V_h (float): Volume of the compressor in m^3. 

+

15 eta_isentropic (float): Constant isentropic efficiency of the compressor. 

+

16 eta_mech (float): Constant mechanical efficiency of the compressor. 

+

17 lambda_h (float): Constant volumetric efficiency. 

+

18 

+

19 Args: 

+

20 N_max (float): Maximal rotations per second of the compressor. 

+

21 V_h (float): Volume of the compressor in m^3. 

+

22 eta_isentropic (float): Constant isentropic efficiency of the compressor. 

+

23 eta_inverter (float): Constant inverter efficiency of the compressor. 

+

24 eta_motor (float): Constant motor efficiency of the compressor. 

+

25 eta_mech (float): Constant mechanical efficiency of the compressor including motor and inverter efficiencies. 

+

26 lambda_h (float): Constant volumetric efficiency. 

+

27 

+

28 Methods: 

+

29 get_lambda_h(inputs: Inputs) -> float: 

+

30 Returns the constant volumetric efficiency of the compressor. 

+

31 

+

32 get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float: 

+

33 Returns the constant isentropic efficiency of the compressor. 

+

34 

+

35 get_eta_mech(inputs: Inputs) -> float: 

+

36 Returns the constant mechanical efficiency including motor and inverter efficiencies. 

+

37 

+

38 """ 

+

39 

+

40 def __init__(self, 

+

41 N_max: float, V_h: float, 

+

42 eta_isentropic: float, 

+

43 eta_mech: float, 

+

44 lambda_h: float): 

+

45 """ 

+

46 Initialize the ConstantEffectivenessCompressor. 

+

47 

+

48 Args: 

+

49 N_max (float): Maximal rotations per second of the compressor. 

+

50 V_h (float): Volume of the compressor in m^3. 

+

51 eta_isentropic (float): Constant isentropic efficiency of the compressor. 

+

52 eta_inverter (float): Constant inverter efficiency of the compressor. 

+

53 eta_motor (float): Constant motor efficiency of the compressor. 

+

54 eta_mech (float): Constant mechanical efficiency of the compressor. 

+

55 lambda_h (float): Constant volumetric efficiency. 

+

56 """ 

+

57 super().__init__(N_max=N_max, V_h=V_h) 

+

58 self.eta_isentropic = eta_isentropic 

+

59 self.eta_mech = eta_mech 

+

60 self.lambda_h = lambda_h 

+

61 

+

62 def get_lambda_h(self, inputs: Inputs) -> float: 

+

63 """ 

+

64 Returns the constant volumetric efficiency of the compressor. 

+

65 

+

66 Args: 

+

67 inputs (Inputs): Input parameters for the calculation. 

+

68 

+

69 Returns: 

+

70 float: Constant volumetric efficiency. 

+

71 """ 

+

72 return self.lambda_h 

+

73 

+

74 def get_eta_isentropic(self, p_outlet: float, inputs: Inputs) -> float: 

+

75 """ 

+

76 Returns the constant isentropic efficiency of the compressor. 

+

77 

+

78 Args: 

+

79 p_outlet (float): High pressure value. 

+

80 inputs (Inputs): Input parameters for the calculation. 

+

81 

+

82 Returns: 

+

83 float: Constant isentropic efficiency. 

+

84 """ 

+

85 return self.eta_isentropic 

+

86 

+

87 def get_eta_mech(self, inputs: Inputs) -> float: 

+

88 """ 

+

89 Returns the product of the constant mechanical, motor, and inverter efficiencies 

+

90 as the effective mechanical efficiency of the compressor. 

+

91 

+

92 Args: 

+

93 inputs (Inputs): Input parameters for the calculation. 

+

94 

+

95 Returns: 

+

96 float: Effective mechanical efficiency. 

+

97 """ 

+

98 return self.eta_mech 

+
+ + + diff --git a/docs/0.1.1/coverage/d_d45aa4312ad3649a_rotary_py.html b/docs/0.1.1/coverage/d_d45aa4312ad3649a_rotary_py.html new file mode 100644 index 0000000..472776b --- /dev/null +++ b/docs/0.1.1/coverage/d_d45aa4312ad3649a_rotary_py.html @@ -0,0 +1,224 @@ + + + + + Coverage for vclibpy/components/compressors/rotary.py: 98% + + + + + +
+
+

+ Coverage for vclibpy/components/compressors/rotary.py: + 98% +

+ +

+ 49 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from vclibpy.components.compressors.compressor import Compressor 

+

2from vclibpy.datamodels import Inputs 

+

3 

+

4 

+

5class RotaryCompressor(Compressor): 

+

6 """ 

+

7 Compressor model based on the thesis of Mirko Engelpracht. 

+

8 

+

9 This compressor is characterized by using regressions provided by Mirko Engelpracht for a family of rotary 

+

10 compressors. The coefficients used in the regressions are sourced from his Master's thesis. 

+

11 

+

12 Parameters: 

+

13 N_max (float): Maximal rotations per second of the compressor. 

+

14 V_h (float): Volume of the compressor in m^3. 

+

15 

+

16 Methods: 

+

17 get_lambda_h(inputs: Inputs) -> float: 

+

18 Returns the volumetric efficiency based on the regressions of Mirko Engelpracht. 

+

19 

+

20 get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float: 

+

21 Returns the isentropic efficiency based on the regressions of Mirko Engelpracht. 

+

22 

+

23 get_eta_mech(inputs: Inputs) -> float: 

+

24 Returns the mechanical efficiency based on the regressions of Mirko Engelpracht. 

+

25 

+

26 """ 

+

27 

+

28 def get_lambda_h(self, inputs: Inputs) -> float: 

+

29 """ 

+

30 Returns the volumetric efficiency based on the regressions of Mirko Engelpracht. 

+

31 

+

32 Args: 

+

33 inputs (Inputs): Input parameters for the calculation. 

+

34 

+

35 Returns: 

+

36 float: Volumetric efficiency. 

+

37 """ 

+

38 p_outlet = self.get_p_outlet() 

+

39 # If not constant value is given, eta_is is calculated based on the regression of Mirko Engelpracht 

+

40 n = self.get_n_absolute(inputs.n) 

+

41 T_1 = self.state_inlet.T 

+

42 

+

43 a_1 = 0.80179 

+

44 a_2 = -0.05210 

+

45 sigma_pi = 1.63495 

+

46 pi_ave = 4.54069 

+

47 a_3 = 3.21616e-4 

+

48 sigma_T_1 = 8.43797 

+

49 T_1_ave = 263.86428 

+

50 a_4 = -0.00494 

+

51 a_5 = 0.04981 

+

52 sigma_n = 20.81378 

+

53 n_ave = 64.41071 

+

54 a_6 = -0.02190 

+

55 

+

56 pi = p_outlet / self.state_inlet.p 

+

57 return ( 

+

58 a_1 + 

+

59 a_2 * (pi - pi_ave) / sigma_pi + 

+

60 a_3 * (T_1 - T_1_ave) / sigma_T_1 * (pi - pi_ave) / sigma_pi + 

+

61 a_4 * (T_1 - T_1_ave) / sigma_T_1 + 

+

62 a_5 * (n - n_ave) / sigma_n + 

+

63 a_6 * ((n - n_ave) / sigma_n) ** 2 

+

64 ) 

+

65 

+

66 def get_eta_isentropic(self, p_outlet: float, inputs: Inputs) -> float: 

+

67 """ 

+

68 Returns the isentropic efficiency based on the regressions of Mirko Engelpracht. 

+

69 

+

70 Args: 

+

71 p_outlet (float): High pressure value. 

+

72 inputs (Inputs): Input parameters for the calculation. 

+

73 

+

74 Returns: 

+

75 float: Isentropic efficiency. 

+

76 """ 

+

77 # If not constant value is given, eta_is is calculated based on the regression of Mirko Engelpracht 

+

78 n = self.get_n_absolute(inputs.n) 

+

79 

+

80 a_1 = 0.5816 

+

81 a_2 = 0.002604 

+

82 a_3 = -1.515e-7 

+

83 a_4 = -0.00473 

+

84 pi = p_outlet / self.state_inlet.p 

+

85 eta = ( 

+

86 a_1 + 

+

87 a_2 * n + 

+

88 a_3 * n ** 3 + 

+

89 a_4 * pi ** 2 

+

90 ) 

+

91 if eta <= 0: 

+

92 raise ValueError("Efficiency is lower or equal to 0") 

+

93 return eta 

+

94 

+

95 def get_eta_mech(self, inputs: Inputs) -> float: 

+

96 """ 

+

97 Returns the mechanical efficiency based on the regressions of Mirko Engelpracht. 

+

98 

+

99 Args: 

+

100 inputs (Inputs): Input parameters for the calculation. 

+

101 

+

102 Returns: 

+

103 float: Mechanical efficiency. 

+

104 """ 

+

105 p_outlet = self.get_p_outlet() 

+

106 n = self.get_n_absolute(inputs.n) 

+

107 # If not constant value is given, eta_is is calculated based on the regression of Mirko Engelpracht 

+

108 a_00 = 0.2199 

+

109 a_10 = -0.0193 

+

110 a_01 = 0.02503 

+

111 a_11 = 8.817e-5 

+

112 a_20 = -0.001345 

+

113 a_02 = -0.0003382 

+

114 a_21 = 1.584e-5 

+

115 a_12 = -1.083e-6 

+

116 a_22 = -5.321e-8 

+

117 a_03 = 1.976e-6 

+

118 a_13 = 4.053e-9 

+

119 a_04 = -4.292e-9 

+

120 pi = p_outlet / self.state_inlet.p 

+

121 return ( 

+

122 a_00 + 

+

123 a_10 * pi + a_01 * n + a_11 * pi * n + 

+

124 a_20 * pi ** 2 + a_02 * n ** 2 + a_21 * pi ** 2 * n + a_12 * pi * n ** 2 + a_22 * pi ** 2 * n ** 2 + 

+

125 a_03 * n ** 3 + a_13 * pi * n ** 3 + 

+

126 a_04 * n ** 4 

+

127 ) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_d45aa4312ad3649a_ten_coefficient_py.html b/docs/0.1.1/coverage/d_d45aa4312ad3649a_ten_coefficient_py.html new file mode 100644 index 0000000..4043673 --- /dev/null +++ b/docs/0.1.1/coverage/d_d45aa4312ad3649a_ten_coefficient_py.html @@ -0,0 +1,464 @@ + + + + + Coverage for vclibpy/components/compressors/ten_coefficient.py: 22% + + + + + +
+
+

+ Coverage for vclibpy/components/compressors/ten_coefficient.py: + 22% +

+ +

+ 95 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import warnings 

+

2from abc import ABC 

+

3import numpy as np 

+

4import pandas as pd 

+

5 

+

6from vclibpy.components.compressors.compressor import Compressor 

+

7from vclibpy.datamodels import Inputs 

+

8 

+

9 

+

10def calc_ten_coefficients(T_eva, T_con, coef_list): 

+

11 """ 

+

12 Calculate the result using the ten-coefficient method. 

+

13 

+

14 Args: 

+

15 T_eva (float): Evaporator temperature in Celsius. 

+

16 T_con (float): Condenser temperature in Celsius. 

+

17 coef_list (list): List of coefficients. 

+

18 

+

19 Returns: 

+

20 float: Result of the calculation. 

+

21 """ 

+

22 # Formula for the ten-coefficient method according to the datasheet 

+

23 z = coef_list[0] + coef_list[1] * T_eva + coef_list[2] * T_con + coef_list[3] * T_eva ** 2 + \ 

+

24 coef_list[4] * T_eva * T_con + coef_list[5] * T_con ** 2 + coef_list[6] * T_eva ** 3 + \ 

+

25 coef_list[7] * T_eva ** 2 * T_con + coef_list[8] * T_con ** 2 * T_eva + coef_list[9] * T_con ** 3 

+

26 return z 

+

27 

+

28 

+

29class BaseTenCoefficientCompressor(Compressor, ABC): 

+

30 """ 

+

31 Base class for compressors using the ten-coefficient method. 

+

32 

+

33 Used table has to be in this format 

+

34 (order of the columns is not important). 

+

35 The values must be the same as in the example tabel. 

+

36 The column names can be different but must 

+

37 then be matched with argument parameter_names. 

+

38 (All typed in numbers are fictional placeholders) 

+

39 

+

40 Capacity(W) Input Power(W) Flow Rate(kg/h) Capacity(W) ... Flow Rate(kg/h) 

+

41 n n1 n1 n1 n2 ... n_last 

+

42 P1 42 12 243 32 ... 412 

+

43 ... ... ... ... ... ... ... 

+

44 P10 10 23 21 41 ... 2434 

+

45 

+

46 Args: 

+

47 N_max (float): Maximal rotations per second of the compressor. 

+

48 V_h (float): Volume of the compressor in m^3. 

+

49 datasheet (str): Path of the datasheet file. 

+

50 **kwargs: 

+

51 parameter_names (dict, optional): 

+

52 Dictionary to match internal parameter names (keys) to the names used in the table values. 

+

53 Default 

+

54 { 

+

55 "m_flow": "Flow Rate(kg/h)", 

+

56 "capacity": "Capacity(W)", 

+

57 "input_power": "Input Power(W)", 

+

58 "eta_s": "Isentropic Efficiency(-)", 

+

59 "lambda_h": "Volumentric Efficiency(-)", 

+

60 "eta_mech": "Mechanical Efficiency(-)" 

+

61 } 

+

62 sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None. 

+

63 """ 

+

64 

+

65 def __init__(self, N_max, V_h, datasheet, **kwargs): 

+

66 """ 

+

67 Initialize the BaseTenCoefficientCompressor. 

+

68 

+

69 Args: 

+

70 N_max (float): Maximal rotations per second of the compressor. 

+

71 V_h (float): Volume of the compressor in m^3. 

+

72 datasheet (str): Path of the datasheet file. 

+

73 parameter_names (dict, optional): Dictionary of parameter names. Defaults to None. 

+

74 sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None. 

+

75 """ 

+

76 

+

77 super().__init__(N_max, V_h) 

+

78 sheet_name = kwargs.get('sheet_name', None) 

+

79 self.md = pd.read_excel(datasheet, sheet_name=sheet_name) 

+

80 parameter_names = kwargs.get('parameter_names', None) 

+

81 if parameter_names is None: 

+

82 self.parameter_names = { 

+

83 "m_flow": "Flow Rate(kg/h)", 

+

84 "capacity": "Capacity(W)", 

+

85 "input_power": "Input Power(W)", 

+

86 "eta_s": "Isentropic Efficiency(-)", 

+

87 "lambda_h": "Volumentric Efficiency(-)", 

+

88 "eta_mech": "Mechanical Efficiency(-)" 

+

89 } 

+

90 else: 

+

91 self.parameter_names = parameter_names 

+

92 

+

93 def get_parameter(self, T_eva, T_con, n, type_): 

+

94 """ 

+

95 Get a parameter based on temperatures, rotations, and parameter type from the datasheet. 

+

96 

+

97 Args: 

+

98 T_eva (float): Evaporator temperature in Celsius. 

+

99 T_con (float): Condenser temperature in Celsius. 

+

100 n (float): Rotations per second. 

+

101 type_ (str): Parameter type in parameter_names. 

+

102 

+

103 Returns: 

+

104 float: Interpolated parameter value. 

+

105 """ 

+

106 param_list = [] 

+

107 n_list = [] 

+

108 

+

109 sampling_points = sum( 

+

110 self.parameter_names[type_] in s for s in list(self.md.columns.values)) # counts number of sampling points 

+

111 

+

112 for i in range(sampling_points): 

+

113 if i == 0: 

+

114 coefficients = self.md[self.parameter_names[type_]].tolist() 

+

115 else: 

+

116 coefficients = self.md[str(self.parameter_names[type_] + "." + str(i))].tolist() 

+

117 n_list.append(coefficients.pop(0)) 

+

118 param_list.append(calc_ten_coefficients(T_eva, T_con, coefficients)) 

+

119 

+

120 return np.interp(self.get_n_absolute(n), n_list, param_list) # linear interpolation 

+

121 

+

122 

+

123class TenCoefficientCompressor(BaseTenCoefficientCompressor): 

+

124 """ 

+

125 Compressor based on the ten coefficient method. 

+

126 

+

127 Used table has to be in this format 

+

128 (order of the columns is not important). 

+

129 The values must be the same as in the example tabel. 

+

130 The column names can be different but must 

+

131 then be matched with the keyword argument parameter_names. 

+

132 (All typed in numbers are fictional placeholders) 

+

133 

+

134 Capacity(W) Input Power(W) Flow Rate(kg/h) Capacity(W) ... Flow Rate(kg/h) 

+

135 n n1 n1 n1 n2 ... n_last 

+

136 P1 42 12 243 32 ... 412 

+

137 ... ... ... ... ... ... ... 

+

138 P10 10 23 21 41 ... 2434 

+

139 

+

140 T_sh and T_sc have to be set according to the data sheet of your compressor. capacity_definition defines the 

+

141 parameter "capacity" in the datasheet. If capacity is the specific cooling capacity (h1-h4), set it on "cooling". 

+

142 If capacity is the specific heating capacity (h2-h3), set it on "heating". 

+

143 In the case of cooling capacity, the mechanical efficiency of the compressor has to be assumed (assumed_eta_mech) 

+

144 as h2 can't be calculated otherwise. Summary: 

+

145 - For the case heating capacity: h2 = h3 + capacity / m_flow 

+

146 - For the case cooling capacity: h2 = h3 + (capacity + p_el * assumed_eta_mech) / m_flow 

+

147 

+

148 Args: 

+

149 N_max (float): Maximal rotations per second of the compressor. 

+

150 V_h (float): Volume of the compressor in m^3. 

+

151 T_sc (float): Subcooling according to datasheet in K. 

+

152 T_sh (float): Superheating according to datasheet in K. 

+

153 capacity_definition (str): Definition of "capacity" in the datasheet. "cooling" or "heating". 

+

154 assumed_eta_mech (float): Assumed mechanical efficiency of the compressor (only needed if cooling). 

+

155 datasheet (str): Path of the modified datasheet. 

+

156 **kwargs: 

+

157 parameter_names (dict, optional): 

+

158 Dictionary to match internal parameter names (keys) to the names used in the table values. 

+

159 Default 

+

160 { 

+

161 "m_flow": "Flow Rate(kg/h)", 

+

162 "capacity": "Capacity(W)", 

+

163 "input_power": "Input Power(W)" 

+

164 } 

+

165 sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None. 

+

166 """ 

+

167 

+

168 def __init__(self, N_max, V_h, T_sc, T_sh, capacity_definition, assumed_eta_mech, datasheet, **kwargs): 

+

169 super().__init__(N_max=N_max, V_h=V_h, datasheet=datasheet, **kwargs) 

+

170 self.T_sc = T_sc 

+

171 self.T_sh = T_sh 

+

172 if capacity_definition not in ["cooling", "heating"]: 

+

173 raise ValueError("capacity_definition has to be either 'heating' or 'cooling'") 

+

174 self._capacity_definition = capacity_definition 

+

175 self.assumed_eta_mech = assumed_eta_mech 

+

176 self.datasheet = datasheet 

+

177 

+

178 def get_lambda_h(self, inputs: Inputs): 

+

179 """ 

+

180 Get the volumetric efficiency. 

+

181 

+

182 Args: 

+

183 inputs (Inputs): Input parameters. 

+

184 

+

185 Returns: 

+

186 float: Volumetric efficiency. 

+

187 """ 

+

188 p_outlet = self.get_p_outlet() 

+

189 

+

190 n_abs = self.get_n_absolute(inputs.n) 

+

191 T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 1).T - 273.15 # [°C] 

+

192 T_con = self.med_prop.calc_state("PQ", p_outlet, 0).T - 273.15 # [°C] 

+

193 

+

194 if round((self.state_inlet.T - T_eva - 273.15), 2) != round(self.T_sh, 2): 

+

195 warnings.warn("The superheating of the given state is not " 

+

196 "equal to the superheating of the datasheet. " 

+

197 "State1.T_sh= " + str(round((self.state_inlet.T - T_eva - 273.15), 2)) + 

+

198 ". Datasheet.T_sh = " + str(self.T_sh)) 

+

199 # The datasheet has a given superheating temperature which can 

+

200 # vary from the superheating of the real state 1 

+

201 # which is given by the user. 

+

202 # Thus a new self.state_inlet_datasheet has to 

+

203 # be defined for all further calculations 

+

204 state_inlet_datasheet = self.med_prop.calc_state("PT", self.state_inlet.p, T_eva + 273.15 + self.T_sh) 

+

205 

+

206 m_flow = self.get_parameter(T_eva, T_con, inputs.n, "m_flow") / 3600 # [kg/s] 

+

207 

+

208 lambda_h = m_flow / (n_abs * state_inlet_datasheet.d * self.V_h) 

+

209 return lambda_h 

+

210 

+

211 def get_eta_isentropic(self, p_outlet: float, inputs: Inputs): 

+

212 """ 

+

213 Get the isentropic efficiency. 

+

214 

+

215 Args: 

+

216 p_outlet (float): Outlet pressure in Pa. 

+

217 inputs (Inputs): Input parameters. 

+

218 

+

219 Returns: 

+

220 float: Isentropic efficiency. 

+

221 """ 

+

222 T_con, state_inlet_datasheet, m_flow, capacity, p_el = self._calculate_values( 

+

223 p_2=p_outlet, inputs=inputs 

+

224 ) 

+

225 

+

226 h3 = self.med_prop.calc_state("PT", p_outlet, T_con + 273.15 - self.T_sc).h # [J/kg] 

+

227 h2s = self.med_prop.calc_state("PS", p_outlet, state_inlet_datasheet.s).h # [J/kg] 

+

228 

+

229 if self._capacity_definition == "heating": 

+

230 h2 = h3 + capacity / m_flow # [J/kg] 

+

231 else: 

+

232 h2 = h3 + (capacity + p_el * self.assumed_eta_mech) / m_flow # [J/kg] 

+

233 

+

234 if h2s > h2: 

+

235 raise ValueError("The calculated eta_s is above 1. You probably chose the wrong capacity_definition") 

+

236 

+

237 eta_s = (h2s - state_inlet_datasheet.h) / (h2 - state_inlet_datasheet.h) 

+

238 return eta_s 

+

239 

+

240 def get_eta_mech(self, inputs: Inputs): 

+

241 """ 

+

242 Get the mechanical efficiency. 

+

243 

+

244 Args: 

+

245 inputs (Inputs): Input parameters. 

+

246 

+

247 Returns: 

+

248 float: Mechanical efficiency. 

+

249 """ 

+

250 p_outlet = self.get_p_outlet() 

+

251 

+

252 if self._capacity_definition == "cooling": 

+

253 return self.assumed_eta_mech 

+

254 # Else heating 

+

255 T_con, state_inlet_datasheet, m_flow, capacity, p_el = self._calculate_values( 

+

256 p_2=p_outlet, inputs=inputs 

+

257 ) 

+

258 

+

259 h3 = self.med_prop.calc_state("PT", p_outlet, T_con + 273.15 - self.T_sc).h # [J/kg] 

+

260 h2 = h3 + capacity / m_flow # [J/kg] 

+

261 

+

262 eta_mech = (m_flow * (h2 - state_inlet_datasheet.h)) / p_el 

+

263 return eta_mech 

+

264 

+

265 def _calculate_values(self, p_2: float, inputs: Inputs): 

+

266 """ 

+

267 Calculate intermediate values for efficiency calculations. 

+

268 

+

269 Args: 

+

270 p_2 (float): Outlet pressure in Pa. 

+

271 inputs (Inputs): Input parameters. 

+

272 

+

273 Returns: 

+

274 Tuple[float, State, float, float, float]: Intermediate values. 

+

275 """ 

+

276 T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 1).T - 273.15 # [°C] 

+

277 T_con = self.med_prop.calc_state("PQ", p_2, 0).T - 273.15 # [°C] 

+

278 

+

279 state_inlet_datasheet = self.med_prop.calc_state("PT", self.state_inlet.p, T_eva + 273.15 + self.T_sh) 

+

280 

+

281 m_flow = self.get_parameter(T_eva, T_con, inputs.n, "m_flow") / 3600 # [kg/s] 

+

282 capacity = self.get_parameter(T_eva, T_con, inputs.n, "capacity") # [W] 

+

283 p_el = self.get_parameter(T_eva, T_con, inputs.n, "input_power") # [W] 

+

284 return T_con, state_inlet_datasheet, m_flow, capacity, p_el 

+

285 

+

286 

+

287class DataSheetCompressor(BaseTenCoefficientCompressor): 

+

288 """ 

+

289 Compressor based on the ten coefficient method. 

+

290 

+

291 Used table has to be in this format 

+

292 (order of the columns is not important). 

+

293 The values must be the same as in the example tabel. 

+

294 The column names can be different but must 

+

295 then be matched with the keyword argument parameter_names. 

+

296 (All typed in numbers are fictional placeholders) 

+

297 

+

298 Isentropic Volumetric Mechanical Isentropic Mechanical 

+

299 Efficiency(-) Efficiency(-) Efficiency(-) Efficiency(-) ... Efficiency(-) 

+

300 n n1 n1 n1 n2 ... n_last 

+

301 P1 42 12 243 32 ... 412 

+

302 ... ... ... ... ... ... ... 

+

303 P10 10 23 21 41 ... 2434 

+

304 

+

305 Args: 

+

306 N_max (float): Maximal rotations per second of the compressor. 

+

307 V_h (float): Volume of the compressor in m^3. 

+

308 datasheet (str): Path of the datasheet file. 

+

309 **kwargs: 

+

310 parameter_names (dict, optional): 

+

311 Dictionary to match internal parameter names (keys) to the names used in the table values. 

+

312 Default 

+

313 { 

+

314 "eta_s": "Isentropic Efficiency(-)", 

+

315 "lambda_h": "Volumetric Efficiency(-)", 

+

316 "eta_mech": "Mechanical Efficiency(-)" 

+

317 } 

+

318 sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None. 

+

319 """ 

+

320 

+

321 def __init__(self, N_max, V_h, datasheet, **kwargs): 

+

322 super().__init__(N_max=N_max, V_h=V_h, datasheet=datasheet, **kwargs) 

+

323 

+

324 def get_lambda_h(self, inputs: Inputs): 

+

325 """ 

+

326 Get the volumetric efficiency. 

+

327 

+

328 Args: 

+

329 inputs (Inputs): Input parameters. 

+

330 

+

331 Returns: 

+

332 float: Volumetric efficiency. 

+

333 """ 

+

334 p_outlet = self.get_p_outlet() 

+

335 T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 0).T 

+

336 T_con = self.med_prop.calc_state("PQ", p_outlet, 0).T 

+

337 return self.get_parameter(T_eva, T_con, inputs.n, "lambda_h") 

+

338 

+

339 def get_eta_isentropic(self, p_outlet: float, inputs: Inputs): 

+

340 """ 

+

341 Get the isentropic efficiency. 

+

342 

+

343 Args: 

+

344 p_outlet (float): Outlet pressure in Pa. 

+

345 inputs (Inputs): Input parameters. 

+

346 

+

347 Returns: 

+

348 float: Isentropic efficiency. 

+

349 """ 

+

350 T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 0).T 

+

351 T_con = self.med_prop.calc_state("PQ", p_outlet, 0).T 

+

352 return self.get_parameter(T_eva, T_con, inputs.n, "eta_s") 

+

353 

+

354 def get_eta_mech(self, inputs: Inputs): 

+

355 """ 

+

356 Get the mechanical efficiency. 

+

357 

+

358 Args: 

+

359 inputs (Inputs): Input parameters. 

+

360 

+

361 Returns: 

+

362 float: Mechanical efficiency. 

+

363 """ 

+

364 p_outlet = self.get_p_outlet() 

+

365 T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 0).T 

+

366 T_con = self.med_prop.calc_state("PQ", p_outlet, 0).T 

+

367 return self.get_parameter(T_eva, T_con, inputs.n, "eta_mech") 

+
+ + + diff --git a/docs/0.1.1/coverage/d_dae209ba2e6604e9___init___py.html b/docs/0.1.1/coverage/d_dae209ba2e6604e9___init___py.html new file mode 100644 index 0000000..da62af9 --- /dev/null +++ b/docs/0.1.1/coverage/d_dae209ba2e6604e9___init___py.html @@ -0,0 +1,101 @@ + + + + + Coverage for vclibpy/flowsheets/__init__.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/flowsheets/__init__.py: + 100% +

+ +

+ 4 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from .base import BaseCycle 

+

2from .standard import StandardCycle 

+

3from .vapor_injection_economizer import VaporInjectionEconomizer 

+

4from .vapor_injection_phase_separator import VaporInjectionPhaseSeparator 

+
+ + + diff --git a/docs/0.1.1/coverage/d_dae209ba2e6604e9_base_py.html b/docs/0.1.1/coverage/d_dae209ba2e6604e9_base_py.html new file mode 100644 index 0000000..0ac898f --- /dev/null +++ b/docs/0.1.1/coverage/d_dae209ba2e6604e9_base_py.html @@ -0,0 +1,528 @@ + + + + + Coverage for vclibpy/flowsheets/base.py: 78% + + + + + +
+
+

+ Coverage for vclibpy/flowsheets/base.py: + 78% +

+ +

+ 211 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import logging 

+

2from typing import List 

+

3import numpy as np 

+

4 

+

5from abc import abstractmethod 

+

6import matplotlib.pyplot as plt 

+

7from vclibpy import media, Inputs 

+

8from vclibpy.datamodels import FlowsheetState 

+

9from vclibpy.components.heat_exchangers import HeatExchanger 

+

10from vclibpy.components.component import BaseComponent 

+

11from vclibpy.utils.plotting import plot_cycle 

+

12 

+

13logger = logging.getLogger(__name__) 

+

14 

+

15 

+

16class BaseCycle: 

+

17 """ 

+

18 Base class for a heat pump. More complex systems may inherit from this class 

+

19 All HP have a compressor, two HE and a source and sink. 

+

20 Therefore, the parameters defined here are general parameters. 

+

21 

+

22 Args: 

+

23 fluid (str): Name of the fluid 

+

24 evaporator (HeatExchanger): Instance of a heat exchanger used for the evaporator 

+

25 condenser (HeatExchanger): Instance of a heat exchanger used for the condenser 

+

26 """ 

+

27 

+

28 flowsheet_name: str = "BaseCLass of all HP classes - not to use for map generation" 

+

29 

+

30 def __init__( 

+

31 self, 

+

32 fluid: str, 

+

33 evaporator: HeatExchanger, 

+

34 condenser: HeatExchanger 

+

35 ): 

+

36 self.fluid: str = fluid 

+

37 self.evaporator = evaporator 

+

38 self.condenser = condenser 

+

39 # Instantiate dummy values 

+

40 self.med_prop = None 

+

41 self._p_min = 10000 # So that p>0 at all times 

+

42 self._p_max = None # Is set by med-prop 

+

43 

+

44 def __str__(self): 

+

45 return self.flowsheet_name 

+

46 

+

47 def setup_new_fluid(self, fluid): 

+

48 # Only do so if new fluid is given 

+

49 if self.med_prop is not None: 

+

50 if self.med_prop.fluid_name == fluid: 

+

51 return 

+

52 self.med_prop.terminate() 

+

53 

+

54 # Else create new instance of MedProp 

+

55 med_prop_class, med_prop_kwargs = media.get_global_med_prop_and_kwargs() 

+

56 self.med_prop = med_prop_class(fluid_name=fluid, **med_prop_kwargs) 

+

57 

+

58 # Write the instance to the components 

+

59 for component in self.get_all_components(): 

+

60 component.med_prop = self.med_prop 

+

61 component.start_secondary_med_prop() 

+

62 

+

63 # Get max and min pressure 

+

64 _, self._p_max, _ = self.med_prop.get_critical_point() 

+

65 self.fluid = fluid 

+

66 

+

67 def terminate(self): 

+

68 self.med_prop.terminate() 

+

69 for component in self.get_all_components(): 

+

70 component.terminate_secondary_med_prop() 

+

71 

+

72 def get_all_components(self) -> List[BaseComponent]: 

+

73 return [self.condenser, self.evaporator] 

+

74 

+

75 def calc_steady_state(self, inputs: Inputs, fluid: str = None, **kwargs): 

+

76 """ 

+

77 Calculate the steady-state performance of a vapor compression cycle 

+

78 based on given inputs and assumptions. 

+

79 

+

80 This function ensures consistent assumptions across different cycles. 

+

81 It calculates the performance of the heat pump under 

+

82 specific conditions while adhering to several general assumptions. 

+

83 

+

84 General Assumptions: 

+

85 --------------------- 

+

86 - Isenthalpic expansion valves: 

+

87 The enthalpy at the inlet equals the enthalpy at the outlet. 

+

88 - No heat losses in any component: 

+

89 The heat input to the condenser equals the heat 

+

90 output of the evaporator plus the power input. 

+

91 - Input to the evaporator is always in the two-phase region. 

+

92 - Output of the evaporator and output of the condenser maintain 

+

93 a constant overheating or subcooling (can be set in Inputs). 

+

94 

+

95 Args: 

+

96 inputs (Inputs): 

+

97 An instance of the Inputs class containing the 

+

98 necessary parameters to calculate the flowsheet state. 

+

99 fluid (str): 

+

100 The fluid to be used in the calculations. 

+

101 Required only if 'fluid' is not specified during the object's initialization. 

+

102 

+

103 Keyword Arguments: 

+

104 min_iteration_step (int): 

+

105 The minimum step size for iterations (default: 1). 

+

106 save_path_plots (str or None): 

+

107 The path to save plots (default: None). 

+

108 If None, no plots are created. 

+

109 show_iteration (bool): 

+

110 Whether to display iteration progress (default: False). 

+

111 T_max (float): 

+

112 Maximum temperature allowed (default: 273.15 + 150). 

+

113 use_quick_solver (bool): 

+

114 Whether to use a quick solver (default: True). 

+

115 max_err_ntu (float): 

+

116 Maximum allowable error for the heat exchanger in percent (default: 0.5). 

+

117 max_err_dT_min (float): 

+

118 Maximum allowable error for minimum temperature difference in K (default: 0.1). 

+

119 max_num_iterations (int or None): 

+

120 Maximum number of iterations allowed (default: None). 

+

121 

+

122 Returns: 

+

123 fs_state (FlowsheetState): 

+

124 An instance of the FlowsheetState class representing 

+

125 the calculated state of the vapor compression cycle. 

+

126 """ 

+

127 # Settings 

+

128 min_iteration_step = kwargs.pop("min_iteration_step", 1) 

+

129 save_path_plots = kwargs.get("save_path_plots", None) 

+

130 input_name = ";".join([k + "=" + str(np.round(v.value, 3)).replace(".", "_") 

+

131 for k, v in inputs.get_variables().items()]) 

+

132 show_iteration = kwargs.get("show_iteration", False) 

+

133 use_quick_solver = kwargs.pop("use_quick_solver", True) 

+

134 err_ntu = kwargs.pop("max_err_ntu", 0.5) 

+

135 err_dT_min = kwargs.pop("max_err_dT_min", 0.1) 

+

136 max_num_iterations = kwargs.pop("max_num_iterations", 1e5) 

+

137 p_1_history = [] 

+

138 p_2_history = [] 

+

139 

+

140 if use_quick_solver: 

+

141 step_p1 = kwargs.get("step_max", 10000) 

+

142 step_p2 = kwargs.get("step_max", 10000) 

+

143 else: 

+

144 step_p1 = min_iteration_step 

+

145 step_p2 = min_iteration_step 

+

146 

+

147 # Setup fluid: 

+

148 if fluid is None: 

+

149 fluid = self.fluid 

+

150 self.setup_new_fluid(fluid) 

+

151 

+

152 # First: Iterate with given conditions to get the 4 states and the mass flow rate: 

+

153 T_1_start = inputs.T_eva_in - inputs.dT_eva_superheating 

+

154 T_3_start = inputs.T_con_in + inputs.dT_con_subcooling 

+

155 p_1_start = self.med_prop.calc_state("TQ", T_1_start, 1).p 

+

156 p_2_start = self.med_prop.calc_state("TQ", T_3_start, 0).p 

+

157 p_1_next = p_1_start 

+

158 p_2_next = p_2_start 

+

159 

+

160 fs_state = FlowsheetState() # Always log what is happening in the whole flowsheet 

+

161 fs_state.set(name="Q_con", value=1, unit="W", description="Condenser heat flow rate") 

+

162 fs_state.set(name="COP", value=0, unit="-", description="Coefficient of performance") 

+

163 

+

164 if show_iteration: 

+

165 fig_iterations, ax_iterations = plt.subplots(2) 

+

166 

+

167 num_iterations = 0 

+

168 

+

169 while True: 

+

170 if isinstance(max_num_iterations, (int, float)): 

+

171 if num_iterations > max_num_iterations: 

+

172 logger.warning("Maximum number of iterations %s exceeded. Stopping.", 

+

173 max_num_iterations) 

+

174 return 

+

175 

+

176 if (num_iterations + 1) % (0.1 * max_num_iterations) == 0: 

+

177 logger.info("Info: %s percent of max_num_iterations %s used", 

+

178 100 * (num_iterations + 1) / max_num_iterations, max_num_iterations) 

+

179 

+

180 p_1 = p_1_next 

+

181 p_2 = p_2_next 

+

182 p_1_history.append(p_1) 

+

183 p_2_history.append(p_2) 

+

184 if show_iteration: 

+

185 ax_iterations[0].cla() 

+

186 ax_iterations[1].cla() 

+

187 ax_iterations[0].scatter(list(range(len(p_1_history))), p_1_history) 

+

188 ax_iterations[1].scatter(list(range(len(p_2_history))), p_2_history) 

+

189 plt.draw() 

+

190 plt.pause(1e-5) 

+

191 

+

192 # Increase counter 

+

193 num_iterations += 1 

+

194 # Check critical pressures: 

+

195 if p_2 >= self._p_max: 

+

196 if step_p2 == min_iteration_step: 

+

197 logger.error("Pressure too high. Configuration is infeasible.") 

+

198 return 

+

199 p_2_next = p_2 - step_p2 

+

200 step_p2 /= 10 

+

201 continue 

+

202 if p_1 <= self._p_min: 

+

203 if p_1_next == min_iteration_step: 

+

204 logger.error("Pressure too low. Configuration is infeasible.") 

+

205 return 

+

206 p_1_next = p_1 + step_p1 

+

207 step_p1 /= 10 

+

208 continue 

+

209 

+

210 # Calculate the states based on the given flowsheet 

+

211 try: 

+

212 self.calc_states(p_1, p_2, inputs=inputs, fs_state=fs_state) 

+

213 except ValueError as err: 

+

214 logger.error("An error occurred while calculating states. " 

+

215 "Can't guess next pressures, thus, exiting: %s", err) 

+

216 return 

+

217 if save_path_plots is not None and num_iterations == 1 and show_iteration: 

+

218 self.plot_cycle(save_path=save_path_plots.joinpath(f"{input_name}_initialization.png"), inputs=inputs) 

+

219 

+

220 # Check heat exchangers: 

+

221 error_eva, dT_min_eva = self.evaporator.calc(inputs=inputs, fs_state=fs_state) 

+

222 if not isinstance(error_eva, float): 

+

223 print(error_eva) 

+

224 if error_eva < 0: 

+

225 p_1_next = p_1 - step_p1 

+

226 continue 

+

227 else: 

+

228 if step_p1 > min_iteration_step: 

+

229 p_1_next = p_1 + step_p1 

+

230 step_p1 /= 10 

+

231 continue 

+

232 elif error_eva > err_ntu and dT_min_eva > err_dT_min: 

+

233 step_p1 = 1000 

+

234 p_1_next = p_1 + step_p1 

+

235 continue 

+

236 

+

237 error_con, dT_min_con = self.condenser.calc(inputs=inputs, fs_state=fs_state) 

+

238 if error_con < 0: 

+

239 p_2_next = p_2 + step_p2 

+

240 continue 

+

241 else: 

+

242 if step_p2 > min_iteration_step: 

+

243 p_2_next = p_2 - step_p2 

+

244 step_p2 /= 10 

+

245 continue 

+

246 elif error_con > err_ntu and dT_min_con > err_dT_min: 

+

247 p_2_next = p_2 - step_p2 

+

248 step_p2 = 1000 

+

249 continue 

+

250 

+

251 # If still here, and the values are equal, we may break. 

+

252 if p_1 == p_1_next and p_2 == p_2_next: 

+

253 # Check if solution was too far away. If so, jump back 

+

254 # And decrease the iteration step by factor 10. 

+

255 if step_p2 > min_iteration_step: 

+

256 p_2_next = p_2 - step_p2 

+

257 step_p2 /= 10 

+

258 continue 

+

259 if step_p1 > min_iteration_step: 

+

260 p_1_next = p_1 + step_p1 

+

261 step_p1 /= 10 

+

262 continue 

+

263 logger.info("Breaking: Converged") 

+

264 break 

+

265 

+

266 # Check if values are not converging at all: 

+

267 p_1_unique = set(p_1_history[-10:]) 

+

268 p_2_unique = set(p_2_history[-10:]) 

+

269 if len(p_1_unique) == 2 and len(p_2_unique) == 2 \ 

+

270 and step_p1 == min_iteration_step and step_p2 == min_iteration_step: 

+

271 logger.critical("Breaking: not converging at all") 

+

272 break 

+

273 

+

274 if show_iteration: 

+

275 plt.close(fig_iterations) 

+

276 

+

277 # Calculate the heat flow rates for the selected states. 

+

278 Q_con = self.condenser.calc_Q_flow() 

+

279 Q_con_outer = self.condenser.calc_secondary_Q_flow(Q_con) 

+

280 Q_eva = self.evaporator.calc_Q_flow() 

+

281 Q_eva_outer = self.evaporator.calc_secondary_Q_flow(Q_eva) 

+

282 self.evaporator.calc(inputs=inputs, fs_state=fs_state) 

+

283 self.condenser.calc(inputs=inputs, fs_state=fs_state) 

+

284 P_el = self.calc_electrical_power(fs_state=fs_state, inputs=inputs) 

+

285 T_con_out = inputs.T_con_in + Q_con_outer / self.condenser.m_flow_secondary_cp 

+

286 

+

287 # COP based on P_el and Q_con: 

+

288 COP_inner = Q_con / P_el 

+

289 COP_outer = Q_con_outer / P_el 

+

290 # Calculate carnot quality as a measure of reliability of model: 

+

291 COP_carnot = (T_con_out / (T_con_out - inputs.T_eva_in)) 

+

292 carnot_quality = COP_inner / COP_carnot 

+

293 # Calc return temperature: 

+

294 fs_state.set( 

+

295 name="P_el", value=P_el, unit="W", 

+

296 description="Power consumption" 

+

297 ) 

+

298 fs_state.set( 

+

299 name="carnot_quality", value=carnot_quality, 

+

300 unit="-", description="Carnot Quality" 

+

301 ) 

+

302 fs_state.set( 

+

303 name="Q_con", value=Q_con, unit="W", 

+

304 description="Condenser refrigerant heat flow rate" 

+

305 ) 

+

306 # COP based on P_el and Q_con: 

+

307 fs_state.set( 

+

308 name="Q_con_outer", value=Q_con_outer, unit="W", 

+

309 description="Secondary medium condenser heat flow rate" 

+

310 ) 

+

311 fs_state.set( 

+

312 name="Q_eva_outer", value=Q_eva_outer, unit="W", 

+

313 description="Secondary medium evaporator heat flow rate" 

+

314 ) 

+

315 fs_state.set( 

+

316 name="COP", value=COP_inner, 

+

317 unit="-", description="Coefficient of Performance" 

+

318 ) 

+

319 fs_state.set( 

+

320 name="COP_outer", value=COP_outer, 

+

321 unit="-", description="Outer COP, including heat losses" 

+

322 ) 

+

323 

+

324 if save_path_plots is not None: 

+

325 self.plot_cycle(save_path=save_path_plots.joinpath(f"{input_name}_final_result.png"), inputs=inputs) 

+

326 

+

327 return fs_state 

+

328 

+

329 @abstractmethod 

+

330 def get_states_in_order_for_plotting(self): 

+

331 """ 

+

332 Function to return all thermodynamic states of cycle 

+

333 in the correct order for plotting. 

+

334 Include phase change states to see if your simulation 

+

335 runs plausible cycles. 

+

336 

+

337 Returns: 

+

338 - List with tuples, first entry being the state and second the mass flow rate 

+

339 """ 

+

340 return [] 

+

341 

+

342 def set_evaporator_outlet_based_on_superheating(self, p_eva: float, inputs: Inputs): 

+

343 """ 

+

344 Calculate the outlet state of the evaporator based on 

+

345 the required degree of superheating. 

+

346 

+

347 Args: 

+

348 p_eva (float): Evaporation pressure 

+

349 inputs (Inputs): Inputs with superheating level 

+

350 """ 

+

351 T_1 = self.med_prop.calc_state("PQ", p_eva, 1).T + inputs.dT_eva_superheating 

+

352 if inputs.dT_eva_superheating > 0: 

+

353 self.evaporator.state_outlet = self.med_prop.calc_state("PT", p_eva, T_1) 

+

354 else: 

+

355 self.evaporator.state_outlet = self.med_prop.calc_state("PQ", p_eva, 1) 

+

356 

+

357 def set_condenser_outlet_based_on_subcooling(self, p_con: float, inputs: Inputs): 

+

358 """ 

+

359 Calculate the outlet state of the evaporator based on 

+

360 the required degree of superheating. 

+

361 

+

362 Args: 

+

363 p_con (float): Condensing pressure 

+

364 inputs (Inputs): Inputs with superheating level 

+

365 """ 

+

366 T_3 = self.med_prop.calc_state("PQ", p_con, 0).T - inputs.dT_con_subcooling 

+

367 if inputs.dT_con_subcooling > 0: 

+

368 self.condenser.state_outlet = self.med_prop.calc_state("PT", p_con, T_3) 

+

369 else: 

+

370 self.condenser.state_outlet = self.med_prop.calc_state("PQ", p_con, 0) 

+

371 

+

372 def plot_cycle(self, save_path: str, inputs: Inputs): 

+

373 """Function to plot the resulting flowsheet of the steady state config.""" 

+

374 states = self.get_states_in_order_for_plotting() 

+

375 fig, ax = plot_cycle( 

+

376 states=states, 

+

377 med_prop=self.med_prop, 

+

378 save_path=None 

+

379 ) 

+

380 self._plot_secondary_heat_flow_rates(ax=ax[0], inputs=inputs) 

+

381 fig.tight_layout() 

+

382 fig.savefig(save_path) 

+

383 plt.close(fig) 

+

384 

+

385 def _plot_secondary_heat_flow_rates(self, ax, inputs): 

+

386 Q_con = self.condenser.calc_Q_flow() 

+

387 Q_eva = self.evaporator.calc_Q_flow() 

+

388 

+

389 delta_H_con = np.array([ 

+

390 self.condenser.state_outlet.h * self.condenser.m_flow, 

+

391 self.condenser.state_outlet.h * self.condenser.m_flow + Q_con 

+

392 ]) / self.condenser.m_flow 

+

393 delta_H_eva = np.array([ 

+

394 self.evaporator.state_outlet.h * self.evaporator.m_flow, 

+

395 self.evaporator.state_outlet.h * self.evaporator.m_flow - Q_eva 

+

396 ]) / self.evaporator.m_flow 

+

397 self.condenser.m_flow_secondary = inputs.m_flow_con 

+

398 self.condenser.calc_secondary_cp(T=inputs.T_con_in) 

+

399 self.evaporator.m_flow_secondary = inputs.m_flow_eva 

+

400 self.evaporator.calc_secondary_cp(T=inputs.T_eva_in) 

+

401 ax.plot(delta_H_con / 1000, [ 

+

402 inputs.T_con_in - 273.15, 

+

403 inputs.T_con_in + Q_con / self.condenser.m_flow_secondary_cp - 273.15 

+

404 ], color="b") 

+

405 ax.plot(delta_H_eva / 1000, [ 

+

406 inputs.T_eva_in - 273.15, 

+

407 inputs.T_eva_in - Q_eva / self.evaporator.m_flow_secondary_cp - 273.15 

+

408 ], color="b") 

+

409 

+

410 @abstractmethod 

+

411 def calc_electrical_power(self, inputs: Inputs, fs_state: FlowsheetState): 

+

412 """Function to calc the electrical power consumption based on the flowsheet used""" 

+

413 raise NotImplementedError 

+

414 

+

415 @abstractmethod 

+

416 def calc_states(self, p_1, p_2, inputs: Inputs, fs_state: FlowsheetState): 

+

417 """ 

+

418 Function to calculate the states and mass flow rates of the flowsheet 

+

419 and set these into each component based on the given pressure levels p_1 and p_2. 

+

420 

+

421 Args: 

+

422 p_1 (float): 

+

423 Lower pressure level. If no pressure losses are assumed, 

+

424 this equals the evaporation pressure and the compressor inlet pressure. 

+

425 p_2 (float): 

+

426 Higher pressure level. If no pressure losses are assumed, 

+

427 this equals the condensing pressure and the compressor outlet pressure. 

+

428 inputs (Inputs): Inputs of calculation. 

+

429 fs_state (FlowsheetState): Flowsheet state to save important variables. 

+

430 """ 

+

431 raise NotImplementedError 

+
+ + + diff --git a/docs/0.1.1/coverage/d_dae209ba2e6604e9_standard_py.html b/docs/0.1.1/coverage/d_dae209ba2e6604e9_standard_py.html new file mode 100644 index 0000000..9e9a7d2 --- /dev/null +++ b/docs/0.1.1/coverage/d_dae209ba2e6604e9_standard_py.html @@ -0,0 +1,189 @@ + + + + + Coverage for vclibpy/flowsheets/standard.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/flowsheets/standard.py: + 100% +

+ +

+ 36 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from vclibpy.flowsheets import BaseCycle 

+

2from vclibpy.datamodels import FlowsheetState, Inputs 

+

3from vclibpy.components.compressors import Compressor 

+

4from vclibpy.components.expansion_valves import ExpansionValve 

+

5 

+

6 

+

7class StandardCycle(BaseCycle): 

+

8 """ 

+

9 Class for a standard cycle with four components. 

+

10 

+

11 For the standard cycle, we have 4 possible states: 

+

12 

+

13 1. Before compressor, after evaporator 

+

14 2. Before condenser, after compressor 

+

15 3. Before EV, after condenser 

+

16 4. Before Evaporator, after EV 

+

17 """ 

+

18 

+

19 flowsheet_name = "Standard" 

+

20 

+

21 def __init__( 

+

22 self, 

+

23 compressor: Compressor, 

+

24 expansion_valve: ExpansionValve, 

+

25 **kwargs 

+

26 ): 

+

27 super().__init__(**kwargs) 

+

28 self.compressor = compressor 

+

29 self.expansion_valve = expansion_valve 

+

30 

+

31 def get_all_components(self): 

+

32 return super().get_all_components() + [ 

+

33 self.compressor, 

+

34 self.expansion_valve 

+

35 ] 

+

36 

+

37 def get_states_in_order_for_plotting(self): 

+

38 return [ 

+

39 self.evaporator.state_inlet, 

+

40 self.med_prop.calc_state("PQ", self.evaporator.state_inlet.p, 1), 

+

41 self.evaporator.state_outlet, 

+

42 self.compressor.state_inlet, 

+

43 self.compressor.state_outlet, 

+

44 self.condenser.state_inlet, 

+

45 self.med_prop.calc_state("PQ", self.condenser.state_inlet.p, 1), 

+

46 self.med_prop.calc_state("PQ", self.condenser.state_inlet.p, 0), 

+

47 self.condenser.state_outlet, 

+

48 self.expansion_valve.state_inlet, 

+

49 self.expansion_valve.state_outlet, 

+

50 ] 

+

51 

+

52 def calc_states(self, p_1, p_2, inputs: Inputs, fs_state: FlowsheetState): 

+

53 self.set_condenser_outlet_based_on_subcooling(p_con=p_2, inputs=inputs) 

+

54 self.expansion_valve.state_inlet = self.condenser.state_outlet 

+

55 self.expansion_valve.calc_outlet(p_outlet=p_1) 

+

56 self.evaporator.state_inlet = self.expansion_valve.state_outlet 

+

57 self.set_evaporator_outlet_based_on_superheating(p_eva=p_1, inputs=inputs) 

+

58 self.compressor.state_inlet = self.evaporator.state_outlet 

+

59 self.compressor.calc_state_outlet(p_outlet=p_2, inputs=inputs, fs_state=fs_state) 

+

60 self.condenser.state_inlet = self.compressor.state_outlet 

+

61 

+

62 # Mass flow rate: 

+

63 self.compressor.calc_m_flow(inputs=inputs, fs_state=fs_state) 

+

64 self.condenser.m_flow = self.compressor.m_flow 

+

65 self.evaporator.m_flow = self.compressor.m_flow 

+

66 self.expansion_valve.m_flow = self.compressor.m_flow 

+

67 fs_state.set( 

+

68 name="y_EV", value=self.expansion_valve.calc_opening_at_m_flow(m_flow=self.expansion_valve.m_flow), 

+

69 unit="-", description="Expansion valve opening" 

+

70 ) 

+

71 fs_state.set( 

+

72 name="T_1", value=self.evaporator.state_outlet.T, 

+

73 unit="K", description="Refrigerant temperature at evaporator outlet" 

+

74 ) 

+

75 fs_state.set( 

+

76 name="T_2", value=self.compressor.state_outlet.T, 

+

77 unit="K", description="Compressor outlet temperature" 

+

78 ) 

+

79 fs_state.set( 

+

80 name="T_3", value=self.condenser.state_outlet.T, unit="K", 

+

81 description="Refrigerant temperature at condenser outlet" 

+

82 ) 

+

83 fs_state.set( 

+

84 name="T_4", value=self.evaporator.state_inlet.T, 

+

85 unit="K", description="Refrigerant temperature at evaporator inlet" 

+

86 ) 

+

87 fs_state.set(name="p_con", value=p_2, unit="Pa", description="Condensation pressure") 

+

88 fs_state.set(name="p_eva", value=p_1, unit="Pa", description="Evaporation pressure") 

+

89 

+

90 def calc_electrical_power(self, inputs: Inputs, fs_state: FlowsheetState): 

+

91 """Based on simple energy balance - Adiabatic""" 

+

92 return self.compressor.calc_electrical_power(inputs=inputs, fs_state=fs_state) 

+
+ + + diff --git a/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_economizer_py.html b/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_economizer_py.html new file mode 100644 index 0000000..61332a6 --- /dev/null +++ b/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_economizer_py.html @@ -0,0 +1,248 @@ + + + + + Coverage for vclibpy/flowsheets/vapor_injection_economizer.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/flowsheets/vapor_injection_economizer.py: + 100% +

+ +

+ 48 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import numpy as np 

+

2 

+

3from vclibpy.flowsheets.vapor_injection import BaseVaporInjection 

+

4from vclibpy.components.heat_exchangers.economizer import VaporInjectionEconomizerNTU 

+

5 

+

6 

+

7class VaporInjectionEconomizer(BaseVaporInjection): 

+

8 """ 

+

9 Cycle with vapor injection using an economizer. 

+

10 

+

11 For this cycle, we have 9 relevant states: 

+

12 

+

13 - 1: Before compressor, after evaporator 

+

14 - 2: Before condenser, after compressor 

+

15 - 3: Before ihx, after condenser 

+

16 - 4: Before Evaporator, after ihx 

+

17 - 5_ihx: Before ihx, after condenser and EV 

+

18 - 6_ihx: Before Mixing with 1_VI, after ihx 

+

19 - 7_ihx: Before second EV, after ihx 

+

20 - 1_VI: Before Mixing with 6_ihx, After first stage 

+

21 - 1_VI_mixed. Before second stage of compressor, after mixing with 6_ihx 

+

22 

+

23 Additional Assumptions: 

+

24 ----------------------- 

+

25 - No heat losses in ihx 

+

26 - No pressure loss in ihx 

+

27 - No losses for splitting of streams 

+

28 - Isenthalpic second EV 

+

29 

+

30 Notes 

+

31 ----- 

+

32 See parent docstring for info on further assumptions and parameters. 

+

33 """ 

+

34 

+

35 flowsheet_name = "VaporInjectionEconomizer" 

+

36 

+

37 def __init__(self, economizer: VaporInjectionEconomizerNTU, **kwargs): 

+

38 self.economizer = economizer 

+

39 super().__init__(**kwargs) 

+

40 

+

41 def get_all_components(self): 

+

42 return super().get_all_components() + [ 

+

43 self.economizer 

+

44 ] 

+

45 

+

46 def calc_injection(self): 

+

47 """ 

+

48 This calculation assumes that the heat transfer 

+

49 of the higher temperature liquid is always in the subcooling 

+

50 region, while the vapor injection is always a two-phase heat 

+

51 transfer. 

+

52 In reality, you would need to achieve a certain degree of superheat. 

+

53 Thus, a moving boundary approach would be more fitting. For simplicity, 

+

54 we assume no superheat. 

+

55 

+

56 This function iterates the amount of vapor injected. 

+

57 The iteration starts with close to no injection and increases 

+

58 the amount of injection as long as enough hotter sub-cooled liquid is 

+

59 present to fully vaporize the injected part. 

+

60 """ 

+

61 self.economizer.state_inlet = self.condenser.state_outlet 

+

62 self.economizer.state_two_phase_inlet = self.high_pressure_valve.state_outlet 

+

63 self.economizer.state_two_phase_outlet = self.med_prop.calc_state( 

+

64 "PQ", self.high_pressure_valve.state_outlet.p, 1 

+

65 ) 

+

66 m_flow_evaporator = self.evaporator.m_flow 

+

67 

+

68 dh_ihe_goal = ( 

+

69 self.economizer.state_two_phase_outlet.h - 

+

70 self.economizer.state_two_phase_inlet.h 

+

71 ) 

+

72 

+

73 # Get transport properties: 

+

74 tra_properties_liquid = self.med_prop.calc_transport_properties( 

+

75 self.economizer.state_inlet 

+

76 ) 

+

77 alpha_liquid = self.economizer.calc_alpha_liquid(tra_properties_liquid) 

+

78 tra_properties_two_phase = self.med_prop.calc_mean_transport_properties( 

+

79 self.economizer.state_two_phase_inlet, 

+

80 self.economizer.state_two_phase_outlet 

+

81 ) 

+

82 alpha_two_phase = self.economizer.calc_alpha_liquid(tra_properties_two_phase) 

+

83 

+

84 # Set cp based on transport properties 

+

85 dT_secondary = ( 

+

86 self.economizer.state_two_phase_outlet.T - 

+

87 self.economizer.state_two_phase_inlet.T 

+

88 ) 

+

89 if dT_secondary == 0: 

+

90 cp_4 = np.inf 

+

91 else: 

+

92 cp_4 = dh_ihe_goal / dT_secondary 

+

93 self.economizer.set_secondary_cp(cp=cp_4) 

+

94 self.economizer.set_primary_cp(cp=tra_properties_liquid.cp) 

+

95 

+

96 # We have to iterate to ensure the correct fraction of mass is 

+

97 # used to ensure state5 has q=1 

+

98 _x_vi_step = 0.1 

+

99 _min_step_x_vi = 0.0001 

+

100 

+

101 x_vi_next = _min_step_x_vi # Don't start with zero! 

+

102 while True: 

+

103 x_vi = x_vi_next 

+

104 x_eva = 1 - x_vi 

+

105 m_flow_vapor_injection = x_vi * m_flow_evaporator 

+

106 Q_flow_goal = dh_ihe_goal * m_flow_vapor_injection 

+

107 

+

108 self.economizer.m_flow = x_eva * m_flow_evaporator 

+

109 self.economizer.m_flow_secondary = m_flow_vapor_injection 

+

110 

+

111 # This dT_max is always valid, as the primary inlet is cooled 

+

112 # and the secondary inlet (the vapor) is either heated 

+

113 # or isothermal for pure fluids 

+

114 Q_flow, k = self.economizer.calc_Q_ntu( 

+

115 dT_max=( 

+

116 self.economizer.state_inlet.T - 

+

117 self.economizer.state_two_phase_inlet.T 

+

118 ), 

+

119 alpha_pri=alpha_liquid, 

+

120 alpha_sec=alpha_two_phase, 

+

121 A=self.economizer.A 

+

122 ) 

+

123 if Q_flow > Q_flow_goal: 

+

124 if _x_vi_step <= _min_step_x_vi: 

+

125 break 

+

126 # We can increase x_vi_next further, as more heat can be extracted 

+

127 x_vi_next = x_vi + _x_vi_step 

+

128 else: 

+

129 x_vi_next = x_vi - _x_vi_step * 0.9 

+

130 _x_vi_step /= 10 

+

131 

+

132 # Solve Energy Balance 

+

133 h_7 = self.economizer.state_inlet.h - dh_ihe_goal * self.economizer.m_flow 

+

134 state_7_ihx = self.med_prop.calc_state("PH", self.economizer.state_inlet.p, h_7) 

+

135 self.economizer.state_outlet = state_7_ihx 

+

136 return x_vi, self.economizer.state_two_phase_outlet.h, state_7_ihx 

+

137 

+

138 def get_states_in_order_for_plotting(self): 

+

139 return super().get_states_in_order_for_plotting() + [ 

+

140 self.economizer.state_two_phase_inlet, 

+

141 self.economizer.state_two_phase_outlet, 

+

142 self.high_pressure_compressor.state_inlet, 

+

143 # Go back to the condenser outlet 

+

144 self.economizer.state_two_phase_outlet, 

+

145 self.economizer.state_two_phase_inlet, 

+

146 self.high_pressure_valve.state_outlet, 

+

147 self.high_pressure_valve.state_inlet, 

+

148 self.condenser.state_outlet, 

+

149 self.economizer.state_inlet, 

+

150 self.economizer.state_outlet 

+

151 ] 

+
+ + + diff --git a/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_phase_separator_py.html b/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_phase_separator_py.html new file mode 100644 index 0000000..4c2057e --- /dev/null +++ b/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_phase_separator_py.html @@ -0,0 +1,158 @@ + + + + + Coverage for vclibpy/flowsheets/vapor_injection_phase_separator.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/flowsheets/vapor_injection_phase_separator.py: + 100% +

+ +

+ 18 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import logging 

+

2 

+

3from vclibpy.flowsheets.vapor_injection import BaseVaporInjection 

+

4from vclibpy.components.phase_separator import PhaseSeparator 

+

5 

+

6 

+

7logger = logging.getLogger(__name__) 

+

8 

+

9 

+

10class VaporInjectionPhaseSeparator(BaseVaporInjection): 

+

11 """ 

+

12 Cycle with vapor injection using an adiabatic ideal phase seperator. 

+

13 

+

14 For this cycle, we have 9 relevant states: 

+

15 

+

16 - 1: Before compressor, after evaporator 

+

17 - 2: Before condenser, after compressor 

+

18 - 3: Before PS, after condenser 

+

19 - 4: Before Evaporator, after PS 

+

20 - 5_vips: Before PS, after first EV 

+

21 - 6_vips: Before Mixing with 1_VI, after PS 

+

22 - 7_vips: Before second EV, after PS 

+

23 - 1_VI: Before Mixing with 6_vips, After first stage 

+

24 - 1_VI_mixed. Before second stage of compressor, after mixing with 6_vips 

+

25 

+

26 Additional Assumptions: 

+

27 ----------------------- 

+

28 - Ideal mixing in compressor of state 5 and state 4 

+

29 

+

30 Notes 

+

31 ----- 

+

32 See parent docstring for info on further assumptions and parameters. 

+

33 """ 

+

34 

+

35 flowsheet_name = "VaporInjectionPhaseSeparator" 

+

36 

+

37 def __init__(self, **kwargs): 

+

38 self.phase_separator = PhaseSeparator() 

+

39 super().__init__(**kwargs) 

+

40 

+

41 def get_all_components(self): 

+

42 return super().get_all_components() + [ 

+

43 self.phase_separator 

+

44 ] 

+

45 

+

46 def calc_injection(self): 

+

47 # Phase separator 

+

48 self.phase_separator.state_inlet = self.high_pressure_valve.state_outlet 

+

49 x_vapor_injection = self.phase_separator.state_inlet.q 

+

50 h_vapor_injection = self.phase_separator.state_outlet_vapor.h 

+

51 return x_vapor_injection, h_vapor_injection, self.phase_separator.state_outlet_liquid 

+

52 

+

53 def get_states_in_order_for_plotting(self): 

+

54 return super().get_states_in_order_for_plotting() + [ 

+

55 self.phase_separator.state_inlet, 

+

56 self.phase_separator.state_outlet_vapor, 

+

57 self.high_pressure_compressor.state_inlet, 

+

58 # Go back to separator for clear lines 

+

59 self.phase_separator.state_outlet_vapor, 

+

60 self.phase_separator.state_outlet_liquid 

+

61 ] 

+
+ + + diff --git a/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_py.html b/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_py.html new file mode 100644 index 0000000..26baf91 --- /dev/null +++ b/docs/0.1.1/coverage/d_dae209ba2e6604e9_vapor_injection_py.html @@ -0,0 +1,287 @@ + + + + + Coverage for vclibpy/flowsheets/vapor_injection.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/flowsheets/vapor_injection.py: + 100% +

+ +

+ 63 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1import abc 

+

2import logging 

+

3from copy import deepcopy 

+

4import numpy as np 

+

5 

+

6from vclibpy.flowsheets import BaseCycle 

+

7from vclibpy.datamodels import Inputs, FlowsheetState 

+

8from vclibpy.components.compressors import Compressor 

+

9from vclibpy.components.expansion_valves import ExpansionValve 

+

10from vclibpy.media import ThermodynamicState 

+

11 

+

12logger = logging.getLogger(__name__) 

+

13 

+

14 

+

15class BaseVaporInjection(BaseCycle, abc.ABC): 

+

16 """ 

+

17 Partial cycle with vapor injection, using 

+

18 two separated compressors and expansion valves. 

+

19 

+

20 Notes 

+

21 ----- 

+

22 See parent docstring for info on further assumptions and parameters. 

+

23 """ 

+

24 

+

25 flowsheet_name = "VaporInjectionPhaseSeparator" 

+

26 

+

27 def __init__( 

+

28 self, 

+

29 high_pressure_compressor: Compressor, 

+

30 low_pressure_compressor: Compressor, 

+

31 high_pressure_valve: ExpansionValve, 

+

32 low_pressure_valve: ExpansionValve, 

+

33 **kwargs): 

+

34 super().__init__(**kwargs) 

+

35 self.high_pressure_compressor = high_pressure_compressor 

+

36 self.low_pressure_compressor = low_pressure_compressor 

+

37 self.high_pressure_valve = high_pressure_valve 

+

38 self.low_pressure_valve = low_pressure_valve 

+

39 # Avoid nasty bugs for setting states 

+

40 if id(high_pressure_compressor) == id(low_pressure_compressor): 

+

41 self.high_pressure_compressor = deepcopy(low_pressure_compressor) 

+

42 if id(low_pressure_valve) == id(high_pressure_valve): 

+

43 self.high_pressure_valve = deepcopy(low_pressure_valve) 

+

44 

+

45 def get_all_components(self): 

+

46 return super().get_all_components() + [ 

+

47 self.high_pressure_compressor, 

+

48 self.low_pressure_compressor, 

+

49 self.high_pressure_valve, 

+

50 self.low_pressure_valve, 

+

51 ] 

+

52 

+

53 def calc_states(self, p_1, p_2, inputs: Inputs, fs_state: FlowsheetState): 

+

54 k_vapor_injection = inputs.get("k_vapor_injection", default=1) 

+

55 # Default according to Xu, 2019 

+

56 

+

57 p_vapor_injection = k_vapor_injection * np.sqrt(p_1 * p_2) 

+

58 

+

59 # Condenser outlet 

+

60 self.set_condenser_outlet_based_on_subcooling(p_con=p_2, inputs=inputs) 

+

61 # High pressure EV 

+

62 self.high_pressure_valve.state_inlet = self.condenser.state_outlet 

+

63 self.high_pressure_valve.calc_outlet(p_outlet=p_vapor_injection) 

+

64 

+

65 # Calculate low compressor stage to already have access to the mass flow rates. 

+

66 self.set_evaporator_outlet_based_on_superheating(p_eva=p_1, inputs=inputs) 

+

67 self.low_pressure_compressor.state_inlet = self.evaporator.state_outlet 

+

68 self.low_pressure_compressor.calc_state_outlet( 

+

69 p_outlet=p_vapor_injection, inputs=inputs, fs_state=fs_state 

+

70 ) 

+

71 m_flow_low = self.low_pressure_compressor.calc_m_flow(inputs=inputs, fs_state=fs_state) 

+

72 self.evaporator.m_flow = self.low_pressure_compressor.m_flow 

+

73 

+

74 # Injection component: 

+

75 x_vapor_injection, h_vapor_injection, state_low_ev_inlet = self.calc_injection() 

+

76 

+

77 # Low pressure EV 

+

78 self.low_pressure_valve.state_inlet = state_low_ev_inlet 

+

79 self.low_pressure_valve.calc_outlet(p_outlet=p_1) 

+

80 # Evaporator 

+

81 self.evaporator.state_inlet = self.low_pressure_valve.state_outlet 

+

82 

+

83 # Ideal Mixing of state_5 and state_1_VI: 

+

84 h_1_VI_mixed = ( 

+

85 (1-x_vapor_injection) * self.low_pressure_compressor.state_outlet.h + 

+

86 x_vapor_injection * h_vapor_injection 

+

87 ) 

+

88 self.high_pressure_compressor.state_inlet = self.med_prop.calc_state( 

+

89 "PH", p_vapor_injection, h_1_VI_mixed 

+

90 ) 

+

91 self.high_pressure_compressor.calc_state_outlet( 

+

92 p_outlet=p_2, inputs=inputs, fs_state=fs_state 

+

93 ) 

+

94 

+

95 # Check m_flow of both compressor stages to check if 

+

96 # there would be an asymmetry of how much refrigerant is transported 

+

97 m_flow_high = self.high_pressure_compressor.calc_m_flow( 

+

98 inputs=inputs, fs_state=fs_state 

+

99 ) 

+

100 m_flow_low_should = m_flow_high * (1-x_vapor_injection) 

+

101 percent_deviation = (m_flow_low - m_flow_low_should) / m_flow_low_should * 100 

+

102 logger.debug("Deviation of mass flow rates is %s percent", percent_deviation) 

+

103 

+

104 # Set states 

+

105 self.condenser.m_flow = self.high_pressure_compressor.m_flow 

+

106 self.condenser.state_inlet = self.high_pressure_compressor.state_outlet 

+

107 

+

108 fs_state.set( 

+

109 name="T_1", value=self.evaporator.state_outlet.T, 

+

110 unit="K", description="Refrigerant temperature at evaporator outlet" 

+

111 ) 

+

112 fs_state.set( 

+

113 name="T_2", value=self.high_pressure_compressor.state_outlet.T, 

+

114 unit="K", description="Compressor outlet temperature" 

+

115 ) 

+

116 fs_state.set( 

+

117 name="T_3", value=self.condenser.state_outlet.T, 

+

118 unit="K", description="Refrigerant temperature at condenser outlet" 

+

119 ) 

+

120 fs_state.set( 

+

121 name="T_4", value=self.evaporator.state_inlet.T, 

+

122 unit="K", description="Refrigerant temperature at evaporator inlet" 

+

123 ) 

+

124 fs_state.set( 

+

125 name="p_con", value=p_2, 

+

126 unit="Pa", description="Condensation pressure" 

+

127 ) 

+

128 fs_state.set( 

+

129 name="p_eva", value=p_1, 

+

130 unit="Pa", description="Evaporation pressure" 

+

131 ) 

+

132 

+

133 def calc_injection(self) -> (float, float, ThermodynamicState): 

+

134 """ 

+

135 Calculate the injection component, e.g. phase separator 

+

136 or heat exchanger. 

+

137 In this function, child classes must set inlets 

+

138 and calculate outlets of additional components. 

+

139 

+

140 Returns: 

+

141 float: Portion of vapor injected (x) 

+

142 float: Enthalpy of vapor injected 

+

143 ThermodynamicState: Inlet state of low pressure expansion valve 

+

144 """ 

+

145 raise NotImplementedError 

+

146 

+

147 def calc_electrical_power(self, inputs: Inputs, fs_state: FlowsheetState): 

+

148 P_el_low = self.low_pressure_compressor.calc_electrical_power( 

+

149 inputs=inputs, fs_state=fs_state 

+

150 ) 

+

151 P_el_high = self.high_pressure_compressor.calc_electrical_power( 

+

152 inputs=inputs, fs_state=fs_state 

+

153 ) 

+

154 fs_state.set( 

+

155 name="P_el_low", 

+

156 value=P_el_low, 

+

157 unit="W", 

+

158 description="Electrical power consumption of low stage compressor" 

+

159 ) 

+

160 fs_state.set( 

+

161 name="P_el_high", 

+

162 value=P_el_high, 

+

163 unit="W", 

+

164 description="Electrical power consumption of high stage compressor" 

+

165 ) 

+

166 return P_el_low + P_el_high 

+

167 

+

168 def get_states_in_order_for_plotting(self): 

+

169 """ 

+

170 List with all relevant states of two-stage cycle 

+

171 except the intermediate component, e.g. phase separator 

+

172 or heat exchanger. 

+

173 """ 

+

174 return [ 

+

175 self.low_pressure_valve.state_inlet, 

+

176 self.low_pressure_valve.state_outlet, 

+

177 self.evaporator.state_inlet, 

+

178 self.med_prop.calc_state("PQ", self.evaporator.state_inlet.p, 1), 

+

179 self.evaporator.state_outlet, 

+

180 self.low_pressure_compressor.state_inlet, 

+

181 self.low_pressure_compressor.state_outlet, 

+

182 self.high_pressure_compressor.state_inlet, 

+

183 self.high_pressure_compressor.state_outlet, 

+

184 self.condenser.state_inlet, 

+

185 self.med_prop.calc_state("PQ", self.condenser.state_inlet.p, 1), 

+

186 self.med_prop.calc_state("PQ", self.condenser.state_inlet.p, 0), 

+

187 self.condenser.state_outlet, 

+

188 self.high_pressure_valve.state_inlet, 

+

189 self.high_pressure_valve.state_outlet, 

+

190 ] 

+
+ + + diff --git a/docs/0.1.1/coverage/d_f54be612a69fd5f7___init___py.html b/docs/0.1.1/coverage/d_f54be612a69fd5f7___init___py.html new file mode 100644 index 0000000..eb0cfed --- /dev/null +++ b/docs/0.1.1/coverage/d_f54be612a69fd5f7___init___py.html @@ -0,0 +1,97 @@ + + + + + Coverage for vclibpy/components/__init__.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/__init__.py: + 100% +

+ +

+ 0 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+
+ + + diff --git a/docs/0.1.1/coverage/d_f54be612a69fd5f7_component_py.html b/docs/0.1.1/coverage/d_f54be612a69fd5f7_component_py.html new file mode 100644 index 0000000..22fff63 --- /dev/null +++ b/docs/0.1.1/coverage/d_f54be612a69fd5f7_component_py.html @@ -0,0 +1,232 @@ + + + + + Coverage for vclibpy/components/component.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/component.py: + 100% +

+ +

+ 36 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1from abc import ABC 

+

2from vclibpy.media import ThermodynamicState, MedProp 

+

3 

+

4 

+

5class BaseComponent(ABC): 

+

6 """ 

+

7 Abstract base class for defining interfaces of components in the vapor compression cycle. 

+

8 

+

9 Methods: 

+

10 start_secondary_med_prop(): 

+

11 To use multiprocessing, MedProp can't start in the main thread, as the object can't be pickled. 

+

12 This function starts possible secondary MedProp classes, for instance in heat exchangers. 

+

13 The default component does not have to override this function. 

+

14 

+

15 Properties: 

+

16 state_inlet (ThermodynamicState): 

+

17 Property for accessing and setting the inlet state of the component. 

+

18 state_outlet (ThermodynamicState): 

+

19 Property for accessing and setting the outlet state of the component. 

+

20 m_flow (float): 

+

21 Property for accessing and setting the mass flow rate through the component. 

+

22 med_prop (MedProp): 

+

23 Property for accessing and setting the property wrapper for the working fluid. 

+

24 """ 

+

25 

+

26 def __init__(self): 

+

27 """ 

+

28 Initialize the BaseComponent. 

+

29 """ 

+

30 self._state_inlet: ThermodynamicState = None 

+

31 self._state_outlet: ThermodynamicState = None 

+

32 self._m_flow: float = None 

+

33 self._med_prop: MedProp = None 

+

34 

+

35 def start_secondary_med_prop(self): 

+

36 """ 

+

37 Start secondary MedProp classes for multiprocessing. 

+

38 

+

39 To use multiprocessing, MedProp can't start in the main thread, as the object can't be pickled. 

+

40 This function starts possible secondary MedProp classes, for instance in heat exchangers. 

+

41 The default component does not have to override this function. 

+

42 """ 

+

43 pass 

+

44 

+

45 def terminate_secondary_med_prop(self): 

+

46 """ 

+

47 To use multi-processing, MedProp can't start 

+

48 in the main thread, as the object can't be pickled. 

+

49 

+

50 This function terminates possible secondary med-prop 

+

51 classes, for instance in heat exchangers. 

+

52 The default component does not have to override 

+

53 this function. 

+

54 """ 

+

55 pass 

+

56 

+

57 @property 

+

58 def state_inlet(self) -> ThermodynamicState: 

+

59 """ 

+

60 Get or set the inlet state of the component. 

+

61 

+

62 Returns: 

+

63 ThermodynamicState: Inlet state of the component. 

+

64 """ 

+

65 return self._state_inlet 

+

66 

+

67 @state_inlet.setter 

+

68 def state_inlet(self, state_inlet: ThermodynamicState): 

+

69 """ 

+

70 Set the inlet state of the component. 

+

71 

+

72 Args: 

+

73 state_inlet (ThermodynamicState): Inlet state to set. 

+

74 """ 

+

75 self._state_inlet = state_inlet 

+

76 

+

77 @property 

+

78 def state_outlet(self) -> ThermodynamicState: 

+

79 """ 

+

80 Get or set the outlet state of the component. 

+

81 

+

82 Returns: 

+

83 ThermodynamicState: Outlet state of the component. 

+

84 """ 

+

85 return self._state_outlet 

+

86 

+

87 @state_outlet.setter 

+

88 def state_outlet(self, state_outlet: ThermodynamicState): 

+

89 """ 

+

90 Set the outlet state of the component. 

+

91 

+

92 Args: 

+

93 state_outlet (ThermodynamicState): Outlet state to set. 

+

94 """ 

+

95 self._state_outlet = state_outlet 

+

96 

+

97 @property 

+

98 def m_flow(self) -> float: 

+

99 """ 

+

100 Get or set the mass flow rate through the component. 

+

101 

+

102 Returns: 

+

103 float: Mass flow rate through the component. 

+

104 """ 

+

105 return self._m_flow 

+

106 

+

107 @m_flow.setter 

+

108 def m_flow(self, m_flow: float): 

+

109 """ 

+

110 Set the mass flow rate through the component. 

+

111 

+

112 Args: 

+

113 m_flow (float): Mass flow rate to set. 

+

114 """ 

+

115 self._m_flow = m_flow 

+

116 

+

117 @property 

+

118 def med_prop(self) -> MedProp: 

+

119 """ 

+

120 Get or set the property wrapper for the working fluid. 

+

121 

+

122 Returns: 

+

123 MedProp: Property wrapper for the working fluid. 

+

124 """ 

+

125 return self._med_prop 

+

126 

+

127 @med_prop.setter 

+

128 def med_prop(self, med_prop: MedProp): 

+

129 """ 

+

130 Set the property wrapper for the working fluid. 

+

131 

+

132 Args: 

+

133 med_prop (MedProp): Property wrapper to set. 

+

134 """ 

+

135 self._med_prop = med_prop 

+
+ + + diff --git a/docs/0.1.1/coverage/d_f54be612a69fd5f7_phase_separator_py.html b/docs/0.1.1/coverage/d_f54be612a69fd5f7_phase_separator_py.html new file mode 100644 index 0000000..10b12c6 --- /dev/null +++ b/docs/0.1.1/coverage/d_f54be612a69fd5f7_phase_separator_py.html @@ -0,0 +1,176 @@ + + + + + Coverage for vclibpy/components/phase_separator.py: 100% + + + + + +
+
+

+ Coverage for vclibpy/components/phase_separator.py: + 100% +

+ +

+ 26 statements   + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+ +
+
+
+

1""" 

+

2Module with a simple phase separator model. 

+

3""" 

+

4 

+

5from vclibpy.media import ThermodynamicState 

+

6from vclibpy.components.component import BaseComponent 

+

7 

+

8 

+

9class PhaseSeparator(BaseComponent): 

+

10 """ 

+

11 A simple phase separator model. 

+

12 """ 

+

13 

+

14 def __init__(self): 

+

15 super().__init__() 

+

16 self._state_outlet_liquid: ThermodynamicState = None 

+

17 self._state_outlet_vapor: ThermodynamicState = None 

+

18 

+

19 @BaseComponent.state_inlet.setter 

+

20 def state_inlet(self, state_inlet: ThermodynamicState): 

+

21 """ 

+

22 Set the state of the inlet and calculate the outlet states for liquid and vapor phases. 

+

23 

+

24 Args: 

+

25 state_inlet (ThermodynamicState): Inlet state. 

+

26 """ 

+

27 self._state_inlet = state_inlet 

+

28 self.state_outlet_vapor = self.med_prop.calc_state("PQ", self.state_inlet.p, 1) 

+

29 self.state_outlet_liquid = self.med_prop.calc_state("PQ", self.state_inlet.p, 0) 

+

30 

+

31 @BaseComponent.state_outlet.setter 

+

32 def state_outlet(self, state: ThermodynamicState): 

+

33 """ 

+

34 This outlet is disabled for this component. 

+

35 

+

36 Args: 

+

37 state (ThermodynamicState): Outlet state. 

+

38 """ 

+

39 raise NotImplementedError("This outlet is disabled for this component") 

+

40 

+

41 @property 

+

42 def state_outlet_vapor(self) -> ThermodynamicState: 

+

43 """ 

+

44 Getter for the outlet state of the vapor phase. 

+

45 

+

46 Returns: 

+

47 ThermodynamicState: Outlet state for the vapor phase. 

+

48 """ 

+

49 return self._state_outlet_vapor 

+

50 

+

51 @state_outlet_vapor.setter 

+

52 def state_outlet_vapor(self, state: ThermodynamicState): 

+

53 """ 

+

54 Setter for the outlet state of the vapor phase. 

+

55 

+

56 Args: 

+

57 state (ThermodynamicState): Outlet state for the vapor phase. 

+

58 """ 

+

59 self._state_outlet_vapor = state 

+

60 

+

61 @property 

+

62 def state_outlet_liquid(self) -> ThermodynamicState: 

+

63 """ 

+

64 Getter for the outlet state of the liquid phase. 

+

65 

+

66 Returns: 

+

67 ThermodynamicState: Outlet state for the liquid phase. 

+

68 """ 

+

69 return self._state_outlet_liquid 

+

70 

+

71 @state_outlet_liquid.setter 

+

72 def state_outlet_liquid(self, state: ThermodynamicState): 

+

73 """ 

+

74 Setter for the outlet state of the liquid phase. 

+

75 

+

76 Args: 

+

77 state (ThermodynamicState): Outlet state for the liquid phase. 

+

78 """ 

+

79 self._state_outlet_liquid = state 

+
+ + + diff --git a/docs/0.1.1/coverage/favicon_32.png b/docs/0.1.1/coverage/favicon_32.png new file mode 100644 index 0000000..8649f04 Binary files /dev/null and b/docs/0.1.1/coverage/favicon_32.png differ diff --git a/docs/0.1.1/coverage/index.html b/docs/0.1.1/coverage/index.html new file mode 100644 index 0000000..858b904 --- /dev/null +++ b/docs/0.1.1/coverage/index.html @@ -0,0 +1,396 @@ + + + + + Coverage report + + + + + +
+
+

Coverage report: + 58% +

+ +
+ +
+

+ coverage.py v7.4.4, + created at 2024-10-30 15:10 +0000 +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Modulestatementsmissingexcludedcoverage
vclibpy/__init__.py200100%
vclibpy/components/__init__.py000100%
vclibpy/components/component.py3600100%
vclibpy/components/compressors/__init__.py400100%
vclibpy/components/compressors/compressor.py3503100%
vclibpy/components/compressors/constant_effectivness.py1400100%
vclibpy/components/compressors/rotary.py491098%
vclibpy/components/compressors/ten_coefficient.py9574022%
vclibpy/components/expansion_valves/__init__.py200100%
vclibpy/components/expansion_valves/bernoulli.py61083%
vclibpy/components/expansion_valves/expansion_valve.py1202100%
vclibpy/components/heat_exchangers/__init__.py200100%
vclibpy/components/heat_exchangers/economizer.py3203100%
vclibpy/components/heat_exchangers/heat_exchanger.py702297%
vclibpy/components/heat_exchangers/heat_transfer/__init__.py300100%
vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py313120%
vclibpy/components/heat_exchangers/heat_transfer/constant.py1200100%
vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py121292%
vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py363600%
vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py727200%
vclibpy/components/heat_exchangers/heat_transfer/wall.py1000100%
vclibpy/components/heat_exchangers/moving_boundary_ntu.py1337095%
vclibpy/components/heat_exchangers/ntu.py509082%
vclibpy/components/phase_separator.py2601100%
vclibpy/datamodels.py521098%
vclibpy/flowsheets/__init__.py400100%
vclibpy/flowsheets/base.py21146278%
vclibpy/flowsheets/standard.py3600100%
vclibpy/flowsheets/vapor_injection.py6301100%
vclibpy/flowsheets/vapor_injection_economizer.py4800100%
vclibpy/flowsheets/vapor_injection_phase_separator.py1800100%
vclibpy/media/__init__.py101090%
vclibpy/media/cool_prop.py5719267%
vclibpy/media/media.py538085%
vclibpy/media/ref_prop.py429379012%
vclibpy/media/states.py605092%
vclibpy/utils/__init__.py200100%
vclibpy/utils/automation.py9922078%
vclibpy/utils/nominal_design.py343400%
vclibpy/utils/plotting.py16972057%
vclibpy/utils/printing.py131300%
vclibpy/utils/sdf_.py7342242%
vclibpy/utils/ten_coefficient_compressor_reqression.py646410%
Total22399402358%
+

+ No items found using the specified filter. +

+
+ + + diff --git a/docs/0.1.1/coverage/keybd_closed.png b/docs/0.1.1/coverage/keybd_closed.png new file mode 100644 index 0000000..ba119c4 Binary files /dev/null and b/docs/0.1.1/coverage/keybd_closed.png differ diff --git a/docs/0.1.1/coverage/keybd_open.png b/docs/0.1.1/coverage/keybd_open.png new file mode 100644 index 0000000..a8bac6c Binary files /dev/null and b/docs/0.1.1/coverage/keybd_open.png differ diff --git a/docs/0.1.1/coverage/status.json b/docs/0.1.1/coverage/status.json new file mode 100644 index 0000000..acfa66a --- /dev/null +++ b/docs/0.1.1/coverage/status.json @@ -0,0 +1 @@ +{"note":"This file is an internal implementation detail to speed up HTML report generation. Its format can change at any time. You might be looking for the JSON report: https://coverage.rtfd.io/cmd.html#cmd-json","format":2,"version":"7.4.4","globals":"2a9fe4d43771f1021d00086a6bab24da","files":{"d_3aa0e56d51a2f798___init___py":{"hash":"8ef4e5d5be6ee96054691248b68c04b0","index":{"nums":[0,1,2,0,0,0,0,0],"html_filename":"d_3aa0e56d51a2f798___init___py.html","relative_filename":"vclibpy/__init__.py"}},"d_f54be612a69fd5f7___init___py":{"hash":"3c77fc9ef7f887ac2508d4109cf92472","index":{"nums":[0,1,0,0,0,0,0,0],"html_filename":"d_f54be612a69fd5f7___init___py.html","relative_filename":"vclibpy/components/__init__.py"}},"d_f54be612a69fd5f7_component_py":{"hash":"3db0ffe89ce541833830e98d0d13344d","index":{"nums":[0,1,36,0,0,0,0,0],"html_filename":"d_f54be612a69fd5f7_component_py.html","relative_filename":"vclibpy/components/component.py"}},"d_d45aa4312ad3649a___init___py":{"hash":"58c79786dd810b608768b6b102ce33bc","index":{"nums":[0,1,4,0,0,0,0,0],"html_filename":"d_d45aa4312ad3649a___init___py.html","relative_filename":"vclibpy/components/compressors/__init__.py"}},"d_d45aa4312ad3649a_compressor_py":{"hash":"e610ba34470ef26ae9ddeb217e8497e8","index":{"nums":[0,1,35,3,0,0,0,0],"html_filename":"d_d45aa4312ad3649a_compressor_py.html","relative_filename":"vclibpy/components/compressors/compressor.py"}},"d_d45aa4312ad3649a_constant_effectivness_py":{"hash":"6c8c3d90d9037e1e4af2177944012a83","index":{"nums":[0,1,14,0,0,0,0,0],"html_filename":"d_d45aa4312ad3649a_constant_effectivness_py.html","relative_filename":"vclibpy/components/compressors/constant_effectivness.py"}},"d_d45aa4312ad3649a_rotary_py":{"hash":"af7b7c2885234cb21c632f304450a2e5","index":{"nums":[0,1,49,0,1,0,0,0],"html_filename":"d_d45aa4312ad3649a_rotary_py.html","relative_filename":"vclibpy/components/compressors/rotary.py"}},"d_d45aa4312ad3649a_ten_coefficient_py":{"hash":"32e8b12aa1e91c3471c205056a136fad","index":{"nums":[0,1,95,0,74,0,0,0],"html_filename":"d_d45aa4312ad3649a_ten_coefficient_py.html","relative_filename":"vclibpy/components/compressors/ten_coefficient.py"}},"d_38531a0795c587f9___init___py":{"hash":"15a488013d0d4fec574cfa29a480f8ec","index":{"nums":[0,1,2,0,0,0,0,0],"html_filename":"d_38531a0795c587f9___init___py.html","relative_filename":"vclibpy/components/expansion_valves/__init__.py"}},"d_38531a0795c587f9_bernoulli_py":{"hash":"8143e3e6a35f9f70527ec9f6f6f58e98","index":{"nums":[0,1,6,0,1,0,0,0],"html_filename":"d_38531a0795c587f9_bernoulli_py.html","relative_filename":"vclibpy/components/expansion_valves/bernoulli.py"}},"d_38531a0795c587f9_expansion_valve_py":{"hash":"c1f6e24fb01bea7b352f52a083ea35f4","index":{"nums":[0,1,12,2,0,0,0,0],"html_filename":"d_38531a0795c587f9_expansion_valve_py.html","relative_filename":"vclibpy/components/expansion_valves/expansion_valve.py"}},"d_35fc0e049e81dfd6___init___py":{"hash":"62edc4ea1ff8cc29b75a2661f82df77c","index":{"nums":[0,1,2,0,0,0,0,0],"html_filename":"d_35fc0e049e81dfd6___init___py.html","relative_filename":"vclibpy/components/heat_exchangers/__init__.py"}},"d_35fc0e049e81dfd6_economizer_py":{"hash":"024c3260fd54d92584c950eed4083cbb","index":{"nums":[0,1,32,3,0,0,0,0],"html_filename":"d_35fc0e049e81dfd6_economizer_py.html","relative_filename":"vclibpy/components/heat_exchangers/economizer.py"}},"d_35fc0e049e81dfd6_heat_exchanger_py":{"hash":"2a399393ce01d2dd626d5e6e0fa8e0a8","index":{"nums":[0,1,70,2,2,0,0,0],"html_filename":"d_35fc0e049e81dfd6_heat_exchanger_py.html","relative_filename":"vclibpy/components/heat_exchangers/heat_exchanger.py"}},"d_4deeb89b86ecce82___init___py":{"hash":"cd0aefd2cbed7a9db71739b8c9cb8b50","index":{"nums":[0,1,3,0,0,0,0,0],"html_filename":"d_4deeb89b86ecce82___init___py.html","relative_filename":"vclibpy/components/heat_exchangers/heat_transfer/__init__.py"}},"d_4deeb89b86ecce82_air_to_wall_py":{"hash":"877afa8d94728f82ab6de27f7fd55dd4","index":{"nums":[0,1,31,2,31,0,0,0],"html_filename":"d_4deeb89b86ecce82_air_to_wall_py.html","relative_filename":"vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py"}},"d_4deeb89b86ecce82_constant_py":{"hash":"0b266129fe2feea7b8baf9c46c055fb7","index":{"nums":[0,1,12,0,0,0,0,0],"html_filename":"d_4deeb89b86ecce82_constant_py.html","relative_filename":"vclibpy/components/heat_exchangers/heat_transfer/constant.py"}},"d_4deeb89b86ecce82_heat_transfer_py":{"hash":"f51fdbae938471bf019d6c28e7cb7872","index":{"nums":[0,1,12,2,1,0,0,0],"html_filename":"d_4deeb89b86ecce82_heat_transfer_py.html","relative_filename":"vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py"}},"d_4deeb89b86ecce82_pipe_to_wall_py":{"hash":"47a45d1a3a597da79c6d257efeab6863","index":{"nums":[0,1,36,0,36,0,0,0],"html_filename":"d_4deeb89b86ecce82_pipe_to_wall_py.html","relative_filename":"vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py"}},"d_4deeb89b86ecce82_vdi_atlas_air_to_wall_py":{"hash":"624025a66375e3409fda3c8494e98e4e","index":{"nums":[0,1,72,0,72,0,0,0],"html_filename":"d_4deeb89b86ecce82_vdi_atlas_air_to_wall_py.html","relative_filename":"vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py"}},"d_4deeb89b86ecce82_wall_py":{"hash":"ac2945ad9159828416ff549823978b51","index":{"nums":[0,1,10,0,0,0,0,0],"html_filename":"d_4deeb89b86ecce82_wall_py.html","relative_filename":"vclibpy/components/heat_exchangers/heat_transfer/wall.py"}},"d_35fc0e049e81dfd6_moving_boundary_ntu_py":{"hash":"5516ecdbe35bed99c3c3519d7c8581af","index":{"nums":[0,1,133,0,7,0,0,0],"html_filename":"d_35fc0e049e81dfd6_moving_boundary_ntu_py.html","relative_filename":"vclibpy/components/heat_exchangers/moving_boundary_ntu.py"}},"d_35fc0e049e81dfd6_ntu_py":{"hash":"b66e671c1b58cf60272dbcb359925ef8","index":{"nums":[0,1,50,0,9,0,0,0],"html_filename":"d_35fc0e049e81dfd6_ntu_py.html","relative_filename":"vclibpy/components/heat_exchangers/ntu.py"}},"d_f54be612a69fd5f7_phase_separator_py":{"hash":"d94ca0bf3649559551e67fc1eee4561d","index":{"nums":[0,1,26,1,0,0,0,0],"html_filename":"d_f54be612a69fd5f7_phase_separator_py.html","relative_filename":"vclibpy/components/phase_separator.py"}},"d_3aa0e56d51a2f798_datamodels_py":{"hash":"67175039a9e725edaa7d401028c8d40b","index":{"nums":[0,1,52,0,1,0,0,0],"html_filename":"d_3aa0e56d51a2f798_datamodels_py.html","relative_filename":"vclibpy/datamodels.py"}},"d_dae209ba2e6604e9___init___py":{"hash":"7281f14e47e81fe0b9ad9a12b319bd57","index":{"nums":[0,1,4,0,0,0,0,0],"html_filename":"d_dae209ba2e6604e9___init___py.html","relative_filename":"vclibpy/flowsheets/__init__.py"}},"d_dae209ba2e6604e9_base_py":{"hash":"71d4e3d737b4edff9966d96410acd5f5","index":{"nums":[0,1,211,2,46,0,0,0],"html_filename":"d_dae209ba2e6604e9_base_py.html","relative_filename":"vclibpy/flowsheets/base.py"}},"d_dae209ba2e6604e9_standard_py":{"hash":"4fb0cef586438a2d17f270cc784297b1","index":{"nums":[0,1,36,0,0,0,0,0],"html_filename":"d_dae209ba2e6604e9_standard_py.html","relative_filename":"vclibpy/flowsheets/standard.py"}},"d_dae209ba2e6604e9_vapor_injection_py":{"hash":"abc9fb0b06ee82c48c40c721eeba403d","index":{"nums":[0,1,63,1,0,0,0,0],"html_filename":"d_dae209ba2e6604e9_vapor_injection_py.html","relative_filename":"vclibpy/flowsheets/vapor_injection.py"}},"d_dae209ba2e6604e9_vapor_injection_economizer_py":{"hash":"84bb7ee40ee94ba593266d83ea146d2b","index":{"nums":[0,1,48,0,0,0,0,0],"html_filename":"d_dae209ba2e6604e9_vapor_injection_economizer_py.html","relative_filename":"vclibpy/flowsheets/vapor_injection_economizer.py"}},"d_dae209ba2e6604e9_vapor_injection_phase_separator_py":{"hash":"3aded356bf6949c71b6701c3ee34d559","index":{"nums":[0,1,18,0,0,0,0,0],"html_filename":"d_dae209ba2e6604e9_vapor_injection_phase_separator_py.html","relative_filename":"vclibpy/flowsheets/vapor_injection_phase_separator.py"}},"d_c048ebee450da2af___init___py":{"hash":"87b8fac9e8e02ce5d66655daa17176d8","index":{"nums":[0,1,10,0,1,0,0,0],"html_filename":"d_c048ebee450da2af___init___py.html","relative_filename":"vclibpy/media/__init__.py"}},"d_c048ebee450da2af_cool_prop_py":{"hash":"73fcbd3358d6190bf6a5b01479fe8439","index":{"nums":[0,1,57,2,19,0,0,0],"html_filename":"d_c048ebee450da2af_cool_prop_py.html","relative_filename":"vclibpy/media/cool_prop.py"}},"d_c048ebee450da2af_media_py":{"hash":"4d3971c7dd207fc4eae4646296604790","index":{"nums":[0,1,53,0,8,0,0,0],"html_filename":"d_c048ebee450da2af_media_py.html","relative_filename":"vclibpy/media/media.py"}},"d_c048ebee450da2af_ref_prop_py":{"hash":"1044a06eaaea85af194aace054ea8ffc","index":{"nums":[0,1,429,0,379,0,0,0],"html_filename":"d_c048ebee450da2af_ref_prop_py.html","relative_filename":"vclibpy/media/ref_prop.py"}},"d_c048ebee450da2af_states_py":{"hash":"15f3bffaf147424b6befa389fb5307b8","index":{"nums":[0,1,60,0,5,0,0,0],"html_filename":"d_c048ebee450da2af_states_py.html","relative_filename":"vclibpy/media/states.py"}},"d_57d6adb9ba5af1cf___init___py":{"hash":"a655ec0211a7f7e93d3f8f156fdafef8","index":{"nums":[0,1,2,0,0,0,0,0],"html_filename":"d_57d6adb9ba5af1cf___init___py.html","relative_filename":"vclibpy/utils/__init__.py"}},"d_57d6adb9ba5af1cf_automation_py":{"hash":"97a292dbb7aa146c23aadc4aec252f7e","index":{"nums":[0,1,99,0,22,0,0,0],"html_filename":"d_57d6adb9ba5af1cf_automation_py.html","relative_filename":"vclibpy/utils/automation.py"}},"d_57d6adb9ba5af1cf_nominal_design_py":{"hash":"4a08a048acd7717988bf6f5af8e281a8","index":{"nums":[0,1,34,0,34,0,0,0],"html_filename":"d_57d6adb9ba5af1cf_nominal_design_py.html","relative_filename":"vclibpy/utils/nominal_design.py"}},"d_57d6adb9ba5af1cf_plotting_py":{"hash":"e09e0d5421b6146273260635cc09af49","index":{"nums":[0,1,169,0,72,0,0,0],"html_filename":"d_57d6adb9ba5af1cf_plotting_py.html","relative_filename":"vclibpy/utils/plotting.py"}},"d_57d6adb9ba5af1cf_printing_py":{"hash":"4648bc565d1f47812c7ecd6ddb8b5232","index":{"nums":[0,1,13,0,13,0,0,0],"html_filename":"d_57d6adb9ba5af1cf_printing_py.html","relative_filename":"vclibpy/utils/printing.py"}},"d_57d6adb9ba5af1cf_sdf__py":{"hash":"f5df962d66e060e06edca81baf7c1bf8","index":{"nums":[0,1,73,2,42,0,0,0],"html_filename":"d_57d6adb9ba5af1cf_sdf__py.html","relative_filename":"vclibpy/utils/sdf_.py"}},"d_57d6adb9ba5af1cf_ten_coefficient_compressor_reqression_py":{"hash":"687adf63f4c478a46a5dcf8332602b77","index":{"nums":[0,1,64,1,64,0,0,0],"html_filename":"d_57d6adb9ba5af1cf_ten_coefficient_compressor_reqression_py.html","relative_filename":"vclibpy/utils/ten_coefficient_compressor_reqression.py"}}}} \ No newline at end of file diff --git a/docs/0.1.1/coverage/style.css b/docs/0.1.1/coverage/style.css new file mode 100644 index 0000000..aec9cbe --- /dev/null +++ b/docs/0.1.1/coverage/style.css @@ -0,0 +1,309 @@ +@charset "UTF-8"; +/* Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 */ +/* For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt */ +/* Don't edit this .css file. Edit the .scss file instead! */ +html, body, h1, h2, h3, p, table, td, th { margin: 0; padding: 0; border: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } + +body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-size: 1em; background: #fff; color: #000; } + +@media (prefers-color-scheme: dark) { body { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { body { color: #eee; } } + +html > body { font-size: 16px; } + +a:active, a:focus { outline: 2px dashed #007acc; } + +p { font-size: .875em; line-height: 1.4em; } + +table { border-collapse: collapse; } + +td { vertical-align: top; } + +table tr.hidden { display: none !important; } + +p#no_rows { display: none; font-size: 1.2em; } + +a.nav { text-decoration: none; color: inherit; } + +a.nav:hover { text-decoration: underline; color: inherit; } + +.hidden { display: none; } + +header { background: #f8f8f8; width: 100%; z-index: 2; border-bottom: 1px solid #ccc; } + +@media (prefers-color-scheme: dark) { header { background: black; } } + +@media (prefers-color-scheme: dark) { header { border-color: #333; } } + +header .content { padding: 1rem 3.5rem; } + +header h2 { margin-top: .5em; font-size: 1em; } + +header p.text { margin: .5em 0 -.5em; color: #666; font-style: italic; } + +@media (prefers-color-scheme: dark) { header p.text { color: #aaa; } } + +header.sticky { position: fixed; left: 0; right: 0; height: 2.5em; } + +header.sticky .text { display: none; } + +header.sticky h1, header.sticky h2 { font-size: 1em; margin-top: 0; display: inline-block; } + +header.sticky .content { padding: 0.5rem 3.5rem; } + +header.sticky .content p { font-size: 1em; } + +header.sticky ~ #source { padding-top: 6.5em; } + +main { position: relative; z-index: 1; } + +footer { margin: 1rem 3.5rem; } + +footer .content { padding: 0; color: #666; font-style: italic; } + +@media (prefers-color-scheme: dark) { footer .content { color: #aaa; } } + +#index { margin: 1rem 0 0 3.5rem; } + +h1 { font-size: 1.25em; display: inline-block; } + +#filter_container { float: right; margin: 0 2em 0 0; } + +#filter_container input { width: 10em; padding: 0.2em 0.5em; border: 2px solid #ccc; background: #fff; color: #000; } + +@media (prefers-color-scheme: dark) { #filter_container input { border-color: #444; } } + +@media (prefers-color-scheme: dark) { #filter_container input { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { #filter_container input { color: #eee; } } + +#filter_container input:focus { border-color: #007acc; } + +header button { font-family: inherit; font-size: inherit; border: 1px solid; border-radius: .2em; color: inherit; padding: .1em .5em; margin: 1px calc(.1em + 1px); cursor: pointer; border-color: #ccc; } + +@media (prefers-color-scheme: dark) { header button { border-color: #444; } } + +header button:active, header button:focus { outline: 2px dashed #007acc; } + +header button.run { background: #eeffee; } + +@media (prefers-color-scheme: dark) { header button.run { background: #373d29; } } + +header button.run.show_run { background: #dfd; border: 2px solid #00dd00; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.run.show_run { background: #373d29; } } + +header button.mis { background: #ffeeee; } + +@media (prefers-color-scheme: dark) { header button.mis { background: #4b1818; } } + +header button.mis.show_mis { background: #fdd; border: 2px solid #ff0000; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.mis.show_mis { background: #4b1818; } } + +header button.exc { background: #f7f7f7; } + +@media (prefers-color-scheme: dark) { header button.exc { background: #333; } } + +header button.exc.show_exc { background: #eee; border: 2px solid #808080; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.exc.show_exc { background: #333; } } + +header button.par { background: #ffffd5; } + +@media (prefers-color-scheme: dark) { header button.par { background: #650; } } + +header button.par.show_par { background: #ffa; border: 2px solid #bbbb00; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.par.show_par { background: #650; } } + +#help_panel, #source p .annotate.long { display: none; position: absolute; z-index: 999; background: #ffffcc; border: 1px solid #888; border-radius: .2em; color: #333; padding: .25em .5em; } + +#source p .annotate.long { white-space: normal; float: right; top: 1.75em; right: 1em; height: auto; } + +#help_panel_wrapper { float: right; position: relative; } + +#keyboard_icon { margin: 5px; } + +#help_panel_state { display: none; } + +#help_panel { top: 25px; right: 0; padding: .75em; border: 1px solid #883; color: #333; } + +#help_panel .keyhelp p { margin-top: .75em; } + +#help_panel .legend { font-style: italic; margin-bottom: 1em; } + +.indexfile #help_panel { width: 25em; } + +.pyfile #help_panel { width: 18em; } + +#help_panel_state:checked ~ #help_panel { display: block; } + +kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight: bold; background: #eee; border-radius: 3px; } + +#source { padding: 1em 0 1em 3.5rem; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; } + +#source p { position: relative; white-space: pre; } + +#source p * { box-sizing: border-box; } + +#source p .n { float: left; text-align: right; width: 3.5rem; box-sizing: border-box; margin-left: -3.5rem; padding-right: 1em; color: #999; user-select: none; } + +@media (prefers-color-scheme: dark) { #source p .n { color: #777; } } + +#source p .n.highlight { background: #ffdd00; } + +#source p .n a { scroll-margin-top: 6em; text-decoration: none; color: #999; } + +@media (prefers-color-scheme: dark) { #source p .n a { color: #777; } } + +#source p .n a:hover { text-decoration: underline; color: #999; } + +@media (prefers-color-scheme: dark) { #source p .n a:hover { color: #777; } } + +#source p .t { display: inline-block; width: 100%; box-sizing: border-box; margin-left: -.5em; padding-left: 0.3em; border-left: 0.2em solid #fff; } + +@media (prefers-color-scheme: dark) { #source p .t { border-color: #1e1e1e; } } + +#source p .t:hover { background: #f2f2f2; } + +@media (prefers-color-scheme: dark) { #source p .t:hover { background: #282828; } } + +#source p .t:hover ~ .r .annotate.long { display: block; } + +#source p .t .com { color: #008000; font-style: italic; line-height: 1px; } + +@media (prefers-color-scheme: dark) { #source p .t .com { color: #6a9955; } } + +#source p .t .key { font-weight: bold; line-height: 1px; } + +#source p .t .str { color: #0451a5; } + +@media (prefers-color-scheme: dark) { #source p .t .str { color: #9cdcfe; } } + +#source p.mis .t { border-left: 0.2em solid #ff0000; } + +#source p.mis.show_mis .t { background: #fdd; } + +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t { background: #4b1818; } } + +#source p.mis.show_mis .t:hover { background: #f2d2d2; } + +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t:hover { background: #532323; } } + +#source p.run .t { border-left: 0.2em solid #00dd00; } + +#source p.run.show_run .t { background: #dfd; } + +@media (prefers-color-scheme: dark) { #source p.run.show_run .t { background: #373d29; } } + +#source p.run.show_run .t:hover { background: #d2f2d2; } + +@media (prefers-color-scheme: dark) { #source p.run.show_run .t:hover { background: #404633; } } + +#source p.exc .t { border-left: 0.2em solid #808080; } + +#source p.exc.show_exc .t { background: #eee; } + +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t { background: #333; } } + +#source p.exc.show_exc .t:hover { background: #e2e2e2; } + +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t:hover { background: #3c3c3c; } } + +#source p.par .t { border-left: 0.2em solid #bbbb00; } + +#source p.par.show_par .t { background: #ffa; } + +@media (prefers-color-scheme: dark) { #source p.par.show_par .t { background: #650; } } + +#source p.par.show_par .t:hover { background: #f2f2a2; } + +@media (prefers-color-scheme: dark) { #source p.par.show_par .t:hover { background: #6d5d0c; } } + +#source p .r { position: absolute; top: 0; right: 2.5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } + +#source p .annotate { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; color: #666; padding-right: .5em; } + +@media (prefers-color-scheme: dark) { #source p .annotate { color: #ddd; } } + +#source p .annotate.short:hover ~ .long { display: block; } + +#source p .annotate.long { width: 30em; right: 2.5em; } + +#source p input { display: none; } + +#source p input ~ .r label.ctx { cursor: pointer; border-radius: .25em; } + +#source p input ~ .r label.ctx::before { content: "▶ "; } + +#source p input ~ .r label.ctx:hover { background: #e8f4ff; color: #666; } + +@media (prefers-color-scheme: dark) { #source p input ~ .r label.ctx:hover { background: #0f3a42; } } + +@media (prefers-color-scheme: dark) { #source p input ~ .r label.ctx:hover { color: #aaa; } } + +#source p input:checked ~ .r label.ctx { background: #d0e8ff; color: #666; border-radius: .75em .75em 0 0; padding: 0 .5em; margin: -.25em 0; } + +@media (prefers-color-scheme: dark) { #source p input:checked ~ .r label.ctx { background: #056; } } + +@media (prefers-color-scheme: dark) { #source p input:checked ~ .r label.ctx { color: #aaa; } } + +#source p input:checked ~ .r label.ctx::before { content: "▼ "; } + +#source p input:checked ~ .ctxs { padding: .25em .5em; overflow-y: scroll; max-height: 10.5em; } + +#source p label.ctx { color: #999; display: inline-block; padding: 0 .5em; font-size: .8333em; } + +@media (prefers-color-scheme: dark) { #source p label.ctx { color: #777; } } + +#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #d0e8ff; border-radius: .25em; margin-right: 1.75em; text-align: right; } + +@media (prefers-color-scheme: dark) { #source p .ctxs { background: #056; } } + +#index { font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.875em; } + +#index table.index { margin-left: -.5em; } + +#index td, #index th { text-align: right; width: 5em; padding: .25em .5em; border-bottom: 1px solid #eee; } + +@media (prefers-color-scheme: dark) { #index td, #index th { border-color: #333; } } + +#index td.name, #index th.name { text-align: left; width: auto; } + +#index th { font-style: italic; color: #333; cursor: pointer; } + +@media (prefers-color-scheme: dark) { #index th { color: #ddd; } } + +#index th:hover { background: #eee; } + +@media (prefers-color-scheme: dark) { #index th:hover { background: #333; } } + +#index th[aria-sort="ascending"], #index th[aria-sort="descending"] { white-space: nowrap; background: #eee; padding-left: .5em; } + +@media (prefers-color-scheme: dark) { #index th[aria-sort="ascending"], #index th[aria-sort="descending"] { background: #333; } } + +#index th[aria-sort="ascending"]::after { font-family: sans-serif; content: " ↑"; } + +#index th[aria-sort="descending"]::after { font-family: sans-serif; content: " ↓"; } + +#index td.name a { text-decoration: none; color: inherit; } + +#index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-top: 1px solid #ccc; border-bottom: none; } + +#index tr.file:hover { background: #eee; } + +@media (prefers-color-scheme: dark) { #index tr.file:hover { background: #333; } } + +#index tr.file:hover td.name { text-decoration: underline; color: inherit; } + +#scroll_marker { position: fixed; z-index: 3; right: 0; top: 0; width: 16px; height: 100%; background: #fff; border-left: 1px solid #eee; will-change: transform; } + +@media (prefers-color-scheme: dark) { #scroll_marker { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { #scroll_marker { border-color: #333; } } + +#scroll_marker .marker { background: #ccc; position: absolute; min-height: 3px; width: 100%; } + +@media (prefers-color-scheme: dark) { #scroll_marker .marker { background: #444; } } diff --git a/docs/0.1.1/docs/.buildinfo b/docs/0.1.1/docs/.buildinfo new file mode 100644 index 0000000..362e8fa --- /dev/null +++ b/docs/0.1.1/docs/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 1dd07c518b80631864c234d8576d8256 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/0.1.1/docs/.doctrees/Contribution.doctree b/docs/0.1.1/docs/.doctrees/Contribution.doctree new file mode 100644 index 0000000..d7ee8c4 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/Contribution.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/modules.doctree b/docs/0.1.1/docs/.doctrees/code/modules.doctree new file mode 100644 index 0000000..034510c Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/modules.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.components.compressors.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.compressors.doctree new file mode 100644 index 0000000..c44aa11 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.compressors.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.components.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.doctree new file mode 100644 index 0000000..44af6d8 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.components.expansion_valves.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.expansion_valves.doctree new file mode 100644 index 0000000..c3eff31 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.expansion_valves.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.components.heat_exchangers.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.heat_exchangers.doctree new file mode 100644 index 0000000..7390101 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.heat_exchangers.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.components.heat_exchangers.heat_transfer.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.heat_exchangers.heat_transfer.doctree new file mode 100644 index 0000000..4b0ac1e Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.components.heat_exchangers.heat_transfer.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.doctree new file mode 100644 index 0000000..75263b8 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.flowsheets.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.flowsheets.doctree new file mode 100644 index 0000000..50cb264 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.flowsheets.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.media.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.media.doctree new file mode 100644 index 0000000..64a3f3c Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.media.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/code/vclibpy.utils.doctree b/docs/0.1.1/docs/.doctrees/code/vclibpy.utils.doctree new file mode 100644 index 0000000..3077d22 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/code/vclibpy.utils.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/environment.pickle b/docs/0.1.1/docs/.doctrees/environment.pickle new file mode 100644 index 0000000..95af28d Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/environment.pickle differ diff --git a/docs/0.1.1/docs/.doctrees/examples/e1_refrigerant_data.doctree b/docs/0.1.1/docs/.doctrees/examples/e1_refrigerant_data.doctree new file mode 100644 index 0000000..9a9e5e9 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/examples/e1_refrigerant_data.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/examples/e2_compressor.doctree b/docs/0.1.1/docs/.doctrees/examples/e2_compressor.doctree new file mode 100644 index 0000000..05ee0f2 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/examples/e2_compressor.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/examples/e3_inputs_and_flowsheet_state.doctree b/docs/0.1.1/docs/.doctrees/examples/e3_inputs_and_flowsheet_state.doctree new file mode 100644 index 0000000..ded570d Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/examples/e3_inputs_and_flowsheet_state.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/examples/e4_heat_exchanger.doctree b/docs/0.1.1/docs/.doctrees/examples/e4_heat_exchanger.doctree new file mode 100644 index 0000000..dfb4842 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/examples/e4_heat_exchanger.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/examples/e5_expansion_valve.doctree b/docs/0.1.1/docs/.doctrees/examples/e5_expansion_valve.doctree new file mode 100644 index 0000000..53dfd94 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/examples/e5_expansion_valve.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/examples/e6_simple_heat_pump.doctree b/docs/0.1.1/docs/.doctrees/examples/e6_simple_heat_pump.doctree new file mode 100644 index 0000000..671f68d Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/examples/e6_simple_heat_pump.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/examples/e7_vapor_injection.doctree b/docs/0.1.1/docs/.doctrees/examples/e7_vapor_injection.doctree new file mode 100644 index 0000000..660881f Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/examples/e7_vapor_injection.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/index.doctree b/docs/0.1.1/docs/.doctrees/index.doctree new file mode 100644 index 0000000..ea9c7a4 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/index.doctree differ diff --git a/docs/0.1.1/docs/.doctrees/version_his.doctree b/docs/0.1.1/docs/.doctrees/version_his.doctree new file mode 100644 index 0000000..c26de14 Binary files /dev/null and b/docs/0.1.1/docs/.doctrees/version_his.doctree differ diff --git a/docs/0.1.1/docs/.nojekyll b/docs/0.1.1/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/0.1.1/docs/Contribution.html b/docs/0.1.1/docs/Contribution.html new file mode 100644 index 0000000..b8a5de2 --- /dev/null +++ b/docs/0.1.1/docs/Contribution.html @@ -0,0 +1,172 @@ + + + + + + + + + Contribute as a user — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Contribute as a user

+

The documentation, examples and tutorials should be understandable and the code bug-free. +As all user’s have different backgrounds, you may not understand everything or encounter bugs. +In that case, PLEASE raise an issue here.

+

Consider labeling the issue using the flag bug or documentation / question.

+
+
+

Contribute as a developer

+

If you instead want to contribute new features or fix bugs yourself, we are more than happy.

+

Please also raise an issue and create a new branch labeled issueXY_some_name. +Here, XY is the number of your issue and some_name is a meaingful description.

+

Once you’re feature is ready, create a pull request and check if the pipeline succeeds. +Assign a reviewer before merging. Once review is finished, you can merge.

+

Before implementing or modifying modules, classes or functions, please read the following page.

+
+

Styleguide

+

We use PEP8 as a styleguide. Some IDEs (like PyCharm) automatically show you code that is not in PEP8. If you don’t have such an IDE, please read this page to get a better understanding of it.

+
+
+

Documentation

+

All created or modified function should be documented properly. Try to follow the structure already present. If possible, write a little doctest example into the docstring to make clear to user’s what the desired output of your function is. All non self-explanatory lines of code should include a comment. We use the pycharm-style for docstrings, e.g.

+
def foo(dummy, dummy2):
+    """
+    Describe what the function does in here.
+    The blank line below is necessary for the doc to render nicely.
+
+    Args:
+        dummy (str):
+            Any parameter description
+        dummy2 (int,float):
+            A variable that may have two types
+    """
+
+
+
+
+

Unit-Tests

+

Espacially when creating new functions or classes, you have to add a unit-test function. +Open the test_module.py file in the \tests-directory and add a function to the class TestModulewith a name like test_my_new_function. If you create a new module, you have to create a new test_my_new_module.py file and follow the existing structure of the +other test-files.

+

If you are not familiar with unit-tests, here is a quick summary:

+
    +
  • Test as many things as possible. Even seemingly silly tests like correct input-format help prevent future problems for new users

  • +
  • use the self.assertSOMETHING functions provided by unittest. This way a test failure is presented correctly An error inside your test function will not be handeled as a failure but an error.

  • +
  • If the success of your test depends on the used device, you can use decorators like skip(), skipif(numpy.__version__<(1, 0), "not supported with your numpy version"), etc.

  • +
  • setUp() and tearDown() are called before and after each test. Use this functions to define parameters used in every test, or to close applications like Dymola once a test is completed.

  • +
  • See the unittest-documentation for further information

  • +
+

You can check your work by running all tests before commiting to git.

+
+
+

Pylint

+

With pylint we try to keep our code clean.
+See the description in this repo on information on what pylint is and how to use it.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/index.html b/docs/0.1.1/docs/_modules/index.html new file mode 100644 index 0000000..703afdf --- /dev/null +++ b/docs/0.1.1/docs/_modules/index.html @@ -0,0 +1,131 @@ + + + + + + + + Overview: module code — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ + +
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/component.html b/docs/0.1.1/docs/_modules/vclibpy/components/component.html new file mode 100644 index 0000000..880c27e --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/component.html @@ -0,0 +1,239 @@ + + + + + + + + vclibpy.components.component — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.components.component

+from abc import ABC
+from vclibpy.media import ThermodynamicState, MedProp
+
+
+
[docs]class BaseComponent(ABC): + """ + Abstract base class for defining interfaces of components in the vapor compression cycle. + + Methods: + start_secondary_med_prop(): + To use multiprocessing, MedProp can't start in the main thread, as the object can't be pickled. + This function starts possible secondary MedProp classes, for instance in heat exchangers. + The default component does not have to override this function. + + Properties: + state_inlet (ThermodynamicState): + Property for accessing and setting the inlet state of the component. + state_outlet (ThermodynamicState): + Property for accessing and setting the outlet state of the component. + m_flow (float): + Property for accessing and setting the mass flow rate through the component. + med_prop (MedProp): + Property for accessing and setting the property wrapper for the working fluid. + """ + + def __init__(self): + """ + Initialize the BaseComponent. + """ + self._state_inlet: ThermodynamicState = None + self._state_outlet: ThermodynamicState = None + self._m_flow: float = None + self._med_prop: MedProp = None + +
[docs] def start_secondary_med_prop(self): + """ + Start secondary MedProp classes for multiprocessing. + + To use multiprocessing, MedProp can't start in the main thread, as the object can't be pickled. + This function starts possible secondary MedProp classes, for instance in heat exchangers. + The default component does not have to override this function. + """ + pass
+ +
[docs] def terminate_secondary_med_prop(self): + """ + To use multi-processing, MedProp can't start + in the main thread, as the object can't be pickled. + + This function terminates possible secondary med-prop + classes, for instance in heat exchangers. + The default component does not have to override + this function. + """ + pass
+ + @property + def state_inlet(self) -> ThermodynamicState: + """ + Get or set the inlet state of the component. + + Returns: + ThermodynamicState: Inlet state of the component. + """ + return self._state_inlet + + @state_inlet.setter + def state_inlet(self, state_inlet: ThermodynamicState): + """ + Set the inlet state of the component. + + Args: + state_inlet (ThermodynamicState): Inlet state to set. + """ + self._state_inlet = state_inlet + + @property + def state_outlet(self) -> ThermodynamicState: + """ + Get or set the outlet state of the component. + + Returns: + ThermodynamicState: Outlet state of the component. + """ + return self._state_outlet + + @state_outlet.setter + def state_outlet(self, state_outlet: ThermodynamicState): + """ + Set the outlet state of the component. + + Args: + state_outlet (ThermodynamicState): Outlet state to set. + """ + self._state_outlet = state_outlet + + @property + def m_flow(self) -> float: + """ + Get or set the mass flow rate through the component. + + Returns: + float: Mass flow rate through the component. + """ + return self._m_flow + + @m_flow.setter + def m_flow(self, m_flow: float): + """ + Set the mass flow rate through the component. + + Args: + m_flow (float): Mass flow rate to set. + """ + self._m_flow = m_flow + + @property + def med_prop(self) -> MedProp: + """ + Get or set the property wrapper for the working fluid. + + Returns: + MedProp: Property wrapper for the working fluid. + """ + return self._med_prop + + @med_prop.setter + def med_prop(self, med_prop: MedProp): + """ + Set the property wrapper for the working fluid. + + Args: + med_prop (MedProp): Property wrapper to set. + """ + self._med_prop = med_prop
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/compressors/compressor.html b/docs/0.1.1/docs/_modules/vclibpy/components/compressors/compressor.html new file mode 100644 index 0000000..edcc6f6 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/compressors/compressor.html @@ -0,0 +1,277 @@ + + + + + + + + vclibpy.components.compressors.compressor — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.compressors.compressor

+"""
+Module for different compressor models
+"""
+
+from vclibpy.components.component import BaseComponent
+from vclibpy.datamodels import Inputs, FlowsheetState
+
+
+
[docs]class Compressor(BaseComponent): + """ + Base compressor class to be extended for specific compressor models. + + Args: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + + Methods: + get_lambda_h(inputs: Inputs) -> float: + Get the volumetric efficiency. + + get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float: + Get the isentropic efficiency. + + get_eta_mech(inputs: Inputs) -> float: + Get the mechanical efficiency. + + get_p_outlet() -> float: + Get the outlet pressure. + + get_n_absolute(n: float) -> float: + Return the absolute compressor frequency based on the relative speed. + + calc_state_outlet(p_outlet: float, inputs: Inputs, fs_state: FlowsheetState): + Calculate the outlet state based on the high pressure level and provided inputs. + + calc_m_flow(inputs: Inputs, fs_state: FlowsheetState) -> float: + Calculate the refrigerant mass flow rate. + + calc_electrical_power(inputs: Inputs, fs_state: FlowsheetState) -> float: + Calculate the electrical power consumed by the compressor based on an adiabatic energy balance. + """ + + def __init__(self, N_max: float, V_h: float): + """ + Initialize the compressor. + + Args: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + """ + super().__init__() + self.N_max = N_max + self.V_h = V_h + +
[docs] def get_lambda_h(self, inputs: Inputs) -> float: + """ + Get the volumetric efficiency. + + Args: + inputs (Inputs): Inputs for the calculation. + + Returns: + float: Volumetric efficiency. + """ + raise NotImplementedError("Re-implement this function to use it")
+ +
[docs] def get_eta_isentropic(self, p_outlet: float, inputs: Inputs) -> float: + """ + Get the isentropic efficiency. + + Args: + p_outlet (float): High pressure value. + inputs (Inputs): Inputs for the calculation. + + Returns: + float: Isentropic efficiency. + """ + raise NotImplementedError("Re-implement this function to use it")
+ +
[docs] def get_eta_mech(self, inputs: Inputs) -> float: + """ + Get the mechanical efficiency including motor and inverter efficiencies. + + Args: + inputs (Inputs): Inputs for the calculation. + + Returns: + float: Mechanical efficiency including motor and inverter efficiencies. + """ + raise NotImplementedError("Re-implement this function to use it")
+ +
[docs] def get_p_outlet(self) -> float: + """ + Get the outlet pressure. + + Returns: + float: Outlet pressure. + """ + assert self.state_outlet is not None, "You have to calculate the outlet state first." + return self.state_outlet.p
+ +
[docs] def get_n_absolute(self, n: float) -> float: + """ + Return given relative n as absolute rounds/sec based on self.N_max. + + Args: + n (float): Relative compressor speed between 0 and 1. + + Returns: + float: Absolute compressor frequency in rounds/sec. + """ + return self.N_max * n
+ +
[docs] def calc_state_outlet(self, p_outlet: float, inputs: Inputs, fs_state: FlowsheetState): + """ + Calculate the output state based on the high pressure level and the provided inputs. + The state is automatically set as the outlet state of this component. + + Args: + p_outlet (float): High pressure value. + inputs (Inputs): Inputs for calculation. + fs_state (FlowsheetState): Flowsheet state. + """ + state_outlet_isentropic = self.med_prop.calc_state("PS", p_outlet, self.state_inlet.s) + eta_is = self.get_eta_isentropic(p_outlet=p_outlet, inputs=inputs) + h_outlet = ( + self.state_inlet.h + (state_outlet_isentropic.h - self.state_inlet.h) / + eta_is + ) + fs_state.set(name="eta_is", value=eta_is, unit="%", description="Isentropic efficiency") + self.state_outlet = self.med_prop.calc_state("PH", p_outlet, h_outlet)
+ +
[docs] def calc_m_flow(self, inputs: Inputs, fs_state: FlowsheetState) -> float: + """ + Calculate the refrigerant mass flow rate. + + Args: + inputs (Inputs): Inputs for the calculation. + fs_state (FlowsheetState): Flowsheet state. + + Returns: + float: Refrigerant mass flow rate. + """ + lambda_h = self.get_lambda_h(inputs=inputs) + V_flow_ref = ( + lambda_h * + self.V_h * + self.get_n_absolute(inputs.n) + ) + self.m_flow = self.state_inlet.d * V_flow_ref + fs_state.set(name="lambda_h", value=lambda_h, unit="%", description="Volumetric efficiency") + fs_state.set(name="V_flow_ref", value=V_flow_ref, unit="m3/s", description="Refrigerant volume flow rate") + fs_state.set(name="m_flow_ref", value=self.m_flow, unit="kg/s", description="Refrigerant mass flow rate") + return self.m_flow
+ +
[docs] def calc_electrical_power(self, inputs: Inputs, fs_state: FlowsheetState) -> float: + """ + Calculate the electrical power consumed by the compressor based on an adiabatic energy balance. + + Args: + inputs (Inputs): Inputs for the calculation. + fs_state (FlowsheetState): Flowsheet state. + + Returns: + float: Electrical power consumed. + """ + # Heat flow in the compressor + P_t = self.m_flow * (self.state_outlet.h - self.state_inlet.h) + # Electrical power consumed + eta_mech = self.get_eta_mech(inputs=inputs) + P_el = P_t / eta_mech + fs_state.set(name="eta_mech", value=eta_mech, unit="-", description="Mechanical efficiency") + return P_el
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/compressors/constant_effectivness.html b/docs/0.1.1/docs/_modules/vclibpy/components/compressors/constant_effectivness.html new file mode 100644 index 0000000..b249cb1 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/compressors/constant_effectivness.html @@ -0,0 +1,202 @@ + + + + + + + + vclibpy.components.compressors.constant_effectivness — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.compressors.constant_effectivness

+from vclibpy.components.compressors.compressor import Compressor
+from vclibpy.datamodels import Inputs
+
+
+
[docs]class ConstantEffectivenessCompressor(Compressor): + """ + Compressor model with constant efficiencies. + + Inherits from the Compressor class, which defines the basic properties and behavior of a compressor in a vapor + compression cycle. + + Parameters: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + eta_isentropic (float): Constant isentropic efficiency of the compressor. + eta_mech (float): Constant mechanical efficiency of the compressor. + lambda_h (float): Constant volumetric efficiency. + + Args: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + eta_isentropic (float): Constant isentropic efficiency of the compressor. + eta_inverter (float): Constant inverter efficiency of the compressor. + eta_motor (float): Constant motor efficiency of the compressor. + eta_mech (float): Constant mechanical efficiency of the compressor including motor and inverter efficiencies. + lambda_h (float): Constant volumetric efficiency. + + Methods: + get_lambda_h(inputs: Inputs) -> float: + Returns the constant volumetric efficiency of the compressor. + + get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float: + Returns the constant isentropic efficiency of the compressor. + + get_eta_mech(inputs: Inputs) -> float: + Returns the constant mechanical efficiency including motor and inverter efficiencies. + + """ + + def __init__(self, + N_max: float, V_h: float, + eta_isentropic: float, + eta_mech: float, + lambda_h: float): + """ + Initialize the ConstantEffectivenessCompressor. + + Args: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + eta_isentropic (float): Constant isentropic efficiency of the compressor. + eta_inverter (float): Constant inverter efficiency of the compressor. + eta_motor (float): Constant motor efficiency of the compressor. + eta_mech (float): Constant mechanical efficiency of the compressor. + lambda_h (float): Constant volumetric efficiency. + """ + super().__init__(N_max=N_max, V_h=V_h) + self.eta_isentropic = eta_isentropic + self.eta_mech = eta_mech + self.lambda_h = lambda_h + +
[docs] def get_lambda_h(self, inputs: Inputs) -> float: + """ + Returns the constant volumetric efficiency of the compressor. + + Args: + inputs (Inputs): Input parameters for the calculation. + + Returns: + float: Constant volumetric efficiency. + """ + return self.lambda_h
+ +
[docs] def get_eta_isentropic(self, p_outlet: float, inputs: Inputs) -> float: + """ + Returns the constant isentropic efficiency of the compressor. + + Args: + p_outlet (float): High pressure value. + inputs (Inputs): Input parameters for the calculation. + + Returns: + float: Constant isentropic efficiency. + """ + return self.eta_isentropic
+ +
[docs] def get_eta_mech(self, inputs: Inputs) -> float: + """ + Returns the product of the constant mechanical, motor, and inverter efficiencies + as the effective mechanical efficiency of the compressor. + + Args: + inputs (Inputs): Input parameters for the calculation. + + Returns: + float: Effective mechanical efficiency. + """ + return self.eta_mech
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/compressors/rotary.html b/docs/0.1.1/docs/_modules/vclibpy/components/compressors/rotary.html new file mode 100644 index 0000000..0d8e802 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/compressors/rotary.html @@ -0,0 +1,231 @@ + + + + + + + + vclibpy.components.compressors.rotary — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.compressors.rotary

+from vclibpy.components.compressors.compressor import Compressor
+from vclibpy.datamodels import Inputs
+
+
+
[docs]class RotaryCompressor(Compressor): + """ + Compressor model based on the thesis of Mirko Engelpracht. + + This compressor is characterized by using regressions provided by Mirko Engelpracht for a family of rotary + compressors. The coefficients used in the regressions are sourced from his Master's thesis. + + Parameters: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + + Methods: + get_lambda_h(inputs: Inputs) -> float: + Returns the volumetric efficiency based on the regressions of Mirko Engelpracht. + + get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float: + Returns the isentropic efficiency based on the regressions of Mirko Engelpracht. + + get_eta_mech(inputs: Inputs) -> float: + Returns the mechanical efficiency based on the regressions of Mirko Engelpracht. + + """ + +
[docs] def get_lambda_h(self, inputs: Inputs) -> float: + """ + Returns the volumetric efficiency based on the regressions of Mirko Engelpracht. + + Args: + inputs (Inputs): Input parameters for the calculation. + + Returns: + float: Volumetric efficiency. + """ + p_outlet = self.get_p_outlet() + # If not constant value is given, eta_is is calculated based on the regression of Mirko Engelpracht + n = self.get_n_absolute(inputs.n) + T_1 = self.state_inlet.T + + a_1 = 0.80179 + a_2 = -0.05210 + sigma_pi = 1.63495 + pi_ave = 4.54069 + a_3 = 3.21616e-4 + sigma_T_1 = 8.43797 + T_1_ave = 263.86428 + a_4 = -0.00494 + a_5 = 0.04981 + sigma_n = 20.81378 + n_ave = 64.41071 + a_6 = -0.02190 + + pi = p_outlet / self.state_inlet.p + return ( + a_1 + + a_2 * (pi - pi_ave) / sigma_pi + + a_3 * (T_1 - T_1_ave) / sigma_T_1 * (pi - pi_ave) / sigma_pi + + a_4 * (T_1 - T_1_ave) / sigma_T_1 + + a_5 * (n - n_ave) / sigma_n + + a_6 * ((n - n_ave) / sigma_n) ** 2 + )
+ +
[docs] def get_eta_isentropic(self, p_outlet: float, inputs: Inputs) -> float: + """ + Returns the isentropic efficiency based on the regressions of Mirko Engelpracht. + + Args: + p_outlet (float): High pressure value. + inputs (Inputs): Input parameters for the calculation. + + Returns: + float: Isentropic efficiency. + """ + # If not constant value is given, eta_is is calculated based on the regression of Mirko Engelpracht + n = self.get_n_absolute(inputs.n) + + a_1 = 0.5816 + a_2 = 0.002604 + a_3 = -1.515e-7 + a_4 = -0.00473 + pi = p_outlet / self.state_inlet.p + eta = ( + a_1 + + a_2 * n + + a_3 * n ** 3 + + a_4 * pi ** 2 + ) + if eta <= 0: + raise ValueError("Efficiency is lower or equal to 0") + return eta
+ +
[docs] def get_eta_mech(self, inputs: Inputs) -> float: + """ + Returns the mechanical efficiency based on the regressions of Mirko Engelpracht. + + Args: + inputs (Inputs): Input parameters for the calculation. + + Returns: + float: Mechanical efficiency. + """ + p_outlet = self.get_p_outlet() + n = self.get_n_absolute(inputs.n) + # If not constant value is given, eta_is is calculated based on the regression of Mirko Engelpracht + a_00 = 0.2199 + a_10 = -0.0193 + a_01 = 0.02503 + a_11 = 8.817e-5 + a_20 = -0.001345 + a_02 = -0.0003382 + a_21 = 1.584e-5 + a_12 = -1.083e-6 + a_22 = -5.321e-8 + a_03 = 1.976e-6 + a_13 = 4.053e-9 + a_04 = -4.292e-9 + pi = p_outlet / self.state_inlet.p + return ( + a_00 + + a_10 * pi + a_01 * n + a_11 * pi * n + + a_20 * pi ** 2 + a_02 * n ** 2 + a_21 * pi ** 2 * n + a_12 * pi * n ** 2 + a_22 * pi ** 2 * n ** 2 + + a_03 * n ** 3 + a_13 * pi * n ** 3 + + a_04 * n ** 4 + )
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/compressors/ten_coefficient.html b/docs/0.1.1/docs/_modules/vclibpy/components/compressors/ten_coefficient.html new file mode 100644 index 0000000..360d607 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/compressors/ten_coefficient.html @@ -0,0 +1,471 @@ + + + + + + + + vclibpy.components.compressors.ten_coefficient — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.compressors.ten_coefficient

+import warnings
+from abc import ABC
+import numpy as np
+import pandas as pd
+
+from vclibpy.components.compressors.compressor import Compressor
+from vclibpy.datamodels import Inputs
+
+
+
[docs]def calc_ten_coefficients(T_eva, T_con, coef_list): + """ + Calculate the result using the ten-coefficient method. + + Args: + T_eva (float): Evaporator temperature in Celsius. + T_con (float): Condenser temperature in Celsius. + coef_list (list): List of coefficients. + + Returns: + float: Result of the calculation. + """ + # Formula for the ten-coefficient method according to the datasheet + z = coef_list[0] + coef_list[1] * T_eva + coef_list[2] * T_con + coef_list[3] * T_eva ** 2 + \ + coef_list[4] * T_eva * T_con + coef_list[5] * T_con ** 2 + coef_list[6] * T_eva ** 3 + \ + coef_list[7] * T_eva ** 2 * T_con + coef_list[8] * T_con ** 2 * T_eva + coef_list[9] * T_con ** 3 + return z
+ + +
[docs]class BaseTenCoefficientCompressor(Compressor, ABC): + """ + Base class for compressors using the ten-coefficient method. + + Used table has to be in this format + (order of the columns is not important). + The values must be the same as in the example tabel. + The column names can be different but must + then be matched with argument parameter_names. + (All typed in numbers are fictional placeholders) + + Capacity(W) Input Power(W) Flow Rate(kg/h) Capacity(W) ... Flow Rate(kg/h) + n n1 n1 n1 n2 ... n_last + P1 42 12 243 32 ... 412 + ... ... ... ... ... ... ... + P10 10 23 21 41 ... 2434 + + Args: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + datasheet (str): Path of the datasheet file. + **kwargs: + parameter_names (dict, optional): + Dictionary to match internal parameter names (keys) to the names used in the table values. + Default + { + "m_flow": "Flow Rate(kg/h)", + "capacity": "Capacity(W)", + "input_power": "Input Power(W)", + "eta_s": "Isentropic Efficiency(-)", + "lambda_h": "Volumentric Efficiency(-)", + "eta_mech": "Mechanical Efficiency(-)" + } + sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None. + """ + + def __init__(self, N_max, V_h, datasheet, **kwargs): + """ + Initialize the BaseTenCoefficientCompressor. + + Args: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + datasheet (str): Path of the datasheet file. + parameter_names (dict, optional): Dictionary of parameter names. Defaults to None. + sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None. + """ + + super().__init__(N_max, V_h) + sheet_name = kwargs.get('sheet_name', None) + self.md = pd.read_excel(datasheet, sheet_name=sheet_name) + parameter_names = kwargs.get('parameter_names', None) + if parameter_names is None: + self.parameter_names = { + "m_flow": "Flow Rate(kg/h)", + "capacity": "Capacity(W)", + "input_power": "Input Power(W)", + "eta_s": "Isentropic Efficiency(-)", + "lambda_h": "Volumentric Efficiency(-)", + "eta_mech": "Mechanical Efficiency(-)" + } + else: + self.parameter_names = parameter_names + +
[docs] def get_parameter(self, T_eva, T_con, n, type_): + """ + Get a parameter based on temperatures, rotations, and parameter type from the datasheet. + + Args: + T_eva (float): Evaporator temperature in Celsius. + T_con (float): Condenser temperature in Celsius. + n (float): Rotations per second. + type_ (str): Parameter type in parameter_names. + + Returns: + float: Interpolated parameter value. + """ + param_list = [] + n_list = [] + + sampling_points = sum( + self.parameter_names[type_] in s for s in list(self.md.columns.values)) # counts number of sampling points + + for i in range(sampling_points): + if i == 0: + coefficients = self.md[self.parameter_names[type_]].tolist() + else: + coefficients = self.md[str(self.parameter_names[type_] + "." + str(i))].tolist() + n_list.append(coefficients.pop(0)) + param_list.append(calc_ten_coefficients(T_eva, T_con, coefficients)) + + return np.interp(self.get_n_absolute(n), n_list, param_list) # linear interpolation
+ + +
[docs]class TenCoefficientCompressor(BaseTenCoefficientCompressor): + """ + Compressor based on the ten coefficient method. + + Used table has to be in this format + (order of the columns is not important). + The values must be the same as in the example tabel. + The column names can be different but must + then be matched with the keyword argument parameter_names. + (All typed in numbers are fictional placeholders) + + Capacity(W) Input Power(W) Flow Rate(kg/h) Capacity(W) ... Flow Rate(kg/h) + n n1 n1 n1 n2 ... n_last + P1 42 12 243 32 ... 412 + ... ... ... ... ... ... ... + P10 10 23 21 41 ... 2434 + + T_sh and T_sc have to be set according to the data sheet of your compressor. capacity_definition defines the + parameter "capacity" in the datasheet. If capacity is the specific cooling capacity (h1-h4), set it on "cooling". + If capacity is the specific heating capacity (h2-h3), set it on "heating". + In the case of cooling capacity, the mechanical efficiency of the compressor has to be assumed (assumed_eta_mech) + as h2 can't be calculated otherwise. Summary: + - For the case heating capacity: h2 = h3 + capacity / m_flow + - For the case cooling capacity: h2 = h3 + (capacity + p_el * assumed_eta_mech) / m_flow + + Args: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + T_sc (float): Subcooling according to datasheet in K. + T_sh (float): Superheating according to datasheet in K. + capacity_definition (str): Definition of "capacity" in the datasheet. "cooling" or "heating". + assumed_eta_mech (float): Assumed mechanical efficiency of the compressor (only needed if cooling). + datasheet (str): Path of the modified datasheet. + **kwargs: + parameter_names (dict, optional): + Dictionary to match internal parameter names (keys) to the names used in the table values. + Default + { + "m_flow": "Flow Rate(kg/h)", + "capacity": "Capacity(W)", + "input_power": "Input Power(W)" + } + sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None. + """ + + def __init__(self, N_max, V_h, T_sc, T_sh, capacity_definition, assumed_eta_mech, datasheet, **kwargs): + super().__init__(N_max=N_max, V_h=V_h, datasheet=datasheet, **kwargs) + self.T_sc = T_sc + self.T_sh = T_sh + if capacity_definition not in ["cooling", "heating"]: + raise ValueError("capacity_definition has to be either 'heating' or 'cooling'") + self._capacity_definition = capacity_definition + self.assumed_eta_mech = assumed_eta_mech + self.datasheet = datasheet + +
[docs] def get_lambda_h(self, inputs: Inputs): + """ + Get the volumetric efficiency. + + Args: + inputs (Inputs): Input parameters. + + Returns: + float: Volumetric efficiency. + """ + p_outlet = self.get_p_outlet() + + n_abs = self.get_n_absolute(inputs.n) + T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 1).T - 273.15 # [°C] + T_con = self.med_prop.calc_state("PQ", p_outlet, 0).T - 273.15 # [°C] + + if round((self.state_inlet.T - T_eva - 273.15), 2) != round(self.T_sh, 2): + warnings.warn("The superheating of the given state is not " + "equal to the superheating of the datasheet. " + "State1.T_sh= " + str(round((self.state_inlet.T - T_eva - 273.15), 2)) + + ". Datasheet.T_sh = " + str(self.T_sh)) + # The datasheet has a given superheating temperature which can + # vary from the superheating of the real state 1 + # which is given by the user. + # Thus a new self.state_inlet_datasheet has to + # be defined for all further calculations + state_inlet_datasheet = self.med_prop.calc_state("PT", self.state_inlet.p, T_eva + 273.15 + self.T_sh) + + m_flow = self.get_parameter(T_eva, T_con, inputs.n, "m_flow") / 3600 # [kg/s] + + lambda_h = m_flow / (n_abs * state_inlet_datasheet.d * self.V_h) + return lambda_h
+ +
[docs] def get_eta_isentropic(self, p_outlet: float, inputs: Inputs): + """ + Get the isentropic efficiency. + + Args: + p_outlet (float): Outlet pressure in Pa. + inputs (Inputs): Input parameters. + + Returns: + float: Isentropic efficiency. + """ + T_con, state_inlet_datasheet, m_flow, capacity, p_el = self._calculate_values( + p_2=p_outlet, inputs=inputs + ) + + h3 = self.med_prop.calc_state("PT", p_outlet, T_con + 273.15 - self.T_sc).h # [J/kg] + h2s = self.med_prop.calc_state("PS", p_outlet, state_inlet_datasheet.s).h # [J/kg] + + if self._capacity_definition == "heating": + h2 = h3 + capacity / m_flow # [J/kg] + else: + h2 = h3 + (capacity + p_el * self.assumed_eta_mech) / m_flow # [J/kg] + + if h2s > h2: + raise ValueError("The calculated eta_s is above 1. You probably chose the wrong capacity_definition") + + eta_s = (h2s - state_inlet_datasheet.h) / (h2 - state_inlet_datasheet.h) + return eta_s
+ +
[docs] def get_eta_mech(self, inputs: Inputs): + """ + Get the mechanical efficiency. + + Args: + inputs (Inputs): Input parameters. + + Returns: + float: Mechanical efficiency. + """ + p_outlet = self.get_p_outlet() + + if self._capacity_definition == "cooling": + return self.assumed_eta_mech + # Else heating + T_con, state_inlet_datasheet, m_flow, capacity, p_el = self._calculate_values( + p_2=p_outlet, inputs=inputs + ) + + h3 = self.med_prop.calc_state("PT", p_outlet, T_con + 273.15 - self.T_sc).h # [J/kg] + h2 = h3 + capacity / m_flow # [J/kg] + + eta_mech = (m_flow * (h2 - state_inlet_datasheet.h)) / p_el + return eta_mech
+ + def _calculate_values(self, p_2: float, inputs: Inputs): + """ + Calculate intermediate values for efficiency calculations. + + Args: + p_2 (float): Outlet pressure in Pa. + inputs (Inputs): Input parameters. + + Returns: + Tuple[float, State, float, float, float]: Intermediate values. + """ + T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 1).T - 273.15 # [°C] + T_con = self.med_prop.calc_state("PQ", p_2, 0).T - 273.15 # [°C] + + state_inlet_datasheet = self.med_prop.calc_state("PT", self.state_inlet.p, T_eva + 273.15 + self.T_sh) + + m_flow = self.get_parameter(T_eva, T_con, inputs.n, "m_flow") / 3600 # [kg/s] + capacity = self.get_parameter(T_eva, T_con, inputs.n, "capacity") # [W] + p_el = self.get_parameter(T_eva, T_con, inputs.n, "input_power") # [W] + return T_con, state_inlet_datasheet, m_flow, capacity, p_el
+ + +
[docs]class DataSheetCompressor(BaseTenCoefficientCompressor): + """ + Compressor based on the ten coefficient method. + + Used table has to be in this format + (order of the columns is not important). + The values must be the same as in the example tabel. + The column names can be different but must + then be matched with the keyword argument parameter_names. + (All typed in numbers are fictional placeholders) + + Isentropic Volumetric Mechanical Isentropic Mechanical + Efficiency(-) Efficiency(-) Efficiency(-) Efficiency(-) ... Efficiency(-) + n n1 n1 n1 n2 ... n_last + P1 42 12 243 32 ... 412 + ... ... ... ... ... ... ... + P10 10 23 21 41 ... 2434 + + Args: + N_max (float): Maximal rotations per second of the compressor. + V_h (float): Volume of the compressor in m^3. + datasheet (str): Path of the datasheet file. + **kwargs: + parameter_names (dict, optional): + Dictionary to match internal parameter names (keys) to the names used in the table values. + Default + { + "eta_s": "Isentropic Efficiency(-)", + "lambda_h": "Volumetric Efficiency(-)", + "eta_mech": "Mechanical Efficiency(-)" + } + sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None. + """ + + def __init__(self, N_max, V_h, datasheet, **kwargs): + super().__init__(N_max=N_max, V_h=V_h, datasheet=datasheet, **kwargs) + +
[docs] def get_lambda_h(self, inputs: Inputs): + """ + Get the volumetric efficiency. + + Args: + inputs (Inputs): Input parameters. + + Returns: + float: Volumetric efficiency. + """ + p_outlet = self.get_p_outlet() + T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 0).T + T_con = self.med_prop.calc_state("PQ", p_outlet, 0).T + return self.get_parameter(T_eva, T_con, inputs.n, "lambda_h")
+ +
[docs] def get_eta_isentropic(self, p_outlet: float, inputs: Inputs): + """ + Get the isentropic efficiency. + + Args: + p_outlet (float): Outlet pressure in Pa. + inputs (Inputs): Input parameters. + + Returns: + float: Isentropic efficiency. + """ + T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 0).T + T_con = self.med_prop.calc_state("PQ", p_outlet, 0).T + return self.get_parameter(T_eva, T_con, inputs.n, "eta_s")
+ +
[docs] def get_eta_mech(self, inputs: Inputs): + """ + Get the mechanical efficiency. + + Args: + inputs (Inputs): Input parameters. + + Returns: + float: Mechanical efficiency. + """ + p_outlet = self.get_p_outlet() + T_eva = self.med_prop.calc_state("PQ", self.state_inlet.p, 0).T + T_con = self.med_prop.calc_state("PQ", p_outlet, 0).T + return self.get_parameter(T_eva, T_con, inputs.n, "eta_mech")
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/expansion_valves/bernoulli.html b/docs/0.1.1/docs/_modules/vclibpy/components/expansion_valves/bernoulli.html new file mode 100644 index 0000000..37f1719 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/expansion_valves/bernoulli.html @@ -0,0 +1,126 @@ + + + + + + + + vclibpy.components.expansion_valves.bernoulli — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.expansion_valves.bernoulli

+"""
+Module with simple bernoulli expansion valve
+"""
+from vclibpy.components.expansion_valves import ExpansionValve
+
+
+
[docs]class Bernoulli(ExpansionValve): + """ + Simple Bernoulli model. + + Args: + A (float): Cross-sectional area of the expansion valve. + """ + +
[docs] def calc_m_flow_at_opening(self, opening): + return opening * self.A * (2 * self.state_inlet.d * (self.state_inlet.p - self.state_outlet.p)) ** 0.5
+ +
[docs] def calc_opening_at_m_flow(self, m_flow, **kwargs): + return ( + m_flow / + (self.A * (2 * self.state_inlet.d * (self.state_inlet.p - self.state_outlet.p)) ** 0.5) + )
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/expansion_valves/expansion_valve.html b/docs/0.1.1/docs/_modules/vclibpy/components/expansion_valves/expansion_valve.html new file mode 100644 index 0000000..1cff0a3 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/expansion_valves/expansion_valve.html @@ -0,0 +1,160 @@ + + + + + + + + vclibpy.components.expansion_valves.expansion_valve — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.expansion_valves.expansion_valve

+"""
+Module with classes for EV models.
+They are not used for the calculation.
+They may be used to see if the output is correct.
+"""
+import abc
+
+from vclibpy.components.component import BaseComponent
+
+
+
[docs]class ExpansionValve(BaseComponent, abc.ABC): + """Base class for an expansion valve. + + Args: + A (float): Cross-sectional area of the expansion valve. + """ + + def __init__(self, A): + super().__init__() + self.A = A # Cross-sectional area of the expansion valve + +
[docs] @abc.abstractmethod + def calc_m_flow_at_opening(self, opening) -> float: + """ + Calculate the mass flow rate for the given opening. + + Args: + opening (float): Opening of valve between 0 and 1 + + Returns: + float: Mass flow rate in kg/s + """ + raise NotImplementedError
+ +
[docs] @abc.abstractmethod + def calc_opening_at_m_flow(self, m_flow, **kwargs) -> float: + """ + Calculate the opening for the given mass flow rate + + Args: + m_flow (float): Mass flow rate in kg/s + **kwargs: Possible keyword arguments for child classes + + Returns: + float: Opening + """ + raise NotImplementedError
+ +
[docs] def calc_outlet(self, p_outlet: float): + """ + Calculate isenthalpic expansion valve. + + Args: + p_outlet (float): Outlet pressure level + """ + self.state_outlet = self.med_prop.calc_state("PH", p_outlet, self.state_inlet.h)
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/economizer.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/economizer.html new file mode 100644 index 0000000..68bea6d --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/economizer.html @@ -0,0 +1,176 @@ + + + + + + + + vclibpy.components.heat_exchangers.economizer — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.economizer

+import logging
+
+from vclibpy.components.heat_exchangers.ntu import BasicNTU
+from vclibpy.media import ThermodynamicState
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class VaporInjectionEconomizerNTU(BasicNTU): + """ + Economizer heat exchanger which is NTU based. + Used only for vapor injection cycles, as + calculations are purely based for two-phase + and liquid estimations. + + See parent class for more arguments. + + Assumptions: + + - Default `flow_type` is counter_flow. + - Default `ratio_outer_to_inner_area` is 1, as + - pipes are nearly same diameter and length + - Secondary heat transfer for alpha is disabled; gas, + liquid and two-phase models are used for both sides. + """ + + def __init__(self, **kwargs): + kwargs.pop("secondary_heat_transfer", None) + kwargs.pop("secondary_medium", None) + self._state_two_phase_outlet = None + self._state_two_phase_inlet = None + super().__init__( + flow_type=kwargs.pop("flow_type", "counter"), + secondary_heat_transfer="None", + secondary_medium="None", + ratio_outer_to_inner_area=kwargs.pop("ratio_outer_to_inner_area", 1), + **kwargs) + + @property + def state_two_phase_inlet(self) -> ThermodynamicState: + return self._state_two_phase_inlet + + @state_two_phase_inlet.setter + def state_two_phase_inlet(self, state_inlet: ThermodynamicState): + self._state_two_phase_inlet = state_inlet + + @property + def state_two_phase_outlet(self) -> ThermodynamicState: + return self._state_two_phase_outlet + + @state_two_phase_outlet.setter + def state_two_phase_outlet(self, state_outlet: ThermodynamicState): + self._state_two_phase_outlet = state_outlet + +
[docs] def calc(self, inputs, fs_state) -> (float, float): + raise NotImplementedError("Could be moved from VaporInjectionEconomizer")
+ +
[docs] def set_secondary_cp(self, cp: float): + """Set primary m_flow_cp""" + self._secondary_cp = cp
+ +
[docs] def start_secondary_med_prop(self): + self.med_prop_sec = self.med_prop
+ +
[docs] def terminate_secondary_med_prop(self): + pass # Not required as it is the central med_prop class
+ +
[docs] def calc_alpha_secondary(self, transport_properties): + raise NotImplementedError("Economizer does not use secondary heat transfer model.")
+ +
[docs] def calc_transport_properties_secondary_medium(self, T, p=None): + raise NotImplementedError("Economizer does not use this method")
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_exchanger.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_exchanger.html new file mode 100644 index 0000000..87f88a9 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_exchanger.html @@ -0,0 +1,343 @@ + + + + + + + + vclibpy.components.heat_exchangers.heat_exchanger — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.heat_exchanger

+import abc
+
+from typing import Tuple
+
+from vclibpy import media
+from vclibpy.datamodels import FlowsheetState, Inputs
+from vclibpy.components.component import BaseComponent
+from vclibpy.components.heat_exchangers.heat_transfer.heat_transfer import HeatTransfer, TwoPhaseHeatTransfer
+
+
+
[docs]class HeatExchanger(BaseComponent, abc.ABC): + """ + Class for a heat exchanger. + + Args: + A (float): + Area of HE in m^2 for NTU calculation + secondary_medium (str): + Name for secondary medium, e.g. `water` or `air` + wall_heat_transfer (HeatTransfer): + Model for heat transfer inside wall + secondary_heat_transfer (HeatTransfer): + Model for heat transfer from secondary medium to wall + gas_heat_transfer (HeatTransfer): + Model for heat transfer from refrigerant gas to wall + liquid_heat_transfer (HeatTransfer): + Model for heat transfer from refrigerant liquid to wall + two_phase_heat_transfer (TwoPhaseHeatTransfer): + Model for heat transfer from refrigerant two phase to wall + """ + + def __init__( + self, + A: float, + wall_heat_transfer: HeatTransfer, + secondary_heat_transfer: HeatTransfer, + gas_heat_transfer: HeatTransfer, + liquid_heat_transfer: HeatTransfer, + two_phase_heat_transfer: TwoPhaseHeatTransfer, + secondary_medium: str + ): + super().__init__() + self.A = A + self.secondary_medium = secondary_medium.lower() + + self._wall_heat_transfer = wall_heat_transfer + self._secondary_heat_transfer = secondary_heat_transfer + self._gas_heat_transfer = gas_heat_transfer + self._liquid_heat_transfer = liquid_heat_transfer + self._two_phase_heat_transfer = two_phase_heat_transfer + + self.med_prop_sec = None # Later start in start_secondary_med_prop + self._m_flow_secondary = None + self._secondary_cp = 0 # Allow initial calculation of _m_flow_secondary_cp if cp is not set + self._m_flow_secondary_cp = 0 + +
[docs] def start_secondary_med_prop(self): + """ + Set up the wrapper for the secondary medium's media properties. + """ + # Set up the secondary_medium wrapper: + med_prop_class, med_prop_kwargs = media.get_global_med_prop_and_kwargs() + if self.secondary_medium == "air" and med_prop_class == media.RefProp: + fluid_name = "AIR.PPF" + else: + fluid_name = self.secondary_medium + if self.med_prop_sec is not None: + if self.med_prop_sec.fluid_name == fluid_name: + return + self.med_prop_sec.terminate() + self.med_prop_sec = med_prop_class(fluid_name=self.secondary_medium, **med_prop_kwargs)
+ +
[docs] def terminate_secondary_med_prop(self): + if self.med_prop_sec is not None: + self.med_prop_sec.terminate()
+ +
[docs] @abc.abstractmethod + def calc(self, inputs: Inputs, fs_state: FlowsheetState) -> Tuple[float, float]: + """ + Calculate the heat exchanger based on the given inputs. + + The flowsheet state can be used to save important variables + during calculation for later analysis. + + Both return values are used to check if the heat transfer is valid or not. + + Args: + inputs (Inputs): The inputs for the calculation. + fs_state (FlowsheetState): The flowsheet state to save important variables. + + Returns: + Tuple[float, float]: + error: Error in percentage between the required and calculated heat flow rates. + dT_min: Minimal temperature difference (can be negative). + """ + raise NotImplementedError
+ +
[docs] def calc_alpha_two_phase(self, state_q0, state_q1, inputs: Inputs, fs_state: FlowsheetState) -> float: + """ + Calculate the two-phase heat transfer coefficient. + + Args: + state_q0: State at vapor quality 0. + state_q1: State at vapor quality 1. + inputs (Inputs): The inputs for the calculation. + fs_state (FlowsheetState): The flowsheet state to save important variables. + + Returns: + float: The two-phase heat transfer coefficient. + """ + return self._two_phase_heat_transfer.calc( + state_q0=state_q0, + state_q1=state_q1, + inputs=inputs, + fs_state=fs_state, + m_flow=self.m_flow, + med_prop=self.med_prop, + state_inlet=self.state_inlet, + state_outlet=self.state_outlet + )
+ +
[docs] def calc_alpha_liquid(self, transport_properties) -> float: + """ + Calculate the liquid-phase heat transfer coefficient. + + Args: + transport_properties: Transport properties for the liquid phase. + + Returns: + float: The liquid-phase heat transfer coefficient. + """ + return self._liquid_heat_transfer.calc( + transport_properties=transport_properties, + m_flow=self.m_flow + )
+ +
[docs] def calc_alpha_gas(self, transport_properties) -> float: + """ + Calculate the gas-phase heat transfer coefficient. + + Args: + transport_properties: Transport properties for the gas phase. + + Returns: + float: The gas-phase heat transfer coefficient. + """ + return self._gas_heat_transfer.calc( + transport_properties=transport_properties, + m_flow=self.m_flow + )
+ +
[docs] def calc_alpha_secondary(self, transport_properties) -> float: + """ + Calculate the secondary-medium heat transfer coefficient. + + Args: + transport_properties: Transport properties for the secondary medium. + + Returns: + float: The secondary-medium heat transfer coefficient. + """ + return self._secondary_heat_transfer.calc( + transport_properties=transport_properties, + m_flow=self.m_flow_secondary + )
+ +
[docs] def calc_wall_heat_transfer(self) -> float: + """ + Calculate the heat transfer coefficient inside the wall. + + Returns: + float: The wall heat transfer coefficient. + """ + # Arguments are not required + return self._wall_heat_transfer.calc( + transport_properties=media.TransportProperties(), + m_flow=0 + )
+ + @property + def m_flow_secondary(self) -> float: + return self._m_flow_secondary + + @m_flow_secondary.setter + def m_flow_secondary(self, m_flow: float): + self._m_flow_secondary = m_flow + self._m_flow_secondary_cp = self._m_flow_secondary * self._secondary_cp + + @property + def m_flow_secondary_cp(self): + return self._m_flow_secondary_cp + +
[docs] def calc_secondary_cp(self, T: float, p=None): + """ + Calculate and set the heat capacity rate m_flow_cp of the secondary medium. + + Args: + T (float): Temperature of the secondary medium. + p (float, optional): Pressure of the secondary medium. Defaults to None. + """ + self._secondary_cp = self.calc_transport_properties_secondary_medium(T=T, p=p).cp + self._m_flow_secondary_cp = self.m_flow_secondary * self._secondary_cp
+ +
[docs] def calc_secondary_Q_flow(self, Q_flow: float) -> float: + return Q_flow
+ +
[docs] def calc_Q_flow(self) -> float: + """ + Calculate the total heat flow rate. + + Returns: + float: The total heat flow rate. + """ + return self.m_flow * abs(self.state_inlet.h - self.state_outlet.h)
+ +
[docs] def calc_transport_properties_secondary_medium(self, T, p=None) -> media.TransportProperties: + """ + Calculate the transport properties for the selected secondary_medium. + + Args: + T (float): Temperature in K. + p (float, optional): Pressure to use. Defaults to None. + + Returns: + media.TransportProperties: The calculated transport properties. + """ + if p is None: + if self.secondary_medium == "water": + p = 2e5 # 2 bar (default hydraulic pressure) + elif self.secondary_medium == "air": + p = 101325 # 1 atm + else: + raise NotImplementedError( + "Default pressures for secondary_mediums aside from water and air are not supported yet." + ) + # Calc state + state = self.med_prop_sec.calc_state("PT", p, T) + # Return properties + return self.med_prop_sec.calc_transport_properties(state)
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.html new file mode 100644 index 0000000..d25eb33 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.html @@ -0,0 +1,215 @@ + + + + + + + + vclibpy.components.heat_exchangers.heat_transfer.air_to_wall — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.heat_transfer.air_to_wall

+import abc
+import logging
+
+from .heat_transfer import HeatTransfer
+from vclibpy.media import TransportProperties
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class AirToWallTransfer(HeatTransfer, abc.ABC): + """ + Heat transfer model for air to wall. + + Args: + A_cross (float): + Cross-section area in m2. + characteristic_length (float): + Length in m to calculate the similitude approach for the + heat transfer from secondary_medium -> wall. + """ + + def __init__(self, A_cross: float, characteristic_length: float): + self.A_cross = A_cross + self.characteristic_length = characteristic_length + +
[docs] def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: + """ + Heat transfer coefficient from air to the wall of the heat exchanger. + The flow is assumed to be always laminar. + + Returns: + float: Heat transfer coefficient in W/(m^2*K). + """ + Re = self.calc_reynolds(dynamic_viscosity=transport_properties.dyn_vis, m_flow=m_flow) + alpha_sec = self.calc_laminar_area_nusselt(Re, transport_properties.Pr, lambda_=transport_properties.lam) + return alpha_sec
+ +
[docs] @abc.abstractmethod + def calc_reynolds(self, dynamic_viscosity: float, m_flow: float): + """ + Calculate the reynolds number of the given flow rate. + + Args: + dynamic_viscosity (float): Dynamic viscosity. + m_flow (float): Mass flow rate. + + Returns: + float: Reynolds number + """ + raise NotImplementedError
+ +
[docs] @abc.abstractmethod + def calc_laminar_area_nusselt(self, Re, Pr, lambda_): + """ + Calculate the Nusselt number for laminar heat transfer + on an area (Used for Air->Wall in the evaporator). + + Args: + Re (float): Reynolds number + Pr (float): Prandlt number + lambda_ (float): Lambda of air + + Returns: + float: Nusselt number + """ + raise NotImplementedError
+ + +
[docs]class WSUAirToWall(AirToWallTransfer): + """ + Class to implement the heat transfer calculations + based on the WSÜ-Script at the RWTH. + """ + +
[docs] def calc_reynolds(self, dynamic_viscosity: float, m_flow: float) -> float: + """ + Calculate the Reynolds number on air side. + + Args: + dynamic_viscosity (float): Dynamic viscosity of air. + m_flow (float): Mass flow rate of air. + + Returns: + float: Reynolds number. + """ + velocity_times_dens = m_flow / self.A_cross + return (velocity_times_dens * self.characteristic_length) / dynamic_viscosity
+ +
[docs] def calc_laminar_area_nusselt(self, Re, Pr, lambda_) -> float: + """ + Calculate the Nusselt number for laminar heat transfer + on an area (Used for Air->Wall in the evaporator). + + Args: + Re (float): Reynolds number of air. + Pr (float): Prandtl number of air. + lambda_ (float): Lambda of air. + + Returns: + float: Nusselt number of air. + """ + const_fac = 0.664 + exp_rey = 0.5 + exp_pra = 1 / 3 + if Re > 2e5: + raise ValueError(f"Given Re {Re} is outside of allowed bounds for WSÜ-Script") + if Pr > 10 or Pr < 0.6: + raise ValueError(f"Given Pr {Pr} is outside of allowed bounds for WSÜ-Script") + Nu = const_fac * Re ** exp_rey * Pr ** exp_pra + return Nu * lambda_ / self.characteristic_length
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/constant.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/constant.html new file mode 100644 index 0000000..8afc932 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/constant.html @@ -0,0 +1,163 @@ + + + + + + + + vclibpy.components.heat_exchangers.heat_transfer.constant — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.heat_transfer.constant

+"""
+Module with constant heat transfer assumptions
+"""
+import abc
+
+from vclibpy.media import TransportProperties
+
+
+
[docs]class ConstantHeatTransfer(abc.ABC): + """ + Constant heat transfer assumption + + Args: + alpha (float): + Constant heat transfer coefficient in W/(m2*K) + """ + + def __init__(self, alpha: float): + self.alpha = alpha + +
[docs] def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: + """ + Calculate constant heat transfer coefficient. + + Args: + transport_properties (TransportProperties): Transport properties of the medium (not used). + m_flow (float): Mass flow rate (not used). + + Returns: + float: Constant heat transfer coefficient in W/(m2*K). + + """ + return self.alpha
+ + +
[docs]class ConstantTwoPhaseHeatTransfer(abc.ABC): + """ + Constant heat transfer assumption. + + Args: + alpha (float): + Constant heat transfer coefficient in W/(m2*K). + """ + + def __init__(self, alpha: float): + self.alpha = alpha + +
[docs] def calc(self, **kwargs) -> float: + """ + Calculate constant two-phase heat transfer coefficient. + + Args: + **kwargs: Allows to set arguments for different heat transfer classes which are not used here. + + Returns: + float: Constant two-phase heat transfer coefficient in W/(m2*K). + + """ + return self.alpha
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.html new file mode 100644 index 0000000..6203caf --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.html @@ -0,0 +1,196 @@ + + + + + + + + vclibpy.components.heat_exchangers.heat_transfer.heat_transfer — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.heat_transfer.heat_transfer

+"""
+Module with basic functions to calculate heat transfer coefficients.
+"""
+import abc
+
+import numpy as np
+
+from vclibpy.media import TransportProperties, ThermodynamicState, MedProp
+from vclibpy.datamodels import FlowsheetState, Inputs
+
+
+
[docs]class HeatTransfer(abc.ABC): + """ + Base class to implement possible heat transfer models. + + Methods: + calc(transport_properties: TransportProperties, m_flow: float) -> float: + Abstract method to calculate heat transfer. + + """ + +
[docs] @abc.abstractmethod + def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: + """ + Calculate heat transfer. + + Args: + transport_properties (TransportProperties): Transport properties of the medium. + m_flow (float): Mass flow rate. + + Returns: + float: Calculated heat transfer coefficient. + + Raises: + NotImplementedError: If the method is not implemented in the subclass. + """ + raise NotImplementedError
+ + +
[docs]class TwoPhaseHeatTransfer(abc.ABC): + """ + Base class to implement possible heat transfer models + """ + +
[docs] @abc.abstractmethod + def calc( + self, + state_q0: ThermodynamicState, + state_q1: ThermodynamicState, + state_inlet: ThermodynamicState, + state_outlet: ThermodynamicState, + med_prop: MedProp, + inputs: Inputs, + fs_state: FlowsheetState, + m_flow: float + ) -> float: + """ + Calculate two-phase heat transfer. + + Args: + state_q0 (ThermodynamicState): Thermodynamic state at the beginning of the two-phase region. + state_q1 (ThermodynamicState): Thermodynamic state at the end of the two-phase region. + state_inlet (ThermodynamicState): Inlet thermodynamic state. + state_outlet (ThermodynamicState): Outlet thermodynamic state. + med_prop (MedProp): Medium properties class. + inputs (Inputs): Input parameters. + fs_state (FlowsheetState): Flowsheet state. + m_flow (float): Mass flow rate. + + Returns: + float: Calculated two-phase heat transfer coefficient. + + Raises: + NotImplementedError: If the method is not implemented in the subclass. + """ + raise NotImplementedError
+ + +
[docs]def calc_reynolds_pipe(dynamic_viscosity: float, m_flow: float, characteristic_length: float) -> float: + """ + Calculate Reynolds number for flow inside a pipe. + + Args: + dynamic_viscosity (float): Dynamic viscosity of the fluid. + m_flow (float): Mass flow rate. + characteristic_length (float): Characteristic length (e.g., diameter) of the pipe. + + Returns: + float: Reynolds number. + + """ + return 4 * m_flow / (np.pi * characteristic_length * dynamic_viscosity)
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.html new file mode 100644 index 0000000..acc909f --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.html @@ -0,0 +1,203 @@ + + + + + + + + vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall

+"""
+Module with models for pipe-to-wall heat transfer.
+"""
+
+from .heat_transfer import HeatTransfer, calc_reynolds_pipe
+from vclibpy.media import TransportProperties
+
+
+
[docs]class TurbulentFluidInPipeToWallTransfer(HeatTransfer): + """ + Class to model turbulent heat exchange in a pipe. + + Args: + method (str): + Equation to calc the nusselt number of turbulent flow for + a given Re and Pr number. + Note: Just for one-phase heat transfer!! + Implemented Options are: + + - Taler2016 + - Domanski1989_sp_smooth + - Amalfi2016 + - ScriptWSÜ. For turbulent regimes, eta_by_eta_w is assumed to be one. + + Refer to the paper / documents or the function in this class for more + info on numbers and assumptions + characteristic_length (float): + Length to calculate the similitude approach for the + heat transfer from ref -> wall. For heat pumps this is + always the Diameter of the HE in m + """ + + def __init__(self, method: str, characteristic_length: float): + self.method = method + self.characteristic_length = characteristic_length + +
[docs] def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: + """ + Calculate heat transfer coefficient from refrigerant to the wall of the heat exchanger. + + The flow is assumed to be always turbulent and is based on a calibrated + Nusselt correlation. + + Args: + transport_properties (TransportProperties): Transport properties of the fluid. + m_flow (float): Mass flow rate of the fluid. + + Returns: + float: Heat transfer coefficient from refrigerant to HE in W/(m^2*K). + """ + Re = calc_reynolds_pipe( + characteristic_length=self.characteristic_length, + dynamic_viscosity=transport_properties.dyn_vis, + m_flow=m_flow + ) + Nu = self.calc_turbulent_tube_nusselt(Re, transport_properties.Pr) + return Nu * transport_properties.lam / self.characteristic_length
+ +
[docs] def calc_turbulent_tube_nusselt(self, Re, Pr) -> float: + """ + Calculate the Nuseelt number for turbulent heat transfer + in a tube (used for ref/water->Wall in the evaporator and condernser). + + Args: + Re (float): Reynolds number. + Pr (float): Prandtl number. + + Returns: + float: Nusselt number. + """ + if self.method == "Taler2016": + if Re < 3e3 or Re > 1e6: + raise ValueError(f"Given Re {Re} is outside of allowed bounds for method {self.method}") + if 0.1 <= Pr <= 1: + return 0.02155 * Re ** 0.8018 * Pr ** 0.7095 + elif 1 < Pr <= 3: + return 0.02155 * Re ** 0.8018 * Pr ** 0.7095 + elif 3 < Pr <= 1000: + return 0.02155 * Re ** 0.8018 * Pr ** 0.7095 + else: + raise ValueError(f"Given Pr {Pr} is outside of allowed bounds for method {self.method}") + elif self.method == "ScriptWSÜ": + if Re < 3000 or Re > 1e5: + raise ValueError(f"Given Re {Re} is outside of allowed bounds for method {self.method}") + eta_by_eta_w = 1 + return 0.027 * Re ** 0.8 ** Pr ** (1 / 3) * eta_by_eta_w ** 0.14 + elif self.method == "Amalfi2016": + if Re <= 700: + Nu = (0.0295 * Pr - 0.115) * Re ** 0.954 + else: + Nu = (1.760 * Pr - 5.391) * Re ** 0.262 + if Nu < 0: + raise ValueError(f"Given Pr {Pr} is outside of allowed bounds for method {self.method}") + return Nu + elif self.method == "Domanski1989_sp_smooth": + # According to Domanski 1989 for singular phase and smooth surfaces + return 0.023 * Re ** 0.8 * Pr ** 0.4 + else: + raise TypeError(f"Method {self.method} not supported!")
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.html new file mode 100644 index 0000000..5bc668b --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.html @@ -0,0 +1,272 @@ + + + + + + + + vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall

+import logging
+from dataclasses import dataclass
+
+import numpy as np
+
+from .air_to_wall import AirToWallTransfer
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]@dataclass +class AirSourceHeatExchangerGeometry: + """ + Geometry of a fin and tube heat exchanger with two rows of pipes in a shifted arrangement. + + Source: VDI-Wärmeatlas, Berechnungsblätter für den Wärmeübergang, 11. Auflage, S.1461 + + As the source is in German, the names are kept in German as well. + """ + t_l: float # Achsabstand der Rohre in Luftrichtung in m + t_q: float # Achsabstand der Rohre quer zur Luftrichtung in m + tiefe: float # Tiefe der Rippe gesamt + d_a: float # Äußerer Rohrdurchmesser + d_i: float # Innener Rohrdurchmesser + lambda_R: float # Wärmeleitfähigkeit Material der Wand + n_Rohre: int = 50 + n_Rippen: int = 500 + a: float = 1.95e-3 + dicke_rippe: float = 0.05e-3 + laenge: float = 1.040 + hoehe: float = 0.64 + + @property + def char_length(self) -> float: + """Return the characteristic length d_a.""" + return self.d_a + + @property + def A_Rippen(self) -> float: + """Return the total surface area of the fins.""" + return 2 * self.n_Rippen * (self.tiefe * self.hoehe - self.n_Rohre * np.pi * 0.25 * self.d_a ** 2) + + @property + def A(self) -> float: + """Total air side heat transfer area.""" + return self.A_Rippen + self.A_FreieOberflaecheRohr + + @property + def A_FreieOberflaecheRohr(self) -> float: + """Free air side area of the tubes.""" + return self.n_Rippen * np.pi * self.d_a * self.a * self.n_Rohre + + @property + def A_RohrInnen(self) -> float: + """Total refrigerant heat transfer area.""" + return self.laenge * self.d_i * np.pi * self.n_Rohre + + @property + def A_RohrUnberippt(self) -> float: + """Total outside area of the tubes without fins""" + return self.laenge * self.d_a * np.pi * self.n_Rohre + + @property + def verjuengungsfaktor(self) -> float: + """Reduction factor A_cross_free/A_cross_smallest""" + return ((self.hoehe * self.laenge) / + (self.hoehe * self.laenge - + self.hoehe * self.n_Rippen * self.dicke_rippe - + self.d_a * self.n_Rohre / 2 * (self.laenge - self.n_Rippen * self.dicke_rippe))) + + @property + def phi(self) -> float: + """Auxiliary variable for fin efficiency""" + if self.t_l >= 0.5 * self.t_q: + b_r = self.t_q + else: + b_r = 2 * self.t_l + l_r = np.sqrt(self.t_l **2 + self.t_q **2 / 4) + phi_strich = 1.27 * b_r / self.d_a * np.sqrt(l_r / b_r - 0.3) + return (phi_strich - 1) * (1 + 0.35 * np.log(phi_strich)) + +
[docs] def eta_R(self, alpha_R) -> float: + """ + Calculate fin efficiency. + + Args: + alpha_R (float): Average heat transfer coefficient for tube and fin. + + Returns: + float: Fin efficiency. + """ + X = self.phi * self.d_a / 2 * np.sqrt(2 * alpha_R / (self.lambda_R * self.dicke_rippe)) + return 1 / X * (np.exp(X) - np.exp(-X)) / (np.exp(X) + np.exp(-X))
+ +
[docs] def alpha_S(self, alpha_R) -> float: + """ + Calculate apparent heat transfer coefficient. + + Args: + alpha_R (float): Average heat transfer coefficient for tube and fin. + + Returns: + float: Apparent heat transfer coefficient. + """ + A_R_to_A = self.A_Rippen / self.A + return alpha_R * (1 - (1 - self.eta_R(alpha_R)) * A_R_to_A)
+ + +
[docs]class VDIAtlasAirToWallTransfer(AirToWallTransfer): + """ + VDI-Atlas based heat transfer estimation. + Check `AirToWallTransfer` for further argument options. + + This class assumes two pipes with a shifted arrangement. + + Args: + A_cross (float): Free cross-sectional area. + characteristic_length (float): Characteristic length d_a. + geometry_parameters (AirSourceHeatExchangerGeometry): + Geometry parameters for heat exchanger according to VDI-Atlas + """ + + def __init__(self, + A_cross: float, characteristic_length: float, + geometry_parameters: AirSourceHeatExchangerGeometry): + super().__init__(A_cross=A_cross, characteristic_length=characteristic_length) + self.geometry_parameters = geometry_parameters + +
[docs] def calc_reynolds(self, dynamic_viscosity: float, m_flow: float) -> float: + """ + Calculate Reynolds number. + + Args: + dynamic_viscosity (float): Dynamic viscosity of the fluid. + m_flow (float): Mass flow rate. + + Returns: + float: Reynolds number. + """ + velocity_times_dens = m_flow / self.A_cross * self.geometry_parameters.verjuengungsfaktor + return (velocity_times_dens * self.characteristic_length) / dynamic_viscosity
+ +
[docs] def calc_laminar_area_nusselt(self, Re: float, Pr: float, lambda_: float) -> float: + """ + Calculate apparent heat transfer coefficient based on Nusselt correlation. + + Args: + Re (float): Reynolds number. + Pr (float): Prandtl number. + lambda_ (float): Thermal conductivity of air. + + Returns: + float: Apparent heat transfer coefficient. + """ + C = 0.33 # Versetzte Anordnung, zwei Rohre + if Re < 1e3 or Re > 1e5: + logger.debug("Given Re %s is outside of allowed bounds for VDI-Atlas", Re) + A_div_A_0 = self.geometry_parameters.A / self.geometry_parameters.A_RohrUnberippt + if A_div_A_0 < 5 or A_div_A_0 > 30: + logger.debug("Given A/A0 is outside of bounds for method VDI-Atlas") + Nu = ( + C * Re ** 0.6 * + A_div_A_0 ** (-0.15) * + Pr ** (1 / 3) + ) + alpha_R = Nu * lambda_ / self.characteristic_length + alpha_S = self.geometry_parameters.alpha_S(alpha_R=alpha_R) + return alpha_S
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/wall.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/wall.html new file mode 100644 index 0000000..3771e0b --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/heat_transfer/wall.html @@ -0,0 +1,135 @@ + + + + + + + + vclibpy.components.heat_exchangers.heat_transfer.wall — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.heat_transfer.wall

+import logging
+
+from .heat_transfer import HeatTransfer
+from vclibpy.media import TransportProperties
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class WallTransfer(HeatTransfer): + """ + Simple wall heat transfer + + Args: + lambda_ (float): + Heat conductivity of wall material in W/Km + thickness (float): + Thickness of wall in m^2 + """ + def __init__(self, lambda_: float, thickness: float): + self.thickness = thickness + self.lambda_ = lambda_ + +
[docs] def calc(self, transport_properties: TransportProperties, m_flow: float) -> float: + """ + Heat transfer coefficient inside wall + + Returns: + float: Heat transfer coefficient in W/(m^2*K) + """ + return self.lambda_ / self.thickness
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/moving_boundary_ntu.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/moving_boundary_ntu.html new file mode 100644 index 0000000..287c3eb --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/moving_boundary_ntu.html @@ -0,0 +1,470 @@ + + + + + + + + vclibpy.components.heat_exchangers.moving_boundary_ntu — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.moving_boundary_ntu

+import abc
+import logging
+
+import numpy as np
+from vclibpy.datamodels import FlowsheetState, Inputs
+from vclibpy.components.heat_exchangers.ntu import BasicNTU
+from vclibpy.media import ThermodynamicState
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class MovingBoundaryNTU(BasicNTU, abc.ABC): + """ + Moving boundary NTU based heat exchanger. + + See parent classe for arguments. + """ + +
[docs] def separate_phases(self, state_max: ThermodynamicState, state_min: ThermodynamicState, p: float): + """ + Separates a flow with possible phase changes into three parts: + subcooling (sc), latent phase change (lat), and superheating (sh) + at the given pressure. + + Args: + state_max (ThermodynamicState): State with higher enthalpy. + state_min (ThermodynamicState): State with lower enthalpy. + p (float): Pressure of phase change. + + Returns: + Tuple[float, float, float, ThermodynamicState, ThermodynamicState]: + Q_sc: Heat for subcooling. + Q_lat: Heat for latent phase change. + Q_sh: Heat for superheating. + state_q0: State at vapor quality 0 and the given pressure. + state_q1: State at vapor quality 1 and the given pressure. + """ + # Get relevant states: + state_q0 = self.med_prop.calc_state("PQ", p, 0) + state_q1 = self.med_prop.calc_state("PQ", p, 1) + Q_sc = max(0.0, + min((state_q0.h - state_min.h), + (state_max.h - state_min.h))) * self.m_flow + Q_lat = max(0.0, + (min(state_max.h, state_q1.h) - + max(state_min.h, state_q0.h))) * self.m_flow + Q_sh = max(0.0, + min((state_max.h - state_q1.h), + (state_max.h - state_min.h))) * self.m_flow + return Q_sc, Q_lat, Q_sh, state_q0, state_q1
+ +
[docs] def iterate_area(self, dT_max, alpha_pri, alpha_sec, Q) -> float: + """ + Iteratively calculates the required area for the heat exchange. + + Args: + dT_max (float): Maximum temperature differential. + alpha_pri (float): Heat transfer coefficient for the primary medium. + alpha_sec (float): Heat transfer coefficient for the secondary medium. + Q (float): Heat flow rate. + + Returns: + float: Required area for heat exchange. + """ + _accuracy = 1e-6 # square mm + _step = 1.0 + R = self.calc_R() + k = self.calc_k(alpha_pri, alpha_sec) + m_flow_cp_min = self.calc_m_flow_cp_min() + # First check if point is feasible at all + if dT_max <= 0: + return self.A + eps_necessary = Q / (m_flow_cp_min * dT_max) + + # Special cases: + # --------------- + # eps is equal or higher than 1, an infinite amount of area would be necessary. + if eps_necessary >= 1: + return self.A + # eps is lower or equal to zero: No Area required (Q<=0) + if eps_necessary <= 0: + return 0 + + area = 0.0 + while True: + NTU = self.calc_NTU(area, k, m_flow_cp_min) + eps = self.calc_eps(R, NTU) + if eps >= eps_necessary: + if _step <= _accuracy: + break + else: + # Go back + area -= _step + _step /= 10 + continue + if _step < _accuracy and area > self.A: + break + area += _step + + return min(area, self.A)
+ + +
[docs]class MovingBoundaryNTUCondenser(MovingBoundaryNTU): + """ + Condenser class which implements the actual `calc` method. + + Assumptions: + - No phase changes in secondary medium + - cp of secondary medium is constant over heat-exchanger + + See parent classes for arguments. + """ + +
[docs] def calc(self, inputs: Inputs, fs_state: FlowsheetState) -> (float, float): + """ + Calculate the heat exchanger with the NTU-Method based on the given inputs. + + The flowsheet state can be used to save important variables + during calculation for later analysis. + + Both return values are used to check if the heat transfer is valid or not. + + Args: + inputs (Inputs): The inputs for the calculation. + fs_state (FlowsheetState): The flowsheet state to save important variables. + + Returns: + Tuple[float, float]: + error: Error in percentage between the required and calculated heat flow rates. + dT_min: Minimal temperature difference (can be negative). + """ + self.m_flow_secondary = inputs.m_flow_con # [kg/s] + self.calc_secondary_cp(T=inputs.T_con_in) + + # First we separate the flow: + Q_sc, Q_lat, Q_sh, state_q0, state_q1 = self.separate_phases( + self.state_inlet, + self.state_outlet, + self.state_inlet.p + ) + Q = Q_sc + Q_lat + Q_sh + + # Note: As Q_con_ntu has to converge to Q_con (m_ref*delta_h), we can safely + # calculate the output temperature. + + T_mean = inputs.T_con_in + self.calc_secondary_Q_flow(Q) / (self.m_flow_secondary_cp * 2) + tra_prop_med = self.calc_transport_properties_secondary_medium(T_mean) + alpha_med_wall = self.calc_alpha_secondary(tra_prop_med) + + # Calculate secondary_medium side temperatures: + # Assumption loss is the same correlation for each regime + T_sc = inputs.T_con_in + self.calc_secondary_Q_flow(Q_sc) / self.m_flow_secondary_cp + T_sh = T_sc + self.calc_secondary_Q_flow(Q_lat) / self.m_flow_secondary_cp + T_out = T_sh + self.calc_secondary_Q_flow(Q_sh) / self.m_flow_secondary_cp + + # 1. Regime: Subcooling + Q_sc_ntu, A_sc = 0, 0 + if Q_sc > 0 and (state_q0.T != self.state_outlet.T): + self.set_primary_cp((state_q0.h - self.state_outlet.h) / (state_q0.T - self.state_outlet.T)) + # Get transport properties: + tra_prop_ref_con = self.med_prop.calc_mean_transport_properties(state_q0, self.state_outlet) + alpha_ref_wall = self.calc_alpha_liquid(tra_prop_ref_con) + + # Only use still available area: + A_sc = self.iterate_area(dT_max=(state_q0.T - inputs.T_con_in), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + Q=Q_sc) + A_sc = min(self.A, A_sc) + + Q_sc_ntu, k_sc = self.calc_Q_ntu(dT_max=(state_q0.T - inputs.T_con_in), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + A=A_sc) + + # 2. Regime: Latent heat exchange + Q_lat_ntu, A_lat = 0, 0 + if Q_lat > 0: + self.set_primary_cp(np.inf) + # Get transport properties: + alpha_ref_wall = self.calc_alpha_two_phase( + state_q0=state_q0, + state_q1=state_q1, + fs_state=fs_state, + inputs=inputs + ) + + A_lat = self.iterate_area(dT_max=(state_q1.T - T_sc), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + Q=Q_lat) + # Only use still available area: + A_lat = min(self.A - A_sc, A_lat) + + Q_lat_ntu, k_lat = self.calc_Q_ntu(dT_max=(state_q1.T - T_sc), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + A=A_lat) + logger.debug(f"con_lat: pri: {round(alpha_ref_wall, 2)} sec: {round(alpha_med_wall, 2)}") + + # 3. Regime: Superheat heat exchange + Q_sh_ntu, A_sh = 0, 0 + if Q_sh and (self.state_inlet.T != state_q1.T): + self.set_primary_cp((self.state_inlet.h - state_q1.h) / (self.state_inlet.T - state_q1.T)) + # Get transport properties: + tra_prop_ref_con = self.med_prop.calc_mean_transport_properties(self.state_inlet, state_q1) + alpha_ref_wall = self.calc_alpha_gas(tra_prop_ref_con) + + # Only use still available area: + A_sh = self.A - A_sc - A_lat + + Q_sh_ntu, k_sh = self.calc_Q_ntu(dT_max=(self.state_inlet.T - T_sh), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + A=A_sh) + logger.debug(f"con_sh: pri: {round(alpha_ref_wall, 2)} sec: {round(alpha_med_wall, 2)}") + + Q_ntu = Q_sh_ntu + Q_sc_ntu + Q_lat_ntu + error = (Q_ntu / Q - 1) * 100 + # Get possible dT_min: + dT_min_in = self.state_outlet.T - inputs.T_con_in + dT_min_out = self.state_inlet.T - T_out + dT_min_LatSH = state_q1.T - T_sh + + fs_state.set(name="A_con_sh", value=A_sh, unit="m2", description="Area for superheat heat exchange in condenser") + fs_state.set(name="A_con_lat", value=A_lat, unit="m2", description="Area for latent heat exchange in condenser") + fs_state.set(name="A_con_sc", value=A_sc, unit="m2", description="Area for subcooling heat exchange in condenser") + + return error, min(dT_min_in, + dT_min_LatSH, + dT_min_out)
+ + +
[docs]class MovingBoundaryNTUEvaporator(MovingBoundaryNTU): + """ + Evaporator class which implements the actual `calc` method. + + Assumptions: + - No phase changes in secondary medium + - cp of secondary medium is constant over heat-exchanger + + See parent classes for arguments. + """ + +
[docs] def calc(self, inputs: Inputs, fs_state: FlowsheetState) -> (float, float): + """ + Calculate the heat exchanger with the NTU-Method based on the given inputs. + + The flowsheet state can be used to save important variables + during calculation for later analysis. + + Both return values are used to check if the heat transfer is valid or not. + + Args: + inputs (Inputs): The inputs for the calculation. + fs_state (FlowsheetState): The flowsheet state to save important variables. + + Returns: + Tuple[float, float]: + error: Error in percentage between the required and calculated heat flow rates. + dT_min: Minimal temperature difference (can be negative). + """ + self.m_flow_secondary = inputs.m_flow_eva # [kg/s] + self.calc_secondary_cp(T=inputs.T_eva_in) + + # First we separate the flow: + Q_sc, Q_lat, Q_sh, state_q0, state_q1 = self.separate_phases( + self.state_outlet, + self.state_inlet, + self.state_inlet.p + ) + + Q = Q_sc + Q_lat + Q_sh + + # Note: As Q_eva_ntu has to converge to Q_eva (m_ref*delta_h), we can safely + # calculate the output temperature. + T_mean = inputs.T_eva_in - Q / (self.m_flow_secondary_cp * 2) + tra_prop_med = self.calc_transport_properties_secondary_medium(T_mean) + alpha_med_wall = self.calc_alpha_secondary(tra_prop_med) + + # Calculate secondary_medium side temperatures: + T_sh = inputs.T_eva_in - Q_sh / self.m_flow_secondary_cp + T_sc = T_sh - Q_lat / self.m_flow_secondary_cp + T_out = T_sc - Q_sc / self.m_flow_secondary_cp + + # 1. Regime: Superheating + Q_sh_ntu, A_sh = 0, 0 + if Q_sh and (self.state_outlet.T != state_q1.T): + self.set_primary_cp((self.state_outlet.h - state_q1.h) / (self.state_outlet.T - state_q1.T)) + # Get transport properties: + tra_prop_ref_eva = self.med_prop.calc_mean_transport_properties(self.state_outlet, state_q1) + alpha_ref_wall = self.calc_alpha_gas(tra_prop_ref_eva) + + if Q_lat > 0: + A_sh = self.iterate_area(dT_max=(inputs.T_eva_in - state_q1.T), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + Q=Q_sh) + else: + # if only sh is present --> full area: + A_sh = self.A + + # Only use still available area + A_sh = min(self.A, A_sh) + + Q_sh_ntu, k_sh = self.calc_Q_ntu(dT_max=(inputs.T_eva_in - state_q1.T), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + A=A_sh) + + logger.debug(f"eva_sh: pri: {round(alpha_ref_wall, 2)} sec: {round(alpha_med_wall, 2)}") + + # 2. Regime: Latent heat exchange + Q_lat_ntu, A_lat = 0, 0 + if Q_lat > 0: + self.set_primary_cp(np.inf) + + alpha_ref_wall = self.calc_alpha_two_phase( + state_q0=state_q0, + state_q1=state_q1, + fs_state=fs_state, + inputs=inputs + ) + + if Q_sc > 0: + A_lat = self.iterate_area(dT_max=(T_sh - self.state_inlet.T), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + Q=Q_lat) + else: + A_lat = self.A - A_sh + + # Only use still available area: + A_lat = min(self.A - A_sh, A_lat) + Q_lat_ntu, k_lat = self.calc_Q_ntu(dT_max=(T_sh - self.state_inlet.T), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + A=A_lat) + logger.debug(f"eva_lat: pri: {round(alpha_ref_wall, 2)} sec: {round(alpha_med_wall, 2)}") + + # 3. Regime: Subcooling + Q_sc_ntu, A_sc = 0, 0 + if Q_sc > 0 and (state_q0.T != self.state_inlet.T): + self.set_primary_cp((state_q0.h - self.state_inlet.h) / (state_q0.T - self.state_inlet.T)) + # Get transport properties: + tra_prop_ref_eva = self.med_prop.calc_mean_transport_properties(state_q0, self.state_inlet) + alpha_ref_wall = self.calc_alpha_liquid(tra_prop_ref_eva) + + # Only use still available area: + A_sc = self.A - A_sh - A_lat + + Q_sc_ntu, k_sc = self.calc_Q_ntu(dT_max=(T_sc - self.state_inlet.T), + alpha_pri=alpha_ref_wall, + alpha_sec=alpha_med_wall, + A=A_sc) + + Q_ntu = Q_sh_ntu + Q_sc_ntu + Q_lat_ntu + error = (Q_ntu / Q - 1) * 100 + # Get dT_min + dT_min_in = inputs.T_eva_in - self.state_outlet.T + dT_min_out = T_out - self.state_inlet.T + + fs_state.set(name="A_eva_sh", value=A_sh, unit="m2", description="Area for superheat heat exchange in evaporator") + fs_state.set(name="A_eva_lat", value=A_lat, unit="m2", description="Area for latent heat exchange in evaporator") + + return error, min(dT_min_out, dT_min_in)
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/ntu.html b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/ntu.html new file mode 100644 index 0000000..3996938 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/heat_exchangers/ntu.html @@ -0,0 +1,277 @@ + + + + + + + + vclibpy.components.heat_exchangers.ntu — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.heat_exchangers.ntu

+import logging
+import abc
+
+import numpy as np
+from vclibpy.components.heat_exchangers.heat_exchanger import HeatExchanger
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class BasicNTU(HeatExchanger, abc.ABC): + """ + Moving boundary NTU based heat exchanger. + + See parent class for more arguments. + + Args: + flow_type (str): + Counter, Cross or parallel flow + ratio_outer_to_inner_area (float): + The NTU method uses the overall heat transfer coefficient `k` + and multiplies it with the outer area `A` (area of the secondary side). + However, depending on the heat exchanger type, the areas may + differ drastically. For instance in an air-to-water heat exchanger. + The VDI-Atlas proposes the ratio of outer area to inner pipe area + to account for this mismatch in sizes. + The calculation follows the code in the function `calc_k`. + Typical values are around 20-30. + """ + + def __init__(self, flow_type: str, ratio_outer_to_inner_area: float, **kwargs): + """ + Initializes BasicNTU. + + Args: + flow_type (str): Type of flow: Counter, Cross, or Parallel. + ratio_outer_to_inner_area (float): + The NTU method uses the overall heat transfer coefficient `k` + and multiplies it with the overall area `A`. + However, depending on the heat exchanger type, the areas may + differ drastically. For instance in an air-to-water heat exchanger. + The VDI-Atlas proposes the ratio of outer area to inner pipe area + to account for this mismatch in sizes. + The calculation follows the code in the function `calc_k`. + **kwargs: Additional keyword arguments passed to the parent class. + """ + super().__init__(**kwargs) + self.ratio_outer_to_inner_area = ratio_outer_to_inner_area + + # Set primary cp: + self._primary_cp = None + + # Type of HE: + self.flow_type = flow_type.lower() + if self.flow_type not in ["counter", "cross", "parallel"]: + raise TypeError("Given flow_type is not supported") + +
[docs] def set_primary_cp(self, cp: float): + """ + Set the specific heat (cp) for the primary medium. + + Args: + cp (float): Specific heat for the primary medium. + """ + self._primary_cp = cp
+ +
[docs] def calc_eps(self, R: float, NTU: float) -> float: + """ + Calculate the effectiveness (eps) of the heat exchanger based on NTU. + + Source of implementation: EBC Lecture SimModelle. + + Args: + R (float): Ratio of heat capacity rates (m_flow*cp) of the primary to secondary medium. + NTU (float): Number of Transfer Units. + + Returns: + float: Effectiveness (eps) of the heat exchanger. + """ + if R in (0, 1): + return NTU / (NTU + 1) + if self.flow_type == "counter": + return (1 - np.exp(-NTU * (1 - R))) / (1 - R * np.exp(-NTU * (1 - R))) + if self.flow_type == "cross": + if NTU == 0: + return 0 + eta = NTU ** -0.22 + return 1 - np.exp((np.exp(- NTU * R * eta) - 1) / (R * eta)) + if self.flow_type == "parallel": + return (1 - np.exp(-NTU * (1 + R))) / (1 + R) + raise TypeError(f"Flow type {self.flow_type} not supported")
+ +
[docs] def calc_R(self) -> float: + """ + Calculate the R value, which is the ratio of heat capacity rates (m_flow*cp) of the primary to secondary medium. + + Returns: + float: R value. + """ + m_flow_pri_cp = self.m_flow * self._primary_cp + if m_flow_pri_cp > self.m_flow_secondary_cp: + return self.m_flow_secondary_cp / m_flow_pri_cp + return m_flow_pri_cp / self.m_flow_secondary_cp
+ +
[docs] def calc_k(self, alpha_pri: float, alpha_sec: float) -> float: + """ + Calculate the overall heat transfer coefficient (k) of the heat exchanger. + + Args: + alpha_pri (float): Heat transfer coefficient for the primary medium. + alpha_sec (float): Heat transfer coefficient for the secondary medium. + + Returns: + float: Overall heat transfer coefficient (k). + """ + k_wall = self.calc_wall_heat_transfer() + k = (1 / ( + (1 / alpha_pri) * self.ratio_outer_to_inner_area + + (1 / k_wall) * self.ratio_outer_to_inner_area + + (1 / alpha_sec) + ) + ) + return k
+ +
[docs] @staticmethod + def calc_NTU(A: float, k: float, m_flow_cp: float) -> float: + """ + Calculate the Number of Transfer Units (NTU) for the heat exchanger. + + Args: + A (float): Area of the heat exchanger. + k (float): Overall heat transfer coefficient. + m_flow_cp (float): Minimal heat capacity rates (m_flow*cp) between primary and secondary side. + + Returns: + float: Number of Transfer Units (NTU). + """ + return k * A / m_flow_cp
+ +
[docs] def calc_m_flow_cp_min(self) -> float: + """ + Calculate the minimum value between the heat capacity rates (m_flow*cp) for the primary and secondary mediums. + + Returns: + float: Minimum value. + """ + return min( + self.m_flow * self._primary_cp, + self.m_flow_secondary_cp + )
+ +
[docs] def calc_Q_ntu(self, dT_max: float, alpha_pri: float, alpha_sec: float, A: float) -> (float, float): + """ + Calculate the heat transfer and overall heat transfer coefficient for the heat exchanger based on NTU. + + Args: + dT_max (float): Maximum temperature differential. + alpha_pri (float): Heat transfer coefficient for the primary medium. + alpha_sec (float): Heat transfer coefficient for the secondary medium. + A (float): Area of the heat exchanger. + + Returns: + Tuple[float, float]: Heat transfer and overall heat transfer coefficient. + """ + R = self.calc_R() + k = self.calc_k(alpha_pri, alpha_sec) + m_flow_cp_min = self.calc_m_flow_cp_min() + NTU = self.calc_NTU(A, k, m_flow_cp_min) + eps = self.calc_eps(R, NTU) + + # Get the maximal allowed heat flow + Q_max = m_flow_cp_min * dT_max + return Q_max * eps, k
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/components/phase_separator.html b/docs/0.1.1/docs/_modules/vclibpy/components/phase_separator.html new file mode 100644 index 0000000..d2c17e4 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/components/phase_separator.html @@ -0,0 +1,183 @@ + + + + + + + + vclibpy.components.phase_separator — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for vclibpy.components.phase_separator

+"""
+Module with a simple phase separator model.
+"""
+
+from vclibpy.media import ThermodynamicState
+from vclibpy.components.component import BaseComponent
+
+
+
[docs]class PhaseSeparator(BaseComponent): + """ + A simple phase separator model. + """ + + def __init__(self): + super().__init__() + self._state_outlet_liquid: ThermodynamicState = None + self._state_outlet_vapor: ThermodynamicState = None + + @BaseComponent.state_inlet.setter + def state_inlet(self, state_inlet: ThermodynamicState): + """ + Set the state of the inlet and calculate the outlet states for liquid and vapor phases. + + Args: + state_inlet (ThermodynamicState): Inlet state. + """ + self._state_inlet = state_inlet + self.state_outlet_vapor = self.med_prop.calc_state("PQ", self.state_inlet.p, 1) + self.state_outlet_liquid = self.med_prop.calc_state("PQ", self.state_inlet.p, 0) + + @BaseComponent.state_outlet.setter + def state_outlet(self, state: ThermodynamicState): + """ + This outlet is disabled for this component. + + Args: + state (ThermodynamicState): Outlet state. + """ + raise NotImplementedError("This outlet is disabled for this component") + + @property + def state_outlet_vapor(self) -> ThermodynamicState: + """ + Getter for the outlet state of the vapor phase. + + Returns: + ThermodynamicState: Outlet state for the vapor phase. + """ + return self._state_outlet_vapor + + @state_outlet_vapor.setter + def state_outlet_vapor(self, state: ThermodynamicState): + """ + Setter for the outlet state of the vapor phase. + + Args: + state (ThermodynamicState): Outlet state for the vapor phase. + """ + self._state_outlet_vapor = state + + @property + def state_outlet_liquid(self) -> ThermodynamicState: + """ + Getter for the outlet state of the liquid phase. + + Returns: + ThermodynamicState: Outlet state for the liquid phase. + """ + return self._state_outlet_liquid + + @state_outlet_liquid.setter + def state_outlet_liquid(self, state: ThermodynamicState): + """ + Setter for the outlet state of the liquid phase. + + Args: + state (ThermodynamicState): Outlet state for the liquid phase. + """ + self._state_outlet_liquid = state
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/datamodels.html b/docs/0.1.1/docs/_modules/vclibpy/datamodels.html new file mode 100644 index 0000000..8b4544b --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/datamodels.html @@ -0,0 +1,345 @@ + + + + + + + + vclibpy.datamodels — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.datamodels

+"""
+Module which contains datamodels which are used in this library.
+"""
+
+from dataclasses import dataclass
+from typing import Dict, Any
+from copy import deepcopy
+
+
+
[docs]@dataclass +class Variable: + """ + Class for a variable used in analysis. + + Args: + name (str): The name of the variable. + value (float): The numerical value of the variable. + unit (str): The unit of measurement for the variable (optional). + description (str): A description of the variable (optional). + """ + name: str + value: float + unit: str = None + description: str = None
+ + +
[docs]class VariableContainer: + """ + Class which holds Variables to be used anywhere in the models. + + This class enables dynamic addition of Variables. + """ + def __init__(self): + self._variables: Dict[str, Variable] = {} + + def __str__(self): + return f"{self.__class__.__name__}:\n" + "\n".join( + [f"{var.name}={var.value} {var.unit} ({var.description})" + for var in self._variables.values()] + ) + +
[docs] def set(self, name: str, value: float, unit: str = None, description: str = None): + """ + Add or update a Variable in the container. + + Args: + name (str): The name of the variable. + value (float): The numerical value of the variable. + unit (str): The unit of measurement for the variable (optional). + description (str): A description of the variable (optional). + """ + if name in self._variables: + self._variables[name].value = value + else: + self._variables[name] = Variable( + name=name, value=value, unit=unit, description=description + )
+ + def __getattr__(self, item): + """ + Overwrite the dunder method to enable usage of e.g. + fs_state.COP + """ + if item in {'__getstate__', '__setstate__'}: + return super().__getattr__(self, item) + if item in self._variables: + return self._variables.get(item).value + raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'") + +
[docs] def get_variable_names(self) -> list: + """ + Get the names of all variables in the container. + + Returns: + list: A list of variable names. + """ + return list(self._variables.keys())
+ +
[docs] def get_variables(self): + """ + Get all variables in the container. + + Returns: + Dict[str, Variable]: A dictionary of variable names and Variable objects. + """ + return self._variables
+ +
[docs] def items(self): + """ + Get items from the container. + + Returns: + Dict[str, Variable]: A dictionary of variable names and Variable objects. + """ + return self._variables.items()
+ +
[docs] def get(self, name: str, default: Any = None): + """ + Get the Variable with the specified name. + + Args: + name (str): The name of the variable. + default (Any): Default value to return if the variable is not found. + + Returns: + Variable: The Variable object. + + """ + return self._variables.get(name, default)
+ +
[docs] def copy(self): + """ + Return a deepcopy of the instance as the variable dict is mutable. + + Returns: + VariableContainer: A deepcopy of the VariableContainer instance. + """ + return deepcopy(self)
+ +
[docs] def convert_to_str_value_format(self, with_unit_and_description: bool) -> Dict[str, float]: + """ + Returns a dictionary with a str: float format which is handy when storing results + in files like .csv or .xlsx. + + Args: + with_unit_and_description (bool): When False, only the name is in the string. + + Returns: + dict: Containing all variables and values. + """ + if with_unit_and_description: + return {f"{k} in {v.unit} ({v.description})": v.value for k, v in self.items()} + return {k: v.value for k, v in self.items()}
+ + +
[docs]class FlowsheetState(VariableContainer): + """ + This class is used to define the unique states of the flowsheet + in the heat pump. + + The class is dynamic in the sense that attributes may be + added during calculation of new flowsheet. This enables + the easy adding of custom values to analyze the whole flowsheet + and not restrict to a certain naming convention. + """
+ + +
[docs]class Inputs(VariableContainer): + """ + Class defining inputs to calculate the FlowsheetState. + + While the inputs are pre-defined, you may add further ones + using the `set` method. + + Args: + n (float): Relative compressor speed between 0 and 1. + T_eva_in (float): Secondary side evaporator inlet temperature. + T_con_in (float): Secondary side condenser inlet temperature. + m_flow_eva (float): Secondary side evaporator mass flow rate. + m_flow_con (float): Secondary side condenser mass flow rate. + dT_eva_superheating (float): Super-heating after evaporator. + dT_con_subcooling (float): Subcooling after condenser. + T_ambient (float): Ambient temperature of the machine. + """ + + def __init__( + self, + n: float = None, + T_eva_in: float = None, + T_con_in: float = None, + m_flow_eva: float = None, + m_flow_con: float = None, + dT_eva_superheating: float = None, + dT_con_subcooling: float = None, + T_ambient: float = None + ): + """ + Initializes an Inputs object with parameters representing external conditions + for the vapor compression cycle. + + Args: + n (float): Relative compressor speed between 0 and 1 (unit: -). + T_eva_in (float): Secondary side evaporator inlet temperature (unit: K). + T_con_in (float): Secondary side condenser inlet temperature (unit: K). + m_flow_eva (float): Secondary side evaporator mass flow rate (unit: kg/s). + m_flow_con (float): Secondary side condenser mass flow rate (unit: kg/s). + dT_eva_superheating (float): Super-heating after evaporator (unit: K). + dT_con_subcooling (float): Subcooling after condenser (unit: K). + T_ambient (float): Ambient temperature of the machine (unit: K). + """ + super().__init__() + self.set( + name="n", + value=n, + unit="-", + description="Relative compressor speed" + ) + self.set( + name="T_eva_in", + value=T_eva_in, + unit="K", + description="Secondary side evaporator inlet temperature" + ) + self.set( + name="T_con_in", + value=T_con_in, + unit="K", + description="Secondary side condenser inlet temperature" + ) + self.set( + name="m_flow_con", + value=m_flow_con, + unit="kg/s", + description="Secondary side condenser mass flow rate" + ) + self.set( + name="m_flow_eva", + value=m_flow_eva, + unit="kg/s", + description="Secondary side evaporator mass flow rate" + ) + self.set( + name="dT_eva_superheating", + value=dT_eva_superheating, + unit="K", + description="Super-heating after evaporator" + ) + self.set( + name="dT_con_subcooling", + value=dT_con_subcooling, + unit="K", + description="Subcooling after condenser" + ) + if T_ambient is None: + T_ambient = T_eva_in + self.set( + name="T_ambient", + value=T_ambient, + unit="K", + description="Ambient temperature of machine" + )
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/media/cool_prop.html b/docs/0.1.1/docs/_modules/vclibpy/media/cool_prop.html new file mode 100644 index 0000000..e8672a0 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/media/cool_prop.html @@ -0,0 +1,246 @@ + + + + + + + + vclibpy.media.cool_prop — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.media.cool_prop

+"""
+Module with cool prop wrapper.
+"""
+import logging
+
+import CoolProp.CoolProp as CoolPropInternal
+
+from vclibpy.media.media import MedProp
+from vclibpy.media.states import ThermodynamicState, TransportProperties
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class CoolProp(MedProp): + """ + Class using the open-source CoolProp package + to access the properties. + + Args: + use_high_level_api (bool): + True to use the high-level api, which is much slower, + but you can use all modes in calc_state. + Default is False. + """ + + _mode_map = { + "PT": (CoolPropInternal.PT_INPUTS, True), + "TQ": (CoolPropInternal.QT_INPUTS, False), + "PS": (CoolPropInternal.PSmass_INPUTS, True), + "PH": (CoolPropInternal.HmassP_INPUTS, False), + "PQ": (CoolPropInternal.PQ_INPUTS, True) + } + + def __init__(self, fluid_name, use_high_level_api: bool = False): + super().__init__(fluid_name=fluid_name) + # Set molar mass and trigger a possible fluid-name error + # if the fluid is not supported. + self._helmholtz_equation_of_state = CoolPropInternal.AbstractState("HEOS", self.fluid_name) + self.M = self._helmholtz_equation_of_state.molar_mass() + self.use_high_level_api = use_high_level_api + +
[docs] def calc_state(self, mode: str, var1: float, var2: float): + super().calc_state(mode=mode, var1=var1, var2=var2) + + if self.use_high_level_api: + _var1_str, _var2_str = mode[0], mode[1] + # CoolProp returns Pa + p = CoolPropInternal.PropsSI('P', _var1_str, var1, _var2_str, var2, self.fluid_name) + # CoolProp returns kg/m^3 + d = CoolPropInternal.PropsSI('D', _var1_str, var1, _var2_str, var2, self.fluid_name) + # CoolProp returns K + T = CoolPropInternal.PropsSI('T', _var1_str, var1, _var2_str, var2, self.fluid_name) + # CoolProp returns J/kg + u = CoolPropInternal.PropsSI('U', _var1_str, var1, _var2_str, var2, self.fluid_name) + # CoolProp returns J/kg + h = CoolPropInternal.PropsSI('H', _var1_str, var1, _var2_str, var2, self.fluid_name) + # CoolProp returns J/kg/K + s = CoolPropInternal.PropsSI('S', _var1_str, var1, _var2_str, var2, self.fluid_name) + # CoolProp returns mol/mol + q = CoolPropInternal.PropsSI('Q', _var1_str, var1, _var2_str, var2, self.fluid_name) + # Return new state + return ThermodynamicState(p=p, T=T, u=u, h=h, s=s, d=d, q=q) + + self._update_coolprop_heos(mode=mode, var1=var1, var2=var2) + # Return new state + return ThermodynamicState( + p=self._helmholtz_equation_of_state.p(), + T=self._helmholtz_equation_of_state.T(), + u=self._helmholtz_equation_of_state.umass(), + h=self._helmholtz_equation_of_state.hmass(), + s=self._helmholtz_equation_of_state.smass(), + d=self._helmholtz_equation_of_state.rhomass(), + q=self._helmholtz_equation_of_state.Q() + )
+ +
[docs] def calc_transport_properties(self, state: ThermodynamicState): + if 0 <= state.q <= 1: + mode = "PQ" + var1, var2 = state.p, state.q + else: + # Get using p and T + mode = "PT" + var1, var2 = state.p, state.T + + if self.use_high_level_api: + args = [mode[0], var1, mode[1], var2, self.fluid_name] + # CoolProp returns - + pr = CoolPropInternal.PropsSI('PRANDTL', *args) + # CoolProp returns J/kg/K + cp = CoolPropInternal.PropsSI('C', *args) + # CoolProp returns J/kg/K + cv = CoolPropInternal.PropsSI('CVMASS', *args) + # CoolProp returns W/m/K + lam = CoolPropInternal.PropsSI('CONDUCTIVITY', *args) + # CoolProp returns Pa*s + dyn_vis = CoolPropInternal.PropsSI('VISCOSITY', *args) + # Internal calculation as kinematic vis is ration of dyn_vis to density + # In m^2/s + kin_vis = dyn_vis / state.d + + # Create transport properties instance + return TransportProperties(lam=lam, dyn_vis=dyn_vis, kin_vis=kin_vis, + pr=pr, cp=cp, cv=cv, state=state) + # Low-level API + self._update_coolprop_heos(mode=mode, var1=var1, var2=var2) + # Create transport properties instance + return TransportProperties( + lam=self._helmholtz_equation_of_state.conductivity(), + dyn_vis=self._helmholtz_equation_of_state.viscosity(), + kin_vis=self._helmholtz_equation_of_state.viscosity() / state.d, + pr=self._helmholtz_equation_of_state.Prandtl(), + cp=self._helmholtz_equation_of_state.cpmass(), + cv=self._helmholtz_equation_of_state.cvmass(), + state=state + )
+ + def _update_coolprop_heos(self, mode, var1, var2): + if mode not in self._mode_map: + raise KeyError( + f"Given mode '{mode}' is currently not supported with the " + f"faster low-level API to cool-prop. " + f"Either use the high-level API or raise an issue. " + f"Supported modes: {', '.join(self._mode_map.keys())}" + ) + i_input, not_reverse_variables = self._mode_map[mode] + if not_reverse_variables: + self._helmholtz_equation_of_state.update(i_input, var1, var2) + else: + self._helmholtz_equation_of_state.update(i_input, var2, var1) + +
[docs] def get_critical_point(self): + Tc = CoolPropInternal.PropsSI("TCRIT", self.fluid_name) + pc = CoolPropInternal.PropsSI("PCRIT", self.fluid_name) + dc = CoolPropInternal.PropsSI("RHOCRIT", self.fluid_name) + return Tc, pc, dc
+ +
[docs] def get_molar_mass(self): + return self.M
+ + +if __name__ == '__main__': + CoolProp("Propan") +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/media/media.html b/docs/0.1.1/docs/_modules/vclibpy/media/media.html new file mode 100644 index 0000000..f697450 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/media/media.html @@ -0,0 +1,340 @@ + + + + + + + + vclibpy.media.media — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.media.media

+"""Module with wrappers to access and handle media property databases.
+
+This module provides interfaces to load media properties using various wrappers and
+handle calculations related to media properties.
+
+Classes:
+    MedProp: Base class for all media property interfaces.
+
+Functions:
+    get_two_phase_limits: Return the states of the boundaries of the two-phase section for a given fluid.
+
+"""
+import abc
+import logging
+import warnings
+from typing import List
+import numpy as np
+
+from vclibpy.media import ThermodynamicState, TransportProperties
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class MedProp(abc.ABC): + """Base class for all media property interfaces. + + This class serves as the base for defining interfaces to access and compute media properties. + + Methods: + calc_state: Calculate the thermodynamic state based on mode and state variables. + calc_transport_properties: Calculate transport properties for a given state. + get_critical_point: Retrieve critical point information. + get_molar_mass: Retrieve molar mass information. + get_two_phase_limits: Retrieve the two-phase limits for plotting. + calc_mean_transport_properties: Calculate the average transport properties for given states. + """ + _fluid_mapper = {} + + def __init__(self, fluid_name): + """Initialize the MedProp class instance. + + Args: + fluid_name (str): The name of the fluid. + """ + # Check if better internal names exist (e.g. air is modelled as air.ppf) + self.fluid_name = self._fluid_mapper.get(fluid_name, fluid_name) + self._two_phase_limits: dict = None + +
[docs] def calc_state(self, mode: str, var1: float, var2: float): + """Calculate the thermodynamic state based on the specified mode and state variables. + + This function calculates the thermodynamic state based on the chosen mode and provided state variables. + The input state variables need to be in SI units. + + Notes: + - PT does not work when the state might fall within the two-phase region. + - Only functions for density are implemented. In cases where you know the specific volume, use the density + functions with the inverse value. + - Quality (q) may have values outside the 'physical' scope: + - q = -998: Subcooled liquid + - q = 998: Superheated vapor + - q = 999: Supercritical state + + Possible modes include: + - "PD": Pressure, Density + - "PH": Pressure, Enthalpy + - "PQ": Pressure, Quality + - "PS": Pressure, Entropy + - "PT": Pressure, Temperature + - "PU": Pressure, Internal Energy + - "TD": Temperature, Density + - "TH": Temperature, Enthalpy + - "TQ": Temperature, Quality + - "TS": Temperature, Entropy + - "TU": Temperature, Internal Energy + - "DH": Density, Enthalpy + - "DS": Density, Entropy + - "DU": Density, Internal Energy + + Args: + mode (str): Defines the given input state variables (see possible modes above). + var1 (float): Value of the first state variable (as specified in the mode) in SI units. + var2 (float): Value of the second state variable (as specified in the mode) in SI units. + + Returns: + ThermodynamicState: A ThermodynamicState instance with state variables. + + Raises: + AssertionError: If the given mode is not within the available options. + """ + available_options = ['PD', 'PH', 'PQ', 'PS', 'PT', + 'PU', 'TD', 'TH', 'TQ', 'TS', + 'TU', 'DH', 'DS', 'DU', ] + assert mode in available_options, f'Given mode {mode} is not in available options'
+ +
[docs] def terminate(self): + """ + Terminate the class. + Default behaviour does nothing. + """ + pass
+ +
[docs] @abc.abstractmethod + def calc_transport_properties(self, state: ThermodynamicState): + """Calculate the transport properties for the given state. + + Args: + state (ThermodynamicState): The current thermodynamic state. + + Returns: + TransportProperties: An instance of TransportProperties. + """ + pass
+ +
[docs] @abc.abstractmethod + def get_critical_point(self): + """Retrieve critical point information for the fluid. + + Returns: + Tuple[float, float, float]: A tuple containing critical point information + (Temperature Tc [K], Pressure pc [Pa], Density dc [kg/m^3]). + """ + pass
+ +
[docs] @abc.abstractmethod + def get_molar_mass(self): + """Retrieve the molar mass of the current fluid. + + Returns: + float: The molar mass M of the current fluid in kg/mol. + """ + pass
+ +
[docs] def get_two_phase_limits(self, quantity: str, p_min: int = 100000, p_step: int = 5000): + """ + Retrieve the two-phase limits for plotting a specified quantity. + + This method returns the two-phase limits for a specified quantity (T, h, s, or p) in an array used for + plotting purposes. It calculates the limits within the pressure range from p_min and quality (q) 0 to the + critical pressure (pc), and then from the critical pressure to the pressure p_min and quality 1. + + Args: + quantity (str): The specified quantity (T, h, s, or p). + p_min (int, optional): The minimum pressure value to start iteration. Default is 100000 Pa. + p_step (int, optional): The step size for pressure variation. Default is 5000 Pa. + + Returns: + numpy.ndarray: An array containing the two-phase limits for the specified quantity. + + Raises: + ValueError: If the given quantity is not supported (T, h, s, or p). + """ + if self._two_phase_limits is not None: + # Check existing two-phase limits + p_min_old = self._two_phase_limits['p'][0] + p_step_old = self._two_phase_limits['p'][1] - p_min_old + if not np.isclose(p_min_old, p_min, 0, 10) or not np.isclose(p_step_old, p_step, 0, 10): + warnings.warn(f"Overwriting previously calculated two-phase limits with " + f"p_min={p_min_old} and p_step={p_step_old}. This might take a few seconds.\n" + f"The quantity might not match with the previously calculated quantities.") + self._two_phase_limits = None + + if self._two_phase_limits is None: + # Calculate new two-phase limits for plotting + _two_phase_limits = get_two_phase_limits(self, p_step=p_step, p_min=p_min) + self._two_phase_limits = { + "T": np.array([state.T for state in _two_phase_limits]), + "h": np.array([state.h for state in _two_phase_limits]), + "s": np.array([state.s for state in _two_phase_limits]), + "p": np.array([state.p for state in _two_phase_limits]), + } + + if quantity not in self._two_phase_limits: + raise ValueError("The given quantity is not supported. T, h, s, or p are supported.") + return self._two_phase_limits[quantity]
+ +
[docs] def calc_mean_transport_properties(self, state_in, state_out): + """ + Calculate the average transport properties for the given states. + + Args: + state_in (ThermodynamicState): First state + state_out (ThermodynamicState): Second state + + Returns: + TransportProperties: Average transport properties + + Notes: + The TransportProperties does not contain a state, as an average + state is not possible to calculate. + """ + tr_pr_in = self.calc_transport_properties(state_in) + tr_pr_out = self.calc_transport_properties(state_out) + + return TransportProperties( + lam=0.5 * (tr_pr_in.lam + tr_pr_out.lam), + dyn_vis=0.5 * (tr_pr_in.dyn_vis + tr_pr_out.dyn_vis), + kin_vis=0.5 * (tr_pr_in.kin_vis + tr_pr_out.kin_vis), + pr=0.5 * (tr_pr_in.Pr + tr_pr_out.Pr), + cp=0.5 * (tr_pr_in.cp + tr_pr_out.cp), + cv=0.5 * (tr_pr_in.cv + tr_pr_out.cv), + state=None)
+ + +
[docs]def get_two_phase_limits(med_prop: MedProp, p_step: int = 1000, p_min: int = int(1e3)) -> List[ThermodynamicState]: + """ + Return the states representing the boundaries of the two-phase section for the given fluid. + + This function is primarily used for visualizing the two-phase section and validating the accuracy of calculations. + + Args: + med_prop (MedProp): An instance of a valid MedProp-Class. + p_step (int): The step size for pressure variation in Pa. Default is 1000 Pa. + p_min (int): The minimum pressure in Pa from where to start calculation. Default is 1000 Pa. + + Returns: + List[ThermodynamicState]: A list of ThermodynamicState instances representing the two-phase limits. + + Notes: + The two-phase limits are computed by iterating over a range of pressures from the minimum pressure up to the + critical point pressure (exclusive) with a specified step size. States at quality 0 (saturated liquid) + and quality 1 (saturated vapor) are appended to form the two-phase boundary. The list is reversed to + maintain the correct order for visualization purposes. + """ + _, _p_max, _ = med_prop.get_critical_point() + q0, q1 = [], [] + for _p in range(p_min, int(_p_max), p_step): + try: + q0.append(med_prop.calc_state("PQ", _p, 0)) + q1.append(med_prop.calc_state("PQ", _p, 1)) + except ValueError as err: + logger.info("Could not calculate two-phase limits for p=%s: %s", + _p, err) + # Reverse list for correct order + return q0 + q1[::-1]
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/media/ref_prop.html b/docs/0.1.1/docs/_modules/vclibpy/media/ref_prop.html new file mode 100644 index 0000000..ec6fb0c --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/media/ref_prop.html @@ -0,0 +1,1335 @@ + + + + + + + + vclibpy.media.ref_prop — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.media.ref_prop

+# -*- coding: utf-8 -*-
+"""
+Created on 21.04.2020
+
+@author: Christoph Hoeges, Fabian Wuellhorst, Jona Brach
+
+To test:
+- Transport properties are not fully tested (Status: 11.06.2020)
+- Error raising is not implemented at all refprop calls
+    - Additional change might be that not all errors and warning are excluded when 'use_error_check' is set to false but
+        only warnings or errors?
+"""
+import logging
+import os
+import warnings
+import shutil
+import atexit
+
+from ctREFPROP.ctREFPROP import REFPROPFunctionLibrary
+
+from vclibpy.media import ThermodynamicState, TransportProperties, MedProp
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class RefProp(MedProp): + """ + Class to connect to refProp package. + + Args: + :param string fluid_name: + Fluid name for RefProp use + :param list or None z: + Fluid composition. Should only be used, when a self-design mixture shall be used. Further information + see notes. + When you want to use a self-design mixture to as follows: + - Fluid-name needs to contain all component names within mixture: "R32.FLD|R125.FLD" + - z needs to be a list with molar fractions: [0.697, 0.303] + - Used example would be similar to R410A + + :param string dll_path: + Specifier for the dll path used for RefProp, + e.g. dll_path='C:\\path_to_dll\\RefProp64.dll'. + If None, the `ref_prop_path` and function `get_dll_path` are + used to determine the dll path + :param boolean use_error_check: + Specifier whether errors and warnings shall be checked when calling RefProp or not + :param boolean use_warnings: + Specifier whether warnings shall be used + :param str ref_prop_path: + Path to RefProp package. Default is the ENV variable `RPPREFIX`. + :param bool copy_dll: + If True (not the default), a copy of the dll is created to enable simultaneous use of + multiple fluids in multiprocessing. + :param str copy_dll_directory: + If `copy_dll` is True, the DLL is copied to this directory. + If None (default), the current working directory is used. + + Note: + - You need to install package ctREFPROP Package + https://github.com/usnistgov/REFPROP-wrappers/tree/master/wrappers/python + - In case you use a self-defined mixture: Entropy reference state might deviate from GUI!! + + Functionality: + - It does not work to have multiple instances simultaneously. When calculating values the last fluid name + somehow will be used even though instance includes "new" name. Need to be fixed at some point. + + + How to use RefProp-Wrapper: + --------------------------- + 1.) Create RefProp instance: rp = RefProp("R32") + 2.) In case you want to calculate fluid properties (state variables) for a specific state: Use calc_state() function + Multiple inputs can be given (but you need to now two in order to define the values). For further + information see function header. + 3.) Further get-Functions implemented + - get_gwp(): Global warming potential + - get_odp(): Ozone depletion potential + - get_safety(): Safety class + - get_mass_fraction(): Mass fractions of pure substances in fluid + - get_molar_mass(): Molar mass of fluid + - get_mol_fraction(): Mol fractions of pure substances in fluid + - get_comp_names(): Pure substances names in fluid + - get_longname(): Long name of fluid within RefProp + - get_critical_point(): Crit. Temperature and Pressure + - get_version(): Version of wrapper and of RefProp dll + + + Version notes: + -------------- + 0.1.0 (21.04.2020, Christoph Hoeges): + First implementation + - Contains multiple functions to call RefProp instance + - Can calculate state, crit, GWP, ODP, Safety class, molar mass etc. of fluid + - Mixtures might work but it wasn't fully testet - R455A e.g. still deviates slightly + + 0.1.1 (25.04.2020, Christoph Hoeges): + Multiple changes, added functionality. Commands are still the same though + - Self designed mixtures are possible now as well (see instructions in init + - Added composition input to __init__ function + - Added modes in calc_state function and removed bug in PH calculation + - Additional protected functions due to different input + - Adjusted _call_refprop function (z is not mass frac but mol fraction) + - Added documentation / instruction + + 0.1.2 (08.05.2020, Christoph Hoeges): + Multiple adjustments + - Added function to call ABFLSHdll function in refprop (high level function) + - Changed function calls in calc_state function to ABFLSH and adjusted conversion + - Change init-function so user can choose which dll shall be used + - Add function to get version of this current wrapper as well as RefProp-dll version + + 0.1.3 (12.05.2020, Christoph Hoeges): + Multiple changes + - Added function to get all files in MIXTURE and FLUIDS directory to check available fluids + - Added error function in order to return errors when RefProp-Functions are called. + NOTE: Not all instances where refprop is called are checked for errors. Currently, it is only used in + init and calc_state + + 0.1.4 (19.05.2020, Christoph Hoeges): + Multiple changes: + - Debugged fluid properties calculation for predefined mixtures + - Fixed option of self-defined mixtures + + 0.1.5 (22.05.2020, Christoph Hoeges): + Include transport properties calculation into wrapper + + 0.1.6 (10.06.2020, Fabian Wuellhorst): + Add option to use a custom dll path. This necessary to use multiple instances with possible + different fluids at the same time. + """ + # General information + # + __version__ = "0.1.6" + __author__ = "Christoph Hoeges" + + _fluid_mapper = {'air': 'air.ppf'} + + def __init__(self, + fluid_name, + z=None, + dll_path: str = None, + use_error_check: bool = True, + use_warnings: bool = True, + ref_prop_path: str = None, + copy_dll: bool = True, + copy_dll_directory: str = None + ): + if ref_prop_path is None: + # Get environment variable for path to dll + ref_prop_path = os.environ["RPPREFIX"] + if dll_path is None: + path_to_dll = self.get_dll_path(ref_prop_path) + else: + path_to_dll = dll_path + + if copy_dll: + if copy_dll_directory is None: + copy_dll_directory = os.getcwd() + try: + self._delete_dll_path = os.path.join( + copy_dll_directory, + f"med_prop_{fluid_name}_REFPRP64.dll" + ) + shutil.copyfile(path_to_dll, self._delete_dll_path) + atexit.register(self.terminate) + path_to_dll = self._delete_dll_path + except (PermissionError, FileExistsError) as err: + logger.error("Can't copy file to new path: %s", err) + else: + self._delete_dll_path = None + logger.info("Using dll: %s", path_to_dll) + + super().__init__(fluid_name=fluid_name) + + self._flag_check_errors = use_error_check + self._flag_warnings = use_warnings + # Set path to RefProp package + self._ref_prop_path = ref_prop_path + self.rp = REFPROPFunctionLibrary(path_to_dll) + self.rp.SETPATHdll(ref_prop_path) + self.molar_base_si = self.rp.GETENUMdll(0, "MOLAR BASE SI").iEnum + # Set fluid name + self.fluid_name = fluid_name + # Get mass and mol fraction and number of components + self._get_comp_frac(z) + # Get component names + self._comp_names = self._get_comp_names() + # Mixture flag + if self._n_comp > 1: + self._mix_flag = True + else: + self._mix_flag = False + + # Setup + self._setup_rp() + # Calculate molar mass in kg/mol + # self.M = self._call_refprop_allprop("M").Output[0] + self.M = self._call_refprop(inp_name="", out_name="M").Output[0] # kg/mol + + self._nbp = None + +
[docs] def terminate(self): + if self._delete_dll_path is not None: + self._delete_dll()
+ + def _delete_dll(self): + try: + # Taken from here: https://stackoverflow.com/questions/21770419/free-the-opened-ctypes-library-in-python + import _ctypes + import sys + _handle = self.rp.dll._handle + if sys.platform.startswith('win'): + _ctypes.FreeLibrary(_handle) + else: + _ctypes.dlclose(_handle) + os.remove(self._delete_dll_path) + self._delete_dll_path = None + except (FileNotFoundError, PermissionError) as err: + logger.error( + "Could not automatically delete the copied RefProp dll at %s. " + "Delete it yourself! Error message: %s", self._delete_dll_path, err + ) + + def _call_refprop_abflsh(self, + inp_name, + value_a, + value_b, + i_flag=1): + """ Call RefProp via ABFLSHdll method + You can define multiple inputs but only "specific ones" where no input values are needed for + e.g. M, Tcrit, pcrit + + Parameters: + ----------- + :param string inp_name: + Input commands: "PQ" + :param float value_a: + Value of parameter b defined in inp_name. In case of None 0 will be used. + :param float value_b: + Value of parameter b defined in inp_name. In case of None 0 will be used. + :param int i_flag: + Flag + Return: + ------- + :return ABFLSHdlloutput tmp: + Returns ABFLSH output + + """ + # TODO + tmp = self.rp.ABFLSHdll(inp_name, value_a, value_b, self._mol_frac, i_flag) + + return tmp + + def _call_refprop_allprop(self, + out_name, + T_val=None, + d_val=None, + i_mass=0, + i_flag=1): + """ Call RefProp via ALLPROPSdll-method + + Parameters: + ----------- + :param string out_name: + Variables you want to calculate. Multiple outputs are possible: + - Single: "M" + - Multiple: "M,TC,PC" + :param float T_val: + Temperature in current state in K. + Note: In case you want to get general fluid parameters such as M, Tcrit, .. Stick to default value! + :param float d_val: + Density in current state (unit depending on i_mass flag - either mol/m^3 or kg/m^3) + Note: In case you want to get general fluid parameters such as M, Tcrit, .. Stick to default value! + :param int i_mass: + Specifies which units the inputs are given in. + - 0: Molar based + - 1: Mass based + Note: In current version (10.0.0.72) Ian Bell says in multiple Git-Issues that you should stick to molar + base! + :param int i_flag: + In current version (10.0.0.72) i_flag is used to define whether a string containing the units is written in + 'hUnits'. + - 0: Deactivated (increases the calculation speed) + - 1: activated + Return: + ------- + :return ALLPROPSdlloutput result: + List with values for parameters + + """ + # Check values of T and d + if T_val is None: + T_val = 0 + if d_val is None: + d_val = 0 + # Define fraction used depending on i_mass flag + if i_mass == 0: + frac = self._mol_frac + elif i_mass == 1: + frac = self._mass_frac + else: + raise ValueError("Chosen i_mass flag '{}' is not possible in ALLPROPSdll function!".format(i_mass)) + + # Call RefProp + res = self.rp.ALLPROPSdll(out_name, self.molar_base_si, i_mass, i_flag, T_val, d_val, frac) + + return res + + def _call_refprop(self, + inp_name, + out_name, + value_a=None, + value_b=None, + i_mass=0, + i_flag=1, + frac=None, + fluid=None): + """ Call general refProp function and calculate values + + Parameters: + ----------- + :param string fluid: + Fluid name - in case default value None is used, stored fluid name will be used for command + :param string inp_name: + Input parameter specification + :param string out_name: + Output string name + :param float value_a: + Value of parameter b defined in inp_name. In case of None 0 will be used. + :param float value_b: + Value of parameter b defined in inp_name. In case of None 0 will be used. + :param integer i_flag: + Defines further settings (see documentation) + :param int i_mass: + Specifies which units the inputs are given in. # TODO: WRONG! iMass determines composition, iUnits determines properties (except q) + - 0: Molar based + - 1: Mass based + Note: In current version (10.0.0.72) Ian Bell says in multiple Git-Issues that you should stick to molar + base! + :param list frac: + List with either mol or mass fraction of pure substances in current fluid + (in case of single pure substance: [1]). + + Return: + ------- + :return REFPROPdlloutput output: + Command of refprop + """ + # Check inputs + if value_a is None: + value_a = 0 + if value_b is None: + value_b = 0 + + if fluid is None: + if self._predefined: + fluid = self.fluid_name # TODO: in general not necessary, decreases performance + else: + fluid = "" + if frac is None: + if self._predefined: + frac = "" + else: + if i_mass == 0: + frac = self._mol_frac + elif i_mass == 1: + frac = self._mass_frac + else: + raise ValueError("Variable i_mass has invalid input '{}'".format(i_mass)) + + # Call refprop function + tmp = self.rp.REFPROPdll(fluid, + inp_name, + out_name, + self.molar_base_si, + i_mass, + i_flag, + value_a, + value_b, + frac) + + return tmp + + def _check_error(self, + err_num, + err_msg, + func_name=""): + """ Check error code and raise error in case it is critical + + Parameters: + ----------- + :param integer err_num: + Error return code + :param string err_msg: + Error message given in RefProp call + :param string func_name: + Name of function error needs to be checked in + """ + # All fine in case error number is 0 + # Throw warning in case error number different than 0 and smaller than 100 is given + # Throw error in case error number higher than 100 is given + if err_num: + if err_num < 100: + if self._flag_warnings: + warnings.warn("[WARNING] Error number {} was given in function '{}'. No critical error but " + "something went wrong maybe. \n Error message is: '{}'".format(str(err_num), + func_name, err_msg)) + else: + if self._flag_check_errors: + raise TypeError("[ERROR] When calling RefProp in function '{}' error number {} was " + "returned. \n Error message is: '{}'".format(func_name, str(err_num), err_msg)) + + def _get_comp_names(self): + """ Get component names. In case current fluid is mixture, only component names will be returned. + In case fluid is a pure substance, substance name is returned. + + Return: + ------- + :return list comp_names: + List with pure substances in current refrigerant + """ + comp_names = [] + if self._predefined: + # Note: While trying it was possible to get fluid name as well, therefore n_comp+1 is used. + if self._n_comp > 1: + for i in range(1, self._n_comp + 3): + test = self.rp.NAMEdll(i) + tmp = test.hn80.replace(".FLD", "") + if not tmp == "": + comp_names.append(tmp) + else: + for i in range(self._n_comp + 3): + tmp = self.rp.NAMEdll(i).hnam + if not tmp == "": + comp_names.append(tmp) + + else: + # Self-defined + tmp_str = self.fluid_name.split("|") + for i in tmp_str: + i = i.replace(".FLD", "") + i = i.replace(".MIX", "") + if len(i) < 2: + continue + else: + comp_names.append(i) + + # Replace Carbon Dioxide for CO2 + for i, tmp in enumerate(comp_names): + if "Carbon dio" in tmp: + comp_names[i] = "CO2" + + return comp_names + + def _get_comp_frac(self, z): + """ Get mass/mol fraction and number of components of current fluid + + Parameters: + ----------- + :param list z: + Contains predefined molar fractions in case one is given. Otherwise, z will be None + """ + # Check if predefined or not + # Predefined + if z is None: + self._predefined = True + # Pure substance + elif len(z) == 1: + self._predefined = True + # Self-designed mixture + else: + self._predefined = False + + # In case predefined mixture or pure substance is used + if self._predefined: + # Dummy function to get values for z in order to specify number of components + tmp_mol = self.rp.REFPROPdll(self.fluid_name, "PQ", "H", self.molar_base_si, 0, 0, 101325, 0, [1]) + tmp_mass = self.rp.REFPROPdll(self.fluid_name, "PQ", "H", self.molar_base_si, 1, 0, 101325, 0, []) + # Check for errors + self._check_error(tmp_mol.ierr, tmp_mol.herr, self._get_comp_frac.__name__) + self._check_error(tmp_mass.ierr, tmp_mass.herr, self._get_comp_frac.__name__) + # Mass and molar fractions of components + self._mol_frac = [zi for zi in tmp_mol.z if zi > 0] + self._mass_frac = [zi for zi in tmp_mass.z if zi > 0] + # Get number of components + self._n_comp = len(self._mol_frac) + # Check, whether error occurred + if self._n_comp < 1: + # It might be possible that z value bugs when calling RefProp. In case of a pure substance this does not + # matter so an additional filter is included + if len(self._mass_frac) == 1: + self._n_comp = 1 + self._mol_frac = [1] + else: + raise ValueError("Number of components for current fluid '{}' is less than " + "one!".format(self.fluid_name)) + + # Get mol fraction + # self._mol_frac = self._transform_to_molfraction(self._mass_frac) + else: + # Mol fraction + self._mol_frac = z + self._mass_frac = [] + # Get number of components + self._n_comp = len(self._mol_frac) + + def _setup_rp(self): + """ Setup for RefProp """ + # Errors can occur in case REFPROP is initalizated multiple time with same fluid - thus a pre setup is used here + self.rp.SETUPdll(1, "N2", "HMX.BNC", "DEF") + # In case of pure substance + if self._n_comp == 1: + self.rp.SETUPdll(self._n_comp, self.fluid_name, "HMX.BNC", "DEF") + # In case of mixtures + else: + # Check if mixture is predefined + if self._predefined: + # Pre defined mixture - different baseline operating point is used + mode = 2 + mixture = "|".join([f+".FLD" for f in self._comp_names]) + n_comp = self._n_comp + else: + # Self defined mixture + mode = 1 + n_comp = self._n_comp + # Define mixtures name + # TODO: Ending is not necessary to create mixtures.... + mixture = "|".join([f+".FLD" for f in self._comp_names]) + + # Setup for mixture + setup = self.rp.SETUPdll(n_comp, mixture, 'HMX.BNC', 'DEF') + setref = self.rp.SETREFdll("DEF", mode, self._mol_frac, 0, 0, 0, 0) + # z = self._mol_frac + # Get mass fraction + self._mass_frac = self._transform_to_massfraction(self._mol_frac) + + # Check whether mixing rules are available + if setup.ierr == 117: + if self._flag_check_errors: + raise ValueError( + "[MIXING ERROR] Mixing rules for mixture '{}' do not exist!".format(self._comp_names)) + else: + print( + "[MIXING ERROR] Mixing rules for mixture '{}' do not exist!".format(self._comp_names)) + elif setup.ierr == -117: + if self._flag_warnings: + warnings.warn( + "[MIXING ERROR] Mixing rules for mixture '{}' are estimated!".format(self._comp_names)) + else: + print( + "[MIXING WARNING] Mixing rules for mixture '{}' are estimated!".format(self._comp_names)) + + def _transform_to_massfraction(self, + mol_frac): + """ Transforms mol fraction to mass fraction + + Parameters: + ----------- + :param list mol_frac: + List containing floats for mol fraction + + Return: + ------- + :return list mass_frac: + List containing floats for mass fraction + """ + tmp = self.rp.XMASSdll(mol_frac) + mass_frac = [yi for yi in tmp.xkg if yi > 0] + return mass_frac + + def _transform_to_molfraction(self, + mass_frac): + """ Transforms mass fraction to mol fraction + + Parameters: + ----------- + :param list mass_frac: + List containing floats for mass fraction + + Return: + ------- + :return list frac: + List containing floats for mol fraction + """ + tmp = self.rp.XMOLEdll(mass_frac) + mol_frac = [xi for xi in tmp.xmol if xi > 0] + return mol_frac + +
[docs] def calc_state(self, mode: str, var1: float, var2: float, kr=1): + """ Calculate state. Depending on mode, different function will be chosen. Input state variables need to be in + SI units! + + Notes: + ------ + 1.) PT does not work when state might be within the two-phase region! + 2.) Only functions for density are implemented. In case you know the specific volume instead use density + functions with inverse value! + 3.) Quality can have values outside of 'physical' scope: + q = -998: Subcooled liquid + q = 998: Superheated vapor + q = 999: Supercritical state + + Possible modes are currently: + - "PD": Pressure, Density + - "PH": Pressure, Enthalpy + - "PQ": Pressure, Quality + - "PS": Pressure, Entropy + - "PT": Pressure, Temperature + - "PU": Pressure, Internal Energy + - "TD": Temperature, Density + - "TH": Temperature, Enthalpy + - "TQ": Temperature, Quality + - "TS": Temperature, Entropy + - "TU": Temperature, Internal Energy + - "DH": Density, Enthalpy + - "DS": Density, Entropy + - "DU": Density, Internal Energy + - "HS": Enthalpy, Entropy + + Parameters: + ----------- + :param string mode: + Defines which input state variables are given (see possible modes above) + :param float var1: + Value of state variable 1 (first one in name) - use SI units! + :param float var2: + Value of state variable 2 (second one in name) - use SI units! + :param int kr: + phase flag (kr=1: lower density, kr=2: higher density) + relevant for "TH", "TS", "TU" + + Return: + ------- + :return ThermodynamicState state: + Thermodynamic state with state variables + """ + # Multiplier for pressure since kPa is used in RefProp + p_multi = 1e-3 + # Multiplier for energy + e_multi = self.M + # Multiplier for density + d_multi = 1 / self.M / 1000 + + # Init all parameters + p = None + d = None + T = None + u = None + h = None + s = None + q = None + + # Check modi + + # Pressure and density + if mode == "PD": + p = var1 + d = var2 + var1 = var1 * p_multi + var2 = var2 * d_multi + tmp = self.rp.PDFLSHdll(var1, var2, self._mol_frac) + # Pressure and enthalpy + elif mode == "PH": + p = var1 + var1 = var1 * p_multi + h = var2 + var2 = var2 * e_multi + tmp = self.rp.PHFLSHdll(var1, var2, self._mol_frac) + # Pressure and quality + elif mode == "PQ": + p = var1 + var1 = var1 * p_multi + q = var2 + # In case current fluid is mixture you need to transform Q to molar base for RefProp-function + if self._mix_flag: + var2 = self._call_refprop("PQMASS", "QMOLE", p, q, i_mass=1).Output[0] + tmp = self.rp.PQFLSHdll(var1, var2, self._mol_frac, 0) + # Pressure and entropy + elif mode == "PS": + p = var1 + var1 = var1 * p_multi + s = var2 + var2 = var2 * e_multi + tmp = self.rp.PSFLSHdll(var1, var2, self._mol_frac) + # Pressure and Temperature + elif mode == "PT": + p = var1 + var1 = var1 * p_multi + T = var2 + tmp = self.rp.TPFLSHdll(var2, var1, self._mol_frac) + # Pressure and internal energy + elif mode == "PU": + p = var1 + var1 = var1 * p_multi + u = var2 + var2 = var2 * e_multi + # mode = "PE" + tmp = self.rp.PEFLSHdll(var1, var2, self._mol_frac) + # Temperature and density + elif mode == "TD": + T = var1 + d = var2 + var2 = var2 * d_multi + tmp = self.rp.TDFLSHdll(var1, var2, self._mol_frac) + # Temperature and enthalpy + elif mode == "TH": + T = var1 + h = var2 + var2 = var2 * e_multi + tmp = self.rp.THFLSHdll(T, var2, self._mol_frac, kr) + # Temperature and quality + elif mode == "TQ": + T = var1 + q = var2 + # In case current fluid is mixture you need to transform Q to molar base for RefProp-function + if self._mix_flag: + var2 = self._call_refprop("TQMASS", "QMOLE", T, q, i_mass=1).Output[0] + tmp = self.rp.TQFLSHdll(T, var2, self._mol_frac, 1) + # Temperature and entropy + elif mode == "TS": + T = var1 + s = var2 + var2 = var2 * e_multi + tmp = self.rp.TSFLSHdll(T, var2, self._mol_frac, kr) + # Temperature and internal energy + elif mode == "TU": + T = var1 + u = var2 + var2 = var2 * e_multi + # mode = "TE" + tmp = self.rp.TEFLSHdll(T, var2, self._mol_frac, kr) + # Density and enthalpy + elif mode == "DH": + d = var1 + var1 = var1 * d_multi + h = var2 + var2 = var2 * e_multi + tmp = self.rp.DHFLSHdll(var1, var2, self._mol_frac) + # Density and entropy + elif mode == "DS": + d = var1 + var1 = var1 * d_multi + s = var2 + var2 = var2 * e_multi + tmp = self.rp.DSFLSHdll(var1, var2, self._mol_frac) + # Density and inner energy + elif mode == "DU": + d = var1 + var1 = var1 * d_multi + u = var2 + var2 = var2 * e_multi + # mode = "DE" + tmp = self.rp.DEFLSHdll(var1, var2, self._mol_frac) + elif mode == "HS": + h = var1 + var1 = var1 * e_multi + s = var2 + var2 = var2 * e_multi + tmp = self.rp.HSFLSHdll(var1, var2, self._mol_frac) + else: + raise ValueError("Chosen mode is not available in refprop calc_state function!") + + # Check for errors + self._check_error(tmp.ierr, tmp.herr, self.calc_state.__name__) + + # Get all state variables + if p is None: + p = tmp.P / p_multi + if T is None: + T = tmp.T + if u is None: + u = tmp.e / e_multi + if h is None: + h = tmp.h / e_multi + if s is None: + s = tmp.s / e_multi + if d is None: + d = tmp.D / d_multi + if q is None: + if self._mix_flag: + # Transform current q (molar) to mass based quality + tmp2 = self._call_refprop("PH", "QMASS", p, h * e_multi, i_mass=1) + if tmp2.Output[0] < 0: + q_mass = tmp2.ierr + else: + q_mass = tmp2.Output[0] + q = q_mass + else: + q = tmp.q + + # # In case not in two phase region reset q to -1 + # if q > 1 or q < 0: + # q = -1 + + # Define state + state = ThermodynamicState(p=p, T=T, u=u, h=h, s=s, d=d, q=q) + return state
+ +
[docs] def calc_satliq_state(self, s): + """s in kJ/kgK""" + s = s * self.M * 1000 # kJ/kgK -> J/molK + tmp = self.rp.SATSdll(s=s, z="", kph=1) + self._check_error(tmp.ierr, tmp.herr, self.calc_satliq_state.__name__) + if tmp.k1 != 1: + raise TypeError + p = tmp.P1 * 1000 # kPa -> Pa + d = tmp.D1 * self.M * 1000 # mol/l -> kg/mol + return self.calc_state("PD", p, d)
+ +
[docs] def calc_transport_properties(self, state: ThermodynamicState): + """ Calculate transport properties of RefProp fluid at given state + + Parameters: + ----------- + :param ThermodynamicState state: + Current thermodynamic state + Return: + ------- + :return TransportProperties props: + Instance of TransportProperties + """ + # Get properties + tmp = self._call_refprop_allprop("PRANDTL,VIS,TCX,KV,CV,CP,BETA,STN,ACF", state.T, state.d / self.M, i_mass=0) + # Create transport properties instance + props = TransportProperties(lam=tmp.Output[2], + dyn_vis=tmp.Output[1], + kin_vis=tmp.Output[3], + pr=tmp.Output[0], + cp=tmp.Output[5] / self.M, + cv=tmp.Output[4] / self.M, + beta=tmp.Output[6], + sur_ten=tmp.Output[7], + ace_fac=tmp.Output[8], + state=state) + # Return props + return props
+ +
[docs] def get_available_substances(self, + mode="all", + include_ending=False, + save_txt=False): + """ Get all available RefProp fluids (mixtures and / or pure substances depending on mode) + + Parameters: + ----------- + :param string mode: + Mode defining which kind of fluids you want to have: 'pure': pure substances, 'mix': mixtures, 'all': all + :param boolean include_ending: + Defines, whether file ending shall be returned as well or not + :param boolean save_txt: + Defines, whether a text file with names shall be created in current working directory + Return: + ------- + :return list names: + String list containing names of available fluids (depending on defined mode) + """ + # Possible endings + _endings = ["MIX", "FLD", "PPF"] + + # Folders where fluid data is located + folders = [r"FLUIDS", r"MIXTURES"] + + # Define paths by mode + if mode == "pure": + paths = [os.path.join(self._ref_prop_path, folders[0])] + elif mode == "mix": + paths = [os.path.join(self._ref_prop_path, folders[1])] + elif mode == "all": + paths = [os.path.join(self._ref_prop_path, folders[0]), + os.path.join(self._ref_prop_path, folders[1])] + else: + raise ValueError("Chosen mode '{}' is not possible!".format(mode)) + + # Get files in folders, remove ending and append to names + names = [] + for p in paths: + # Get all files in directory + files = [f for f in os.listdir(p) if os.path.isfile(os.path.join(p, f))] + # Remove ending + if include_ending: + tmp = [path for path in files if path.split(".")[1] in _endings] + else: + tmp = [path.split(".")[0] for path in files if path.split(".")[1] in _endings] + # Append names to names list + names.extend(tmp) + + # In case names shall be stored + if save_txt: + with open("available_fluids.txt", "w") as output: + for i in names: + output.write("{} \n".format(i)) + + if not names: + raise ValueError("No fluids are in current RefProp directory. Check path '{}'!".format(self._ref_prop_path)) + + # Return names + return names
+ +
[docs] def get_comp_names(self): + """ Get name of components within current fluid" + + Return: + ------- + :return list comp_names: + String names of components within current fluid + """ + return self._comp_names
+ +
[docs] def get_nbp(self): + """ Get normal boiling point (T @ q=0 and 1 bar) + + Return: + ------- + :return float nbp: + Normal boiling point of refrigerant in °C + """ + if not self._nbp: + self._nbp = self.calc_state("PQ", 1e5, 0.0).T - 273.15 + + return self._nbp
+ +
[docs] def get_molar_composition(self, state: ThermodynamicState, z_molar=None): + """ Get composition on molar base. Liquid phase, vapor phase and total. + + :param ThermodynamicState state: the state whose compositions will be returned + :param list z_molar: molar composition of fluid. In case of None, default value _mol_frac is used + :return: + - list x: + composition of liquid phase + - list y: + composition of vapor phase + - list z: + composition in total + """ + if z_molar is None: + z = self._mol_frac + M = self.M + else: + z = z_molar + M = self.rp.REFPROPdll(hFld="", + hIn="", + hOut="M", + iUnits=self.molar_base_si, + iMass=0, + iFlag=1, + a=0, + b=0, + z=z_molar).Output[0] + num_components = len(z) + + tmp = self.rp.TDFLSHdll(T=state.T, + D=state.d / M / 1000, + z=z) + # TDFLSHdll is deprecated, use the following in future: + # tmp = self.rp.ABFLSHdll(ab="TD", + # a=state.T, + # b=state.d / self.M / 1000, + # z=self._mol_frac, + # iFlag=0) # molar units + + x = list(tmp.x[:num_components]) + y = list(tmp.y[:num_components]) + + return x, y, z
+ +
[docs] def get_critical_point(self): + """ Get T and p of critical point + + Return: + ------- + :return float Tc: + Temperature at critical point in K + :return float pc: + Pressure at critical point in Pa + :return float dc: + Density at critical point in kg/m^3 + """ + mode = 2 + if mode == 1: + tmp = self._call_refprop("CRIT", "T,P,D", i_mass=1) + Tc = tmp.Output[0] + pc = tmp.Output[1] + dc = tmp.Output[2] * self.M + else: + res = self._call_refprop_allprop("TC,PC,DC") + Tc = res.Output[0] + pc = res.Output[1] + dc = res.Output[2] * self.M + return Tc, pc, dc
+ + # + # +
[docs] def get_def_limits(self): + """ Get limits of current ref prop fluid + Limits contain Tmin, Tmax, Dmax and Pmax (Temperatures, density, pressure) + + :return dict limits: + Dictionary with definition limits in RefProp. Contains min/max temperature, max density, max pressure. + """ + tmp = self._call_refprop_allprop("TMIN,TMAX,DMAX,PMAX") + limits = {"Tmin": tmp.Output[0], + "Tmax": tmp.Output[1], + "Dmax": tmp.Output[2] * self.M, + "Pmax": tmp.Output[3]} + return limits
+ +
[docs] @staticmethod + def get_dll_path(ref_prop_path: str): + """ + Return the location of the dll + + Return: + :return: string path_to_dll: + Path of a valid dll + """ + path_to_dll = os.path.join(ref_prop_path, r"REFPRP64.DLL") + + # Check if dll actually exists: + if not os.path.exists(path_to_dll): + raise FileNotFoundError("Selected dll not found automatically. " + "Please alter the local attribute or search for yourself.") + + return path_to_dll
+ +
[docs] def get_fluid_name(self): + """ Get fluid name. + + Return: + ------- + :return string fluid_name: + Fluid name + """ + return self.fluid_name
+ +
[docs] def get_gwp(self): + """ Get gwp of current fluid from refProp + + Return: + ------- + :return float gwp: + Global warming potential of fluid. In case calculation failed, None will be returned. + """ + # Call refProp + tmp = self._call_refprop("", + "GWP", + i_mass=1) + # Calculate gwp + gwp = round(sum(max(tmp.Output[i], 0) * self._mass_frac[i] for i in range(self._n_comp)), 2) + # In case GWP cannot be calculated + if gwp < 0: + gwp = 0 + return gwp
+ +
[docs] def get_longname(self): + """ Get longname of fluid + + Return: + ------- + :return string longname: + Name of current fluid in refprop - provides mass fractions and components as well (in case of mixture) + """ + longname = self._call_refprop("", "LONGNAME(0)").hUnits + return longname
+ +
[docs] def get_mass_fraction(self, use_round=True): + """ Get mass fractions of pure substances in current fluid + + Parameters: + :param boolean use_round: + Flag to define, whether the exact values or rounded values (by the fourth number) shall be used + Return: + ------- + :return list mass_frac: + List of component mass fractions + """ + if use_round: + mass_frac = [round(i, 4) for i in self._mass_frac] + else: + mass_frac = self._mass_frac + return mass_frac
+ +
[docs] def get_molar_mass(self): + """ Get molar mass of current fluid + + Return: + ------- + :return float M: + Molar mass of current fluid in kg/mol + """ + return self.M
+ +
[docs] def get_mol_fraction(self, use_round=True): + """ Get mol fractions of pure substances in current fluid + + Parameters: + :param boolean use_round: + Flag to define, whether the exact values or rounded values (by the fourth number) shall be used + Return: + ------- + :return list frac: + List of component mol fractions + """ + if use_round: + mol_frac = [round(i, 4) for i in self._mol_frac] + else: + mol_frac = self._mol_frac + return mol_frac
+ +
[docs] def get_odp(self): + """ Calculate ozone depletion potential + In case of mixtures: Maximum value of pure substances will be used + + Return: + ------- + :return float odp: + ODP of fluid. In case calculation failed, None will be returned. + """ + # Call refProp + tmp = self._call_refprop("", + "ODP", + i_mass=1) + # Calculate odp + odp = max(max(tmp.Output), 0) + # In case some error occured + if odp < 0: + odp = 0 + return odp
+ +
[docs] def get_safety(self): + """ Calculate safety class of refrigerant + + Return: + ------- + :return string safety: + Safety class of fluid. + """ + # Call refProp + tmp = self._call_refprop("", + "SAFETY", + i_mass=1) + # Get safety class + safety = tmp.hUnits + # Return safety + return safety
+ +
[docs] def get_sat_vap_pressure(self, T_sat): + """ Get pressure of saturated vapor for defined temperature + + Note: + - works for vapor, liquid and solid + - returns equilibrium pressure at defined line (q=1) + + Parameters: + :param float T_sat: + Temperature in K + Return: + :return float p_sat: + Vapor pressure in Pa + """ + trip = self.get_triple_point() + if trip[0] <= T_sat: + p_sat = self.calc_state("TQ", T_sat, 1.0).p + else: + tmp = self.rp.REFPROPdll("", "TSUBL", "P", self.molar_base_si, 0, 0, T_sat, 0.0, self._mol_frac) + p_sat = tmp.Output[0] + return p_sat
+ +
[docs] def get_triple_point(self): + """ Get temperature and pressure at triple point of current fluid + + Note: Works fine for pure substances, mixtures might not work properly + + Return: + :return float T_tpl: + Temperature at triple point in K + :return float p_tpl: + Pressure at triple point in Pa + """ + # Call Refprop + tmp = self._call_refprop("TRIP", "T;P") + return tmp.Output[0], tmp.Output[1]
+ +
[docs] def get_version(self): + """ Get version of wrapper and used RefProp dll + + Return: + :return string wrapper_version: + Refprop wrapper version + :return string refprop_version: + Version of used RefProp dll + """ + return self.__version__, self.rp.RPVersion()
+ +
[docs] def is_mixture(self): + """ Find out if fluid is mixture or not. + In case current fluid is mixture, true is returned. + In case current fluid is pure substance, false is returned. + + Return: + ------- + :return boolean _mix_flag: + Boolean for mixture (True), pure substance (False) + """ + return self._mix_flag
+ +
[docs] def set_error_flag(self, flag): + """ Set error flag + + Parameters: + :param boolean flag: + New error flag + Return: + :return int err: + Notifier for error code - in case everything went fine, 0 is returned + """ + self._flag_check_errors = flag + return 0
+ +
[docs] def set_warning_flag(self, flag): + """ Set warning flag + + Parameters: + :param boolean flag: + New warning flag + Return: + :return int err: + Notifier for error code - in case everything went fine, 0 is returned + """ + self._flag_warnings = flag + return 0
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/media/states.html b/docs/0.1.1/docs/_modules/vclibpy/media/states.html new file mode 100644 index 0000000..83bae8b --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/media/states.html @@ -0,0 +1,286 @@ + + + + + + + + vclibpy.media.states — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.media.states

+"""
+Module containing classes for thermodynamic state and transport properties.
+"""
+from vclibpy.datamodels import VariableContainer
+
+
+__all__ = [
+    'ThermodynamicState',
+    'TransportProperties',
+]
+
+
+
[docs]class ThermodynamicState: + """ + Represents a thermodynamic state within a cycle. + + Notes: + Does not necessarily need to have all state variables defined! + + Args: + p (float): Pressure at the state in Pa. + T (float): Temperature at the state in K. + u (float): Inner energy at the state in J/kg. + h (float): Enthalpy at the state in J/kg. + s (float): Entropy at the state in J/(kg * K). + v (float): Specific volume at the state in m^3/kg. + q (float): Quality at the state (between 0 and 1). + d (float): Density at the state in kg/m^3. + + Methods: + __init__: Initializes the state class. + __str__: Provides a string representation of the state. + get_pretty_print: Formats the state with names, units, and descriptions. + """ + + def __init__(self, + p=None, + T=None, + u=None, + h=None, + s=None, + v=None, + q=None, + d=None): + """ + Initializes a thermodynamic state. + + Args: + p (float): Pressure at the state in Pa. + T (float): Temperature at the state in K. + u (float): Inner energy at the state in J/kg. + h (float): Enthalpy at the state in J/kg. + s (float): Entropy at the state in J/(kg * K). + v (float): Specific volume at the state in m^3/kg. + q (float): Quality at the state (between 0 and 1). + d (float): Density at the state in kg/m^3. + + Notes: + If only v or d is provided, the other attribute will be calculated. If both are given and they are similar, + an error will be raised. + """ + self.p = p + self.T = T + self.u = u + self.h = h + self.s = s + self.v = v + self.q = q + self.d = d + # Define density + if v and d: + if not round(1/v, 4) == round(d, 4): + raise ValueError("At current state d and v do not match", d, v) + elif v: + self.d = 1/v + elif d: + self.v = 1/d + + def __str__(self): + """ + Returns a string representation of the state. + """ + return ";".join([f"{k}={v}" for k, v in self.__dict__.items()]) + +
[docs] def get_pretty_print(self): + """ + Provides a formatted representation of the state with names, units, and descriptions. + """ + _container = VariableContainer() + _container.__class__.__name__ = self.__class__.__name__ + _container.set(name="p", value=self.p, unit="Pa", description="Pressure") + _container.set(name="T", value=self.T, unit="K", description="Temperature") + _container.set(name="u", value=self.u, unit="J/kg", description="Inner energy") + _container.set(name="h", value=self.h, unit="J/kg", description="Enthalpy") + _container.set(name="s", value=self.s, unit="J/(kg*K)", description="Entropy") + _container.set(name="v", value=self.v, unit="m^3/kg", description="Specific volume") + _container.set(name="q", value=self.q, unit="-", description="Quality") + _container.set(name="d", value=self.d, unit="kg/m^3", description="Density") + return str(_container)
+ + +
[docs]class TransportProperties: + """ + Represents transport properties at a specific thermodynamic state. + + Args: + lam (float): Thermal conductivity in W/(m*K). + dyn_vis (float): Dynamic viscosity in Pa*s. + kin_vis (float): Kinematic viscosity in m^2/s. + Pr (float): Prandtl number. + cp (float): Isobaric specific heat capacity in J/(kg*K). + cv (float): Isochoric specific heat capacity in J/(kg*K). + beta (float): Thermal expansion coefficient in 1/K. + sur_ten (float): Surface tension in N/m. + ace_fac (float): Acentric factor. + state (ThermodynamicState): The state the transport properties belong to. + + Methods: + __init__: Initializes the transport properties class. + __str__: Provides a string representation of the transport properties. + get_pretty_print: Formats the properties with names, units, and descriptions. + """ + + def __init__(self, + lam=None, + dyn_vis=None, + kin_vis=None, + pr=None, + cp=None, + cv=None, + beta=None, + sur_ten=None, + ace_fac=None, + state=None): + """ + Initializes transport properties. + + Args: + lam (float): Thermal conductivity in W/(m*K). + dyn_vis (float): Dynamic viscosity in Pa*s. + kin_vis (float): Kinematic viscosity in m^2/s. + pr (float): Prandtl number. + cp (float): Isobaric specific heat capacity in J/(kg*K). + cv (float): Isochoric specific heat capacity in J/(kg*K). + beta (float): Thermal expansion coefficient in 1/K. + sur_ten (float): Surface tension in N/m. + ace_fac (float): Acentric factor. + state (ThermodynamicState): The state the transport properties belong to. + """ + self.lam = lam + self.dyn_vis = dyn_vis + self.kin_vis = kin_vis + self.Pr = pr + self.cp = cp + self.cv = cv + self.beta = beta + self.sur_ten = sur_ten + self.ace_fac = ace_fac + self.state = state + + def __str__(self): + """ + Returns a string representation of the transport properties. + """ + return ";".join([f"{k}={v}" for k, v in self.__dict__.items()]) + +
[docs] def get_pretty_print(self): + """ + Provides a formatted representation of the properties with names, units, and descriptions. + """ + _container = VariableContainer() + _container.__class__.__name__ = self.__class__.__name__ + _container.set(name="lam", value=self.lam, unit="W/(m*K)", description="Thermal conductivity") + _container.set(name="dyn_vis", value=self.dyn_vis, unit="Pa*s", description="Dynamic viscosity") + _container.set(name="kin_vis", value=self.kin_vis, unit="m^2/s", description="Kinematic viscosity") + _container.set(name="pr", value=self.Pr, unit="-", description="Prandtl number") + _container.set(name="cp", value=self.cp, unit="J/(kg*K)", description="Isobaric specific heat capacity") + _container.set(name="cv", value=self.cv, unit="J/(kg*K)", description="Isochoric specific heat capacity") + _container.set(name="beta", value=self.beta, unit="1/K", description="Thermal expansion coefficient") + _container.set(name="sur_ten", value=self.sur_ten, unit="N/m", description="Surface tension") + _container.set(name="ace_fac", value=self.ace_fac, unit="-", description="Acentric factor") + return str(_container)
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/utils/automation.html b/docs/0.1.1/docs/_modules/vclibpy/utils/automation.html new file mode 100644 index 0000000..0b5848d --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/utils/automation.html @@ -0,0 +1,324 @@ + + + + + + + + vclibpy.utils.automation — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.utils.automation

+"""
+Functions to generate HP Maps automatically
+"""
+import logging
+import pathlib
+import os
+from typing import List, Union
+import multiprocessing
+import numpy as np
+import pandas as pd
+from vclibpy.datamodels import FlowsheetState, Inputs
+from vclibpy.flowsheets import BaseCycle
+from vclibpy import utils
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]def calc_multiple_states( + save_path: pathlib.Path, + heat_pump: BaseCycle, + inputs: List[Inputs], + **kwargs): + """ + Function to calculate the flowsheet states for all given inputs. + All results are stored as a .xlsx file in the given save-path + + Args: + save_path (pathlib.Path): Location where to save the results as xlsx. + heat_pump (BaseCycle): A valid flowsheet + inputs (List[Inputs]): A list with all inputs to simulate + **kwargs: Solver settings for the flowsheet + """ + rel_infos = [] + for i, single_inputs in enumerate(inputs): + fs_state = None + logger.info(f"Running combination {i+1}/{len(inputs)}.") + try: + fs_state = heat_pump.calc_steady_state(inputs=single_inputs, + **kwargs) + except Exception as e: + # Avoid loss of data if un-excepted errors occur. + logger.error(f"An error occurred: {e}") + if fs_state is None: + fs_state = FlowsheetState() + hp_state_dic = { + **single_inputs.convert_to_str_value_format(with_unit_and_description=True), + **fs_state.convert_to_str_value_format(with_unit_and_description=True) + } + rel_infos.append(hp_state_dic) + df = pd.DataFrame(rel_infos) + df.index.name = "State Number" + df.to_excel(save_path.joinpath(f"{heat_pump}_{heat_pump.fluid}.xlsx"), sheet_name="HP_states", float_format="%.5f")
+ + +
[docs]def full_factorial_map_generation( + heat_pump: BaseCycle, + T_eva_in_ar: Union[list, np.ndarray], + T_con_in_ar: Union[list, np.ndarray], + n_ar: Union[list, np.ndarray], + m_flow_con: float, + m_flow_eva: float, + save_path: Union[pathlib.Path, str], + dT_eva_superheating=5, + dT_con_subcooling=0, + use_multiprocessing: bool = False, + save_plots: bool = False, + **kwargs +) -> (pathlib.Path, pathlib.Path): + """ + Run a full-factorial simulation to create performance maps + used in other simulation tools like Modelica or to analyze + the off-design of the flowsheet. + The results are stored and returned as .sdf and .csv files. + Currently, only varying T_eva_in, T_con_in, and n is implemented. + However, changing this to more dimensions or other variables + is not much work. In this case, please raise an issue. + + Args: + heat_pump (BaseCycle): The flowsheet to use + T_eva_in_ar: Array with inputs for T_eva_in + T_con_in_ar: Array with inputs for T_con_in + n_ar: Array with inputs for n_ar + m_flow_con: Condenser mass flow rate + m_flow_eva: Evaporator mass flow rate + save_path: Where to save all results. + dT_eva_superheating: Evaporator superheating + dT_con_subcooling: Condenser subcooling + use_multiprocessing: + True to use multiprocessing. May speed up the calculation. Default is False + save_plots: + True to save plots of each steady state point. Default is False + **kwargs: Solver settings for the flowsheet + + Returns: + tuple (pathlib.Path, pathlib.Path): + Path to the created .sdf file and to the .csv file + """ + if isinstance(save_path, str): + save_path = pathlib.Path(save_path) + if save_plots: + kwargs["save_path_plots"] = pathlib.Path(save_path).joinpath(f"plots_{heat_pump.flowsheet_name}_{heat_pump.fluid}") + os.makedirs(kwargs["save_path_plots"], exist_ok=True) + + list_mp_inputs = [] + list_inputs = [] + idx_for_access_later = [] + for i_T_eva_in, T_eva_in in enumerate(T_eva_in_ar): + for i_n, n in enumerate(n_ar): + for i_T_con_in, T_con_in in enumerate(T_con_in_ar): + idx_for_access_later.append([i_n, i_T_con_in, i_T_eva_in]) + inputs = Inputs(n=n, + T_eva_in=T_eva_in, + T_con_in=T_con_in, + m_flow_eva=m_flow_eva, + m_flow_con=m_flow_con, + dT_eva_superheating=dT_eva_superheating, + dT_con_subcooling=dT_con_subcooling) + list_mp_inputs.append([heat_pump, inputs, kwargs]) + list_inputs.append(inputs) + fs_states = [] + i = 0 + if use_multiprocessing: + pool = multiprocessing.Pool(processes=multiprocessing.cpu_count()) + for fs_state in pool.imap(_calc_single_hp_state, list_mp_inputs): + fs_states.append(fs_state) + i += 1 + logger.info(f"Ran {i} of {len(list_mp_inputs)} points") + else: + for inputs in list_inputs: + fs_state = _calc_single_hp_state([heat_pump, inputs, kwargs]) + fs_states.append(fs_state) + i += 1 + logger.info(f"Ran {i} of {len(list_mp_inputs)} points") + + # Save to sdf + result_shape = (len(n_ar), len(T_con_in_ar), len(T_eva_in_ar)) + _dummy = np.zeros(result_shape) # Use a copy to avoid overwriting of values of any sort. + _dummy[:] = np.nan + # Get all possible values: + all_variables = {} + all_variables_info = {} + variables_to_excel = [] + for fs_state, inputs in zip(fs_states, list_inputs): + all_variables.update({var: _dummy.copy() for var in fs_state.get_variable_names()}) + all_variables_info.update({var: variable for var, variable in fs_state.get_variables().items()}) + variables_to_excel.append({ + **inputs.convert_to_str_value_format(with_unit_and_description=True), + **fs_state.convert_to_str_value_format(with_unit_and_description=True), + }) + + # Save to excel + save_path_sdf = save_path.joinpath(f"{heat_pump.flowsheet_name}_{heat_pump.fluid}.sdf") + save_path_csv = save_path.joinpath(f"{heat_pump.flowsheet_name}_{heat_pump.fluid}.csv") + pd.DataFrame(variables_to_excel).to_csv( + save_path_csv + ) + + for fs_state, idx_triple in zip(fs_states, idx_for_access_later): + i_n, i_T_con_in, i_T_eva_in = idx_triple + for variable_name, variable in fs_state.get_variables().items(): + all_variables[variable_name][i_n][i_T_con_in][i_T_eva_in] = variable.value + + _nd_data = {} + for variable, nd_data in all_variables.items(): + _nd_data.update({ + variable: { + "data": nd_data, + "unit": all_variables_info[variable].unit, + "comment": all_variables_info[variable].description} + }) + + _scale_values = { + "n": n_ar, + "T_con_in": T_con_in_ar, + "T_eva_in": T_eva_in_ar + } + inputs: Inputs = list_inputs[0] + _parameters = {} + for name, variable in inputs.items(): + if name not in _scale_values: + _parameters[name] = { + "data": variable.value, + "unit": variable.unit, + "comment": variable.description + } + _scales = {} + for name, data in _scale_values.items(): + _scales[name] = { + "data": data, + "unit": inputs.get(name).unit, + "comment": inputs.get(name).description + } + + sdf_data = { + heat_pump.flowsheet_name: + { + heat_pump.fluid: (_scales, _nd_data, _parameters) + } + } + utils.save_to_sdf(data=sdf_data, save_path=save_path_sdf) + + # Terminate heat pump med-props: + heat_pump.terminate() + + return save_path_sdf, save_path_csv
+ + +def _calc_single_hp_state(data): + """Helper function for a single state to enable multiprocessing""" + heat_pump, inputs, kwargs = data + fs_state = None + try: + fs_state = heat_pump.calc_steady_state(inputs=inputs, + **kwargs) + except Exception as e: + logger.error(f"An error occurred for input: {inputs.__dict__}: {e}") + if fs_state is None: + fs_state = FlowsheetState() + # Append the data to the dataframe + return fs_state +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/utils/nominal_design.html b/docs/0.1.1/docs/_modules/vclibpy/utils/nominal_design.html new file mode 100644 index 0000000..4989c26 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/utils/nominal_design.html @@ -0,0 +1,190 @@ + + + + + + + + vclibpy.utils.nominal_design — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.utils.nominal_design

+import time
+import logging
+
+from vclibpy import Inputs
+from vclibpy.flowsheets import BaseCycle
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]def nominal_hp_design( + heat_pump: BaseCycle, + inputs: Inputs, + fluid: str, + dT_con: float = None, + dT_eva: float = None, + **kwargs) -> dict: + """ + Function to calculate the heat pump design + at a given nominal point. + Args: + heat_pump (BaseCycle): A supported flowsheet + inputs (Inputs): + The input values at the nominal point. + If the mass flow rates are not given, you + can use dT_con and dT_eva to iteratively calculate + the mass flow rates in order to achieve the required + temperature differences at the nominal point. + dT_con (float): + Condenser temperature difference to calculate mass flow rate + dT_eva (float): + Evaporator temperature difference to calculate mass flow rate + fluid (str): Fluid to be used. + **kwargs: + m_flow_eva_start: Guess start-value for iteration. Default 0.2 + m_flow_con_start: Guess start-value for iteration. Default 1 + accuracy: Minimal accuracy for mass flow rate iteration (in kg/s). + Default 0.001 kg/s + + Returns: + dict: A dictionary with all flowsheet states and inputs containing + information about the nominal design. + """ + t0 = time.time() + # Define nominal values: + m_flow_con_start = kwargs.get("m_flow_con_start", 0.2) + m_flow_eva_start = kwargs.get("m_flow_eva_start", 1) + accuracy = kwargs.get("accuracy", 0.001) + calculate_m_flow = dT_eva is not None and dT_con is not None + if calculate_m_flow: + # Get nominal value: + fs_state = heat_pump.calc_steady_state(fluid=fluid, inputs=inputs) + if fs_state is None: + raise ValueError("Given configuration is infeasible at nominal point.") + + else: + # We have to iterate to match the m_flows to the Q_cons: + m_flow_eva_next = m_flow_eva_start + m_flow_con_next = m_flow_con_start + while True: + # Set values + m_flow_eva = m_flow_eva_next + m_flow_con = m_flow_con_next + inputs.set("m_flow_con", m_flow_con) + inputs.set("m_flow_eva", m_flow_eva) + # Get nominal value: + fs_state = heat_pump.calc_steady_state(fluid=fluid, inputs=inputs) + if fs_state is None: + raise ValueError("Given configuration is infeasible at nominal point.") + cp_eva = heat_pump.evaporator._secondary_cp + cp_con = heat_pump.condenser._secondary_cp + m_flow_con_next = fs_state.get("Q_con") / (dT_con * cp_con) + m_flow_eva_next = (fs_state.get("Q_con") * (1 - 1 / fs_state.get("COP"))) / (dT_eva * cp_eva) + # Check convergence: + if abs(m_flow_eva_next - m_flow_eva) < accuracy and abs(m_flow_con-m_flow_con_next) < accuracy: + break + + nominal_design_info = { + **inputs.convert_to_str_value_format(with_unit_and_description=False), + **fs_state.convert_to_str_value_format(with_unit_and_description=False), + "dT_con": dT_con, + "dT_eva": dT_eva + } + logger.info("Auto-generation of nominal values took %s seconds", time.time()-t0) + logger.info('Nominal values: %s', nominal_design_info) + + return nominal_design_info
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/utils/plotting.html b/docs/0.1.1/docs/_modules/vclibpy/utils/plotting.html new file mode 100644 index 0000000..8bd0f58 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/utils/plotting.html @@ -0,0 +1,403 @@ + + + + + + + + vclibpy.utils.plotting — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.utils.plotting

+import pathlib
+from typing import List
+
+import numpy as np
+import matplotlib.pyplot as plt
+import sdf
+
+from vclibpy.media import ThermodynamicState, MedProp
+
+
+
[docs]def plot_cycle( + med_prop: MedProp, + states: List[ThermodynamicState], + save_path: pathlib.Path = None, + show: bool = False +): + """ + Creates T-h and p-h diagrams for a thermodynamic cycle. + + Args: + med_prop (MedProp): + Object containing the medium properties and two-phase limits. + states (List[ThermodynamicState]): + List of thermodynamic states defining the cycle points. Each state + should contain T, p, and h properties. + save_path (pathlib.Path, optional): + Path where the plot should be saved. If None, returns the figure + and axes objects instead. Defaults to None. + show (bool): + If True, plots are displayed. Default is False. + + Returns: + tuple(matplotlib.figure.Figure, numpy.ndarray) or None: + If save_path is provided, saves the plot and returns None. + If show is True, shows the plot. + """ + states.append(states[0]) # Plot full cycle + # Unpack state var: + h_T = np.array([state.h for state in states]) / 1000 + T = [state.T - 273.15 for state in states] + p = np.array([state.p / 1e5 for state in states]) + h_p = h_T + + fig, ax = plt.subplots(2, 1, sharex=True) + ax[0].set_ylabel("$T$ in °C") + ax[1].set_xlabel("$h$ in kJ/kgK") + # Two phase limits + ax[0].plot( + med_prop.get_two_phase_limits("h") / 1000, + med_prop.get_two_phase_limits("T") - 273.15, color="black" + ) + + ax[0].plot(h_T, T, color="r", marker="s") + ax[1].set_yscale('log') # Set y-axis to logarithmic scale + ax[1].plot(h_p, p, marker="s", color="r") + # Two phase limits + ax[1].plot( + med_prop.get_two_phase_limits("h") / 1000, + med_prop.get_two_phase_limits("p") / 1e5, + color="black" + ) + ax[1].set_ylabel("$log(p)$ in bar") + ax[1].set_ylim([np.min(p) * 0.9, np.max(p) * 1.1]) + ax[0].set_ylim([np.min(T) - 5, np.max(T) + 5]) + ax[1].set_xlim([np.min(h_T) * 0.9, np.max(h_T) * 1.1]) + ax[0].set_xlim([np.min(h_T) * 0.9, np.max(h_T) * 1.1]) + if show: + plt.show() + if save_path is not None: + fig.tight_layout() + fig.savefig(save_path) + plt.close(fig) + return + return fig, ax
+ + +
[docs]def plot_sdf_map( + filepath_sdf: pathlib.Path, + nd_data: str, + first_dimension: str, + second_dimension: str, + fluids: List[str] = None, + flowsheets: List[str] = None, + violin_plot_variable: str = None, + third_dimension: str = None +): + """ + Generate and display visualizations based on data from an SDF (Structured Data File) dataset. + This function generates various types of visualizations based on the provided parameters, + including 3D scatter plots, 3D surface plots, and violin plots, and displays them using Matplotlib. + + Args: + filepath_sdf (pathlib.Path): + The path to the SDF dataset file. + nd_data (str): + The name of the primary data to be plotted. + first_dimension (str): + The name of the first dimension for the visualization. + second_dimension (str): + The name of the second dimension for the visualization. + fluids (List[str], optional): + List of specific fluids to include in the visualization. + Default is None, which includes all fluids. + flowsheets (List[str], optional): + List of specific flowsheets to include in the visualization. + Default is None, which includes all flowsheets. + violin_plot_variable (str, optional): + The variable to be used for creating violin plots. + Default is None, which disables violin plots. + third_dimension (str, optional): + The name of the third dimension for 4D visualizations. + Default is None, which disables 4D plotting. + + Raises: + KeyError: If the specified data or dimensions are not found in the dataset. + + Examples: + >>> FILEPATH_SDF = r"HeatPumpMaps.sdf" + >>> plot_sdf_map( + >>> filepath_sdf=FILEPATH_SDF, + >>> nd_data="COP", + >>> first_dimension="T_eva_in", + >>> second_dimension="n", + >>> fluids=["R410A"], + >>> flowsheets=["OptiHorn"], + >>> ) + + """ + if fluids is None: + fluids = [] + if flowsheets is None: + flowsheets = [] + if "T_" in second_dimension: + offset_sec = -273.15 + else: + offset_sec = 0 + if "T_" in first_dimension: + offset_pri = -273.15 + else: + offset_pri = 0 + offset_thi = 0 + plot_4D = False + if third_dimension is not None: + plot_4D = True + if "T_" in third_dimension: + offset_thi = -273.15 + + dataset = sdf.load(str(filepath_sdf)) + plot_violin = True + if violin_plot_variable is None: + plot_violin = False + violin_plot_variable = "" + if plot_violin: + if flowsheets: + n_rows = len(flowsheets) + else: + n_rows = len(dataset.groups) + fig_v, ax_v = plt.subplots(nrows=n_rows, ncols=1, sharex=True, + squeeze=False) + fig_v.suptitle(violin_plot_variable) + i_fs = 0 + nd_str_plot = nd_data + fac = 1 + if nd_data == "dT_eva_min": + nd_data = "T_1" + sub_str = "T_eva_in" + fac = - 1 + elif nd_data == "dT_con": + nd_data = "T_3" + sub_str = "T_con_in" + elif nd_data == "dT_sh": + nd_data = "T_1" + sub_str = "T_4" + else: + sub_str = "" + + if nd_str_plot.startswith("T_"): + offset_nd = -273.15 + else: + offset_nd = 0 + + for flowsheet in dataset.groups: + violin_data = {} + if flowsheet.name not in flowsheets and len(flowsheets) > 0: + continue + for fluid in flowsheet.groups: + if fluid.name not in fluids and len(fluids) > 0: + continue + nd, fd, sd, sub_data, td = None, None, None, None, None + _other_scale = {} + for ds in fluid.datasets: + if ds.name == nd_data: + nd = ds + elif ds.name == first_dimension: + fd = ds.data + elif ds.name == second_dimension: + sd = ds.data + if ds.name == sub_str: + sub_data = ds.data + if ds.name == violin_plot_variable: + data = ds.data.flatten() + violin_data[fluid.name] = data[~np.isnan(data)] + if plot_4D and ds.name == third_dimension: + td = ds.data + + if nd is None: + raise KeyError("nd-String not found in dataset") + + if sub_data is None: + sub_data = np.zeros(nd.data.shape) + + # Check other scales: + for i, scale in enumerate(nd.scales): + if scale.name not in [first_dimension, second_dimension]: + _other_scale[i] = scale + + if fd is None or sd is None or not _other_scale or (plot_4D and td is None): + raise KeyError("One of the given strings was not found in dataset") + + if plot_4D: + fig = plt.figure() + figtitle = f"{flowsheet.name}_{fluid.name}_{nd_str_plot}" + fig.suptitle(figtitle) + ax = fig.add_subplot(111, projection='3d') + ax.set_xlabel(first_dimension) + ax.set_ylabel(second_dimension) + ax.set_zlabel(third_dimension) + fourth_dim = (nd.data - sub_data) * fac + offset_nd + # Scale values for better sizes of circles: + bounds = [fourth_dim.min(), fourth_dim.max()] + _max_circle_size = 30 + fourth_dim_scaled = (fourth_dim - bounds[0]) / (bounds[1] - bounds[0]) * _max_circle_size + inp = [fd + offset_pri, sd + offset_sec, td + offset_thi] + import itertools + scattergrid = np.array([c for c in itertools.product(*inp)]) + ax.scatter(scattergrid[:, 0], + scattergrid[:, 1], + scattergrid[:, 2], + c=fourth_dim_scaled, + s=fourth_dim_scaled) + else: + for index, scale in _other_scale.items(): + for idx_data, value in enumerate(scale.data): + if index==0: + Z = nd.data[idx_data, :, :] + if sub_str in ["T_4", ""]: + sub_data_use = sub_data[idx_data, :, :] + else: + sub_data_use = sub_data + elif index == 1: + Z = nd.data[:, idx_data, :] + if sub_str in ["T_4", ""]: + sub_data_use = sub_data[:, idx_data, :] + else: + sub_data_use = sub_data + else: + Z = nd.data[:, :, idx_data] + if sub_str in ["T_4", ""]: + sub_data_use = sub_data[:, :, idx_data] + else: + sub_data_use = sub_data + if not plot_violin: + fig = plt.figure() + figtitle = f"{flowsheet.name}_{fluid.name}_{nd_str_plot}_{scale.name}={round(value, 3)}" + fig.suptitle(figtitle) + ax = fig.add_subplot(111, projection='3d') + ax.set_xlabel(first_dimension) + ax.set_ylabel(second_dimension) + X, Y = np.meshgrid(fd, sd) + ax.plot_surface(X + offset_pri, Y + offset_sec, (Z - sub_data_use)*fac + offset_nd) + + if plot_violin: + for key, value in violin_data.items(): + print(f"{violin_plot_variable}: {flowsheet.name}_{key}") + print(f"Min: {np.min(value)}") + print(f"Max: {np.max(value)}") + print(f"Mean: {np.mean(value)}") + print(f"Median: {np.median(value)}\n") + ax_v[i_fs][0].violinplot( + list(violin_data.values()), + showextrema=True, + showmeans=True, + showmedians=True + ) + set_axis_style(ax_v[i_fs][0], list(violin_data.keys())) + ax_v[i_fs][0].set_ylabel(flowsheet.name.replace("Flowsheet", "")) + i_fs += 1 + plt.show()
+ + +
[docs]def set_axis_style(ax, labels): + """ + From: https://matplotlib.org/3.1.1/gallery/statistics/customized_violin.html#sphx-glr-gallery-statistics-customized-violin-py + """ + ax.get_xaxis().set_tick_params(direction='out') + ax.xaxis.set_ticks_position('bottom') + ax.set_xticks(np.arange(1, len(labels) + 1)) + ax.set_xticklabels(labels) + ax.set_xlim(0.25, len(labels) + 0.75)
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/utils/printing.html b/docs/0.1.1/docs/_modules/vclibpy/utils/printing.html new file mode 100644 index 0000000..0013f56 --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/utils/printing.html @@ -0,0 +1,150 @@ + + + + + + + + vclibpy.utils.printing — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.utils.printing

+# -*- coding: utf-8 -*-
+"""
+Created on 24.04.2023
+
+@author: Christoph Hoeges
+
+Last Update: 24.04.2023
+"""
+import pandas as pd
+
+
+
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_modules/vclibpy/utils/sdf_.html b/docs/0.1.1/docs/_modules/vclibpy/utils/sdf_.html new file mode 100644 index 0000000..618197c --- /dev/null +++ b/docs/0.1.1/docs/_modules/vclibpy/utils/sdf_.html @@ -0,0 +1,267 @@ + + + + + + + + vclibpy.utils.sdf_ — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for vclibpy.utils.sdf_

+import itertools
+import pathlib
+
+import pandas as pd
+import sdf
+
+
+
[docs]def save_to_sdf(data: dict, save_path: pathlib.Path): + """ + Save given input dictionary to a sdf file in the given save_path + + Args: + data (dict): + A dictionary with the following structure: + Keys: Flowsheet_name + Values: A dictionary with the following structure: + + - Keys: Fluids + - Values: Data dictionaries with the following structure: + A tuple with three values, in that order: + + - scales: Of the given nd_data, e.g. T_Amb, n + - nd_data: More-dimensional data, e.g. COP + - parameters: Scalar values, like m_flow_con or similar + + save_path (pathlib.Path): Where to store the data + flowsheet_name (str): Name of the flowsheet. This is the top level group + :return: + """ + if isinstance(save_path, str): + save_path = pathlib.Path(save_path) + _all_groups = [] + + for flowsheet_name, fluid_dict in data.items(): + _all_fluids = [] + for fluid, fluid_data in fluid_dict.items(): + # First write scales + _scales = [] + for scale_name, scale_values in fluid_data[0].items(): + _scales.append(sdf.Dataset(scale_name, + data=scale_values["data"], + unit=scale_values["unit"], + is_scale=True, + display_name=scale_name, + comment=scale_values.get("comment", ""))) + # Now the ND-Data: + _nd_data = [] + for data_name, data_values in fluid_data[1].items(): + _nd_data.append(sdf.Dataset(data_name, + data=data_values["data"], + unit=data_values["unit"], + scales=_scales, + comment=data_values.get("comment", ""))) + # Now the constant parameters + _paras = [] + for para_name, para_value in fluid_data[2].items(): + _paras.append(sdf.Dataset(para_name, + data=para_value["data"], + unit=para_value["unit"], + comment=para_value.get("comment", ""))) + + # Save everything + fluid_group = sdf.Group(fluid, comment="Values for fluid", datasets=_scales + _nd_data + _paras) + _all_fluids.append(fluid_group) + + flowsheet_group = sdf.Group(flowsheet_name, + comment="Multiple fluids for the flowsheet", + groups=_all_fluids) + _all_groups.append(flowsheet_group) + + parent_group = sdf.Group("/", comment="Generated with VCLibPy", groups=_all_groups) + sdf.save(save_path, group=parent_group) + return save_path
+ + +
[docs]def merge_sdfs(filepaths, save_path): + """ + Merge given files and return a merged file. + Be careful if both files contain the same combination. + Then, the latter element of the list will overwrite the first one. + + Args: + filepaths (list): List with paths to the files + save_path (str): Save path for the new file + """ + _all_flowsheets = {} + # Merge to structure + for fpath in filepaths: + dataset = sdf.load(fpath) + for flowsheet in dataset.groups: + fluid_data = {fluid.name: fluid for fluid in flowsheet.groups} + if flowsheet.name not in _all_flowsheets: + _all_flowsheets.update({flowsheet.name: fluid_data}) + else: + _all_flowsheets[flowsheet.name].update(fluid_data) + + # Write structure + _all_groups = [] + for flowsheet_name, fluid_dict in _all_flowsheets.items(): + _all_fluids = [] + for fluid, data in fluid_dict.items(): + _all_fluids.append(data) + flowsheet_group = sdf.Group(flowsheet_name, + comment="Multiple fluids for the flowsheet", + groups=_all_fluids) + _all_groups.append(flowsheet_group) + + parent_group = sdf.Group("/", comment="Generated with python script", groups=_all_groups) + sdf.save(save_path, group=parent_group) + return save_path
+ + +
[docs]def sdf_to_csv(filepath: pathlib.Path, save_path: pathlib.Path): + """ + Convert a given .sdf file to multiple excel files, + for each combination of flowsheet and refrigerant one file. + + Args: + filepath (pathlib.Path): sdf file + save_path (pathlib.Path): Directory where to store the csv files. + """ + dataset = sdf.load(str(filepath)) + for flowsheet in dataset.groups: + for fluid in flowsheet.groups: + dfs = [] + for data in fluid.datasets: + if _is_nd(data): + dfs.append(_unpack_nd_data(data)) + df = pd.concat(dfs, axis=1) + df = df.loc[:, ~df.columns.duplicated()] + df.to_csv(save_path.joinpath(f"{flowsheet.name}_{fluid.name}.csv"))
+ + +def _get_name(data): + return f"{data.name} in {data.unit} ({data.comment})" + + +def _is_nd(data): + if data.scales == [None]: + return False + return True + + +def _unpack_nd_data(data): + column_name = _get_name(data) + scale_names = [_get_name(scale) for scale in data.scales] + scales_with_idx = [[(idx, value) for idx, value in enumerate(scale.data)] for scale in data.scales] + all_data = [] + for scales in itertools.product(*scales_with_idx): + indexer = tuple([scale[0] for scale in scales]) + values = [scale[1] for scale in scales] + all_data.append({ + column_name: data.data[indexer], + **{name: value for name, value in zip(scale_names, values)} + }) + return pd.DataFrame(all_data) + + +if __name__ == '__main__': + sdf_to_csv( + filepath=pathlib.Path(r"D:\00_temp\calibration_jmo\Optihorst_3D_vclibpy.sdf"), + save_path=pathlib.Path(r"D:\04_git\vclibpy\tests\regression_data") + ) +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/_sources/Contribution.md.txt b/docs/0.1.1/docs/_sources/Contribution.md.txt new file mode 100644 index 0000000..35f1d83 --- /dev/null +++ b/docs/0.1.1/docs/_sources/Contribution.md.txt @@ -0,0 +1,55 @@ +# Contribute as a user + +The documentation, examples and tutorials should be understandable and the code bug-free. +As all user's have different backgrounds, you may not understand everything or encounter bugs. +In that case, PLEASE raise an issue [here](https://github.com/RWTH-EBC/vclibpy/issues/new). + +Consider labeling the issue using the flag `bug` or `documentation` / `question`. + +# Contribute as a developer + +If you instead want to contribute new features or fix bugs yourself, we are more than happy. + +Please also [raise an issue](https://github.com/RWTH-EBC/vclibpy/issues/new) and create a new branch labeled `issueXY_some_name`. +Here, `XY` is the number of your issue and `some_name` is a meaingful description. + +Once you're feature is ready, create a pull request and check if the pipeline succeeds. +Assign a reviewer before merging. Once review is finished, you can merge. + +**Before** implementing or modifying modules, classes or functions, please read the following page. + +## Styleguide +We use PEP8 as a styleguide. Some IDEs (like PyCharm) automatically show you code that is not in PEP8. If you don't have such an IDE, please read [this page](https://pep8.org/) to get a better understanding of it. + +## Documentation +All created or modified function should be documented properly. Try to follow the structure already present. If possible, write a little doctest example into the docstring to make clear to user's what the desired output of your function is. All non self-explanatory lines of code should include a comment. We use the pycharm-style for docstrings, e.g. +```python +def foo(dummy, dummy2): + """ + Describe what the function does in here. + The blank line below is necessary for the doc to render nicely. + + Args: + dummy (str): + Any parameter description + dummy2 (int,float): + A variable that may have two types + """ +``` +## Unit-Tests +Espacially when creating new functions or classes, you have to add a unit-test function. +Open the `test_module.py` file in the `\tests`-directory and add a function to the class `TestModule`with a name like `test_my_new_function`. If you create a new module, you have to create a new `test_my_new_module.py` file and follow the existing structure of the +other test-files. + +If you are not familiar with unit-tests, here is a quick summary: +- Test as many things as possible. Even seemingly silly tests like correct input-format help prevent future problems for new users +- use the `self.assertSOMETHING` functions provided by `unittest`. This way a test failure is presented correctly An error inside your test function will not be handeled as a failure but an error. +- If the success of your test depends on the used device, you can use decorators like `skip()`, `skipif(numpy.__version__<(1, 0), "not supported with your numpy version")`, etc. +- `setUp()` and `tearDown()` are called before and after each test. Use this functions to define parameters used in every test, or to close applications like Dymola once a test is completed. +- See the [unittest-documentation](https://docs.python.org/3/library/unittest.html#organizing-tests) for further information + +You can check your work by running all tests before commiting to git. + +## Pylint +With pylint we try to keep our code clean. +See the description in [this repo](https://git.rwth-aachen.de/EBC/EBC_all/gitlab_ci/templates/tree/master/pylint) on information on what pylint is and how to use it. diff --git a/docs/0.1.1/docs/_sources/code/modules.rst.txt b/docs/0.1.1/docs/_sources/code/modules.rst.txt new file mode 100644 index 0000000..5803024 --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/modules.rst.txt @@ -0,0 +1,7 @@ +vclibpy +======= + +.. toctree:: + :maxdepth: 4 + + vclibpy diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.components.compressors.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.components.compressors.rst.txt new file mode 100644 index 0000000..fed295d --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.components.compressors.rst.txt @@ -0,0 +1,42 @@ +vclibpy.components.compressors package +====================================== + +.. automodule:: vclibpy.components.compressors + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +vclibpy.components.compressors.compressor module +------------------------------------------------ + +.. automodule:: vclibpy.components.compressors.compressor + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.compressors.constant\_effectivness module +------------------------------------------------------------ + +.. automodule:: vclibpy.components.compressors.constant_effectivness + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.compressors.rotary module +-------------------------------------------- + +.. automodule:: vclibpy.components.compressors.rotary + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.compressors.ten\_coefficient module +------------------------------------------------------ + +.. automodule:: vclibpy.components.compressors.ten_coefficient + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.components.expansion_valves.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.components.expansion_valves.rst.txt new file mode 100644 index 0000000..be60da9 --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.components.expansion_valves.rst.txt @@ -0,0 +1,26 @@ +vclibpy.components.expansion\_valves package +============================================ + +.. automodule:: vclibpy.components.expansion_valves + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +vclibpy.components.expansion\_valves.bernoulli module +----------------------------------------------------- + +.. automodule:: vclibpy.components.expansion_valves.bernoulli + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.expansion\_valves.expansion\_valve module +------------------------------------------------------------ + +.. automodule:: vclibpy.components.expansion_valves.expansion_valve + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.components.heat_exchangers.heat_transfer.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.components.heat_exchangers.heat_transfer.rst.txt new file mode 100644 index 0000000..1e5f331 --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.components.heat_exchangers.heat_transfer.rst.txt @@ -0,0 +1,58 @@ +vclibpy.components.heat\_exchangers.heat\_transfer package +========================================================== + +.. automodule:: vclibpy.components.heat_exchangers.heat_transfer + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +vclibpy.components.heat\_exchangers.heat\_transfer.air\_to\_wall module +----------------------------------------------------------------------- + +.. automodule:: vclibpy.components.heat_exchangers.heat_transfer.air_to_wall + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.heat\_exchangers.heat\_transfer.constant module +------------------------------------------------------------------ + +.. automodule:: vclibpy.components.heat_exchangers.heat_transfer.constant + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.heat\_exchangers.heat\_transfer.heat\_transfer module +------------------------------------------------------------------------ + +.. automodule:: vclibpy.components.heat_exchangers.heat_transfer.heat_transfer + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.heat\_exchangers.heat\_transfer.pipe\_to\_wall module +------------------------------------------------------------------------ + +.. automodule:: vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.heat\_exchangers.heat\_transfer.vdi\_atlas\_air\_to\_wall module +----------------------------------------------------------------------------------- + +.. automodule:: vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.heat\_exchangers.heat\_transfer.wall module +-------------------------------------------------------------- + +.. automodule:: vclibpy.components.heat_exchangers.heat_transfer.wall + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.components.heat_exchangers.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.components.heat_exchangers.rst.txt new file mode 100644 index 0000000..c78f0bc --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.components.heat_exchangers.rst.txt @@ -0,0 +1,50 @@ +vclibpy.components.heat\_exchangers package +=========================================== + +.. automodule:: vclibpy.components.heat_exchangers + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + vclibpy.components.heat_exchangers.heat_transfer + +Submodules +---------- + +vclibpy.components.heat\_exchangers.economizer module +----------------------------------------------------- + +.. automodule:: vclibpy.components.heat_exchangers.economizer + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.heat\_exchangers.heat\_exchanger module +---------------------------------------------------------- + +.. automodule:: vclibpy.components.heat_exchangers.heat_exchanger + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.heat\_exchangers.moving\_boundary\_ntu module +---------------------------------------------------------------- + +.. automodule:: vclibpy.components.heat_exchangers.moving_boundary_ntu + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.heat\_exchangers.ntu module +---------------------------------------------- + +.. automodule:: vclibpy.components.heat_exchangers.ntu + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.components.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.components.rst.txt new file mode 100644 index 0000000..67eec7c --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.components.rst.txt @@ -0,0 +1,36 @@ +vclibpy.components package +========================== + +.. automodule:: vclibpy.components + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + vclibpy.components.compressors + vclibpy.components.expansion_valves + vclibpy.components.heat_exchangers + +Submodules +---------- + +vclibpy.components.component module +----------------------------------- + +.. automodule:: vclibpy.components.component + :members: + :undoc-members: + :show-inheritance: + +vclibpy.components.phase\_separator module +------------------------------------------ + +.. automodule:: vclibpy.components.phase_separator + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.flowsheets.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.flowsheets.rst.txt new file mode 100644 index 0000000..6b88af4 --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.flowsheets.rst.txt @@ -0,0 +1,50 @@ +vclibpy.flowsheets package +========================== + +.. automodule:: vclibpy.flowsheets + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +vclibpy.flowsheets.base module +------------------------------ + +.. automodule:: vclibpy.flowsheets.base + :members: + :undoc-members: + :show-inheritance: + +vclibpy.flowsheets.standard module +---------------------------------- + +.. automodule:: vclibpy.flowsheets.standard + :members: + :undoc-members: + :show-inheritance: + +vclibpy.flowsheets.vapor\_injection module +------------------------------------------ + +.. automodule:: vclibpy.flowsheets.vapor_injection + :members: + :undoc-members: + :show-inheritance: + +vclibpy.flowsheets.vapor\_injection\_economizer module +------------------------------------------------------ + +.. automodule:: vclibpy.flowsheets.vapor_injection_economizer + :members: + :undoc-members: + :show-inheritance: + +vclibpy.flowsheets.vapor\_injection\_phase\_separator module +------------------------------------------------------------ + +.. automodule:: vclibpy.flowsheets.vapor_injection_phase_separator + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.media.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.media.rst.txt new file mode 100644 index 0000000..5ed31b7 --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.media.rst.txt @@ -0,0 +1,42 @@ +vclibpy.media package +===================== + +.. automodule:: vclibpy.media + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +vclibpy.media.cool\_prop module +------------------------------- + +.. automodule:: vclibpy.media.cool_prop + :members: + :undoc-members: + :show-inheritance: + +vclibpy.media.media module +-------------------------- + +.. automodule:: vclibpy.media.media + :members: + :undoc-members: + :show-inheritance: + +vclibpy.media.ref\_prop module +------------------------------ + +.. automodule:: vclibpy.media.ref_prop + :members: + :undoc-members: + :show-inheritance: + +vclibpy.media.states module +--------------------------- + +.. automodule:: vclibpy.media.states + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.rst.txt new file mode 100644 index 0000000..d015637 --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.rst.txt @@ -0,0 +1,29 @@ +vclibpy package +=============== + +.. automodule:: vclibpy + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + vclibpy.components + vclibpy.flowsheets + vclibpy.media + vclibpy.utils + +Submodules +---------- + +vclibpy.datamodels module +------------------------- + +.. automodule:: vclibpy.datamodels + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/code/vclibpy.utils.rst.txt b/docs/0.1.1/docs/_sources/code/vclibpy.utils.rst.txt new file mode 100644 index 0000000..e602c35 --- /dev/null +++ b/docs/0.1.1/docs/_sources/code/vclibpy.utils.rst.txt @@ -0,0 +1,58 @@ +vclibpy.utils package +===================== + +.. automodule:: vclibpy.utils + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +vclibpy.utils.automation module +------------------------------- + +.. automodule:: vclibpy.utils.automation + :members: + :undoc-members: + :show-inheritance: + +vclibpy.utils.nominal\_design module +------------------------------------ + +.. automodule:: vclibpy.utils.nominal_design + :members: + :undoc-members: + :show-inheritance: + +vclibpy.utils.plotting module +----------------------------- + +.. automodule:: vclibpy.utils.plotting + :members: + :undoc-members: + :show-inheritance: + +vclibpy.utils.printing module +----------------------------- + +.. automodule:: vclibpy.utils.printing + :members: + :undoc-members: + :show-inheritance: + +vclibpy.utils.sdf\_ module +-------------------------- + +.. automodule:: vclibpy.utils.sdf_ + :members: + :undoc-members: + :show-inheritance: + +vclibpy.utils.ten\_coefficient\_compressor\_reqression module +------------------------------------------------------------- + +.. automodule:: vclibpy.utils.ten_coefficient_compressor_reqression + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/0.1.1/docs/_sources/examples/e1_refrigerant_data.md.txt b/docs/0.1.1/docs/_sources/examples/e1_refrigerant_data.md.txt new file mode 100644 index 0000000..055aa27 --- /dev/null +++ b/docs/0.1.1/docs/_sources/examples/e1_refrigerant_data.md.txt @@ -0,0 +1,135 @@ + +# Refrigerant Data Example +This example demonstrates how to use the classes `MedProp` (and its children), +`ThermodynamicState`, and `TransportProperties`. +Further, basic plotting is shown using this data. + +First, let's import the important classes from vclibpy's +`media` module: + +```python +from vclibpy.media import CoolProp, ThermodynamicState, TransportProperties +``` + +We have two media property classes, `CoolProp` and `RefProp`. +The latter requires a dll, which you have to purchase together with RefProp. +Thus, in this example, we will use `CoolProp`. Pass the `fluid_name` to +select the fluid you are going to use. + +```python +cool_prop = CoolProp(fluid_name="Propane") +``` + +## ThermodynamicState calculation +Let's start and show how the media property classes work. You always +call `calc_state()`. The documentation explains how to use it: + +```python +help(cool_prop.calc_state) +``` + +Let's try and start with pressure of 2 bar (2e5 Pa) and 100 kJ/kg enthalpy: + +```python +state = cool_prop.calc_state("PH", 2e5, 100e3) +``` + +The state is an instance of `ThermodynamicState`: + +```python +print(type(state)) +``` + +The state contains all important specific values: + +```python +print(state.get_pretty_print()) +``` + +For these values, we are outside of the two phase region, as q (quality) is -1. +You can play around with the possible options to get a better understanding. +## TransportProperties calculation +With a given state, we can calculate the transport properties. Those include +relevant information for component models, e.g. heat conductivity. +For information on all properties, look at the documentation: + +```python +help(cool_prop.calc_transport_properties) +``` + +You just have to pass a valid state: + +```python +transport_properties = cool_prop.calc_transport_properties(state=state) +print(transport_properties.get_pretty_print()) +``` + +## Plotting +To plot fluid data, we may plot the two phase limits. +While we have the function `get_two_phase_limits` in the `media` model, +we will define it here again so that you can further learn how to use `media`. +The idea is to loop over all pressure from some minimum value. +Let's use the pressure at -40 °C. +to the maximum, which is the critical point. +You can get the critical point using the function: `get_critical_point`: + +```python +p_min = cool_prop.calc_state("TQ", 273.15 - 40, 0).p # Pa +T_crit, p_crit, d_crit = cool_prop.get_critical_point() +p_max = p_crit +``` + +Let's create two lists, q0 and q1 for states with quality of 0 and 1. Further, +we loop only each 10000 Pa to reduce number of function calls. + +```python +p_step = 10000 # Pa +q0 = [] +q1 = [] +for p in range(int(p_min), int(p_max), p_step): + q0.append(cool_prop.calc_state("PQ", p, 0)) + q1.append(cool_prop.calc_state("PQ", p, 1)) +``` + +Now, we can plot these states, for example in a T-h Diagram. +Note: [::-1] reverts the list, letting it start from the critical point. +`[state.T for state in q0]` is a list comprehension, quite useful in Python. + +```python +T = [state.T for state in q0 + q1[::-1]] +h = [state.h for state in q0 + q1[::-1]] +import matplotlib.pyplot as plt +plt.ylabel("$T$ in K") +plt.xlabel("$h$ in J/kg") +plt.plot(h, T, color="black") +``` + +Now, without any component models, let's try to plot a closed vapor compression cycle: +Assumptions: +- No superheat nor subcooling +- isobaric heat exchange +- isentropic compression and expansion +- 0 °C evaporation and 40 °C condensation temperature + +```python +state_1 = cool_prop.calc_state("TQ", 273.15, 1) +state_3 = cool_prop.calc_state("TQ", 273.15 + 40, 0) +state_4 = cool_prop.calc_state("PH", state_1.p, state_3.h) +state_2 = cool_prop.calc_state("PS", state_3.p, state_1.s) +``` + +Now, let's plot them with some markers: + +```python +plot_lines_h = [state_1.h, state_2.h, state_3.h, state_4.h, state_1.h] +plot_lines_t = [state_1.T, state_2.T, state_3.T, state_4.T, state_1.T] +plt.plot(plot_lines_h, plot_lines_t, marker="s", color="red") +plt.show() +``` + +Try to use the skills you've learned in this example and tweak the assumptions +and the plot format: Plot log(p)-h, T-s, or similar. Assume some level +of superheat, non-isentropic compression etc. + +After getting familiar with calling the refrigerant data module `media`, you will +learn how to use the `Compressor` classes in the next example. diff --git a/docs/0.1.1/docs/_sources/examples/e2_compressor.md.txt b/docs/0.1.1/docs/_sources/examples/e2_compressor.md.txt new file mode 100644 index 0000000..cd82e6d --- /dev/null +++ b/docs/0.1.1/docs/_sources/examples/e2_compressor.md.txt @@ -0,0 +1,171 @@ + +# Compressor Example +This example demonstrates how to use the classes `Compressor`, +and its children. + +First, let's import an exemplary compressor from vclibpy's +`compressor` package: + +```python +from vclibpy.components.compressors import ConstantEffectivenessCompressor +``` + +The `ConstantEffectivenessCompressor` uses constant efficiencies to model the compressor. +Check out the documentation to see relevant parameters: + +```python +help(ConstantEffectivenessCompressor) +``` + +Let's specify some dummy parameters: + +```python +constant_efficiency_compressor = ConstantEffectivenessCompressor( + N_max=120, + V_h=19e-6, + eta_isentropic=0.7, + eta_mech=0.95*0.95*0.95, + lambda_h=0.9 +) +``` + +Before we can do any calculations, the compressor needs +access to refrigerant data. Each component in VcLibPy has +the property med_prop (media property) which you can set like this: + +```python +from vclibpy.media import CoolProp +med_prop = CoolProp(fluid_name="Propane") +constant_efficiency_compressor.med_prop = med_prop +``` + +Now, you have to define the input state of the compressor. +Each component has inlet and outlet states, which are, same as `med_prop` +properties of the component. +We assume a super-heated vapor at 1bar as an input state: + +```python +p_inlet = 1e5 +T_superheat = med_prop.calc_state("PQ", p_inlet, 1).T + 10 +constant_efficiency_compressor.state_inlet = med_prop.calc_state("PT", p_inlet, T_superheat) +``` + +Last but not least, most functions in VcLibPy require +the argument `inputs` and `fs_state`. The whole concept of the two +classes are explained in the third example. For now, we just instantiate +the classes and pass a relative compressor speed of 50 % (0.5) as an input. + +```python +from vclibpy import FlowsheetState, Inputs +fs_state = FlowsheetState() +inputs = Inputs(n=0.5) +``` + +Now, we can calculate multiple things. +### Outlet state +While the constant efficiency compressor does not rely on any +states to calculate the constant efficiencies, most other models do. +Thus, we first want to calculate the outlet state for the given input state. +We can do so by passing an outlet pressure to the function `calc_state_outlet`: + +```python +p_outlet = 6e5 +print(f"{constant_efficiency_compressor.state_outlet=}") # still None +constant_efficiency_compressor.calc_state_outlet(p_outlet=p_outlet, inputs=inputs, fs_state=fs_state) +print(f"{constant_efficiency_compressor.state_outlet=}") # now calculated +``` + +Also, relevant results are automatically added to the `fs_state`: + +```python +print(fs_state) +``` + +You can play around with the compressor speed (which has no effect due to constant efficiencies) +or the compression ratio. Let's do the latter for the outlet temperature: + +```python +import numpy as np +ratios = np.arange(2, 10, 0.5) +T_outlets = [] +for ratio in ratios: + constant_efficiency_compressor.calc_state_outlet( + p_outlet=p_inlet * ratio, inputs=inputs, fs_state=fs_state + ) + T_outlets.append(constant_efficiency_compressor.state_outlet.T) +``` + +Let's plot the results: + +```python +import matplotlib.pyplot as plt +plt.plot(ratios, np.array(T_outlets) - 273.15) +plt.ylabel("$T_\mathrm{Outlet}$ in °C") +plt.xlabel("$\Pi$ in -") +plt.show() +``` + +### Mass flow rate +Now, let's continue with the mass flow rate. Again, each component has the property +`m_flow`, which always refers to the refrigerant mass flow rate. +The function `calc_m_flow` calculates and set's the mass flow rate to this property. + +```python +m_flow = constant_efficiency_compressor.calc_m_flow(inputs=inputs, fs_state=fs_state) +print(f"{m_flow=}, {constant_efficiency_compressor.m_flow=}") +``` + +Again, some interesting results are automatically added to the `fs_state`: + +```python +print(fs_state) +``` + +Now, we can check how the compressor will work for different compressor speeds: + +```python +m_flows = [] +speeds = np.arange(0, 1, 0.1) +for speed in speeds: + m_flows.append(constant_efficiency_compressor.calc_m_flow(Inputs(n=speed), fs_state=fs_state)) +``` + +Let's plot the results: + +```python +import matplotlib.pyplot as plt +plt.plot(speeds, m_flows) +plt.ylabel("$\dot{m}$ in kg/s") +plt.xlabel("$n$ in -") +plt.show() +``` + +### Electrical power consumption +If mass flow rates and outlet states are calculated, we can calculate the +electrical power consumption of the compressor. Note, that +if you change input values here, you first have to calculate the +mass flow rate and outlet state again, as this may influence the result. + +```python +constant_efficiency_compressor.calc_m_flow(inputs=inputs, fs_state=fs_state) +constant_efficiency_compressor.calc_state_outlet(p_outlet=p_outlet, inputs=inputs, fs_state=fs_state) +P_el = constant_efficiency_compressor.calc_electrical_power(inputs=inputs, fs_state=fs_state) +print(f"{P_el=}") +``` + +Again, important metrics are added to the fs_state: + +```python +print(fs_state) +``` + +After learning the basics of each component and using `Inputs` and `FlowsheetState` +for the first time, we will go deeper into these classes in the third example. +You can alter the compressor in use by importing other compressors, such as +`RotaryCompressor` or `TenCoefficientCompressor`. Check if you can use these components as well. + +```python +from vclibpy.components.compressors import RotaryCompressor, TenCoefficientCompressor +help(RotaryCompressor) +help(TenCoefficientCompressor) +``` diff --git a/docs/0.1.1/docs/_sources/examples/e3_inputs_and_flowsheet_state.md.txt b/docs/0.1.1/docs/_sources/examples/e3_inputs_and_flowsheet_state.md.txt new file mode 100644 index 0000000..a2738e0 --- /dev/null +++ b/docs/0.1.1/docs/_sources/examples/e3_inputs_and_flowsheet_state.md.txt @@ -0,0 +1,104 @@ + +# Inputs and FlowsheetState +This example demonstrates how to use the classes `Inputs`, +and `FlowsheetState` + +All Variables in the `Inputs` and `FlowsheetState` will be saved in +output formats like .csv or .sdf +Thus, the concept of these two classes is important to +understand and analyze simulations in VcLibPy. + +## Inputs +All external boundary conditions which act on the vapor compression +cycle may be inputs. This could be the compressor speed, ambient temperature, +or the inlet temperatures and mass flow rates of the secondary side +in the heat exchangers. +You can see all default options by just printing the empty instance: + +```python +from vclibpy import Inputs +print(Inputs()) +``` + +Currently, the flowsheets need all of these parameters, except for +the ambient temperature. This is only required for heat loss estimations or +efficiency calculations in certain models. +Handling all the inputs in one object makes it easy for component models +to access any relevant data it needs. Also, you can add new inputs +as you like. For instance, let's say you want to control the pressure +level ratio, at which vapor is injected in the vapor-injection flowsheets. +Here, the flowsheets can act on the input `k_vapor_injection`. The default is 1. +You can set custom inputs like this: + +```python +inputs = Inputs() +inputs.set(name="k_vapor_injection", value=1.05) +print(inputs) +``` + +Optional arguments of the `set` function are unit and description. +You should pass those along with the name and value to make +your results easier to analyze, for others and your future self: + +```python +inputs.set( + name="k_vapor_injection", value=1.05, + unit="-", + description="Calculates the injection pressure level according to " + "k_vapor_injection * np.sqrt(p_1 * p_2)" +) +``` + +The `set` function registers a Variable in the `inputs` object. +You can get different information types like this: + +```python +print(f"{inputs.get_variables()=}") +print(f"{inputs.get_variable_names()=}") +print(f"{inputs.get(name='k_vapor_injection')=}") +print(f"{inputs.items()=}") # To loop over the variable dict. +``` + +## FlowsheetState +The class `FlowsheetState` is essentially the same as `Inputs`. +The only difference is its use, which is for outputs of the vapor +compression cycle like COP, heat flow rate, temperatures, etc. +Basically, anything a users might be interested in analyzing when +simulating a steady state vapor compression cycle. +As the outputs are flowsheet specific, we define no default +Variables in the `FlowsheetState` as with `Inputs`. +However, you can set variables the same way as with `Inputs`: + +```python +from vclibpy import FlowsheetState +fs_state = FlowsheetState() +print(fs_state) +fs_state.set(name="some_interesting_output", value=3.14, + unit="-", description="This is just an example") +print(fs_state) +``` + +As the fs_state is passed to all components, it's important to +use distinct names. If two components set a variable `T_1`, the latter +one will override the first one. +As the `fs_state` and `inputs` are mutable, no history is preserved. +If you want to, for example, plot the history of the `fs_state`, +you have to store copies of the instance: + +```python +fs_states = [] +for some_value in range(10): + fs_state.set(name="some_interesting_output", value=some_value) + fs_states.append(fs_state.copy()) +print([fs_state.get("some_interesting_output").value for fs_state in fs_states]) +``` + +Without the copy, it would not work: + +```python +fs_states = [] +for some_value in range(10): + fs_state.set(name="some_interesting_output", value=some_value) + fs_states.append(fs_state) +print([fs_state.get("some_interesting_output").value for fs_state in fs_states]) +``` diff --git a/docs/0.1.1/docs/_sources/examples/e4_heat_exchanger.md.txt b/docs/0.1.1/docs/_sources/examples/e4_heat_exchanger.md.txt new file mode 100644 index 0000000..e91b7b4 --- /dev/null +++ b/docs/0.1.1/docs/_sources/examples/e4_heat_exchanger.md.txt @@ -0,0 +1,263 @@ + +# Heat Exchanger Example +This example demonstrates how to use the heat exchanger +classes. + +Contrary to the first examples, the heat exchanger is +more complex, in the sense that the only current +models follows a moving boundary epsNTU approach. +Thus, you need to assume heat transfer correlations +for different regimes. +We will use the evaporator for this example. Let's check the doc: + +```python +from vclibpy.components.heat_exchangers import MovingBoundaryNTUEvaporator +help(MovingBoundaryNTUEvaporator) +``` + +As you can see, we have to define a lot of parameters. +Let's model a simple air-to-refrigerant heat exchanger with +constant heat transfer correlations. The areas are not that important +for this example. +For heat transfer, you can import models from the `heat_transfer` package +inside the `heat_exchangers` package. +You will find all options in the documentation of VcLibPy + +```python +from vclibpy.components.heat_exchangers.heat_transfer.constant import ( + ConstantHeatTransfer, ConstantTwoPhaseHeatTransfer +) +from vclibpy.components.heat_exchangers.heat_transfer.wall import WallTransfer +``` + +Now, we can instantiate the class: + +```python +evaporator = MovingBoundaryNTUEvaporator( + A=15, + secondary_medium="air", + flow_type="counter", + ratio_outer_to_inner_area=10, + two_phase_heat_transfer=ConstantTwoPhaseHeatTransfer(alpha=1000), + gas_heat_transfer=ConstantHeatTransfer(alpha=1000), + wall_heat_transfer=WallTransfer(lambda_=236, thickness=2e-3), + liquid_heat_transfer=ConstantHeatTransfer(alpha=5000), + secondary_heat_transfer=ConstantHeatTransfer(alpha=25) +) +``` + +## Heat exchanger iterations +To understand the heat exchanger functions in VcLibPy, +you have to understand how we iterate to solve the closed +cycle simulation. +In reality, the expansion valve would +adjust its opening until a certain degree of superheat +is met. While this may oscillate in dynamic operation, +we assume that the control is able to meet a constant +degree of superheat in steady state. +This means, we have to find the pressure level which +ensures this superheat. So instead of iterating +the valve opening, we iterate the evaporation pressure +directly. The same holds for the condenser and subcooling. +However, levels of subcooling are not directly controlled in +real devices, at least in the standard cycle. +The assumption of keeping the degree of subcooling as an input +could be changed in future work. + +For iteration, heat exchangers have the function `calc`. +In order for it to work, you have to assign both inlet and +outlet state, as well as the mass flow rate. Note that, +as we assume the levels of superheat and subcooling, we +will always have these states in our iterations. +Further, the inputs need to contain the evaporator inlet temperature T_eva_in and +the evaporator mass flow rate (secondary side): + +```python +from vclibpy import FlowsheetState, Inputs +fs_state = FlowsheetState() +from vclibpy.media import CoolProp +med_prop = CoolProp(fluid_name="Propane") +evaporator.med_prop = med_prop # We have to set it, same as in the second example. +evaporator.m_flow = 0.01 +``` + +Also, we have to start the secondary med-prop. This is done for you +in the calculations, but required to be an extra function to enable multi-processing: + +```python +evaporator.start_secondary_med_prop() +``` + +Let's assume a superheat of 10 K and a condenser subcooling of 0 K. +With an isenthalp expansion valve, the inlet and outlet are given. +Further, let's assume a condensation temperature of 40 °C and +an air temperature of 2 °C, corresponding to the typical heat pump point A2W25 + +```python +T_eva_in = 273.15 + 2 +dT_eva_superheating = 10 +dT_con_subcooling = 0 +inputs = Inputs( + T_eva_in=T_eva_in, m_flow_eva=0.47, + dT_eva_superheating=dT_eva_superheating, dT_con_subcooling=dT_con_subcooling +) +``` + +Let's start with a simple assumption, no temperature difference +at the evaporator outlet (or inlet of air): + +```python +p_evaporation = med_prop.calc_state("TQ", T_eva_in - dT_eva_superheating, 1).p +``` + +Calculate the condenser outlet and expansion valve outlet, thus evaporator inlet + +```python +state_condenser_outlet = med_prop.calc_state("TQ", 273.15 + 40, 0) +evaporator.state_inlet = med_prop.calc_state("PH", p_evaporation, state_condenser_outlet.h) +T_evaporation = med_prop.calc_state("PQ", p_evaporation, 1).T +evaporator.state_outlet = med_prop.calc_state("PT", p_evaporation, T_evaporation + dT_eva_superheating) +print(evaporator.calc_Q_flow()) +``` + +What do they mean? +They are used in the iterative logic of VcLibPy and indicate that +the heat exchanger is valid, if the error is smaller than a pre-defined +margin and dT_min is greater than 0. + +```python +error, dT_min = evaporator.calc(inputs=inputs, fs_state=fs_state) +print(f"{error=}, {dT_min=}") +``` + +dT_min is, as assumed, close to zero. However, the error is very large. +The error is calculated as follows: `(Q_ntu / Q - 1) * 100`. +`Q` is the amount of heat required to be transported, `Q_ntu` is +the amount possible to transfer according to NTU method. +This means, a negative value of 100 means we could transport 2 times +less heat than we want to. +Thus, we have to iterate the pressure assumptions and lower it, +as we need a higher temperature difference to the air. +For this, we will use a loop: + +```python +import numpy as np +p_evaporations = np.linspace(p_evaporation - 1e4, p_evaporation, 1000) +errors, dT_mins = [], [] +for p_evaporation in p_evaporations: + evaporator.state_inlet = med_prop.calc_state("PH", p_evaporation, state_condenser_outlet.h) + T_evaporation = med_prop.calc_state("PQ", p_evaporation, 1).T + evaporator.state_outlet = med_prop.calc_state("PT", p_evaporation, T_evaporation + dT_eva_superheating) + error, dT_min = evaporator.calc(inputs=inputs, fs_state=fs_state) + errors.append(error) + dT_mins.append(dT_min) +``` + +The iteration of VcLibPy is largely based on this method, so nothing fancy. +If the error is positive, we step back to the old value and decrease the +step-size by a factor of 10. At the end, we iterate with a `min_iteration_step`, +which is, by default 1 Pa. + +Let's plot the result: + +```python +import matplotlib.pyplot as plt +fig, ax = plt.subplots(2, 1, sharex=True) +ax[0].plot(p_evaporations / 1e5, errors) +ax[0].set_ylabel("Error in %") +ax[1].plot(p_evaporations / 1e5, dT_mins) +ax[1].set_ylabel("$\Delta T$ in K") +ax[1].set_xlabel("$p_\mathrm{Eva}$ in bar") +plt.show() +``` + +## Implement your own iteration +As the result is still not good, let's implement this really basic iteration logic. +For iterating, we use a while-loop. Let's define a max-iteration +counter to avoid an infinite iteration. + +```python +max_iterations = 100 +n_iteration = 0 +p_eva_next = p_evaporation # Start with simple assumption +p_step = 10000 # Pa +min_step = 1 # Pa +min_error = 0.1 # 0.1 % maximal error +errors, dT_mins, p_evaporations = [], [], [] # Store for later plotting +while n_iteration < max_iterations: + evaporator.state_inlet = med_prop.calc_state("PH", p_eva_next, state_condenser_outlet.h) + T_eva = med_prop.calc_state("PQ", p_eva_next, 1).T + evaporator.state_outlet = med_prop.calc_state("PT", p_eva_next, T_eva + inputs.get("dT_eva_superheating").value) + error, dT_min = evaporator.calc(inputs=inputs, fs_state=fs_state) + # Store for later plotting + errors.append(error) + dT_mins.append(dT_min) + p_evaporations.append(p_eva_next / 1e5) + n_iteration += 1 + if error < min_error: + p_eva_next -= p_step + continue + elif error > min_error: + p_eva_next += p_step # Go back + if p_step <= min_step: + print("Error: Can't solve any more accurate with given size of min_step") + break + p_step /= 10 + continue + else: + print(f"Converged") +else: + print("Did not converged in the given max_iterations.") +print(f"Solution: {error=}, {dT_min=}, p_evaporation={p_evaporations[-1]}. Took {n_iteration=}") +``` + +Again, let's plot the iteration: + +```python +import matplotlib.pyplot as plt +fig, ax = plt.subplots(3, 1, sharex=True) +ax[0].plot(range(n_iteration), errors, marker="s") +ax[0].set_ylabel("Error in %") +ax[1].plot(range(n_iteration), dT_mins, marker="s") +ax[1].set_ylabel("$\Delta T$ in K") +ax[2].plot(range(n_iteration), p_evaporations, marker="s") +ax[2].set_ylabel("$p_\mathrm{Eva}$ in bar") +ax[2].set_xlabel("Iterations in -") +plt.show() +``` + +You can see that the iterative process converges to an error +Close to zero. However, it's not really an efficient optimization. +This could, and should, be optimized using optimization techniques. + +## Pinch plotting +What also helps to understand the heat exchanger better is to +plot the states and secondary media. We can use the +`get_two_phase_limits` function of med_prop to quickly plot +those: + +```python +plt.plot( + med_prop.get_two_phase_limits("h") / 1000, + med_prop.get_two_phase_limits("T") - 273.15, color="black" +) +state_vapor = med_prop.calc_state("PQ", evaporator.state_inlet.p, 1) # define intermediate state +states_to_plot = [evaporator.state_inlet, state_vapor, evaporator.state_outlet] +plt.plot( + [state.h / 1000 for state in states_to_plot], + [state.T - 273.15 for state in states_to_plot], + marker="s", color="red" +) +Q_flow = evaporator.calc_Q_flow() +T_eva_in = T_eva_in - 273.15 +T_eva_out = T_eva_in - Q_flow / inputs.get("m_flow_eva").value / 1000 +plt.plot( + [evaporator.state_outlet.h / 1000, evaporator.state_inlet.h / 1000], + [T_eva_in, T_eva_out], + color="blue" +) +plt.ylabel("$T$ in °C") +plt.xlabel("$h$ in kJ/kgK") +plt.ylim([evaporator.state_inlet.T - 275.15, T_eva_in + 2]) +plt.show() +``` diff --git a/docs/0.1.1/docs/_sources/examples/e5_expansion_valve.md.txt b/docs/0.1.1/docs/_sources/examples/e5_expansion_valve.md.txt new file mode 100644 index 0000000..6fdbeff --- /dev/null +++ b/docs/0.1.1/docs/_sources/examples/e5_expansion_valve.md.txt @@ -0,0 +1,96 @@ + +# Expansion Valve Example +This example demonstrates how to use the classes `ExpansionValve`, +and its children. + +First, let's import an exemplary valve from vclibpy's +`expansion_valve` package. The only one currently implemented +is Bernoulli: + +```python +from vclibpy.components.expansion_valves import Bernoulli +``` + +The valves are not that important for the vapor compression simulation, +as we iterate the pressure levels directly. However, you can still check +if a given valve cross-section area is large enough for your required level of +superheat. + +```python +help(Bernoulli) +``` + +Let's specify some dummy parameters: + +```python +d = 5e-3 # 5 mm diameter +area = 3.14 * d ** 2 / 4 +expansion_valve = Bernoulli(A=area) +``` + +Again, we have to start a med-prop, and give some input state: + +```python +from vclibpy.media import CoolProp +med_prop = CoolProp(fluid_name="Propane") +expansion_valve.med_prop = med_prop +``` + +Let's use the inlet state as in the last example +Also, we will use the evaporation pressure level: + +```python +state_condenser_outlet = med_prop.calc_state("TQ", 273.15 + 40, 0) +expansion_valve.state_inlet = state_condenser_outlet +p_evaporation = 3.149034617014494 * 1e5 +``` + +Now, we can calculate the outlet: + +```python +expansion_valve.calc_outlet(p_outlet=p_evaporation) +``` + +Note that the outlet has the same enthalpy as the inlet: + +```python +print(f"{expansion_valve.state_inlet.h=}; {expansion_valve.state_outlet.h=}") +``` + +## Valve opening: +Let's assume we want to match the mass flow rate of the last example: +What opening would we require for the given cross section area? +For this, we can use expansion_valve.ca + +```python +m_flow_ref_goal = 0.01 +opening = expansion_valve.calc_opening_at_m_flow(m_flow=m_flow_ref_goal) +print(f"Required opening: {opening}") +``` + +Not that much. Now, we can repeat the process with different diameters in mm. + +```python +import numpy as np +openings = [] +d_mm_array = np.arange(0.5, 5, 0.5) +for d_mm in d_mm_array: + expansion_valve.A = 3.14 * (d_mm * 1e-3) ** 2 / 4 + opening = expansion_valve.calc_opening_at_m_flow(m_flow=m_flow_ref_goal) + print(f"Required opening for area={expansion_valve.A}: {opening * 100} %") + openings.append(opening * 100) +``` + +Let's plot the result: + +```python +import matplotlib.pyplot as plt +plt.plot(d_mm_array, openings, marker="s") +plt.ylabel("Opening in %") +plt.xlabel("$d$ in mm") +plt.show() +``` + +Looking only at this point, the diameter should not be smaller than 1 mm. +You can tweak the assumptions around, check for different mass flow rates +or different pressure levels. diff --git a/docs/0.1.1/docs/_sources/examples/e6_simple_heat_pump.md.txt b/docs/0.1.1/docs/_sources/examples/e6_simple_heat_pump.md.txt new file mode 100644 index 0000000..7b5c84e --- /dev/null +++ b/docs/0.1.1/docs/_sources/examples/e6_simple_heat_pump.md.txt @@ -0,0 +1,152 @@ + +# Example for a heat pump with a standard cycle + +Let's start the complete cycle simulation with the +most basic flowsheet, the standard-cycle. As all flowsheets +contain a condenser and an evaporator, we defined a common BaseCycle +to avoid code-repetition. +We can import this flowsheet and see how to use it. Note that +modern coding IDEs like PyCharm will tell you which arguments belong +to a class or function. If you don't have that at hand, you need +to look into the documentation. + +```python +from vclibpy.flowsheets import BaseCycle, StandardCycle +help(BaseCycle) +help(StandardCycle) +``` + +We fist need to define the components in the cycle. +Here we are using the components developed in the previous examples. +Also, note again that the expansion valve model does not influence the results +for the current algorithm. But, you could size the expansion valve +using vclibpy, including off-design, but this is one for another example. + +```python +from vclibpy.components.heat_exchangers import moving_boundary_ntu +from vclibpy.components.heat_exchangers import heat_transfer +condenser = moving_boundary_ntu.MovingBoundaryNTUCondenser( + A=5, + secondary_medium="water", + flow_type="counter", + ratio_outer_to_inner_area=1, + two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=5000), + gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000), + wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3), + liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000), + secondary_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000) +) +evaporator = moving_boundary_ntu.MovingBoundaryNTUEvaporator( + A=15, + secondary_medium="air", + flow_type="counter", + ratio_outer_to_inner_area=10, + two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=1000), + gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=1000), + wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3), + liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000), + secondary_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=25) +) +from vclibpy.components.expansion_valves import Bernoulli +expansion_valve = Bernoulli(A=0.1) + +from vclibpy.components.compressors import RotaryCompressor +compressor = RotaryCompressor( + N_max=125, + V_h=19e-6 +) +``` + +Now, we can plug everything into the flowsheet: + +```python +heat_pump = StandardCycle( + evaporator=evaporator, + condenser=condenser, + fluid="Propane", + compressor=compressor, + expansion_valve=expansion_valve, +) +``` + +As in the other example, we can specify save-paths, +solver settings and inputs to vary: + +```python +save_path = r"D:\00_temp\simple_heat_pump" +T_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15] +T_con_in_ar = [30 + 273.15, 50 + 273.15, 70 + 273.15] +n_ar = [0.3, 0.7, 1] +``` + +Now, we can generate the full-factorial performance map +using all inputs. The results will be stored under the +save-path. To see some logs, we can import the logging module +and get, for example, all messages equal or above the INFO-level + +```python +import logging +logging.basicConfig(level="INFO") + +from vclibpy import utils +save_path_sdf, save_path_csv = utils.full_factorial_map_generation( + heat_pump=heat_pump, + save_path=save_path, + T_con_in_ar=T_con_in_ar, + T_eva_in_ar=T_eva_in_ar, + n_ar=n_ar, + use_multiprocessing=False, + save_plots=True, + m_flow_con=0.2, + m_flow_eva=0.9, + dT_eva_superheating=5, + dT_con_subcooling=0, +) +``` + +What did just happen? We can analyze all results by listing the +files in the save-path - or just open it in our default system explorer. + +```python +import os +print(os.listdir(save_path)) +``` + +One file should be: `Standard_Propane.csv`. We can load this file and plot + +```python +import pandas as pd +df = pd.read_csv(save_path_csv, index_col=0) +df +``` + +Now, we can plot variables, for example as a scatter plot using matplotlib. +You have to know the names, which are the column headers. + +```python +import matplotlib.pyplot as plt +x_name = "n in - (Relative compressor speed)" +y_name = "COP in - (Coefficient of performance)" +plt.scatter(df[x_name], df[y_name]) +plt.ylabel(y_name) +plt.xlabel(x_name) +plt.show() +``` + +Looking at the results, we see that a higher frequency often leads to lower COP values. +However, other inputs (temperatures) have a greater impact on the COP. +We can also use existing 3D-plotting scripts in vclibpy to analyze the +dependencies. For this, we need the .sdf file. In the sdf, the field names are without +the unit and description, as those are accessible in the file-format in other columns. + +```python +from vclibpy.utils.plotting import plot_sdf_map +plot_sdf_map( + filepath_sdf=save_path_sdf, + nd_data="COP", + first_dimension="T_eva_in", + second_dimension="T_con_in", + fluids=["Propane"], + flowsheets=["Standard"] +) +``` diff --git a/docs/0.1.1/docs/_sources/examples/e7_vapor_injection.md.txt b/docs/0.1.1/docs/_sources/examples/e7_vapor_injection.md.txt new file mode 100644 index 0000000..05e47cf --- /dev/null +++ b/docs/0.1.1/docs/_sources/examples/e7_vapor_injection.md.txt @@ -0,0 +1,174 @@ + +# Example for a heat pump with vapor injection using a phase separator + +Let's use a flowsheet which is more complex, e.g. the vapor injection +with a phase seperator. +We can import this flowsheet and how to use it like this: + +```python +from vclibpy.flowsheets import VaporInjectionPhaseSeparator +help(VaporInjectionPhaseSeparator) +``` + +As it needs the same heat exchanger model as a standard heat pump, +we will just use the ones from the standard cycle. Also, as +the expansion valve model does not influence the results for +the current algorithm, we will just use the same expansion-valve +twice. Note, that you could size the two expansion valves +using vclibpy, including off-design, but this is one for another +example. + +```python +from vclibpy.components.heat_exchangers import moving_boundary_ntu +from vclibpy.components.heat_exchangers import heat_transfer +condenser = moving_boundary_ntu.MovingBoundaryNTUCondenser( + A=5, + secondary_medium="water", + flow_type="counter", + ratio_outer_to_inner_area=1, + two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=5000), + gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000), + wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3), + liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000), + secondary_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000) +) +evaporator = moving_boundary_ntu.MovingBoundaryNTUEvaporator( + A=15, + secondary_medium="air", + flow_type="counter", + ratio_outer_to_inner_area=10, + two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=1000), + gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=1000), + wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3), + liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000), + secondary_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=25) +) +from vclibpy.components.expansion_valves import Bernoulli +high_pressure_valve = Bernoulli(A=0.1) +low_pressure_valve = Bernoulli(A=0.1) +``` + +For the compressors, we need to specify low- and high-pressure +compressors. To achieve a somewhat similar heat pump as the +one in the standard-cycle example, we will assume that we +use two smaller compressors instead of one larger one: + +```python +from vclibpy.components.compressors import RotaryCompressor +high_pressure_compressor = RotaryCompressor( + N_max=125, + V_h=19e-6 / 2 +) +low_pressure_compressor = RotaryCompressor( + N_max=125, + V_h=19e-6 / 2 +) +``` + +Now, we can plug everything into the flowsheet: + +```python +heat_pump = VaporInjectionPhaseSeparator( + evaporator=evaporator, + condenser=condenser, + fluid="Propane", + high_pressure_compressor=high_pressure_compressor, + low_pressure_compressor=low_pressure_compressor, + high_pressure_valve=high_pressure_valve, + low_pressure_valve=low_pressure_valve +) +``` + +As in the other example, we can specify save-paths, +solver settings and inputs to vary: + +```python +save_path = r"D:\00_temp\vapor_injection" +T_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15] +T_con_in_ar = [30 + 273.15, 50 + 273.15, 60 + 273.15] +n_ar = [0.3, 0.7, 1] +``` + +Now, we can generate the full-factorial performance map +using all inputs. The results will be stored under the +save-path. To see some logs, we can import the logging module +and get, for example, all messages equal or above the INFO-level + +```python +import logging +logging.basicConfig(level="INFO") + +from vclibpy import utils +utils.full_factorial_map_generation( + heat_pump=heat_pump, + save_path=save_path, + T_con_in_ar=T_con_in_ar, + T_eva_in_ar=T_eva_in_ar, + n_ar=n_ar, + use_multiprocessing=False, + save_plots=True, + m_flow_con=0.2, + m_flow_eva=0.9, + dT_eva_superheating=5, + dT_con_subcooling=0, +) +``` + +As in the prior examples, feel free to load the plots, +.csv or .sdf result files and further analyze them +# Vapor injection with an economizer. +Aside from the phase-separator flowsheet, we have one with +an economizer (additional heat exchanger). +The assumptions are similar, and the usage as well: + +```python +from vclibpy.flowsheets import VaporInjectionEconomizer +help(VaporInjectionEconomizer) +``` + +We need an additional economizer, which can be found in the heat exchangers: + +```python +from vclibpy.components.heat_exchangers.economizer import VaporInjectionEconomizerNTU +help(VaporInjectionEconomizerNTU) +``` + +Let's assume some dummy parameters: + +```python +economizer = VaporInjectionEconomizerNTU( + A=2, + two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=50000), + gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=50000), + wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3), + liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=50000), +) +``` + +And create the heat pump, and run the map generation: + +```python +heat_pump = VaporInjectionEconomizer( + evaporator=evaporator, + condenser=condenser, + fluid="Propane", + economizer=economizer, + high_pressure_compressor=high_pressure_compressor, + low_pressure_compressor=low_pressure_compressor, + high_pressure_valve=high_pressure_valve, + low_pressure_valve=low_pressure_valve +) +utils.full_factorial_map_generation( + heat_pump=heat_pump, + save_path=r"D:\00_temp\vapor_injection_economizer", + T_con_in_ar=T_con_in_ar, + T_eva_in_ar=T_eva_in_ar, + n_ar=n_ar, + use_multiprocessing=False, + save_plots=True, + m_flow_con=0.2, + m_flow_eva=0.9, + dT_eva_superheating=5, + dT_con_subcooling=0, +) +``` diff --git a/docs/0.1.1/docs/_sources/index.rst.txt b/docs/0.1.1/docs/_sources/index.rst.txt new file mode 100644 index 0000000..31bfb89 --- /dev/null +++ b/docs/0.1.1/docs/_sources/index.rst.txt @@ -0,0 +1,24 @@ +.. vcliby documentation master file, created by + sphinx-quickstart on Thu Jul 11 08:20:35 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +About vcliby +------------------- + +.. mdinclude:: ../../README.md + +.. toctree:: + :maxdepth: 2 + + code/modules + Contribution + version_his + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/0.1.1/docs/_sources/version_his.rst.txt b/docs/0.1.1/docs/_sources/version_his.rst.txt new file mode 100644 index 0000000..0b08378 --- /dev/null +++ b/docs/0.1.1/docs/_sources/version_his.rst.txt @@ -0,0 +1,4 @@ +Version History +--------------- + +.. mdinclude:: ../../CHANGELOG.md \ No newline at end of file diff --git a/docs/0.1.1/docs/_static/_sphinx_javascript_frameworks_compat.js b/docs/0.1.1/docs/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/docs/0.1.1/docs/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/0.1.1/docs/_static/autodoc_pydantic.css b/docs/0.1.1/docs/_static/autodoc_pydantic.css new file mode 100644 index 0000000..994a3e5 --- /dev/null +++ b/docs/0.1.1/docs/_static/autodoc_pydantic.css @@ -0,0 +1,11 @@ +.autodoc_pydantic_validator_arrow { + padding-left: 8px; + } + +.autodoc_pydantic_collapsable_json { + cursor: pointer; + } + +.autodoc_pydantic_collapsable_erd { + cursor: pointer; + } \ No newline at end of file diff --git a/docs/0.1.1/docs/_static/basic.css b/docs/0.1.1/docs/_static/basic.css new file mode 100644 index 0000000..7577acb --- /dev/null +++ b/docs/0.1.1/docs/_static/basic.css @@ -0,0 +1,903 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/0.1.1/docs/_static/css/badge_only.css b/docs/0.1.1/docs/_static/css/badge_only.css new file mode 100644 index 0000000..88ba55b --- /dev/null +++ b/docs/0.1.1/docs/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.eot b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.svg b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.ttf b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.woff b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.woff2 b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/0.1.1/docs/_static/css/fonts/lato-bold-italic.woff b/docs/0.1.1/docs/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/0.1.1/docs/_static/css/fonts/lato-bold-italic.woff2 b/docs/0.1.1/docs/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/0.1.1/docs/_static/css/fonts/lato-bold.woff b/docs/0.1.1/docs/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/lato-bold.woff differ diff --git a/docs/0.1.1/docs/_static/css/fonts/lato-bold.woff2 b/docs/0.1.1/docs/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/0.1.1/docs/_static/css/fonts/lato-normal-italic.woff b/docs/0.1.1/docs/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/0.1.1/docs/_static/css/fonts/lato-normal-italic.woff2 b/docs/0.1.1/docs/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/0.1.1/docs/_static/css/fonts/lato-normal.woff b/docs/0.1.1/docs/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/lato-normal.woff differ diff --git a/docs/0.1.1/docs/_static/css/fonts/lato-normal.woff2 b/docs/0.1.1/docs/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/docs/0.1.1/docs/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/0.1.1/docs/_static/css/theme.css b/docs/0.1.1/docs/_static/css/theme.css new file mode 100644 index 0000000..0f14f10 --- /dev/null +++ b/docs/0.1.1/docs/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/0.1.1/docs/_static/doctools.js b/docs/0.1.1/docs/_static/doctools.js new file mode 100644 index 0000000..d06a71d --- /dev/null +++ b/docs/0.1.1/docs/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/docs/0.1.1/docs/_static/documentation_options.js b/docs/0.1.1/docs/_static/documentation_options.js new file mode 100644 index 0000000..3462e59 --- /dev/null +++ b/docs/0.1.1/docs/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '0.1.1', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/docs/0.1.1/docs/_static/file.png b/docs/0.1.1/docs/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/docs/0.1.1/docs/_static/file.png differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.eot b/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.eot new file mode 100644 index 0000000..3361183 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.eot differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.ttf b/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.ttf new file mode 100644 index 0000000..29f691d Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.ttf differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.woff b/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.woff differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.woff2 b/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-bold.woff2 differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.eot b/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.eot new file mode 100644 index 0000000..3d41549 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.eot differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.ttf b/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.ttf new file mode 100644 index 0000000..f402040 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.ttf differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.woff b/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.woff differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.woff2 b/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-bolditalic.woff2 differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.eot b/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.eot new file mode 100644 index 0000000..3f82642 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.eot differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.ttf b/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.ttf new file mode 100644 index 0000000..b4bfc9b Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.ttf differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.woff b/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.woff differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.woff2 b/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-italic.woff2 differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.eot b/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.eot new file mode 100644 index 0000000..11e3f2a Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.eot differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.ttf b/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.ttf new file mode 100644 index 0000000..74decd9 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.ttf differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.woff b/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.woff differ diff --git a/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.woff2 b/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/Lato/lato-regular.woff2 differ diff --git a/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot new file mode 100644 index 0000000..79dc8ef Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot differ diff --git a/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf new file mode 100644 index 0000000..df5d1df Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf differ diff --git a/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff differ diff --git a/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 differ diff --git a/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot new file mode 100644 index 0000000..2f7ca78 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot differ diff --git a/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf new file mode 100644 index 0000000..eb52a79 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf differ diff --git a/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff differ diff --git a/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/docs/0.1.1/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 differ diff --git a/docs/0.1.1/docs/_static/jquery.js b/docs/0.1.1/docs/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/docs/0.1.1/docs/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t +
Languages
+ ${config.projects.translations + .map( + (translation) => ` +
+ ${translation.language.code} +
+ `, + ) + .join("\n")} + + `; + return languagesHTML; + } + + function renderVersions(config) { + if (!config.versions.active.length) { + return ""; + } + const versionsHTML = ` +
+
Versions
+ ${config.versions.active + .map( + (version) => ` +
+ ${version.slug} +
+ `, + ) + .join("\n")} +
+ `; + return versionsHTML; + } + + function renderDownloads(config) { + if (!Object.keys(config.versions.current.downloads).length) { + return ""; + } + const downloadsNameDisplay = { + pdf: "PDF", + epub: "Epub", + htmlzip: "HTML", + }; + + const downloadsHTML = ` +
+
Downloads
+ ${Object.entries(config.versions.current.downloads) + .map( + ([name, url]) => ` +
+ ${downloadsNameDisplay[name]} +
+ `, + ) + .join("\n")} +
+ `; + return downloadsHTML; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const flyout = ` +
+ + Read the Docs + v: ${config.versions.current.slug} + + +
+
+ ${renderLanguages(config)} + ${renderVersions(config)} + ${renderDownloads(config)} +
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+ Downloads +
+
+
+
Search
+
+
+ +
+
+
+
+ + Hosted by Read the Docs + +
+
+ `; + + // Inject the generated flyout into the body HTML element. + document.body.insertAdjacentHTML("beforeend", flyout); + + // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. + document + .querySelector("#flyout-search-form") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); + }) +} + +if (themeLanguageSelector || themeVersionSelector) { + function onSelectorSwitch(event) { + const option = event.target.selectedIndex; + const item = event.target.options[option]; + window.location.href = item.dataset.url; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const versionSwitch = document.querySelector( + "div.switch-menus > div.version-switch", + ); + if (themeVersionSelector) { + let versions = config.versions.active; + if (config.versions.current.hidden || config.versions.current.type === "external") { + versions.unshift(config.versions.current); + } + const versionSelect = ` + + `; + + versionSwitch.innerHTML = versionSelect; + versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + + const languageSwitch = document.querySelector( + "div.switch-menus > div.language-switch", + ); + + if (themeLanguageSelector) { + if (config.projects.translations.length) { + // Add the current language to the options on the selector + let languages = config.projects.translations.concat( + config.projects.current, + ); + languages = languages.sort((a, b) => + a.language.name.localeCompare(b.language.name), + ); + + const languageSelect = ` + + `; + + languageSwitch.innerHTML = languageSelect; + languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + else { + languageSwitch.remove(); + } + } + }); +} + +document.addEventListener("readthedocs-addons-data-ready", function (event) { + // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. + document + .querySelector("[role='search'] input") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); +}); \ No newline at end of file diff --git a/docs/0.1.1/docs/_static/language_data.js b/docs/0.1.1/docs/_static/language_data.js new file mode 100644 index 0000000..250f566 --- /dev/null +++ b/docs/0.1.1/docs/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, is available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/docs/0.1.1/docs/_static/minus.png b/docs/0.1.1/docs/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/docs/0.1.1/docs/_static/minus.png differ diff --git a/docs/0.1.1/docs/_static/plus.png b/docs/0.1.1/docs/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/docs/0.1.1/docs/_static/plus.png differ diff --git a/docs/0.1.1/docs/_static/pygments.css b/docs/0.1.1/docs/_static/pygments.css new file mode 100644 index 0000000..0d49244 --- /dev/null +++ b/docs/0.1.1/docs/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/0.1.1/docs/_static/searchtools.js b/docs/0.1.1/docs/_static/searchtools.js new file mode 100644 index 0000000..97d56a7 --- /dev/null +++ b/docs/0.1.1/docs/_static/searchtools.js @@ -0,0 +1,566 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = docUrlRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = docUrlRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/docs/0.1.1/docs/_static/sphinx_highlight.js b/docs/0.1.1/docs/_static/sphinx_highlight.js new file mode 100644 index 0000000..aae669d --- /dev/null +++ b/docs/0.1.1/docs/_static/sphinx_highlight.js @@ -0,0 +1,144 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(SphinxHighlight.highlightSearchWords); +_ready(SphinxHighlight.initEscapeListener); diff --git a/docs/0.1.1/docs/code/modules.html b/docs/0.1.1/docs/code/modules.html new file mode 100644 index 0000000..0ce4f36 --- /dev/null +++ b/docs/0.1.1/docs/code/modules.html @@ -0,0 +1,187 @@ + + + + + + + + + vclibpy — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.components.compressors.html b/docs/0.1.1/docs/code/vclibpy.components.compressors.html new file mode 100644 index 0000000..b1a998d --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.components.compressors.html @@ -0,0 +1,654 @@ + + + + + + + + + vclibpy.components.compressors package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy.components.compressors package

+
+

Submodules

+
+
+

vclibpy.components.compressors.compressor module

+

Module for different compressor models

+
+
+class vclibpy.components.compressors.compressor.Compressor(N_max: float, V_h: float)[source]
+

Bases: BaseComponent

+

Base compressor class to be extended for specific compressor models.

+
+
Args:

N_max (float): Maximal rotations per second of the compressor. +V_h (float): Volume of the compressor in m^3.

+
+
Methods:
+
get_lambda_h(inputs: Inputs) -> float:

Get the volumetric efficiency.

+
+
get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float:

Get the isentropic efficiency.

+
+
get_eta_mech(inputs: Inputs) -> float:

Get the mechanical efficiency.

+
+
get_p_outlet() -> float:

Get the outlet pressure.

+
+
get_n_absolute(n: float) -> float:

Return the absolute compressor frequency based on the relative speed.

+
+
calc_state_outlet(p_outlet: float, inputs: Inputs, fs_state: FlowsheetState):

Calculate the outlet state based on the high pressure level and provided inputs.

+
+
calc_m_flow(inputs: Inputs, fs_state: FlowsheetState) -> float:

Calculate the refrigerant mass flow rate.

+
+
calc_electrical_power(inputs: Inputs, fs_state: FlowsheetState) -> float:

Calculate the electrical power consumed by the compressor based on an adiabatic energy balance.

+
+
+
+
+
+
+calc_electrical_power(inputs: Inputs, fs_state: FlowsheetState) float[source]
+

Calculate the electrical power consumed by the compressor based on an adiabatic energy balance.

+
+
Args:

inputs (Inputs): Inputs for the calculation. +fs_state (FlowsheetState): Flowsheet state.

+
+
Returns:

float: Electrical power consumed.

+
+
+
+ +
+
+calc_m_flow(inputs: Inputs, fs_state: FlowsheetState) float[source]
+

Calculate the refrigerant mass flow rate.

+
+
Args:

inputs (Inputs): Inputs for the calculation. +fs_state (FlowsheetState): Flowsheet state.

+
+
Returns:

float: Refrigerant mass flow rate.

+
+
+
+ +
+
+calc_state_outlet(p_outlet: float, inputs: Inputs, fs_state: FlowsheetState)[source]
+

Calculate the output state based on the high pressure level and the provided inputs. +The state is automatically set as the outlet state of this component.

+
+
Args:

p_outlet (float): High pressure value. +inputs (Inputs): Inputs for calculation. +fs_state (FlowsheetState): Flowsheet state.

+
+
+
+ +
+
+get_eta_isentropic(p_outlet: float, inputs: Inputs) float[source]
+

Get the isentropic efficiency.

+
+
Args:

p_outlet (float): High pressure value. +inputs (Inputs): Inputs for the calculation.

+
+
Returns:

float: Isentropic efficiency.

+
+
+
+ +
+
+get_eta_mech(inputs: Inputs) float[source]
+

Get the mechanical efficiency including motor and inverter efficiencies.

+
+
Args:

inputs (Inputs): Inputs for the calculation.

+
+
Returns:

float: Mechanical efficiency including motor and inverter efficiencies.

+
+
+
+ +
+
+get_lambda_h(inputs: Inputs) float[source]
+

Get the volumetric efficiency.

+
+
Args:

inputs (Inputs): Inputs for the calculation.

+
+
Returns:

float: Volumetric efficiency.

+
+
+
+ +
+
+get_n_absolute(n: float) float[source]
+

Return given relative n as absolute rounds/sec based on self.N_max.

+
+
Args:

n (float): Relative compressor speed between 0 and 1.

+
+
Returns:

float: Absolute compressor frequency in rounds/sec.

+
+
+
+ +
+
+get_p_outlet() float[source]
+

Get the outlet pressure.

+
+
Returns:

float: Outlet pressure.

+
+
+
+ +
+ +
+
+

vclibpy.components.compressors.constant_effectivness module

+
+
+class vclibpy.components.compressors.constant_effectivness.ConstantEffectivenessCompressor(N_max: float, V_h: float, eta_isentropic: float, eta_mech: float, lambda_h: float)[source]
+

Bases: Compressor

+

Compressor model with constant efficiencies.

+

Inherits from the Compressor class, which defines the basic properties and behavior of a compressor in a vapor +compression cycle.

+
+
Parameters:

N_max (float): Maximal rotations per second of the compressor. +V_h (float): Volume of the compressor in m^3. +eta_isentropic (float): Constant isentropic efficiency of the compressor. +eta_mech (float): Constant mechanical efficiency of the compressor. +lambda_h (float): Constant volumetric efficiency.

+
+
Args:

N_max (float): Maximal rotations per second of the compressor. +V_h (float): Volume of the compressor in m^3. +eta_isentropic (float): Constant isentropic efficiency of the compressor. +eta_inverter (float): Constant inverter efficiency of the compressor. +eta_motor (float): Constant motor efficiency of the compressor. +eta_mech (float): Constant mechanical efficiency of the compressor including motor and inverter efficiencies. +lambda_h (float): Constant volumetric efficiency.

+
+
Methods:
+
get_lambda_h(inputs: Inputs) -> float:

Returns the constant volumetric efficiency of the compressor.

+
+
get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float:

Returns the constant isentropic efficiency of the compressor.

+
+
get_eta_mech(inputs: Inputs) -> float:

Returns the constant mechanical efficiency including motor and inverter efficiencies.

+
+
+
+
+
+
+get_eta_isentropic(p_outlet: float, inputs: Inputs) float[source]
+

Returns the constant isentropic efficiency of the compressor.

+
+
Args:

p_outlet (float): High pressure value. +inputs (Inputs): Input parameters for the calculation.

+
+
Returns:

float: Constant isentropic efficiency.

+
+
+
+ +
+
+get_eta_mech(inputs: Inputs) float[source]
+

Returns the product of the constant mechanical, motor, and inverter efficiencies +as the effective mechanical efficiency of the compressor.

+
+
Args:

inputs (Inputs): Input parameters for the calculation.

+
+
Returns:

float: Effective mechanical efficiency.

+
+
+
+ +
+
+get_lambda_h(inputs: Inputs) float[source]
+

Returns the constant volumetric efficiency of the compressor.

+
+
Args:

inputs (Inputs): Input parameters for the calculation.

+
+
Returns:

float: Constant volumetric efficiency.

+
+
+
+ +
+ +
+
+

vclibpy.components.compressors.rotary module

+
+
+class vclibpy.components.compressors.rotary.RotaryCompressor(N_max: float, V_h: float)[source]
+

Bases: Compressor

+

Compressor model based on the thesis of Mirko Engelpracht.

+

This compressor is characterized by using regressions provided by Mirko Engelpracht for a family of rotary +compressors. The coefficients used in the regressions are sourced from his Master’s thesis.

+
+
Parameters:

N_max (float): Maximal rotations per second of the compressor. +V_h (float): Volume of the compressor in m^3.

+
+
Methods:
+
get_lambda_h(inputs: Inputs) -> float:

Returns the volumetric efficiency based on the regressions of Mirko Engelpracht.

+
+
get_eta_isentropic(p_outlet: float, inputs: Inputs) -> float:

Returns the isentropic efficiency based on the regressions of Mirko Engelpracht.

+
+
get_eta_mech(inputs: Inputs) -> float:

Returns the mechanical efficiency based on the regressions of Mirko Engelpracht.

+
+
+
+
+
+
+get_eta_isentropic(p_outlet: float, inputs: Inputs) float[source]
+

Returns the isentropic efficiency based on the regressions of Mirko Engelpracht.

+
+
Args:

p_outlet (float): High pressure value. +inputs (Inputs): Input parameters for the calculation.

+
+
Returns:

float: Isentropic efficiency.

+
+
+
+ +
+
+get_eta_mech(inputs: Inputs) float[source]
+

Returns the mechanical efficiency based on the regressions of Mirko Engelpracht.

+
+
Args:

inputs (Inputs): Input parameters for the calculation.

+
+
Returns:

float: Mechanical efficiency.

+
+
+
+ +
+
+get_lambda_h(inputs: Inputs) float[source]
+

Returns the volumetric efficiency based on the regressions of Mirko Engelpracht.

+
+
Args:

inputs (Inputs): Input parameters for the calculation.

+
+
Returns:

float: Volumetric efficiency.

+
+
+
+ +
+ +
+
+

vclibpy.components.compressors.ten_coefficient module

+
+
+class vclibpy.components.compressors.ten_coefficient.BaseTenCoefficientCompressor(N_max, V_h, datasheet, **kwargs)[source]
+

Bases: Compressor, ABC

+

Base class for compressors using the ten-coefficient method.

+

Used table has to be in this format +(order of the columns is not important). +The values must be the same as in the example tabel. +The column names can be different but must +then be matched with argument parameter_names. +(All typed in numbers are fictional placeholders)

+
+

Capacity(W) Input Power(W) Flow Rate(kg/h) Capacity(W) … Flow Rate(kg/h)

+
+

n n1 n1 n1 n2 … n_last +P1 42 12 243 32 … 412 +… … … … … … … +P10 10 23 21 41 … 2434

+
+
Args:

N_max (float): Maximal rotations per second of the compressor. +V_h (float): Volume of the compressor in m^3. +datasheet (str): Path of the datasheet file. +**kwargs:

+
+
+
parameter_names (dict, optional):

Dictionary to match internal parameter names (keys) to the names used in the table values. +Default +{

+
+

“m_flow”: “Flow Rate(kg/h)”, +“capacity”: “Capacity(W)”, +“input_power”: “Input Power(W)”, +“eta_s”: “Isentropic Efficiency(-)”, +“lambda_h”: “Volumentric Efficiency(-)”, +“eta_mech”: “Mechanical Efficiency(-)”

+
+

}

+
+
+

sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None.

+
+
+
+
+
+get_parameter(T_eva, T_con, n, type_)[source]
+

Get a parameter based on temperatures, rotations, and parameter type from the datasheet.

+
+
Args:

T_eva (float): Evaporator temperature in Celsius. +T_con (float): Condenser temperature in Celsius. +n (float): Rotations per second. +type_ (str): Parameter type in parameter_names.

+
+
Returns:

float: Interpolated parameter value.

+
+
+
+ +
+ +
+
+class vclibpy.components.compressors.ten_coefficient.DataSheetCompressor(N_max, V_h, datasheet, **kwargs)[source]
+

Bases: BaseTenCoefficientCompressor

+

Compressor based on the ten coefficient method.

+

Used table has to be in this format +(order of the columns is not important). +The values must be the same as in the example tabel. +The column names can be different but must +then be matched with the keyword argument parameter_names. +(All typed in numbers are fictional placeholders)

+
+

Isentropic Volumetric Mechanical Isentropic Mechanical +Efficiency(-) Efficiency(-) Efficiency(-) Efficiency(-) … Efficiency(-)

+
+

n n1 n1 n1 n2 … n_last +P1 42 12 243 32 … 412 +… … … … … … … +P10 10 23 21 41 … 2434

+
+
Args:

N_max (float): Maximal rotations per second of the compressor. +V_h (float): Volume of the compressor in m^3. +datasheet (str): Path of the datasheet file. +**kwargs:

+
+
+
parameter_names (dict, optional):

Dictionary to match internal parameter names (keys) to the names used in the table values. +Default +{

+
+

“eta_s”: “Isentropic Efficiency(-)”, +“lambda_h”: “Volumetric Efficiency(-)”, +“eta_mech”: “Mechanical Efficiency(-)”

+
+

}

+
+
+

sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None.

+
+
+
+
+
+get_eta_isentropic(p_outlet: float, inputs: Inputs)[source]
+

Get the isentropic efficiency.

+
+
Args:

p_outlet (float): Outlet pressure in Pa. +inputs (Inputs): Input parameters.

+
+
Returns:

float: Isentropic efficiency.

+
+
+
+ +
+
+get_eta_mech(inputs: Inputs)[source]
+

Get the mechanical efficiency.

+
+
Args:

inputs (Inputs): Input parameters.

+
+
Returns:

float: Mechanical efficiency.

+
+
+
+ +
+
+get_lambda_h(inputs: Inputs)[source]
+

Get the volumetric efficiency.

+
+
Args:

inputs (Inputs): Input parameters.

+
+
Returns:

float: Volumetric efficiency.

+
+
+
+ +
+ +
+
+class vclibpy.components.compressors.ten_coefficient.TenCoefficientCompressor(N_max, V_h, T_sc, T_sh, capacity_definition, assumed_eta_mech, datasheet, **kwargs)[source]
+

Bases: BaseTenCoefficientCompressor

+

Compressor based on the ten coefficient method.

+

Used table has to be in this format +(order of the columns is not important). +The values must be the same as in the example tabel. +The column names can be different but must +then be matched with the keyword argument parameter_names. +(All typed in numbers are fictional placeholders)

+
+

Capacity(W) Input Power(W) Flow Rate(kg/h) Capacity(W) … Flow Rate(kg/h)

+
+

n n1 n1 n1 n2 … n_last +P1 42 12 243 32 … 412 +… … … … … … … +P10 10 23 21 41 … 2434

+

T_sh and T_sc have to be set according to the data sheet of your compressor. capacity_definition defines the +parameter “capacity” in the datasheet. If capacity is the specific cooling capacity (h1-h4), set it on “cooling”. +If capacity is the specific heating capacity (h2-h3), set it on “heating”. +In the case of cooling capacity, the mechanical efficiency of the compressor has to be assumed (assumed_eta_mech) +as h2 can’t be calculated otherwise. Summary:

+
+
    +
  • For the case heating capacity: h2 = h3 + capacity / m_flow

  • +
  • For the case cooling capacity: h2 = h3 + (capacity + p_el * assumed_eta_mech) / m_flow

  • +
+
+
+
Args:

N_max (float): Maximal rotations per second of the compressor. +V_h (float): Volume of the compressor in m^3. +T_sc (float): Subcooling according to datasheet in K. +T_sh (float): Superheating according to datasheet in K. +capacity_definition (str): Definition of “capacity” in the datasheet. “cooling” or “heating”. +assumed_eta_mech (float): Assumed mechanical efficiency of the compressor (only needed if cooling). +datasheet (str): Path of the modified datasheet. +**kwargs:

+
+
+
parameter_names (dict, optional):

Dictionary to match internal parameter names (keys) to the names used in the table values. +Default +{

+
+

“m_flow”: “Flow Rate(kg/h)”, +“capacity”: “Capacity(W)”, +“input_power”: “Input Power(W)”

+
+

}

+
+
+

sheet_name (str, optional): Name of the sheet in the datasheet. Defaults to None.

+
+
+
+
+
+get_eta_isentropic(p_outlet: float, inputs: Inputs)[source]
+

Get the isentropic efficiency.

+
+
Args:

p_outlet (float): Outlet pressure in Pa. +inputs (Inputs): Input parameters.

+
+
Returns:

float: Isentropic efficiency.

+
+
+
+ +
+
+get_eta_mech(inputs: Inputs)[source]
+

Get the mechanical efficiency.

+
+
Args:

inputs (Inputs): Input parameters.

+
+
Returns:

float: Mechanical efficiency.

+
+
+
+ +
+
+get_lambda_h(inputs: Inputs)[source]
+

Get the volumetric efficiency.

+
+
Args:

inputs (Inputs): Input parameters.

+
+
Returns:

float: Volumetric efficiency.

+
+
+
+ +
+ +
+
+vclibpy.components.compressors.ten_coefficient.calc_ten_coefficients(T_eva, T_con, coef_list)[source]
+

Calculate the result using the ten-coefficient method.

+
+
Args:

T_eva (float): Evaporator temperature in Celsius. +T_con (float): Condenser temperature in Celsius. +coef_list (list): List of coefficients.

+
+
Returns:

float: Result of the calculation.

+
+
+
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.components.expansion_valves.html b/docs/0.1.1/docs/code/vclibpy.components.expansion_valves.html new file mode 100644 index 0000000..d006c75 --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.components.expansion_valves.html @@ -0,0 +1,224 @@ + + + + + + + + + vclibpy.components.expansion_valves package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy.components.expansion_valves package

+
+

Submodules

+
+
+

vclibpy.components.expansion_valves.bernoulli module

+

Module with simple bernoulli expansion valve

+
+
+class vclibpy.components.expansion_valves.bernoulli.Bernoulli(A)[source]
+

Bases: ExpansionValve

+

Simple Bernoulli model.

+
+
Args:

A (float): Cross-sectional area of the expansion valve.

+
+
+
+
+calc_m_flow_at_opening(opening)[source]
+

Calculate the mass flow rate for the given opening.

+
+
Args:

opening (float): Opening of valve between 0 and 1

+
+
Returns:

float: Mass flow rate in kg/s

+
+
+
+ +
+
+calc_opening_at_m_flow(m_flow, **kwargs)[source]
+

Calculate the opening for the given mass flow rate

+
+
Args:

m_flow (float): Mass flow rate in kg/s +**kwargs: Possible keyword arguments for child classes

+
+
Returns:

float: Opening

+
+
+
+ +
+ +
+
+

vclibpy.components.expansion_valves.expansion_valve module

+

Module with classes for EV models. +They are not used for the calculation. +They may be used to see if the output is correct.

+
+
+class vclibpy.components.expansion_valves.expansion_valve.ExpansionValve(A)[source]
+

Bases: BaseComponent, ABC

+

Base class for an expansion valve.

+
+
Args:

A (float): Cross-sectional area of the expansion valve.

+
+
+
+
+abstract calc_m_flow_at_opening(opening) float[source]
+

Calculate the mass flow rate for the given opening.

+
+
Args:

opening (float): Opening of valve between 0 and 1

+
+
Returns:

float: Mass flow rate in kg/s

+
+
+
+ +
+
+abstract calc_opening_at_m_flow(m_flow, **kwargs) float[source]
+

Calculate the opening for the given mass flow rate

+
+
Args:

m_flow (float): Mass flow rate in kg/s +**kwargs: Possible keyword arguments for child classes

+
+
Returns:

float: Opening

+
+
+
+ +
+
+calc_outlet(p_outlet: float)[source]
+

Calculate isenthalpic expansion valve.

+
+
Args:

p_outlet (float): Outlet pressure level

+
+
+
+ +
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.components.heat_exchangers.heat_transfer.html b/docs/0.1.1/docs/code/vclibpy.components.heat_exchangers.heat_transfer.html new file mode 100644 index 0000000..8cced0f --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.components.heat_exchangers.heat_transfer.html @@ -0,0 +1,640 @@ + + + + + + + + + vclibpy.components.heat_exchangers.heat_transfer package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy.components.heat_exchangers.heat_transfer package

+
+

Submodules

+
+
+

vclibpy.components.heat_exchangers.heat_transfer.air_to_wall module

+
+
+class vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.AirToWallTransfer(A_cross: float, characteristic_length: float)[source]
+

Bases: HeatTransfer, ABC

+

Heat transfer model for air to wall.

+
+
Args:
+
A_cross (float):

Cross-section area in m2.

+
+
characteristic_length (float):

Length in m to calculate the similitude approach for the +heat transfer from secondary_medium -> wall.

+
+
+
+
+
+
+calc(transport_properties: TransportProperties, m_flow: float) float[source]
+

Heat transfer coefficient from air to the wall of the heat exchanger. +The flow is assumed to be always laminar.

+
+
Returns:

float: Heat transfer coefficient in W/(m^2*K).

+
+
+
+ +
+
+abstract calc_laminar_area_nusselt(Re, Pr, lambda_)[source]
+

Calculate the Nusselt number for laminar heat transfer +on an area (Used for Air->Wall in the evaporator).

+
+
Args:

Re (float): Reynolds number +Pr (float): Prandlt number +lambda_ (float): Lambda of air

+
+
Returns:

float: Nusselt number

+
+
+
+ +
+
+abstract calc_reynolds(dynamic_viscosity: float, m_flow: float)[source]
+

Calculate the reynolds number of the given flow rate.

+
+
Args:

dynamic_viscosity (float): Dynamic viscosity. +m_flow (float): Mass flow rate.

+
+
Returns:

float: Reynolds number

+
+
+
+ +
+ +
+
+class vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.WSUAirToWall(A_cross: float, characteristic_length: float)[source]
+

Bases: AirToWallTransfer

+

Class to implement the heat transfer calculations +based on the WSÜ-Script at the RWTH.

+
+
+calc_laminar_area_nusselt(Re, Pr, lambda_) float[source]
+

Calculate the Nusselt number for laminar heat transfer +on an area (Used for Air->Wall in the evaporator).

+
+
Args:

Re (float): Reynolds number of air. +Pr (float): Prandtl number of air. +lambda_ (float): Lambda of air.

+
+
Returns:

float: Nusselt number of air.

+
+
+
+ +
+
+calc_reynolds(dynamic_viscosity: float, m_flow: float) float[source]
+

Calculate the Reynolds number on air side.

+
+
Args:

dynamic_viscosity (float): Dynamic viscosity of air. +m_flow (float): Mass flow rate of air.

+
+
Returns:

float: Reynolds number.

+
+
+
+ +
+ +
+
+

vclibpy.components.heat_exchangers.heat_transfer.constant module

+

Module with constant heat transfer assumptions

+
+
+class vclibpy.components.heat_exchangers.heat_transfer.constant.ConstantHeatTransfer(alpha: float)[source]
+

Bases: ABC

+

Constant heat transfer assumption

+
+
Args:
+
alpha (float):

Constant heat transfer coefficient in W/(m2*K)

+
+
+
+
+
+
+calc(transport_properties: TransportProperties, m_flow: float) float[source]
+

Calculate constant heat transfer coefficient.

+
+
Args:

transport_properties (TransportProperties): Transport properties of the medium (not used). +m_flow (float): Mass flow rate (not used).

+
+
Returns:

float: Constant heat transfer coefficient in W/(m2*K).

+
+
+
+ +
+ +
+
+class vclibpy.components.heat_exchangers.heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha: float)[source]
+

Bases: ABC

+

Constant heat transfer assumption.

+
+
Args:
+
alpha (float):

Constant heat transfer coefficient in W/(m2*K).

+
+
+
+
+
+
+calc(**kwargs) float[source]
+

Calculate constant two-phase heat transfer coefficient.

+
+
Args:

**kwargs: Allows to set arguments for different heat transfer classes which are not used here.

+
+
Returns:

float: Constant two-phase heat transfer coefficient in W/(m2*K).

+
+
+
+ +
+ +
+
+

vclibpy.components.heat_exchangers.heat_transfer.heat_transfer module

+

Module with basic functions to calculate heat transfer coefficients.

+
+
+class vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.HeatTransfer[source]
+

Bases: ABC

+

Base class to implement possible heat transfer models.

+
+
Methods:
+
calc(transport_properties: TransportProperties, m_flow: float) -> float:

Abstract method to calculate heat transfer.

+
+
+
+
+
+
+abstract calc(transport_properties: TransportProperties, m_flow: float) float[source]
+

Calculate heat transfer.

+
+
Args:

transport_properties (TransportProperties): Transport properties of the medium. +m_flow (float): Mass flow rate.

+
+
Returns:

float: Calculated heat transfer coefficient.

+
+
Raises:

NotImplementedError: If the method is not implemented in the subclass.

+
+
+
+ +
+ +
+
+class vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.TwoPhaseHeatTransfer[source]
+

Bases: ABC

+

Base class to implement possible heat transfer models

+
+
+abstract calc(state_q0: ThermodynamicState, state_q1: ThermodynamicState, state_inlet: ThermodynamicState, state_outlet: ThermodynamicState, med_prop: MedProp, inputs: Inputs, fs_state: FlowsheetState, m_flow: float) float[source]
+

Calculate two-phase heat transfer.

+
+
Args:

state_q0 (ThermodynamicState): Thermodynamic state at the beginning of the two-phase region. +state_q1 (ThermodynamicState): Thermodynamic state at the end of the two-phase region. +state_inlet (ThermodynamicState): Inlet thermodynamic state. +state_outlet (ThermodynamicState): Outlet thermodynamic state. +med_prop (MedProp): Medium properties class. +inputs (Inputs): Input parameters. +fs_state (FlowsheetState): Flowsheet state. +m_flow (float): Mass flow rate.

+
+
Returns:

float: Calculated two-phase heat transfer coefficient.

+
+
Raises:

NotImplementedError: If the method is not implemented in the subclass.

+
+
+
+ +
+ +
+
+vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.calc_reynolds_pipe(dynamic_viscosity: float, m_flow: float, characteristic_length: float) float[source]
+

Calculate Reynolds number for flow inside a pipe.

+
+
Args:

dynamic_viscosity (float): Dynamic viscosity of the fluid. +m_flow (float): Mass flow rate. +characteristic_length (float): Characteristic length (e.g., diameter) of the pipe.

+
+
Returns:

float: Reynolds number.

+
+
+
+ +
+
+

vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall module

+

Module with models for pipe-to-wall heat transfer.

+
+
+class vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall.TurbulentFluidInPipeToWallTransfer(method: str, characteristic_length: float)[source]
+

Bases: HeatTransfer

+

Class to model turbulent heat exchange in a pipe.

+
+
Args:
+
method (str):

Equation to calc the nusselt number of turbulent flow for +a given Re and Pr number. +Note: Just for one-phase heat transfer!! +Implemented Options are:

+
    +
  • Taler2016

  • +
  • Domanski1989_sp_smooth

  • +
  • Amalfi2016

  • +
  • ScriptWSÜ. For turbulent regimes, eta_by_eta_w is assumed to be one.

  • +
+

Refer to the paper / documents or the function in this class for more +info on numbers and assumptions

+
+
characteristic_length (float):

Length to calculate the similitude approach for the +heat transfer from ref -> wall. For heat pumps this is +always the Diameter of the HE in m

+
+
+
+
+
+
+calc(transport_properties: TransportProperties, m_flow: float) float[source]
+

Calculate heat transfer coefficient from refrigerant to the wall of the heat exchanger.

+

The flow is assumed to be always turbulent and is based on a calibrated +Nusselt correlation.

+
+
Args:

transport_properties (TransportProperties): Transport properties of the fluid. +m_flow (float): Mass flow rate of the fluid.

+
+
Returns:

float: Heat transfer coefficient from refrigerant to HE in W/(m^2*K).

+
+
+
+ +
+
+calc_turbulent_tube_nusselt(Re, Pr) float[source]
+

Calculate the Nuseelt number for turbulent heat transfer +in a tube (used for ref/water->Wall in the evaporator and condernser).

+
+
Args:

Re (float): Reynolds number. +Pr (float): Prandtl number.

+
+
Returns:

float: Nusselt number.

+
+
+
+ +
+ +
+
+

vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall module

+
+
+class vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry(t_l: float, t_q: float, tiefe: float, d_a: float, d_i: float, lambda_R: float, n_Rohre: int = 50, n_Rippen: int = 500, a: float = 0.00195, dicke_rippe: float = 5e-05, laenge: float = 1.04, hoehe: float = 0.64)[source]
+

Bases: object

+

Geometry of a fin and tube heat exchanger with two rows of pipes in a shifted arrangement.

+

Source: VDI-Wärmeatlas, Berechnungsblätter für den Wärmeübergang, 11. Auflage, S.1461

+

As the source is in German, the names are kept in German as well.

+
+
+property A: float
+

Total air side heat transfer area.

+
+ +
+
+property A_FreieOberflaecheRohr: float
+

Free air side area of the tubes.

+
+ +
+
+property A_Rippen: float
+

Return the total surface area of the fins.

+
+ +
+
+property A_RohrInnen: float
+

Total refrigerant heat transfer area.

+
+ +
+
+property A_RohrUnberippt: float
+

Total outside area of the tubes without fins

+
+ +
+
+a: float = 0.00195
+
+ +
+
+alpha_S(alpha_R) float[source]
+

Calculate apparent heat transfer coefficient.

+
+
Args:

alpha_R (float): Average heat transfer coefficient for tube and fin.

+
+
Returns:

float: Apparent heat transfer coefficient.

+
+
+
+ +
+
+property char_length: float
+

Return the characteristic length d_a.

+
+ +
+
+d_a: float
+
+ +
+
+d_i: float
+
+ +
+
+dicke_rippe: float = 5e-05
+
+ +
+
+eta_R(alpha_R) float[source]
+

Calculate fin efficiency.

+
+
Args:

alpha_R (float): Average heat transfer coefficient for tube and fin.

+
+
Returns:

float: Fin efficiency.

+
+
+
+ +
+
+hoehe: float = 0.64
+
+ +
+
+laenge: float = 1.04
+
+ +
+
+lambda_R: float
+
+ +
+
+n_Rippen: int = 500
+
+ +
+
+n_Rohre: int = 50
+
+ +
+
+property phi: float
+

Auxiliary variable for fin efficiency

+
+ +
+
+t_l: float
+
+ +
+
+t_q: float
+
+ +
+
+tiefe: float
+
+ +
+
+property verjuengungsfaktor: float
+

Reduction factor A_cross_free/A_cross_smallest

+
+ +
+ +
+
+class vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.VDIAtlasAirToWallTransfer(A_cross: float, characteristic_length: float, geometry_parameters: AirSourceHeatExchangerGeometry)[source]
+

Bases: AirToWallTransfer

+

VDI-Atlas based heat transfer estimation. +Check AirToWallTransfer for further argument options.

+

This class assumes two pipes with a shifted arrangement.

+
+
Args:

A_cross (float): Free cross-sectional area. +characteristic_length (float): Characteristic length d_a. +geometry_parameters (AirSourceHeatExchangerGeometry):

+
+

Geometry parameters for heat exchanger according to VDI-Atlas

+
+
+
+
+
+calc_laminar_area_nusselt(Re: float, Pr: float, lambda_: float) float[source]
+

Calculate apparent heat transfer coefficient based on Nusselt correlation.

+
+
Args:

Re (float): Reynolds number. +Pr (float): Prandtl number. +lambda_ (float): Thermal conductivity of air.

+
+
Returns:

float: Apparent heat transfer coefficient.

+
+
+
+ +
+
+calc_reynolds(dynamic_viscosity: float, m_flow: float) float[source]
+

Calculate Reynolds number.

+
+
Args:

dynamic_viscosity (float): Dynamic viscosity of the fluid. +m_flow (float): Mass flow rate.

+
+
Returns:

float: Reynolds number.

+
+
+
+ +
+ +
+
+

vclibpy.components.heat_exchangers.heat_transfer.wall module

+
+
+class vclibpy.components.heat_exchangers.heat_transfer.wall.WallTransfer(lambda_: float, thickness: float)[source]
+

Bases: HeatTransfer

+

Simple wall heat transfer

+
+
Args:
+
lambda_ (float):

Heat conductivity of wall material in W/Km

+
+
thickness (float):

Thickness of wall in m^2

+
+
+
+
+
+
+calc(transport_properties: TransportProperties, m_flow: float) float[source]
+

Heat transfer coefficient inside wall

+
+
Returns:

float: Heat transfer coefficient in W/(m^2*K)

+
+
+
+ +
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.components.heat_exchangers.html b/docs/0.1.1/docs/code/vclibpy.components.heat_exchangers.html new file mode 100644 index 0000000..ed5bc49 --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.components.heat_exchangers.html @@ -0,0 +1,728 @@ + + + + + + + + + vclibpy.components.heat_exchangers package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy.components.heat_exchangers package

+
+

Subpackages

+
+ +
+
+
+

Submodules

+
+
+

vclibpy.components.heat_exchangers.economizer module

+
+
+class vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU(**kwargs)[source]
+

Bases: BasicNTU

+

Economizer heat exchanger which is NTU based. +Used only for vapor injection cycles, as +calculations are purely based for two-phase +and liquid estimations.

+

See parent class for more arguments.

+

Assumptions:

+
    +
  • Default flow_type is counter_flow.

  • +
  • Default ratio_outer_to_inner_area is 1, as

  • +
  • pipes are nearly same diameter and length

  • +
  • Secondary heat transfer for alpha is disabled; gas,

  • +
+

liquid and two-phase models are used for both sides.

+
+
+calc(inputs, fs_state) -> (<class 'float'>, <class 'float'>)[source]
+

Calculate the heat exchanger based on the given inputs.

+

The flowsheet state can be used to save important variables +during calculation for later analysis.

+

Both return values are used to check if the heat transfer is valid or not.

+
+
Args:

inputs (Inputs): The inputs for the calculation. +fs_state (FlowsheetState): The flowsheet state to save important variables.

+
+
Returns:
+
Tuple[float, float]:

error: Error in percentage between the required and calculated heat flow rates. +dT_min: Minimal temperature difference (can be negative).

+
+
+
+
+
+ +
+
+calc_alpha_secondary(transport_properties)[source]
+

Calculate the secondary-medium heat transfer coefficient.

+
+
Args:

transport_properties: Transport properties for the secondary medium.

+
+
Returns:

float: The secondary-medium heat transfer coefficient.

+
+
+
+ +
+
+calc_transport_properties_secondary_medium(T, p=None)[source]
+

Calculate the transport properties for the selected secondary_medium.

+
+
Args:

T (float): Temperature in K. +p (float, optional): Pressure to use. Defaults to None.

+
+
Returns:

media.TransportProperties: The calculated transport properties.

+
+
+
+ +
+
+set_secondary_cp(cp: float)[source]
+

Set primary m_flow_cp

+
+ +
+
+start_secondary_med_prop()[source]
+

Set up the wrapper for the secondary medium’s media properties.

+
+ +
+
+property state_two_phase_inlet: ThermodynamicState
+
+ +
+
+property state_two_phase_outlet: ThermodynamicState
+
+ +
+
+terminate_secondary_med_prop()[source]
+

To use multi-processing, MedProp can’t start +in the main thread, as the object can’t be pickled.

+

This function terminates possible secondary med-prop +classes, for instance in heat exchangers. +The default component does not have to override +this function.

+
+ +
+ +
+
+

vclibpy.components.heat_exchangers.heat_exchanger module

+
+
+class vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger(A: float, wall_heat_transfer: HeatTransfer, secondary_heat_transfer: HeatTransfer, gas_heat_transfer: HeatTransfer, liquid_heat_transfer: HeatTransfer, two_phase_heat_transfer: TwoPhaseHeatTransfer, secondary_medium: str)[source]
+

Bases: BaseComponent, ABC

+

Class for a heat exchanger.

+
+
Args:
+
A (float):

Area of HE in m^2 for NTU calculation

+
+
secondary_medium (str):

Name for secondary medium, e.g. water or air

+
+
wall_heat_transfer (HeatTransfer):

Model for heat transfer inside wall

+
+
secondary_heat_transfer (HeatTransfer):

Model for heat transfer from secondary medium to wall

+
+
gas_heat_transfer (HeatTransfer):

Model for heat transfer from refrigerant gas to wall

+
+
liquid_heat_transfer (HeatTransfer):

Model for heat transfer from refrigerant liquid to wall

+
+
two_phase_heat_transfer (TwoPhaseHeatTransfer):

Model for heat transfer from refrigerant two phase to wall

+
+
+
+
+
+
+abstract calc(inputs: Inputs, fs_state: FlowsheetState) Tuple[float, float][source]
+

Calculate the heat exchanger based on the given inputs.

+

The flowsheet state can be used to save important variables +during calculation for later analysis.

+

Both return values are used to check if the heat transfer is valid or not.

+
+
Args:

inputs (Inputs): The inputs for the calculation. +fs_state (FlowsheetState): The flowsheet state to save important variables.

+
+
Returns:
+
Tuple[float, float]:

error: Error in percentage between the required and calculated heat flow rates. +dT_min: Minimal temperature difference (can be negative).

+
+
+
+
+
+ +
+
+calc_Q_flow() float[source]
+

Calculate the total heat flow rate.

+
+
Returns:

float: The total heat flow rate.

+
+
+
+ +
+
+calc_alpha_gas(transport_properties) float[source]
+

Calculate the gas-phase heat transfer coefficient.

+
+
Args:

transport_properties: Transport properties for the gas phase.

+
+
Returns:

float: The gas-phase heat transfer coefficient.

+
+
+
+ +
+
+calc_alpha_liquid(transport_properties) float[source]
+

Calculate the liquid-phase heat transfer coefficient.

+
+
Args:

transport_properties: Transport properties for the liquid phase.

+
+
Returns:

float: The liquid-phase heat transfer coefficient.

+
+
+
+ +
+
+calc_alpha_secondary(transport_properties) float[source]
+

Calculate the secondary-medium heat transfer coefficient.

+
+
Args:

transport_properties: Transport properties for the secondary medium.

+
+
Returns:

float: The secondary-medium heat transfer coefficient.

+
+
+
+ +
+
+calc_alpha_two_phase(state_q0, state_q1, inputs: Inputs, fs_state: FlowsheetState) float[source]
+

Calculate the two-phase heat transfer coefficient.

+
+
Args:

state_q0: State at vapor quality 0. +state_q1: State at vapor quality 1. +inputs (Inputs): The inputs for the calculation. +fs_state (FlowsheetState): The flowsheet state to save important variables.

+
+
Returns:

float: The two-phase heat transfer coefficient.

+
+
+
+ +
+
+calc_secondary_Q_flow(Q_flow: float) float[source]
+
+ +
+
+calc_secondary_cp(T: float, p=None)[source]
+

Calculate and set the heat capacity rate m_flow_cp of the secondary medium.

+
+
Args:

T (float): Temperature of the secondary medium. +p (float, optional): Pressure of the secondary medium. Defaults to None.

+
+
+
+ +
+
+calc_transport_properties_secondary_medium(T, p=None) TransportProperties[source]
+

Calculate the transport properties for the selected secondary_medium.

+
+
Args:

T (float): Temperature in K. +p (float, optional): Pressure to use. Defaults to None.

+
+
Returns:

media.TransportProperties: The calculated transport properties.

+
+
+
+ +
+
+calc_wall_heat_transfer() float[source]
+

Calculate the heat transfer coefficient inside the wall.

+
+
Returns:

float: The wall heat transfer coefficient.

+
+
+
+ +
+
+property m_flow_secondary: float
+
+ +
+
+property m_flow_secondary_cp
+
+ +
+
+start_secondary_med_prop()[source]
+

Set up the wrapper for the secondary medium’s media properties.

+
+ +
+
+terminate_secondary_med_prop()[source]
+

To use multi-processing, MedProp can’t start +in the main thread, as the object can’t be pickled.

+

This function terminates possible secondary med-prop +classes, for instance in heat exchangers. +The default component does not have to override +this function.

+
+ +
+ +
+
+

vclibpy.components.heat_exchangers.moving_boundary_ntu module

+
+
+class vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTU(flow_type: str, ratio_outer_to_inner_area: float, **kwargs)[source]
+

Bases: BasicNTU, ABC

+

Moving boundary NTU based heat exchanger.

+

See parent classe for arguments.

+
+
+iterate_area(dT_max, alpha_pri, alpha_sec, Q) float[source]
+

Iteratively calculates the required area for the heat exchange.

+
+
Args:

dT_max (float): Maximum temperature differential. +alpha_pri (float): Heat transfer coefficient for the primary medium. +alpha_sec (float): Heat transfer coefficient for the secondary medium. +Q (float): Heat flow rate.

+
+
Returns:

float: Required area for heat exchange.

+
+
+
+ +
+
+separate_phases(state_max: ThermodynamicState, state_min: ThermodynamicState, p: float)[source]
+

Separates a flow with possible phase changes into three parts: +subcooling (sc), latent phase change (lat), and superheating (sh) +at the given pressure.

+
+
Args:

state_max (ThermodynamicState): State with higher enthalpy. +state_min (ThermodynamicState): State with lower enthalpy. +p (float): Pressure of phase change.

+
+
Returns:
+
Tuple[float, float, float, ThermodynamicState, ThermodynamicState]:

Q_sc: Heat for subcooling. +Q_lat: Heat for latent phase change. +Q_sh: Heat for superheating. +state_q0: State at vapor quality 0 and the given pressure. +state_q1: State at vapor quality 1 and the given pressure.

+
+
+
+
+
+ +
+ +
+
+class vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTUCondenser(flow_type: str, ratio_outer_to_inner_area: float, **kwargs)[source]
+

Bases: MovingBoundaryNTU

+

Condenser class which implements the actual calc method.

+

Assumptions: +- No phase changes in secondary medium +- cp of secondary medium is constant over heat-exchanger

+

See parent classes for arguments.

+
+
+calc(inputs: ~vclibpy.datamodels.Inputs, fs_state: ~vclibpy.datamodels.FlowsheetState) -> (<class 'float'>, <class 'float'>)[source]
+

Calculate the heat exchanger with the NTU-Method based on the given inputs.

+

The flowsheet state can be used to save important variables +during calculation for later analysis.

+

Both return values are used to check if the heat transfer is valid or not.

+
+
Args:

inputs (Inputs): The inputs for the calculation. +fs_state (FlowsheetState): The flowsheet state to save important variables.

+
+
Returns:
+
Tuple[float, float]:

error: Error in percentage between the required and calculated heat flow rates. +dT_min: Minimal temperature difference (can be negative).

+
+
+
+
+
+ +
+ +
+
+class vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTUEvaporator(flow_type: str, ratio_outer_to_inner_area: float, **kwargs)[source]
+

Bases: MovingBoundaryNTU

+

Evaporator class which implements the actual calc method.

+

Assumptions: +- No phase changes in secondary medium +- cp of secondary medium is constant over heat-exchanger

+

See parent classes for arguments.

+
+
+calc(inputs: ~vclibpy.datamodels.Inputs, fs_state: ~vclibpy.datamodels.FlowsheetState) -> (<class 'float'>, <class 'float'>)[source]
+

Calculate the heat exchanger with the NTU-Method based on the given inputs.

+

The flowsheet state can be used to save important variables +during calculation for later analysis.

+

Both return values are used to check if the heat transfer is valid or not.

+
+
Args:

inputs (Inputs): The inputs for the calculation. +fs_state (FlowsheetState): The flowsheet state to save important variables.

+
+
Returns:
+
Tuple[float, float]:

error: Error in percentage between the required and calculated heat flow rates. +dT_min: Minimal temperature difference (can be negative).

+
+
+
+
+
+ +
+ +
+
+

vclibpy.components.heat_exchangers.ntu module

+
+
+class vclibpy.components.heat_exchangers.ntu.BasicNTU(flow_type: str, ratio_outer_to_inner_area: float, **kwargs)[source]
+

Bases: HeatExchanger, ABC

+

Moving boundary NTU based heat exchanger.

+

See parent class for more arguments.

+
+
Args:
+
flow_type (str):

Counter, Cross or parallel flow

+
+
ratio_outer_to_inner_area (float):

The NTU method uses the overall heat transfer coefficient k +and multiplies it with the outer area A (area of the secondary side). +However, depending on the heat exchanger type, the areas may +differ drastically. For instance in an air-to-water heat exchanger. +The VDI-Atlas proposes the ratio of outer area to inner pipe area +to account for this mismatch in sizes. +The calculation follows the code in the function calc_k. +Typical values are around 20-30.

+
+
+
+
+
+
+static calc_NTU(A: float, k: float, m_flow_cp: float) float[source]
+

Calculate the Number of Transfer Units (NTU) for the heat exchanger.

+
+
Args:

A (float): Area of the heat exchanger. +k (float): Overall heat transfer coefficient. +m_flow_cp (float): Minimal heat capacity rates (m_flow*cp) between primary and secondary side.

+
+
Returns:

float: Number of Transfer Units (NTU).

+
+
+
+ +
+
+calc_Q_ntu(dT_max: float, alpha_pri: float, alpha_sec: float, A: float) -> (<class 'float'>, <class 'float'>)[source]
+

Calculate the heat transfer and overall heat transfer coefficient for the heat exchanger based on NTU.

+
+
Args:

dT_max (float): Maximum temperature differential. +alpha_pri (float): Heat transfer coefficient for the primary medium. +alpha_sec (float): Heat transfer coefficient for the secondary medium. +A (float): Area of the heat exchanger.

+
+
Returns:

Tuple[float, float]: Heat transfer and overall heat transfer coefficient.

+
+
+
+ +
+
+calc_R() float[source]
+

Calculate the R value, which is the ratio of heat capacity rates (m_flow*cp) of the primary to secondary medium.

+
+
Returns:

float: R value.

+
+
+
+ +
+
+calc_eps(R: float, NTU: float) float[source]
+

Calculate the effectiveness (eps) of the heat exchanger based on NTU.

+

Source of implementation: EBC Lecture SimModelle.

+
+
Args:

R (float): Ratio of heat capacity rates (m_flow*cp) of the primary to secondary medium. +NTU (float): Number of Transfer Units.

+
+
Returns:

float: Effectiveness (eps) of the heat exchanger.

+
+
+
+ +
+
+calc_k(alpha_pri: float, alpha_sec: float) float[source]
+

Calculate the overall heat transfer coefficient (k) of the heat exchanger.

+
+
Args:

alpha_pri (float): Heat transfer coefficient for the primary medium. +alpha_sec (float): Heat transfer coefficient for the secondary medium.

+
+
Returns:

float: Overall heat transfer coefficient (k).

+
+
+
+ +
+
+calc_m_flow_cp_min() float[source]
+

Calculate the minimum value between the heat capacity rates (m_flow*cp) for the primary and secondary mediums.

+
+
Returns:

float: Minimum value.

+
+
+
+ +
+
+set_primary_cp(cp: float)[source]
+

Set the specific heat (cp) for the primary medium.

+
+
Args:

cp (float): Specific heat for the primary medium.

+
+
+
+ +
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.components.html b/docs/0.1.1/docs/code/vclibpy.components.html new file mode 100644 index 0000000..aa0482a --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.components.html @@ -0,0 +1,436 @@ + + + + + + + + + vclibpy.components package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy.components package

+
+

Subpackages

+
+ +
+
+
+

Submodules

+
+
+

vclibpy.components.component module

+
+
+class vclibpy.components.component.BaseComponent[source]
+

Bases: ABC

+

Abstract base class for defining interfaces of components in the vapor compression cycle.

+
+
Methods:
+
start_secondary_med_prop():

To use multiprocessing, MedProp can’t start in the main thread, as the object can’t be pickled. +This function starts possible secondary MedProp classes, for instance in heat exchangers. +The default component does not have to override this function.

+
+
+
+
Properties:
+
state_inlet (ThermodynamicState):

Property for accessing and setting the inlet state of the component.

+
+
state_outlet (ThermodynamicState):

Property for accessing and setting the outlet state of the component.

+
+
m_flow (float):

Property for accessing and setting the mass flow rate through the component.

+
+
med_prop (MedProp):

Property for accessing and setting the property wrapper for the working fluid.

+
+
+
+
+
+
+property m_flow: float
+

Get or set the mass flow rate through the component.

+
+
Returns:

float: Mass flow rate through the component.

+
+
+
+ +
+
+property med_prop: MedProp
+

Get or set the property wrapper for the working fluid.

+
+
Returns:

MedProp: Property wrapper for the working fluid.

+
+
+
+ +
+
+start_secondary_med_prop()[source]
+

Start secondary MedProp classes for multiprocessing.

+

To use multiprocessing, MedProp can’t start in the main thread, as the object can’t be pickled. +This function starts possible secondary MedProp classes, for instance in heat exchangers. +The default component does not have to override this function.

+
+ +
+
+property state_inlet: ThermodynamicState
+

Get or set the inlet state of the component.

+
+
Returns:

ThermodynamicState: Inlet state of the component.

+
+
+
+ +
+
+property state_outlet: ThermodynamicState
+

Get or set the outlet state of the component.

+
+
Returns:

ThermodynamicState: Outlet state of the component.

+
+
+
+ +
+
+terminate_secondary_med_prop()[source]
+

To use multi-processing, MedProp can’t start +in the main thread, as the object can’t be pickled.

+

This function terminates possible secondary med-prop +classes, for instance in heat exchangers. +The default component does not have to override +this function.

+
+ +
+ +
+
+

vclibpy.components.phase_separator module

+

Module with a simple phase separator model.

+
+
+class vclibpy.components.phase_separator.PhaseSeparator[source]
+

Bases: BaseComponent

+

A simple phase separator model.

+
+
+property state_inlet: ThermodynamicState
+

Get or set the inlet state of the component.

+
+
Returns:

ThermodynamicState: Inlet state of the component.

+
+
+
+ +
+
+property state_outlet: ThermodynamicState
+

Get or set the outlet state of the component.

+
+
Returns:

ThermodynamicState: Outlet state of the component.

+
+
+
+ +
+
+property state_outlet_liquid: ThermodynamicState
+

Getter for the outlet state of the liquid phase.

+
+
Returns:

ThermodynamicState: Outlet state for the liquid phase.

+
+
+
+ +
+
+property state_outlet_vapor: ThermodynamicState
+

Getter for the outlet state of the vapor phase.

+
+
Returns:

ThermodynamicState: Outlet state for the vapor phase.

+
+
+
+ +
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.flowsheets.html b/docs/0.1.1/docs/code/vclibpy.flowsheets.html new file mode 100644 index 0000000..fe26241 --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.flowsheets.html @@ -0,0 +1,146 @@ + + + + + + + + + vclibpy.flowsheets package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy.flowsheets package

+
+

Submodules

+
+
+

vclibpy.flowsheets.base module

+
+
+

vclibpy.flowsheets.standard module

+
+
+

vclibpy.flowsheets.vapor_injection module

+
+
+

vclibpy.flowsheets.vapor_injection_economizer module

+
+
+

vclibpy.flowsheets.vapor_injection_phase_separator module

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.html b/docs/0.1.1/docs/code/vclibpy.html new file mode 100644 index 0000000..f9ceb4b --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.html @@ -0,0 +1,515 @@ + + + + + + + + + vclibpy package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy package

+

Package for stationary vapor compression models and their analysis

+
+

Subpackages

+
+ +
+
+
+

Submodules

+
+
+

vclibpy.datamodels module

+

Module which contains datamodels which are used in this library.

+
+
+class vclibpy.datamodels.FlowsheetState[source]
+

Bases: VariableContainer

+

This class is used to define the unique states of the flowsheet +in the heat pump.

+

The class is dynamic in the sense that attributes may be +added during calculation of new flowsheet. This enables +the easy adding of custom values to analyze the whole flowsheet +and not restrict to a certain naming convention.

+
+ +
+
+class vclibpy.datamodels.Inputs(n: float | None = None, T_eva_in: float | None = None, T_con_in: float | None = None, m_flow_eva: float | None = None, m_flow_con: float | None = None, dT_eva_superheating: float | None = None, dT_con_subcooling: float | None = None, T_ambient: float | None = None)[source]
+

Bases: VariableContainer

+

Class defining inputs to calculate the FlowsheetState.

+

While the inputs are pre-defined, you may add further ones +using the set method.

+
+
Args:

n (float): Relative compressor speed between 0 and 1. +T_eva_in (float): Secondary side evaporator inlet temperature. +T_con_in (float): Secondary side condenser inlet temperature. +m_flow_eva (float): Secondary side evaporator mass flow rate. +m_flow_con (float): Secondary side condenser mass flow rate. +dT_eva_superheating (float): Super-heating after evaporator. +dT_con_subcooling (float): Subcooling after condenser. +T_ambient (float): Ambient temperature of the machine.

+
+
+
+ +
+
+class vclibpy.datamodels.Variable(name: str, value: float, unit: str | None = None, description: str | None = None)[source]
+

Bases: object

+

Class for a variable used in analysis.

+
+
Args:

name (str): The name of the variable. +value (float): The numerical value of the variable. +unit (str): The unit of measurement for the variable (optional). +description (str): A description of the variable (optional).

+
+
+
+
+description: str = None
+
+ +
+
+name: str
+
+ +
+
+unit: str = None
+
+ +
+
+value: float
+
+ +
+ +
+
+class vclibpy.datamodels.VariableContainer[source]
+

Bases: object

+

Class which holds Variables to be used anywhere in the models.

+

This class enables dynamic addition of Variables.

+
+
+convert_to_str_value_format(with_unit_and_description: bool) Dict[str, float][source]
+

Returns a dictionary with a str: float format which is handy when storing results +in files like .csv or .xlsx.

+
+
Args:

with_unit_and_description (bool): When False, only the name is in the string.

+
+
Returns:

dict: Containing all variables and values.

+
+
+
+ +
+
+copy()[source]
+

Return a deepcopy of the instance as the variable dict is mutable.

+
+
Returns:

VariableContainer: A deepcopy of the VariableContainer instance.

+
+
+
+ +
+
+get(name: str, default: Any | None = None)[source]
+

Get the Variable with the specified name.

+
+
Args:

name (str): The name of the variable. +default (Any): Default value to return if the variable is not found.

+
+
Returns:

Variable: The Variable object.

+
+
+
+ +
+
+get_variable_names() list[source]
+

Get the names of all variables in the container.

+
+
Returns:

list: A list of variable names.

+
+
+
+ +
+
+get_variables()[source]
+

Get all variables in the container.

+
+
Returns:

Dict[str, Variable]: A dictionary of variable names and Variable objects.

+
+
+
+ +
+
+items()[source]
+

Get items from the container.

+
+
Returns:

Dict[str, Variable]: A dictionary of variable names and Variable objects.

+
+
+
+ +
+
+set(name: str, value: float, unit: str | None = None, description: str | None = None)[source]
+

Add or update a Variable in the container.

+
+
Args:

name (str): The name of the variable. +value (float): The numerical value of the variable. +unit (str): The unit of measurement for the variable (optional). +description (str): A description of the variable (optional).

+
+
+
+ +
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.media.html b/docs/0.1.1/docs/code/vclibpy.media.html new file mode 100644 index 0000000..cf30782 --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.media.html @@ -0,0 +1,1990 @@ + + + + + + + + + vclibpy.media package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy.media package

+
+
+class vclibpy.media.CoolProp(fluid_name, use_high_level_api: bool = False)[source]
+

Bases: MedProp

+

Class using the open-source CoolProp package +to access the properties.

+
+
Args:
+
use_high_level_api (bool):

True to use the high-level api, which is much slower, +but you can use all modes in calc_state. +Default is False.

+
+
+
+
+
+
+calc_state(mode: str, var1: float, var2: float)[source]
+

Calculate the thermodynamic state based on the specified mode and state variables.

+

This function calculates the thermodynamic state based on the chosen mode and provided state variables. +The input state variables need to be in SI units.

+
+
Notes:
    +
  • PT does not work when the state might fall within the two-phase region.

  • +
  • Only functions for density are implemented. In cases where you know the specific volume, use the density +functions with the inverse value.

  • +
  • +
    Quality (q) may have values outside the ‘physical’ scope:
      +
    • q = -998: Subcooled liquid

    • +
    • q = 998: Superheated vapor

    • +
    • q = 999: Supercritical state

    • +
    +
    +
    +
  • +
+
+
Possible modes include:
    +
  • “PD”: Pressure, Density

  • +
  • “PH”: Pressure, Enthalpy

  • +
  • “PQ”: Pressure, Quality

  • +
  • “PS”: Pressure, Entropy

  • +
  • “PT”: Pressure, Temperature

  • +
  • “PU”: Pressure, Internal Energy

  • +
  • “TD”: Temperature, Density

  • +
  • “TH”: Temperature, Enthalpy

  • +
  • “TQ”: Temperature, Quality

  • +
  • “TS”: Temperature, Entropy

  • +
  • “TU”: Temperature, Internal Energy

  • +
  • “DH”: Density, Enthalpy

  • +
  • “DS”: Density, Entropy

  • +
  • “DU”: Density, Internal Energy

  • +
+
+
Args:

mode (str): Defines the given input state variables (see possible modes above). +var1 (float): Value of the first state variable (as specified in the mode) in SI units. +var2 (float): Value of the second state variable (as specified in the mode) in SI units.

+
+
Returns:

ThermodynamicState: A ThermodynamicState instance with state variables.

+
+
Raises:

AssertionError: If the given mode is not within the available options.

+
+
+
+ +
+
+calc_transport_properties(state: ThermodynamicState)[source]
+

Calculate the transport properties for the given state.

+
+
Args:

state (ThermodynamicState): The current thermodynamic state.

+
+
Returns:

TransportProperties: An instance of TransportProperties.

+
+
+
+ +
+
+get_critical_point()[source]
+

Retrieve critical point information for the fluid.

+
+
Returns:

Tuple[float, float, float]: A tuple containing critical point information +(Temperature Tc [K], Pressure pc [Pa], Density dc [kg/m^3]).

+
+
+
+ +
+
+get_molar_mass()[source]
+

Retrieve the molar mass of the current fluid.

+
+
Returns:

float: The molar mass M of the current fluid in kg/mol.

+
+
+
+ +
+ +
+
+class vclibpy.media.MedProp(fluid_name)[source]
+

Bases: ABC

+

Base class for all media property interfaces.

+

This class serves as the base for defining interfaces to access and compute media properties.

+
+
Methods:

calc_state: Calculate the thermodynamic state based on mode and state variables. +calc_transport_properties: Calculate transport properties for a given state. +get_critical_point: Retrieve critical point information. +get_molar_mass: Retrieve molar mass information. +get_two_phase_limits: Retrieve the two-phase limits for plotting. +calc_mean_transport_properties: Calculate the average transport properties for given states.

+
+
+
+
+calc_mean_transport_properties(state_in, state_out)[source]
+

Calculate the average transport properties for the given states.

+
+
Args:

state_in (ThermodynamicState): First state +state_out (ThermodynamicState): Second state

+
+
Returns:

TransportProperties: Average transport properties

+
+
Notes:

The TransportProperties does not contain a state, as an average +state is not possible to calculate.

+
+
+
+ +
+
+calc_state(mode: str, var1: float, var2: float)[source]
+

Calculate the thermodynamic state based on the specified mode and state variables.

+

This function calculates the thermodynamic state based on the chosen mode and provided state variables. +The input state variables need to be in SI units.

+
+
Notes:
    +
  • PT does not work when the state might fall within the two-phase region.

  • +
  • Only functions for density are implemented. In cases where you know the specific volume, use the density +functions with the inverse value.

  • +
  • +
    Quality (q) may have values outside the ‘physical’ scope:
      +
    • q = -998: Subcooled liquid

    • +
    • q = 998: Superheated vapor

    • +
    • q = 999: Supercritical state

    • +
    +
    +
    +
  • +
+
+
Possible modes include:
    +
  • “PD”: Pressure, Density

  • +
  • “PH”: Pressure, Enthalpy

  • +
  • “PQ”: Pressure, Quality

  • +
  • “PS”: Pressure, Entropy

  • +
  • “PT”: Pressure, Temperature

  • +
  • “PU”: Pressure, Internal Energy

  • +
  • “TD”: Temperature, Density

  • +
  • “TH”: Temperature, Enthalpy

  • +
  • “TQ”: Temperature, Quality

  • +
  • “TS”: Temperature, Entropy

  • +
  • “TU”: Temperature, Internal Energy

  • +
  • “DH”: Density, Enthalpy

  • +
  • “DS”: Density, Entropy

  • +
  • “DU”: Density, Internal Energy

  • +
+
+
Args:

mode (str): Defines the given input state variables (see possible modes above). +var1 (float): Value of the first state variable (as specified in the mode) in SI units. +var2 (float): Value of the second state variable (as specified in the mode) in SI units.

+
+
Returns:

ThermodynamicState: A ThermodynamicState instance with state variables.

+
+
Raises:

AssertionError: If the given mode is not within the available options.

+
+
+
+ +
+
+abstract calc_transport_properties(state: ThermodynamicState)[source]
+

Calculate the transport properties for the given state.

+
+
Args:

state (ThermodynamicState): The current thermodynamic state.

+
+
Returns:

TransportProperties: An instance of TransportProperties.

+
+
+
+ +
+
+abstract get_critical_point()[source]
+

Retrieve critical point information for the fluid.

+
+
Returns:

Tuple[float, float, float]: A tuple containing critical point information +(Temperature Tc [K], Pressure pc [Pa], Density dc [kg/m^3]).

+
+
+
+ +
+
+abstract get_molar_mass()[source]
+

Retrieve the molar mass of the current fluid.

+
+
Returns:

float: The molar mass M of the current fluid in kg/mol.

+
+
+
+ +
+
+get_two_phase_limits(quantity: str, p_min: int = 100000, p_step: int = 5000)[source]
+

Retrieve the two-phase limits for plotting a specified quantity.

+

This method returns the two-phase limits for a specified quantity (T, h, s, or p) in an array used for +plotting purposes. It calculates the limits within the pressure range from p_min and quality (q) 0 to the +critical pressure (pc), and then from the critical pressure to the pressure p_min and quality 1.

+
+
Args:

quantity (str): The specified quantity (T, h, s, or p). +p_min (int, optional): The minimum pressure value to start iteration. Default is 100000 Pa. +p_step (int, optional): The step size for pressure variation. Default is 5000 Pa.

+
+
Returns:

numpy.ndarray: An array containing the two-phase limits for the specified quantity.

+
+
Raises:

ValueError: If the given quantity is not supported (T, h, s, or p).

+
+
+
+ +
+
+terminate()[source]
+

Terminate the class. +Default behaviour does nothing.

+
+ +
+ +
+
+class vclibpy.media.RefProp(fluid_name, z=None, dll_path: str | None = None, use_error_check: bool = True, use_warnings: bool = True, ref_prop_path: str | None = None, copy_dll: bool = True, copy_dll_directory: str | None = None)[source]
+

Bases: MedProp

+

Class to connect to refProp package.

+

Args: +:param string fluid_name:

+
+

Fluid name for RefProp use

+
+
+
Parameters:
+
    +
  • z (list or None) – Fluid composition. Should only be used, when a self-design mixture shall be used. Further information +see notes. +When you want to use a self-design mixture to as follows: +- Fluid-name needs to contain all component names within mixture: “R32.FLD|R125.FLD” +- z needs to be a list with molar fractions: [0.697, 0.303] +- Used example would be similar to R410A

  • +
  • dll_path (string) – Specifier for the dll path used for RefProp, +e.g. dll_path=’C:path_to_dllRefProp64.dll’. +If None, the ref_prop_path and function get_dll_path are +used to determine the dll path

  • +
  • use_error_check (boolean) – Specifier whether errors and warnings shall be checked when calling RefProp or not

  • +
  • use_warnings (boolean) – Specifier whether warnings shall be used

  • +
  • ref_prop_path (str) – Path to RefProp package. Default is the ENV variable RPPREFIX.

  • +
  • copy_dll (bool) – If True (not the default), a copy of the dll is created to enable simultaneous use of +multiple fluids in multiprocessing.

  • +
  • copy_dll_directory (str) – If copy_dll is True, the DLL is copied to this directory. +If None (default), the current working directory is used.

  • +
+
+
+
+
Note:
+
+
Functionality:
    +
  • +
    It does not work to have multiple instances simultaneously. When calculating values the last fluid name

    somehow will be used even though instance includes “new” name. Need to be fixed at some point.

    +
    +
    +
  • +
+
+
+
+

How to use RefProp-Wrapper:

+

1.) Create RefProp instance: rp = RefProp(“R32”) +2.) In case you want to calculate fluid properties (state variables) for a specific state: Use calc_state() function

+
+

Multiple inputs can be given (but you need to now two in order to define the values). For further +information see function header.

+
+
+
3.) Further get-Functions implemented
    +
  • get_gwp(): Global warming potential

  • +
  • get_odp(): Ozone depletion potential

  • +
  • get_safety(): Safety class

  • +
  • get_mass_fraction(): Mass fractions of pure substances in fluid

  • +
  • get_molar_mass(): Molar mass of fluid

  • +
  • get_mol_fraction(): Mol fractions of pure substances in fluid

  • +
  • get_comp_names(): Pure substances names in fluid

  • +
  • get_longname(): Long name of fluid within RefProp

  • +
  • get_critical_point(): Crit. Temperature and Pressure

  • +
  • get_version(): Version of wrapper and of RefProp dll

  • +
+
+
+
+
+

Version notes:

+
+
0.1.0 (21.04.2020, Christoph Hoeges):
+
First implementation
    +
  • Contains multiple functions to call RefProp instance

  • +
  • Can calculate state, crit, GWP, ODP, Safety class, molar mass etc. of fluid

  • +
  • Mixtures might work but it wasn’t fully testet - R455A e.g. still deviates slightly

  • +
+
+
+
+
0.1.1 (25.04.2020, Christoph Hoeges):
+
Multiple changes, added functionality. Commands are still the same though
    +
  • Self designed mixtures are possible now as well (see instructions in init

  • +
  • Added composition input to __init__ function

  • +
  • Added modes in calc_state function and removed bug in PH calculation

  • +
  • Additional protected functions due to different input

  • +
  • Adjusted _call_refprop function (z is not mass frac but mol fraction)

  • +
  • Added documentation / instruction

  • +
+
+
+
+
0.1.2 (08.05.2020, Christoph Hoeges):
+
Multiple adjustments
    +
  • Added function to call ABFLSHdll function in refprop (high level function)

  • +
  • Changed function calls in calc_state function to ABFLSH and adjusted conversion

  • +
  • Change init-function so user can choose which dll shall be used

  • +
  • Add function to get version of this current wrapper as well as RefProp-dll version

  • +
+
+
+
+
0.1.3 (12.05.2020, Christoph Hoeges):
+
Multiple changes
    +
  • Added function to get all files in MIXTURE and FLUIDS directory to check available fluids

  • +
  • +
    Added error function in order to return errors when RefProp-Functions are called.
    +
    NOTE: Not all instances where refprop is called are checked for errors. Currently, it is only used in

    init and calc_state

    +
    +
    +
    +
    +
  • +
+
+
+
+
0.1.4 (19.05.2020, Christoph Hoeges):
+
Multiple changes:
    +
  • Debugged fluid properties calculation for predefined mixtures

  • +
  • Fixed option of self-defined mixtures

  • +
+
+
+
+
0.1.5 (22.05.2020, Christoph Hoeges):

Include transport properties calculation into wrapper

+
+
0.1.6 (10.06.2020, Fabian Wuellhorst):

Add option to use a custom dll path. This necessary to use multiple instances with possible +different fluids at the same time.

+
+
+
+
+calc_satliq_state(s)[source]
+

s in kJ/kgK

+
+ +
+
+calc_state(mode: str, var1: float, var2: float, kr=1)[source]
+

Calculate state. Depending on mode, different function will be chosen. Input state variables need to be in +SI units!

+
+

Notes:

+

1.) PT does not work when state might be within the two-phase region! +2.) Only functions for density are implemented. In case you know the specific volume instead use density

+
+

functions with inverse value!

+
+
+
3.) Quality can have values outside of ‘physical’ scope:

q = -998: Subcooled liquid +q = 998: Superheated vapor +q = 999: Supercritical state

+
+
Possible modes are currently:
    +
  • “PD”: Pressure, Density

  • +
  • “PH”: Pressure, Enthalpy

  • +
  • “PQ”: Pressure, Quality

  • +
  • “PS”: Pressure, Entropy

  • +
  • “PT”: Pressure, Temperature

  • +
  • “PU”: Pressure, Internal Energy

  • +
  • “TD”: Temperature, Density

  • +
  • “TH”: Temperature, Enthalpy

  • +
  • “TQ”: Temperature, Quality

  • +
  • “TS”: Temperature, Entropy

  • +
  • “TU”: Temperature, Internal Energy

  • +
  • “DH”: Density, Enthalpy

  • +
  • “DS”: Density, Entropy

  • +
  • “DU”: Density, Internal Energy

  • +
  • “HS”: Enthalpy, Entropy

  • +
+
+
+
+
+

Parameters:

+
+
param string mode:
+

Defines which input state variables are given (see possible modes above)

+
+
param float var1:
+

Value of state variable 1 (first one in name) - use SI units!

+
+
param float var2:
+

Value of state variable 2 (second one in name) - use SI units!

+
+
param int kr:
+

phase flag (kr=1: lower density, kr=2: higher density) +relevant for “TH”, “TS”, “TU”

+
+
+
+
+

Return:

+
+
return ThermodynamicState state:
+

Thermodynamic state with state variables

+
+
+
+
+ +
+
+calc_transport_properties(state: ThermodynamicState)[source]
+

Calculate transport properties of RefProp fluid at given state

+
+

Parameters:

+
+
param ThermodynamicState state:
+

Current thermodynamic state

+
+
+
+
+

Return:

+
+
return TransportProperties props:
+

Instance of TransportProperties

+
+
+
+
+ +
+
+get_available_substances(mode='all', include_ending=False, save_txt=False)[source]
+

Get all available RefProp fluids (mixtures and / or pure substances depending on mode)

+
+

Parameters:

+
+
param string mode:
+

Mode defining which kind of fluids you want to have: ‘pure’: pure substances, ‘mix’: mixtures, ‘all’: all

+
+
param boolean include_ending:
+

Defines, whether file ending shall be returned as well or not

+
+
param boolean save_txt:
+

Defines, whether a text file with names shall be created in current working directory

+
+
+
+
+

Return:

+
+
return list names:
+

String list containing names of available fluids (depending on defined mode)

+
+
+
+
+ +
+
+get_comp_names()[source]
+

Get name of components within current fluid”

+
+

Return:

+
+
return list comp_names:
+

String names of components within current fluid

+
+
+
+
+ +
+
+get_critical_point()[source]
+

Get T and p of critical point

+
+

Return:

+
+
return float Tc:
+

Temperature at critical point in K

+
+
return float pc:
+

Pressure at critical point in Pa

+
+
return float dc:
+

Density at critical point in kg/m^3

+
+
+
+
+ +
+
+get_def_limits()[source]
+

Get limits of current ref prop fluid +Limits contain Tmin, Tmax, Dmax and Pmax (Temperatures, density, pressure)

+
+
Return dict limits:
+

Dictionary with definition limits in RefProp. Contains min/max temperature, max density, max pressure.

+
+
+
+ +
+
+static get_dll_path(ref_prop_path: str)[source]
+

Return the location of the dll

+

Return: +:return: string path_to_dll:

+
+

Path of a valid dll

+
+
+ +
+
+get_fluid_name()[source]
+

Get fluid name.

+
+

Return:

+
+
return string fluid_name:
+

Fluid name

+
+
+
+
+ +
+
+get_gwp()[source]
+

Get gwp of current fluid from refProp

+
+

Return:

+
+
return float gwp:
+

Global warming potential of fluid. In case calculation failed, None will be returned.

+
+
+
+
+ +
+
+get_longname()[source]
+

Get longname of fluid

+
+

Return:

+
+
return string longname:
+

Name of current fluid in refprop - provides mass fractions and components as well (in case of mixture)

+
+
+
+
+ +
+
+get_mass_fraction(use_round=True)[source]
+

Get mass fractions of pure substances in current fluid

+

Parameters: +:param boolean use_round:

+
+

Flag to define, whether the exact values or rounded values (by the fourth number) shall be used

+
+
+

Return:

+
+
return list mass_frac:
+

List of component mass fractions

+
+
+
+
+ +
+
+get_mol_fraction(use_round=True)[source]
+

Get mol fractions of pure substances in current fluid

+

Parameters: +:param boolean use_round:

+
+

Flag to define, whether the exact values or rounded values (by the fourth number) shall be used

+
+
+

Return:

+
+
return list frac:
+

List of component mol fractions

+
+
+
+
+ +
+
+get_molar_composition(state: ThermodynamicState, z_molar=None)[source]
+

Get composition on molar base. Liquid phase, vapor phase and total.

+
+
Parameters:
+
    +
  • state (ThermodynamicState) – the state whose compositions will be returned

  • +
  • z_molar (list) – molar composition of fluid. In case of None, default value _mol_frac is used

  • +
+
+
Returns:
+

    +
  • +
    list x:

    composition of liquid phase

    +
    +
    +
  • +
  • +
    list y:

    composition of vapor phase

    +
    +
    +
  • +
  • +
    list z:

    composition in total

    +
    +
    +
  • +
+

+
+
+
+ +
+
+get_molar_mass()[source]
+

Get molar mass of current fluid

+
+

Return:

+
+
return float M:
+

Molar mass of current fluid in kg/mol

+
+
+
+
+ +
+
+get_nbp()[source]
+

Get normal boiling point (T @ q=0 and 1 bar)

+
+

Return:

+
+
return float nbp:
+

Normal boiling point of refrigerant in °C

+
+
+
+
+ +
+
+get_odp()[source]
+

Calculate ozone depletion potential +In case of mixtures: Maximum value of pure substances will be used

+
+

Return:

+
+
return float odp:
+

ODP of fluid. In case calculation failed, None will be returned.

+
+
+
+
+ +
+
+get_safety()[source]
+

Calculate safety class of refrigerant

+
+

Return:

+
+
return string safety:
+

Safety class of fluid.

+
+
+
+
+ +
+
+get_sat_vap_pressure(T_sat)[source]
+

Get pressure of saturated vapor for defined temperature

+
+
Note:
    +
  • works for vapor, liquid and solid

  • +
  • returns equilibrium pressure at defined line (q=1)

  • +
+
+
+

Parameters: +:param float T_sat:

+
+

Temperature in K

+
+

Return: +:return float p_sat:

+
+

Vapor pressure in Pa

+
+
+ +
+
+get_triple_point()[source]
+

Get temperature and pressure at triple point of current fluid

+

Note: Works fine for pure substances, mixtures might not work properly

+

Return: +:return float T_tpl:

+
+

Temperature at triple point in K

+
+
+
Return float p_tpl:
+

Pressure at triple point in Pa

+
+
+
+ +
+
+get_version()[source]
+

Get version of wrapper and used RefProp dll

+

Return: +:return string wrapper_version:

+
+

Refprop wrapper version

+
+
+
Return string refprop_version:
+

Version of used RefProp dll

+
+
+
+ +
+
+is_mixture()[source]
+

Find out if fluid is mixture or not. +In case current fluid is mixture, true is returned. +In case current fluid is pure substance, false is returned.

+
+

Return:

+
+
return boolean _mix_flag:
+

Boolean for mixture (True), pure substance (False)

+
+
+
+
+ +
+
+set_error_flag(flag)[source]
+

Set error flag

+

Parameters: +:param boolean flag:

+
+

New error flag

+
+

Return: +:return int err:

+
+

Notifier for error code - in case everything went fine, 0 is returned

+
+
+ +
+
+set_warning_flag(flag)[source]
+

Set warning flag

+

Parameters: +:param boolean flag:

+
+

New warning flag

+
+

Return: +:return int err:

+
+

Notifier for error code - in case everything went fine, 0 is returned

+
+
+ +
+
+terminate()[source]
+

Terminate the class. +Default behaviour does nothing.

+
+ +
+
+ +
+
+class vclibpy.media.ThermodynamicState(p=None, T=None, u=None, h=None, s=None, v=None, q=None, d=None)[source]
+

Bases: object

+

Represents a thermodynamic state within a cycle.

+
+
Notes:

Does not necessarily need to have all state variables defined!

+
+
Args:

p (float): Pressure at the state in Pa. +T (float): Temperature at the state in K. +u (float): Inner energy at the state in J/kg. +h (float): Enthalpy at the state in J/kg. +s (float): Entropy at the state in J/(kg * K). +v (float): Specific volume at the state in m^3/kg. +q (float): Quality at the state (between 0 and 1). +d (float): Density at the state in kg/m^3.

+
+
Methods:

__init__: Initializes the state class. +__str__: Provides a string representation of the state. +get_pretty_print: Formats the state with names, units, and descriptions.

+
+
+
+
+get_pretty_print()[source]
+

Provides a formatted representation of the state with names, units, and descriptions.

+
+ +
+ +
+
+class vclibpy.media.TransportProperties(lam=None, dyn_vis=None, kin_vis=None, pr=None, cp=None, cv=None, beta=None, sur_ten=None, ace_fac=None, state=None)[source]
+

Bases: object

+

Represents transport properties at a specific thermodynamic state.

+
+
Args:

lam (float): Thermal conductivity in W/(m*K). +dyn_vis (float): Dynamic viscosity in Pa*s. +kin_vis (float): Kinematic viscosity in m^2/s. +Pr (float): Prandtl number. +cp (float): Isobaric specific heat capacity in J/(kg*K). +cv (float): Isochoric specific heat capacity in J/(kg*K). +beta (float): Thermal expansion coefficient in 1/K. +sur_ten (float): Surface tension in N/m. +ace_fac (float): Acentric factor. +state (ThermodynamicState): The state the transport properties belong to.

+
+
Methods:

__init__: Initializes the transport properties class. +__str__: Provides a string representation of the transport properties. +get_pretty_print: Formats the properties with names, units, and descriptions.

+
+
+
+
+get_pretty_print()[source]
+

Provides a formatted representation of the properties with names, units, and descriptions.

+
+ +
+ +
+

Submodules

+
+
+

vclibpy.media.cool_prop module

+

Module with cool prop wrapper.

+
+
+class vclibpy.media.cool_prop.CoolProp(fluid_name, use_high_level_api: bool = False)[source]
+

Bases: MedProp

+

Class using the open-source CoolProp package +to access the properties.

+
+
Args:
+
use_high_level_api (bool):

True to use the high-level api, which is much slower, +but you can use all modes in calc_state. +Default is False.

+
+
+
+
+
+
+calc_state(mode: str, var1: float, var2: float)[source]
+

Calculate the thermodynamic state based on the specified mode and state variables.

+

This function calculates the thermodynamic state based on the chosen mode and provided state variables. +The input state variables need to be in SI units.

+
+
Notes:
    +
  • PT does not work when the state might fall within the two-phase region.

  • +
  • Only functions for density are implemented. In cases where you know the specific volume, use the density +functions with the inverse value.

  • +
  • +
    Quality (q) may have values outside the ‘physical’ scope:
      +
    • q = -998: Subcooled liquid

    • +
    • q = 998: Superheated vapor

    • +
    • q = 999: Supercritical state

    • +
    +
    +
    +
  • +
+
+
Possible modes include:
    +
  • “PD”: Pressure, Density

  • +
  • “PH”: Pressure, Enthalpy

  • +
  • “PQ”: Pressure, Quality

  • +
  • “PS”: Pressure, Entropy

  • +
  • “PT”: Pressure, Temperature

  • +
  • “PU”: Pressure, Internal Energy

  • +
  • “TD”: Temperature, Density

  • +
  • “TH”: Temperature, Enthalpy

  • +
  • “TQ”: Temperature, Quality

  • +
  • “TS”: Temperature, Entropy

  • +
  • “TU”: Temperature, Internal Energy

  • +
  • “DH”: Density, Enthalpy

  • +
  • “DS”: Density, Entropy

  • +
  • “DU”: Density, Internal Energy

  • +
+
+
Args:

mode (str): Defines the given input state variables (see possible modes above). +var1 (float): Value of the first state variable (as specified in the mode) in SI units. +var2 (float): Value of the second state variable (as specified in the mode) in SI units.

+
+
Returns:

ThermodynamicState: A ThermodynamicState instance with state variables.

+
+
Raises:

AssertionError: If the given mode is not within the available options.

+
+
+
+ +
+
+calc_transport_properties(state: ThermodynamicState)[source]
+

Calculate the transport properties for the given state.

+
+
Args:

state (ThermodynamicState): The current thermodynamic state.

+
+
Returns:

TransportProperties: An instance of TransportProperties.

+
+
+
+ +
+
+get_critical_point()[source]
+

Retrieve critical point information for the fluid.

+
+
Returns:

Tuple[float, float, float]: A tuple containing critical point information +(Temperature Tc [K], Pressure pc [Pa], Density dc [kg/m^3]).

+
+
+
+ +
+
+get_molar_mass()[source]
+

Retrieve the molar mass of the current fluid.

+
+
Returns:

float: The molar mass M of the current fluid in kg/mol.

+
+
+
+ +
+ +
+
+

vclibpy.media.media module

+

Module with wrappers to access and handle media property databases.

+

This module provides interfaces to load media properties using various wrappers and +handle calculations related to media properties.

+
+
Classes:

MedProp: Base class for all media property interfaces.

+
+
Functions:

get_two_phase_limits: Return the states of the boundaries of the two-phase section for a given fluid.

+
+
+
+
+class vclibpy.media.media.MedProp(fluid_name)[source]
+

Bases: ABC

+

Base class for all media property interfaces.

+

This class serves as the base for defining interfaces to access and compute media properties.

+
+
Methods:

calc_state: Calculate the thermodynamic state based on mode and state variables. +calc_transport_properties: Calculate transport properties for a given state. +get_critical_point: Retrieve critical point information. +get_molar_mass: Retrieve molar mass information. +get_two_phase_limits: Retrieve the two-phase limits for plotting. +calc_mean_transport_properties: Calculate the average transport properties for given states.

+
+
+
+
+calc_mean_transport_properties(state_in, state_out)[source]
+

Calculate the average transport properties for the given states.

+
+
Args:

state_in (ThermodynamicState): First state +state_out (ThermodynamicState): Second state

+
+
Returns:

TransportProperties: Average transport properties

+
+
Notes:

The TransportProperties does not contain a state, as an average +state is not possible to calculate.

+
+
+
+ +
+
+calc_state(mode: str, var1: float, var2: float)[source]
+

Calculate the thermodynamic state based on the specified mode and state variables.

+

This function calculates the thermodynamic state based on the chosen mode and provided state variables. +The input state variables need to be in SI units.

+
+
Notes:
    +
  • PT does not work when the state might fall within the two-phase region.

  • +
  • Only functions for density are implemented. In cases where you know the specific volume, use the density +functions with the inverse value.

  • +
  • +
    Quality (q) may have values outside the ‘physical’ scope:
      +
    • q = -998: Subcooled liquid

    • +
    • q = 998: Superheated vapor

    • +
    • q = 999: Supercritical state

    • +
    +
    +
    +
  • +
+
+
Possible modes include:
    +
  • “PD”: Pressure, Density

  • +
  • “PH”: Pressure, Enthalpy

  • +
  • “PQ”: Pressure, Quality

  • +
  • “PS”: Pressure, Entropy

  • +
  • “PT”: Pressure, Temperature

  • +
  • “PU”: Pressure, Internal Energy

  • +
  • “TD”: Temperature, Density

  • +
  • “TH”: Temperature, Enthalpy

  • +
  • “TQ”: Temperature, Quality

  • +
  • “TS”: Temperature, Entropy

  • +
  • “TU”: Temperature, Internal Energy

  • +
  • “DH”: Density, Enthalpy

  • +
  • “DS”: Density, Entropy

  • +
  • “DU”: Density, Internal Energy

  • +
+
+
Args:

mode (str): Defines the given input state variables (see possible modes above). +var1 (float): Value of the first state variable (as specified in the mode) in SI units. +var2 (float): Value of the second state variable (as specified in the mode) in SI units.

+
+
Returns:

ThermodynamicState: A ThermodynamicState instance with state variables.

+
+
Raises:

AssertionError: If the given mode is not within the available options.

+
+
+
+ +
+
+abstract calc_transport_properties(state: ThermodynamicState)[source]
+

Calculate the transport properties for the given state.

+
+
Args:

state (ThermodynamicState): The current thermodynamic state.

+
+
Returns:

TransportProperties: An instance of TransportProperties.

+
+
+
+ +
+
+abstract get_critical_point()[source]
+

Retrieve critical point information for the fluid.

+
+
Returns:

Tuple[float, float, float]: A tuple containing critical point information +(Temperature Tc [K], Pressure pc [Pa], Density dc [kg/m^3]).

+
+
+
+ +
+
+abstract get_molar_mass()[source]
+

Retrieve the molar mass of the current fluid.

+
+
Returns:

float: The molar mass M of the current fluid in kg/mol.

+
+
+
+ +
+
+get_two_phase_limits(quantity: str, p_min: int = 100000, p_step: int = 5000)[source]
+

Retrieve the two-phase limits for plotting a specified quantity.

+

This method returns the two-phase limits for a specified quantity (T, h, s, or p) in an array used for +plotting purposes. It calculates the limits within the pressure range from p_min and quality (q) 0 to the +critical pressure (pc), and then from the critical pressure to the pressure p_min and quality 1.

+
+
Args:

quantity (str): The specified quantity (T, h, s, or p). +p_min (int, optional): The minimum pressure value to start iteration. Default is 100000 Pa. +p_step (int, optional): The step size for pressure variation. Default is 5000 Pa.

+
+
Returns:

numpy.ndarray: An array containing the two-phase limits for the specified quantity.

+
+
Raises:

ValueError: If the given quantity is not supported (T, h, s, or p).

+
+
+
+ +
+
+terminate()[source]
+

Terminate the class. +Default behaviour does nothing.

+
+ +
+ +
+
+vclibpy.media.media.get_two_phase_limits(med_prop: MedProp, p_step: int = 1000, p_min: int = 1000) List[ThermodynamicState][source]
+

Return the states representing the boundaries of the two-phase section for the given fluid.

+

This function is primarily used for visualizing the two-phase section and validating the accuracy of calculations.

+
+
Args:

med_prop (MedProp): An instance of a valid MedProp-Class. +p_step (int): The step size for pressure variation in Pa. Default is 1000 Pa. +p_min (int): The minimum pressure in Pa from where to start calculation. Default is 1000 Pa.

+
+
Returns:

List[ThermodynamicState]: A list of ThermodynamicState instances representing the two-phase limits.

+
+
Notes:

The two-phase limits are computed by iterating over a range of pressures from the minimum pressure up to the +critical point pressure (exclusive) with a specified step size. States at quality 0 (saturated liquid) +and quality 1 (saturated vapor) are appended to form the two-phase boundary. The list is reversed to +maintain the correct order for visualization purposes.

+
+
+
+ +
+
+

vclibpy.media.ref_prop module

+

Created on 21.04.2020

+

@author: Christoph Hoeges, Fabian Wuellhorst, Jona Brach

+

To test: +- Transport properties are not fully tested (Status: 11.06.2020) +- Error raising is not implemented at all refprop calls

+
+
    +
  • +
    Additional change might be that not all errors and warning are excluded when ‘use_error_check’ is set to false but

    only warnings or errors?

    +
    +
    +
  • +
+
+
+
+class vclibpy.media.ref_prop.RefProp(fluid_name, z=None, dll_path: str | None = None, use_error_check: bool = True, use_warnings: bool = True, ref_prop_path: str | None = None, copy_dll: bool = True, copy_dll_directory: str | None = None)[source]
+

Bases: MedProp

+

Class to connect to refProp package.

+

Args: +:param string fluid_name:

+
+

Fluid name for RefProp use

+
+
+
Parameters:
+
    +
  • z (list or None) – Fluid composition. Should only be used, when a self-design mixture shall be used. Further information +see notes. +When you want to use a self-design mixture to as follows: +- Fluid-name needs to contain all component names within mixture: “R32.FLD|R125.FLD” +- z needs to be a list with molar fractions: [0.697, 0.303] +- Used example would be similar to R410A

  • +
  • dll_path (string) – Specifier for the dll path used for RefProp, +e.g. dll_path=’C:path_to_dllRefProp64.dll’. +If None, the ref_prop_path and function get_dll_path are +used to determine the dll path

  • +
  • use_error_check (boolean) – Specifier whether errors and warnings shall be checked when calling RefProp or not

  • +
  • use_warnings (boolean) – Specifier whether warnings shall be used

  • +
  • ref_prop_path (str) – Path to RefProp package. Default is the ENV variable RPPREFIX.

  • +
  • copy_dll (bool) – If True (not the default), a copy of the dll is created to enable simultaneous use of +multiple fluids in multiprocessing.

  • +
  • copy_dll_directory (str) – If copy_dll is True, the DLL is copied to this directory. +If None (default), the current working directory is used.

  • +
+
+
+
+
Note:
+
+
Functionality:
    +
  • +
    It does not work to have multiple instances simultaneously. When calculating values the last fluid name

    somehow will be used even though instance includes “new” name. Need to be fixed at some point.

    +
    +
    +
  • +
+
+
+
+

How to use RefProp-Wrapper:

+

1.) Create RefProp instance: rp = RefProp(“R32”) +2.) In case you want to calculate fluid properties (state variables) for a specific state: Use calc_state() function

+
+

Multiple inputs can be given (but you need to now two in order to define the values). For further +information see function header.

+
+
+
3.) Further get-Functions implemented
    +
  • get_gwp(): Global warming potential

  • +
  • get_odp(): Ozone depletion potential

  • +
  • get_safety(): Safety class

  • +
  • get_mass_fraction(): Mass fractions of pure substances in fluid

  • +
  • get_molar_mass(): Molar mass of fluid

  • +
  • get_mol_fraction(): Mol fractions of pure substances in fluid

  • +
  • get_comp_names(): Pure substances names in fluid

  • +
  • get_longname(): Long name of fluid within RefProp

  • +
  • get_critical_point(): Crit. Temperature and Pressure

  • +
  • get_version(): Version of wrapper and of RefProp dll

  • +
+
+
+
+
+

Version notes:

+
+
0.1.0 (21.04.2020, Christoph Hoeges):
+
First implementation
    +
  • Contains multiple functions to call RefProp instance

  • +
  • Can calculate state, crit, GWP, ODP, Safety class, molar mass etc. of fluid

  • +
  • Mixtures might work but it wasn’t fully testet - R455A e.g. still deviates slightly

  • +
+
+
+
+
0.1.1 (25.04.2020, Christoph Hoeges):
+
Multiple changes, added functionality. Commands are still the same though
    +
  • Self designed mixtures are possible now as well (see instructions in init

  • +
  • Added composition input to __init__ function

  • +
  • Added modes in calc_state function and removed bug in PH calculation

  • +
  • Additional protected functions due to different input

  • +
  • Adjusted _call_refprop function (z is not mass frac but mol fraction)

  • +
  • Added documentation / instruction

  • +
+
+
+
+
0.1.2 (08.05.2020, Christoph Hoeges):
+
Multiple adjustments
    +
  • Added function to call ABFLSHdll function in refprop (high level function)

  • +
  • Changed function calls in calc_state function to ABFLSH and adjusted conversion

  • +
  • Change init-function so user can choose which dll shall be used

  • +
  • Add function to get version of this current wrapper as well as RefProp-dll version

  • +
+
+
+
+
0.1.3 (12.05.2020, Christoph Hoeges):
+
Multiple changes
    +
  • Added function to get all files in MIXTURE and FLUIDS directory to check available fluids

  • +
  • +
    Added error function in order to return errors when RefProp-Functions are called.
    +
    NOTE: Not all instances where refprop is called are checked for errors. Currently, it is only used in

    init and calc_state

    +
    +
    +
    +
    +
  • +
+
+
+
+
0.1.4 (19.05.2020, Christoph Hoeges):
+
Multiple changes:
    +
  • Debugged fluid properties calculation for predefined mixtures

  • +
  • Fixed option of self-defined mixtures

  • +
+
+
+
+
0.1.5 (22.05.2020, Christoph Hoeges):

Include transport properties calculation into wrapper

+
+
0.1.6 (10.06.2020, Fabian Wuellhorst):

Add option to use a custom dll path. This necessary to use multiple instances with possible +different fluids at the same time.

+
+
+
+
+calc_satliq_state(s)[source]
+

s in kJ/kgK

+
+ +
+
+calc_state(mode: str, var1: float, var2: float, kr=1)[source]
+

Calculate state. Depending on mode, different function will be chosen. Input state variables need to be in +SI units!

+
+

Notes:

+

1.) PT does not work when state might be within the two-phase region! +2.) Only functions for density are implemented. In case you know the specific volume instead use density

+
+

functions with inverse value!

+
+
+
3.) Quality can have values outside of ‘physical’ scope:

q = -998: Subcooled liquid +q = 998: Superheated vapor +q = 999: Supercritical state

+
+
Possible modes are currently:
    +
  • “PD”: Pressure, Density

  • +
  • “PH”: Pressure, Enthalpy

  • +
  • “PQ”: Pressure, Quality

  • +
  • “PS”: Pressure, Entropy

  • +
  • “PT”: Pressure, Temperature

  • +
  • “PU”: Pressure, Internal Energy

  • +
  • “TD”: Temperature, Density

  • +
  • “TH”: Temperature, Enthalpy

  • +
  • “TQ”: Temperature, Quality

  • +
  • “TS”: Temperature, Entropy

  • +
  • “TU”: Temperature, Internal Energy

  • +
  • “DH”: Density, Enthalpy

  • +
  • “DS”: Density, Entropy

  • +
  • “DU”: Density, Internal Energy

  • +
  • “HS”: Enthalpy, Entropy

  • +
+
+
+
+
+

Parameters:

+
+
param string mode:
+

Defines which input state variables are given (see possible modes above)

+
+
param float var1:
+

Value of state variable 1 (first one in name) - use SI units!

+
+
param float var2:
+

Value of state variable 2 (second one in name) - use SI units!

+
+
param int kr:
+

phase flag (kr=1: lower density, kr=2: higher density) +relevant for “TH”, “TS”, “TU”

+
+
+
+
+

Return:

+
+
return ThermodynamicState state:
+

Thermodynamic state with state variables

+
+
+
+
+ +
+
+calc_transport_properties(state: ThermodynamicState)[source]
+

Calculate transport properties of RefProp fluid at given state

+
+

Parameters:

+
+
param ThermodynamicState state:
+

Current thermodynamic state

+
+
+
+
+

Return:

+
+
return TransportProperties props:
+

Instance of TransportProperties

+
+
+
+
+ +
+
+get_available_substances(mode='all', include_ending=False, save_txt=False)[source]
+

Get all available RefProp fluids (mixtures and / or pure substances depending on mode)

+
+

Parameters:

+
+
param string mode:
+

Mode defining which kind of fluids you want to have: ‘pure’: pure substances, ‘mix’: mixtures, ‘all’: all

+
+
param boolean include_ending:
+

Defines, whether file ending shall be returned as well or not

+
+
param boolean save_txt:
+

Defines, whether a text file with names shall be created in current working directory

+
+
+
+
+

Return:

+
+
return list names:
+

String list containing names of available fluids (depending on defined mode)

+
+
+
+
+ +
+
+get_comp_names()[source]
+

Get name of components within current fluid”

+
+

Return:

+
+
return list comp_names:
+

String names of components within current fluid

+
+
+
+
+ +
+
+get_critical_point()[source]
+

Get T and p of critical point

+
+

Return:

+
+
return float Tc:
+

Temperature at critical point in K

+
+
return float pc:
+

Pressure at critical point in Pa

+
+
return float dc:
+

Density at critical point in kg/m^3

+
+
+
+
+ +
+
+get_def_limits()[source]
+

Get limits of current ref prop fluid +Limits contain Tmin, Tmax, Dmax and Pmax (Temperatures, density, pressure)

+
+
Return dict limits:
+

Dictionary with definition limits in RefProp. Contains min/max temperature, max density, max pressure.

+
+
+
+ +
+
+static get_dll_path(ref_prop_path: str)[source]
+

Return the location of the dll

+

Return: +:return: string path_to_dll:

+
+

Path of a valid dll

+
+
+ +
+
+get_fluid_name()[source]
+

Get fluid name.

+
+

Return:

+
+
return string fluid_name:
+

Fluid name

+
+
+
+
+ +
+
+get_gwp()[source]
+

Get gwp of current fluid from refProp

+
+

Return:

+
+
return float gwp:
+

Global warming potential of fluid. In case calculation failed, None will be returned.

+
+
+
+
+ +
+
+get_longname()[source]
+

Get longname of fluid

+
+

Return:

+
+
return string longname:
+

Name of current fluid in refprop - provides mass fractions and components as well (in case of mixture)

+
+
+
+
+ +
+
+get_mass_fraction(use_round=True)[source]
+

Get mass fractions of pure substances in current fluid

+

Parameters: +:param boolean use_round:

+
+

Flag to define, whether the exact values or rounded values (by the fourth number) shall be used

+
+
+

Return:

+
+
return list mass_frac:
+

List of component mass fractions

+
+
+
+
+ +
+
+get_mol_fraction(use_round=True)[source]
+

Get mol fractions of pure substances in current fluid

+

Parameters: +:param boolean use_round:

+
+

Flag to define, whether the exact values or rounded values (by the fourth number) shall be used

+
+
+

Return:

+
+
return list frac:
+

List of component mol fractions

+
+
+
+
+ +
+
+get_molar_composition(state: ThermodynamicState, z_molar=None)[source]
+

Get composition on molar base. Liquid phase, vapor phase and total.

+
+
Parameters:
+
    +
  • state (ThermodynamicState) – the state whose compositions will be returned

  • +
  • z_molar (list) – molar composition of fluid. In case of None, default value _mol_frac is used

  • +
+
+
Returns:
+

    +
  • +
    list x:

    composition of liquid phase

    +
    +
    +
  • +
  • +
    list y:

    composition of vapor phase

    +
    +
    +
  • +
  • +
    list z:

    composition in total

    +
    +
    +
  • +
+

+
+
+
+ +
+
+get_molar_mass()[source]
+

Get molar mass of current fluid

+
+

Return:

+
+
return float M:
+

Molar mass of current fluid in kg/mol

+
+
+
+
+ +
+
+get_nbp()[source]
+

Get normal boiling point (T @ q=0 and 1 bar)

+
+

Return:

+
+
return float nbp:
+

Normal boiling point of refrigerant in °C

+
+
+
+
+ +
+
+get_odp()[source]
+

Calculate ozone depletion potential +In case of mixtures: Maximum value of pure substances will be used

+
+

Return:

+
+
return float odp:
+

ODP of fluid. In case calculation failed, None will be returned.

+
+
+
+
+ +
+
+get_safety()[source]
+

Calculate safety class of refrigerant

+
+

Return:

+
+
return string safety:
+

Safety class of fluid.

+
+
+
+
+ +
+
+get_sat_vap_pressure(T_sat)[source]
+

Get pressure of saturated vapor for defined temperature

+
+
Note:
    +
  • works for vapor, liquid and solid

  • +
  • returns equilibrium pressure at defined line (q=1)

  • +
+
+
+

Parameters: +:param float T_sat:

+
+

Temperature in K

+
+

Return: +:return float p_sat:

+
+

Vapor pressure in Pa

+
+
+ +
+
+get_triple_point()[source]
+

Get temperature and pressure at triple point of current fluid

+

Note: Works fine for pure substances, mixtures might not work properly

+

Return: +:return float T_tpl:

+
+

Temperature at triple point in K

+
+
+
Return float p_tpl:
+

Pressure at triple point in Pa

+
+
+
+ +
+
+get_version()[source]
+

Get version of wrapper and used RefProp dll

+

Return: +:return string wrapper_version:

+
+

Refprop wrapper version

+
+
+
Return string refprop_version:
+

Version of used RefProp dll

+
+
+
+ +
+
+is_mixture()[source]
+

Find out if fluid is mixture or not. +In case current fluid is mixture, true is returned. +In case current fluid is pure substance, false is returned.

+
+

Return:

+
+
return boolean _mix_flag:
+

Boolean for mixture (True), pure substance (False)

+
+
+
+
+ +
+
+set_error_flag(flag)[source]
+

Set error flag

+

Parameters: +:param boolean flag:

+
+

New error flag

+
+

Return: +:return int err:

+
+

Notifier for error code - in case everything went fine, 0 is returned

+
+
+ +
+
+set_warning_flag(flag)[source]
+

Set warning flag

+

Parameters: +:param boolean flag:

+
+

New warning flag

+
+

Return: +:return int err:

+
+

Notifier for error code - in case everything went fine, 0 is returned

+
+
+ +
+
+terminate()[source]
+

Terminate the class. +Default behaviour does nothing.

+
+ +
+
+ +
+
+

vclibpy.media.states module

+

Module containing classes for thermodynamic state and transport properties.

+
+
+class vclibpy.media.states.ThermodynamicState(p=None, T=None, u=None, h=None, s=None, v=None, q=None, d=None)[source]
+

Bases: object

+

Represents a thermodynamic state within a cycle.

+
+
Notes:

Does not necessarily need to have all state variables defined!

+
+
Args:

p (float): Pressure at the state in Pa. +T (float): Temperature at the state in K. +u (float): Inner energy at the state in J/kg. +h (float): Enthalpy at the state in J/kg. +s (float): Entropy at the state in J/(kg * K). +v (float): Specific volume at the state in m^3/kg. +q (float): Quality at the state (between 0 and 1). +d (float): Density at the state in kg/m^3.

+
+
Methods:

__init__: Initializes the state class. +__str__: Provides a string representation of the state. +get_pretty_print: Formats the state with names, units, and descriptions.

+
+
+
+
+get_pretty_print()[source]
+

Provides a formatted representation of the state with names, units, and descriptions.

+
+ +
+ +
+
+class vclibpy.media.states.TransportProperties(lam=None, dyn_vis=None, kin_vis=None, pr=None, cp=None, cv=None, beta=None, sur_ten=None, ace_fac=None, state=None)[source]
+

Bases: object

+

Represents transport properties at a specific thermodynamic state.

+
+
Args:

lam (float): Thermal conductivity in W/(m*K). +dyn_vis (float): Dynamic viscosity in Pa*s. +kin_vis (float): Kinematic viscosity in m^2/s. +Pr (float): Prandtl number. +cp (float): Isobaric specific heat capacity in J/(kg*K). +cv (float): Isochoric specific heat capacity in J/(kg*K). +beta (float): Thermal expansion coefficient in 1/K. +sur_ten (float): Surface tension in N/m. +ace_fac (float): Acentric factor. +state (ThermodynamicState): The state the transport properties belong to.

+
+
Methods:

__init__: Initializes the transport properties class. +__str__: Provides a string representation of the transport properties. +get_pretty_print: Formats the properties with names, units, and descriptions.

+
+
+
+
+get_pretty_print()[source]
+

Provides a formatted representation of the properties with names, units, and descriptions.

+
+ +
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/code/vclibpy.utils.html b/docs/0.1.1/docs/code/vclibpy.utils.html new file mode 100644 index 0000000..4eaf4dc --- /dev/null +++ b/docs/0.1.1/docs/code/vclibpy.utils.html @@ -0,0 +1,397 @@ + + + + + + + + + vclibpy.utils package — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

vclibpy.utils package

+
+

Submodules

+
+
+

vclibpy.utils.automation module

+

Functions to generate HP Maps automatically

+
+
+vclibpy.utils.automation.calc_multiple_states(save_path: Path, heat_pump: BaseCycle, inputs: List[Inputs], **kwargs)[source]
+

Function to calculate the flowsheet states for all given inputs. +All results are stored as a .xlsx file in the given save-path

+
+
Args:

save_path (pathlib.Path): Location where to save the results as xlsx. +heat_pump (BaseCycle): A valid flowsheet +inputs (List[Inputs]): A list with all inputs to simulate +**kwargs: Solver settings for the flowsheet

+
+
+
+ +
+
+vclibpy.utils.automation.full_factorial_map_generation(heat_pump: ~vclibpy.flowsheets.base.BaseCycle, T_eva_in_ar: list | ~numpy.ndarray, T_con_in_ar: list | ~numpy.ndarray, n_ar: list | ~numpy.ndarray, m_flow_con: float, m_flow_eva: float, save_path: ~pathlib.Path | str, dT_eva_superheating=5, dT_con_subcooling=0, use_multiprocessing: bool = False, save_plots: bool = False, **kwargs) -> (<class 'pathlib.Path'>, <class 'pathlib.Path'>)[source]
+

Run a full-factorial simulation to create performance maps +used in other simulation tools like Modelica or to analyze +the off-design of the flowsheet. +The results are stored and returned as .sdf and .csv files. +Currently, only varying T_eva_in, T_con_in, and n is implemented. +However, changing this to more dimensions or other variables +is not much work. In this case, please raise an issue.

+
+
Args:

heat_pump (BaseCycle): The flowsheet to use +T_eva_in_ar: Array with inputs for T_eva_in +T_con_in_ar: Array with inputs for T_con_in +n_ar: Array with inputs for n_ar +m_flow_con: Condenser mass flow rate +m_flow_eva: Evaporator mass flow rate +save_path: Where to save all results. +dT_eva_superheating: Evaporator superheating +dT_con_subcooling: Condenser subcooling +use_multiprocessing:

+
+

True to use multiprocessing. May speed up the calculation. Default is False

+
+
+
save_plots:

True to save plots of each steady state point. Default is False

+
+
+

**kwargs: Solver settings for the flowsheet

+
+
Returns:
+
tuple (pathlib.Path, pathlib.Path):

Path to the created .sdf file and to the .csv file

+
+
+
+
+
+ +
+
+

vclibpy.utils.nominal_design module

+
+
+vclibpy.utils.nominal_design.nominal_hp_design(heat_pump: BaseCycle, inputs: Inputs, fluid: str, dT_con: float | None = None, dT_eva: float | None = None, **kwargs) dict[source]
+

Function to calculate the heat pump design +at a given nominal point. +Args:

+
+

heat_pump (BaseCycle): A supported flowsheet +inputs (Inputs):

+
+

The input values at the nominal point. +If the mass flow rates are not given, you +can use dT_con and dT_eva to iteratively calculate +the mass flow rates in order to achieve the required +temperature differences at the nominal point.

+
+
+
dT_con (float):

Condenser temperature difference to calculate mass flow rate

+
+
dT_eva (float):

Evaporator temperature difference to calculate mass flow rate

+
+
+

fluid (str): Fluid to be used. +**kwargs:

+
+

m_flow_eva_start: Guess start-value for iteration. Default 0.2 +m_flow_con_start: Guess start-value for iteration. Default 1 +accuracy: Minimal accuracy for mass flow rate iteration (in kg/s).

+
+

Default 0.001 kg/s

+
+
+
+
+
Returns:
+
dict: A dictionary with all flowsheet states and inputs containing

information about the nominal design.

+
+
+
+
+
+ +
+
+

vclibpy.utils.plotting module

+
+
+vclibpy.utils.plotting.plot_cycle(med_prop: MedProp, states: List[ThermodynamicState], save_path: Path | None = None, show: bool = False)[source]
+

Creates T-h and p-h diagrams for a thermodynamic cycle.

+
+
Args:
+
med_prop (MedProp):

Object containing the medium properties and two-phase limits.

+
+
states (List[ThermodynamicState]):

List of thermodynamic states defining the cycle points. Each state +should contain T, p, and h properties.

+
+
save_path (pathlib.Path, optional):

Path where the plot should be saved. If None, returns the figure +and axes objects instead. Defaults to None.

+
+
show (bool):

If True, plots are displayed. Default is False.

+
+
+
+
Returns:
+
tuple(matplotlib.figure.Figure, numpy.ndarray) or None:

If save_path is provided, saves the plot and returns None. +If show is True, shows the plot.

+
+
+
+
+
+ +
+
+vclibpy.utils.plotting.plot_sdf_map(filepath_sdf: Path, nd_data: str, first_dimension: str, second_dimension: str, fluids: List[str] | None = None, flowsheets: List[str] | None = None, violin_plot_variable: str | None = None, third_dimension: str | None = None)[source]
+

Generate and display visualizations based on data from an SDF (Structured Data File) dataset. +This function generates various types of visualizations based on the provided parameters, +including 3D scatter plots, 3D surface plots, and violin plots, and displays them using Matplotlib.

+
+
Args:
+
filepath_sdf (pathlib.Path):

The path to the SDF dataset file.

+
+
nd_data (str):

The name of the primary data to be plotted.

+
+
first_dimension (str):

The name of the first dimension for the visualization.

+
+
second_dimension (str):

The name of the second dimension for the visualization.

+
+
fluids (List[str], optional):

List of specific fluids to include in the visualization. +Default is None, which includes all fluids.

+
+
flowsheets (List[str], optional):

List of specific flowsheets to include in the visualization. +Default is None, which includes all flowsheets.

+
+
violin_plot_variable (str, optional):

The variable to be used for creating violin plots. +Default is None, which disables violin plots.

+
+
third_dimension (str, optional):

The name of the third dimension for 4D visualizations. +Default is None, which disables 4D plotting.

+
+
+
+
Raises:

KeyError: If the specified data or dimensions are not found in the dataset.

+
+
+

Examples: +>>> FILEPATH_SDF = r”HeatPumpMaps.sdf” +>>> plot_sdf_map( +>>> filepath_sdf=FILEPATH_SDF, +>>> nd_data=”COP”, +>>> first_dimension=”T_eva_in”, +>>> second_dimension=”n”, +>>> fluids=[“R410A”], +>>> flowsheets=[“OptiHorn”], +>>> )

+
+ +
+
+vclibpy.utils.plotting.set_axis_style(ax, labels)[source]
+

From: https://matplotlib.org/3.1.1/gallery/statistics/customized_violin.html#sphx-glr-gallery-statistics-customized-violin-py

+
+ +
+
+

vclibpy.utils.printing module

+

Created on 24.04.2023

+

@author: Christoph Hoeges

+

Last Update: 24.04.2023

+
+
+vclibpy.utils.printing.print_states(**kwargs)[source]
+

Transforms given states to DataFrame and prints table layout. +Declaration of state must start with ‘state’

+

Returns: +:return pandas.DataFrame df_states:

+
+

DataFrame with states

+
+
+ +
+
+

vclibpy.utils.sdf_ module

+
+
+vclibpy.utils.sdf_.merge_sdfs(filepaths, save_path)[source]
+

Merge given files and return a merged file. +Be careful if both files contain the same combination. +Then, the latter element of the list will overwrite the first one.

+
+
Args:

filepaths (list): List with paths to the files +save_path (str): Save path for the new file

+
+
+
+ +
+
+vclibpy.utils.sdf_.save_to_sdf(data: dict, save_path: Path)[source]
+

Save given input dictionary to a sdf file in the given save_path

+
+
Args:
+
data (dict):

A dictionary with the following structure: +Keys: Flowsheet_name +Values: A dictionary with the following structure:

+
    +
  • Keys: Fluids

  • +
  • +
    Values: Data dictionaries with the following structure:

    A tuple with three values, in that order:

    +
      +
    • scales: Of the given nd_data, e.g. T_Amb, n

    • +
    • nd_data: More-dimensional data, e.g. COP

    • +
    • parameters: Scalar values, like m_flow_con or similar

    • +
    +
    +
    +
  • +
+
+
+

save_path (pathlib.Path): Where to store the data +flowsheet_name (str): Name of the flowsheet. This is the top level group

+
+
+
+
Returns:
+

+
+
+
+ +
+
+vclibpy.utils.sdf_.sdf_to_csv(filepath: Path, save_path: Path)[source]
+

Convert a given .sdf file to multiple excel files, +for each combination of flowsheet and refrigerant one file.

+
+
Args:

filepath (pathlib.Path): sdf file +save_path (pathlib.Path): Directory where to store the csv files.

+
+
+
+ +
+
+

vclibpy.utils.ten_coefficient_compressor_reqression module

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/doc.svg b/docs/0.1.1/docs/doc.svg new file mode 100644 index 0000000..06e33d8 --- /dev/null +++ b/docs/0.1.1/docs/doc.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + documentation + documentation + + + passing + passing + + diff --git a/docs/0.1.1/docs/examples/e1_refrigerant_data.html b/docs/0.1.1/docs/examples/e1_refrigerant_data.html new file mode 100644 index 0000000..ab8549a --- /dev/null +++ b/docs/0.1.1/docs/examples/e1_refrigerant_data.html @@ -0,0 +1,220 @@ + + + + + + + + + Refrigerant Data Example — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Refrigerant Data Example

+

This example demonstrates how to use the classes MedProp (and its children), +ThermodynamicState, and TransportProperties. +Further, basic plotting is shown using this data.

+

First, let’s import the important classes from vclibpy’s +media module:

+
from vclibpy.media import CoolProp, ThermodynamicState, TransportProperties
+
+
+

We have two media property classes, CoolProp and RefProp. +The latter requires a dll, which you have to purchase together with RefProp. +Thus, in this example, we will use CoolProp. Pass the fluid_name to +select the fluid you are going to use.

+
cool_prop = CoolProp(fluid_name="Propane")
+
+
+
+

ThermodynamicState calculation

+

Let’s start and show how the media property classes work. You always +call calc_state(). The documentation explains how to use it:

+
help(cool_prop.calc_state)
+
+
+

Let’s try and start with pressure of 2 bar (2e5 Pa) and 100 kJ/kg enthalpy:

+
state = cool_prop.calc_state("PH", 2e5, 100e3)
+
+
+

The state is an instance of ThermodynamicState:

+
print(type(state))
+
+
+

The state contains all important specific values:

+
print(state.get_pretty_print())
+
+
+

For these values, we are outside of the two phase region, as q (quality) is -1. +You can play around with the possible options to get a better understanding.

+
+
+

TransportProperties calculation

+

With a given state, we can calculate the transport properties. Those include +relevant information for component models, e.g. heat conductivity. +For information on all properties, look at the documentation:

+
help(cool_prop.calc_transport_properties)
+
+
+

You just have to pass a valid state:

+
transport_properties = cool_prop.calc_transport_properties(state=state)
+print(transport_properties.get_pretty_print())
+
+
+
+
+

Plotting

+

To plot fluid data, we may plot the two phase limits. +While we have the function get_two_phase_limits in the media model, +we will define it here again so that you can further learn how to use media. +The idea is to loop over all pressure from some minimum value. +Let’s use the pressure at -40 °C. +to the maximum, which is the critical point. +You can get the critical point using the function: get_critical_point:

+
p_min = cool_prop.calc_state("TQ", 273.15 - 40, 0).p  # Pa
+T_crit, p_crit, d_crit = cool_prop.get_critical_point()
+p_max = p_crit
+
+
+

Let’s create two lists, q0 and q1 for states with quality of 0 and 1. Further, +we loop only each 10000 Pa to reduce number of function calls.

+
p_step = 10000  # Pa
+q0 = []
+q1 = []
+for p in range(int(p_min), int(p_max), p_step):
+    q0.append(cool_prop.calc_state("PQ", p, 0))
+    q1.append(cool_prop.calc_state("PQ", p, 1))
+
+
+

Now, we can plot these states, for example in a T-h Diagram. +Note: [::-1] reverts the list, letting it start from the critical point. +[state.T for state in q0] is a list comprehension, quite useful in Python.

+
T = [state.T for state in q0 + q1[::-1]]
+h = [state.h for state in q0 + q1[::-1]]
+import matplotlib.pyplot as plt
+plt.ylabel("$T$ in K")
+plt.xlabel("$h$ in J/kg")
+plt.plot(h, T, color="black")
+
+
+

Now, without any component models, let’s try to plot a closed vapor compression cycle: +Assumptions:

+
    +
  • No superheat nor subcooling

  • +
  • isobaric heat exchange

  • +
  • isentropic compression and expansion

  • +
  • 0 °C evaporation and 40 °C condensation temperature

  • +
+
state_1 = cool_prop.calc_state("TQ", 273.15, 1)
+state_3 = cool_prop.calc_state("TQ", 273.15 + 40, 0)
+state_4 = cool_prop.calc_state("PH", state_1.p, state_3.h)
+state_2 = cool_prop.calc_state("PS", state_3.p, state_1.s)
+
+
+

Now, let’s plot them with some markers:

+
plot_lines_h = [state_1.h, state_2.h, state_3.h, state_4.h, state_1.h]
+plot_lines_t = [state_1.T, state_2.T, state_3.T, state_4.T, state_1.T]
+plt.plot(plot_lines_h, plot_lines_t, marker="s", color="red")
+plt.show()
+
+
+

Try to use the skills you’ve learned in this example and tweak the assumptions +and the plot format: Plot log(p)-h, T-s, or similar. Assume some level +of superheat, non-isentropic compression etc.

+

After getting familiar with calling the refrigerant data module media, you will +learn how to use the Compressor classes in the next example.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/examples/e2_compressor.html b/docs/0.1.1/docs/examples/e2_compressor.html new file mode 100644 index 0000000..98a115f --- /dev/null +++ b/docs/0.1.1/docs/examples/e2_compressor.html @@ -0,0 +1,248 @@ + + + + + + + + + Compressor Example — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Compressor Example

+

This example demonstrates how to use the classes Compressor, +and its children.

+

First, let’s import an exemplary compressor from vclibpy’s +compressor package:

+
from vclibpy.components.compressors import ConstantEffectivenessCompressor
+
+
+

The ConstantEffectivenessCompressor uses constant efficiencies to model the compressor. +Check out the documentation to see relevant parameters:

+
help(ConstantEffectivenessCompressor)
+
+
+

Let’s specify some dummy parameters:

+
constant_efficiency_compressor = ConstantEffectivenessCompressor(
+    N_max=120,
+    V_h=19e-6,
+    eta_isentropic=0.7,
+    eta_mech=0.95*0.95*0.95,
+    lambda_h=0.9
+)
+
+
+

Before we can do any calculations, the compressor needs +access to refrigerant data. Each component in VcLibPy has +the property med_prop (media property) which you can set like this:

+
from vclibpy.media import CoolProp
+med_prop = CoolProp(fluid_name="Propane")
+constant_efficiency_compressor.med_prop = med_prop
+
+
+

Now, you have to define the input state of the compressor. +Each component has inlet and outlet states, which are, same as med_prop +properties of the component. +We assume a super-heated vapor at 1bar as an input state:

+
p_inlet = 1e5
+T_superheat = med_prop.calc_state("PQ", p_inlet, 1).T + 10
+constant_efficiency_compressor.state_inlet = med_prop.calc_state("PT", p_inlet, T_superheat)
+
+
+

Last but not least, most functions in VcLibPy require +the argument inputs and fs_state. The whole concept of the two +classes are explained in the third example. For now, we just instantiate +the classes and pass a relative compressor speed of 50 % (0.5) as an input.

+
from vclibpy import FlowsheetState, Inputs
+fs_state = FlowsheetState()
+inputs = Inputs(n=0.5)
+
+
+

Now, we can calculate multiple things.

+
+

Outlet state

+

While the constant efficiency compressor does not rely on any +states to calculate the constant efficiencies, most other models do. +Thus, we first want to calculate the outlet state for the given input state. +We can do so by passing an outlet pressure to the function calc_state_outlet:

+
p_outlet = 6e5
+print(f"{constant_efficiency_compressor.state_outlet=}")  # still None
+constant_efficiency_compressor.calc_state_outlet(p_outlet=p_outlet, inputs=inputs, fs_state=fs_state)
+print(f"{constant_efficiency_compressor.state_outlet=}")  # now calculated
+
+
+

Also, relevant results are automatically added to the fs_state:

+
print(fs_state)
+
+
+

You can play around with the compressor speed (which has no effect due to constant efficiencies) +or the compression ratio. Let’s do the latter for the outlet temperature:

+
import numpy as np
+ratios = np.arange(2, 10, 0.5)
+T_outlets = []
+for ratio in ratios:
+    constant_efficiency_compressor.calc_state_outlet(
+        p_outlet=p_inlet * ratio, inputs=inputs, fs_state=fs_state
+    )
+    T_outlets.append(constant_efficiency_compressor.state_outlet.T)
+
+
+

Let’s plot the results:

+
import matplotlib.pyplot as plt
+plt.plot(ratios, np.array(T_outlets) - 273.15)
+plt.ylabel("$T_\mathrm{Outlet}$ in °C")
+plt.xlabel("$\Pi$ in -")
+plt.show()
+
+
+
+
+

Mass flow rate

+

Now, let’s continue with the mass flow rate. Again, each component has the property +m_flow, which always refers to the refrigerant mass flow rate. +The function calc_m_flow calculates and set’s the mass flow rate to this property.

+
m_flow = constant_efficiency_compressor.calc_m_flow(inputs=inputs, fs_state=fs_state)
+print(f"{m_flow=}, {constant_efficiency_compressor.m_flow=}")
+
+
+

Again, some interesting results are automatically added to the fs_state:

+
print(fs_state)
+
+
+

Now, we can check how the compressor will work for different compressor speeds:

+
m_flows = []
+speeds = np.arange(0, 1, 0.1)
+for speed in speeds:
+    m_flows.append(constant_efficiency_compressor.calc_m_flow(Inputs(n=speed), fs_state=fs_state))
+
+
+

Let’s plot the results:

+
import matplotlib.pyplot as plt
+plt.plot(speeds, m_flows)
+plt.ylabel("$\dot{m}$ in kg/s")
+plt.xlabel("$n$ in -")
+plt.show()
+
+
+
+
+

Electrical power consumption

+

If mass flow rates and outlet states are calculated, we can calculate the +electrical power consumption of the compressor. Note, that +if you change input values here, you first have to calculate the +mass flow rate and outlet state again, as this may influence the result.

+
constant_efficiency_compressor.calc_m_flow(inputs=inputs, fs_state=fs_state)
+constant_efficiency_compressor.calc_state_outlet(p_outlet=p_outlet, inputs=inputs, fs_state=fs_state)
+P_el = constant_efficiency_compressor.calc_electrical_power(inputs=inputs, fs_state=fs_state)
+print(f"{P_el=}")
+
+
+

Again, important metrics are added to the fs_state:

+
print(fs_state)
+
+
+

After learning the basics of each component and using Inputs and FlowsheetState +for the first time, we will go deeper into these classes in the third example. +You can alter the compressor in use by importing other compressors, such as +RotaryCompressor or TenCoefficientCompressor. Check if you can use these components as well.

+
from vclibpy.components.compressors import RotaryCompressor, TenCoefficientCompressor
+help(RotaryCompressor)
+help(TenCoefficientCompressor)
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/examples/e3_inputs_and_flowsheet_state.html b/docs/0.1.1/docs/examples/e3_inputs_and_flowsheet_state.html new file mode 100644 index 0000000..30c7d06 --- /dev/null +++ b/docs/0.1.1/docs/examples/e3_inputs_and_flowsheet_state.html @@ -0,0 +1,198 @@ + + + + + + + + + Inputs and FlowsheetState — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Inputs and FlowsheetState

+

This example demonstrates how to use the classes Inputs, +and FlowsheetState

+

All Variables in the Inputs and FlowsheetState will be saved in +output formats like .csv or .sdf +Thus, the concept of these two classes is important to +understand and analyze simulations in VcLibPy.

+
+

Inputs

+

All external boundary conditions which act on the vapor compression +cycle may be inputs. This could be the compressor speed, ambient temperature, +or the inlet temperatures and mass flow rates of the secondary side +in the heat exchangers. +You can see all default options by just printing the empty instance:

+
from vclibpy import Inputs
+print(Inputs())
+
+
+

Currently, the flowsheets need all of these parameters, except for +the ambient temperature. This is only required for heat loss estimations or +efficiency calculations in certain models. +Handling all the inputs in one object makes it easy for component models +to access any relevant data it needs. Also, you can add new inputs +as you like. For instance, let’s say you want to control the pressure +level ratio, at which vapor is injected in the vapor-injection flowsheets. +Here, the flowsheets can act on the input k_vapor_injection. The default is 1. +You can set custom inputs like this:

+
inputs = Inputs()
+inputs.set(name="k_vapor_injection", value=1.05)
+print(inputs)
+
+
+

Optional arguments of the set function are unit and description. +You should pass those along with the name and value to make +your results easier to analyze, for others and your future self:

+
inputs.set(
+    name="k_vapor_injection", value=1.05,
+    unit="-",
+    description="Calculates the injection pressure level according to "
+                "k_vapor_injection * np.sqrt(p_1 * p_2)"
+)
+
+
+

The set function registers a Variable in the inputs object. +You can get different information types like this:

+
print(f"{inputs.get_variables()=}")
+print(f"{inputs.get_variable_names()=}")
+print(f"{inputs.get(name='k_vapor_injection')=}")
+print(f"{inputs.items()=}")  # To loop over the variable dict.
+
+
+
+
+

FlowsheetState

+

The class FlowsheetState is essentially the same as Inputs. +The only difference is its use, which is for outputs of the vapor +compression cycle like COP, heat flow rate, temperatures, etc. +Basically, anything a users might be interested in analyzing when +simulating a steady state vapor compression cycle. +As the outputs are flowsheet specific, we define no default +Variables in the FlowsheetState as with Inputs. +However, you can set variables the same way as with Inputs:

+
from vclibpy import FlowsheetState
+fs_state = FlowsheetState()
+print(fs_state)
+fs_state.set(name="some_interesting_output", value=3.14,
+             unit="-", description="This is just an example")
+print(fs_state)
+
+
+

As the fs_state is passed to all components, it’s important to +use distinct names. If two components set a variable T_1, the latter +one will override the first one. +As the fs_state and inputs are mutable, no history is preserved. +If you want to, for example, plot the history of the fs_state, +you have to store copies of the instance:

+
fs_states = []
+for some_value in range(10):
+    fs_state.set(name="some_interesting_output", value=some_value)
+    fs_states.append(fs_state.copy())
+print([fs_state.get("some_interesting_output").value for fs_state in fs_states])
+
+
+

Without the copy, it would not work:

+
fs_states = []
+for some_value in range(10):
+    fs_state.set(name="some_interesting_output", value=some_value)
+    fs_states.append(fs_state)
+print([fs_state.get("some_interesting_output").value for fs_state in fs_states])
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/examples/e4_heat_exchanger.html b/docs/0.1.1/docs/examples/e4_heat_exchanger.html new file mode 100644 index 0000000..7e18b39 --- /dev/null +++ b/docs/0.1.1/docs/examples/e4_heat_exchanger.html @@ -0,0 +1,343 @@ + + + + + + + + + Heat Exchanger Example — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Heat Exchanger Example

+

This example demonstrates how to use the heat exchanger +classes.

+

Contrary to the first examples, the heat exchanger is +more complex, in the sense that the only current +models follows a moving boundary epsNTU approach. +Thus, you need to assume heat transfer correlations +for different regimes. +We will use the evaporator for this example. Let’s check the doc:

+
from vclibpy.components.heat_exchangers import MovingBoundaryNTUEvaporator
+help(MovingBoundaryNTUEvaporator)
+
+
+

As you can see, we have to define a lot of parameters. +Let’s model a simple air-to-refrigerant heat exchanger with +constant heat transfer correlations. The areas are not that important +for this example. +For heat transfer, you can import models from the heat_transfer package +inside the heat_exchangers package. +You will find all options in the documentation of VcLibPy

+
from vclibpy.components.heat_exchangers.heat_transfer.constant import (
+    ConstantHeatTransfer, ConstantTwoPhaseHeatTransfer
+)
+from vclibpy.components.heat_exchangers.heat_transfer.wall import WallTransfer
+
+
+

Now, we can instantiate the class:

+
evaporator = MovingBoundaryNTUEvaporator(
+    A=15,
+    secondary_medium="air",
+    flow_type="counter",
+    ratio_outer_to_inner_area=10,
+    two_phase_heat_transfer=ConstantTwoPhaseHeatTransfer(alpha=1000),
+    gas_heat_transfer=ConstantHeatTransfer(alpha=1000),
+    wall_heat_transfer=WallTransfer(lambda_=236, thickness=2e-3),
+    liquid_heat_transfer=ConstantHeatTransfer(alpha=5000),
+    secondary_heat_transfer=ConstantHeatTransfer(alpha=25)
+)
+
+
+
+

Heat exchanger iterations

+

To understand the heat exchanger functions in VcLibPy, +you have to understand how we iterate to solve the closed +cycle simulation. +In reality, the expansion valve would +adjust its opening until a certain degree of superheat +is met. While this may oscillate in dynamic operation, +we assume that the control is able to meet a constant +degree of superheat in steady state. +This means, we have to find the pressure level which +ensures this superheat. So instead of iterating +the valve opening, we iterate the evaporation pressure +directly. The same holds for the condenser and subcooling. +However, levels of subcooling are not directly controlled in +real devices, at least in the standard cycle. +The assumption of keeping the degree of subcooling as an input +could be changed in future work.

+

For iteration, heat exchangers have the function calc. +In order for it to work, you have to assign both inlet and +outlet state, as well as the mass flow rate. Note that, +as we assume the levels of superheat and subcooling, we +will always have these states in our iterations. +Further, the inputs need to contain the evaporator inlet temperature T_eva_in and +the evaporator mass flow rate (secondary side):

+
from vclibpy import FlowsheetState, Inputs
+fs_state = FlowsheetState()
+from vclibpy.media import CoolProp
+med_prop = CoolProp(fluid_name="Propane")
+evaporator.med_prop = med_prop  # We have to set it, same as in the second example.
+evaporator.m_flow = 0.01
+
+
+

Also, we have to start the secondary med-prop. This is done for you +in the calculations, but required to be an extra function to enable multi-processing:

+
evaporator.start_secondary_med_prop()
+
+
+

Let’s assume a superheat of 10 K and a condenser subcooling of 0 K. +With an isenthalp expansion valve, the inlet and outlet are given. +Further, let’s assume a condensation temperature of 40 °C and +an air temperature of 2 °C, corresponding to the typical heat pump point A2W25

+
T_eva_in = 273.15 + 2
+dT_eva_superheating = 10
+dT_con_subcooling = 0
+inputs = Inputs(
+    T_eva_in=T_eva_in, m_flow_eva=0.47,
+    dT_eva_superheating=dT_eva_superheating, dT_con_subcooling=dT_con_subcooling
+)
+
+
+

Let’s start with a simple assumption, no temperature difference +at the evaporator outlet (or inlet of air):

+
p_evaporation = med_prop.calc_state("TQ", T_eva_in - dT_eva_superheating, 1).p
+
+
+

Calculate the condenser outlet and expansion valve outlet, thus evaporator inlet

+
state_condenser_outlet = med_prop.calc_state("TQ", 273.15 + 40, 0)
+evaporator.state_inlet = med_prop.calc_state("PH", p_evaporation, state_condenser_outlet.h)
+T_evaporation = med_prop.calc_state("PQ", p_evaporation, 1).T
+evaporator.state_outlet = med_prop.calc_state("PT", p_evaporation, T_evaporation + dT_eva_superheating)
+print(evaporator.calc_Q_flow())
+
+
+

What do they mean? +They are used in the iterative logic of VcLibPy and indicate that +the heat exchanger is valid, if the error is smaller than a pre-defined +margin and dT_min is greater than 0.

+
error, dT_min = evaporator.calc(inputs=inputs, fs_state=fs_state)
+print(f"{error=}, {dT_min=}")
+
+
+

dT_min is, as assumed, close to zero. However, the error is very large. +The error is calculated as follows: (Q_ntu / Q - 1) * 100. +Q is the amount of heat required to be transported, Q_ntu is +the amount possible to transfer according to NTU method. +This means, a negative value of 100 means we could transport 2 times +less heat than we want to. +Thus, we have to iterate the pressure assumptions and lower it, +as we need a higher temperature difference to the air. +For this, we will use a loop:

+
import numpy as np
+p_evaporations = np.linspace(p_evaporation - 1e4, p_evaporation, 1000)
+errors, dT_mins = [], []
+for p_evaporation in p_evaporations:
+    evaporator.state_inlet = med_prop.calc_state("PH", p_evaporation, state_condenser_outlet.h)
+    T_evaporation = med_prop.calc_state("PQ", p_evaporation, 1).T
+    evaporator.state_outlet = med_prop.calc_state("PT", p_evaporation, T_evaporation + dT_eva_superheating)
+    error, dT_min = evaporator.calc(inputs=inputs, fs_state=fs_state)
+    errors.append(error)
+    dT_mins.append(dT_min)
+
+
+

The iteration of VcLibPy is largely based on this method, so nothing fancy. +If the error is positive, we step back to the old value and decrease the +step-size by a factor of 10. At the end, we iterate with a min_iteration_step, +which is, by default 1 Pa.

+

Let’s plot the result:

+
import matplotlib.pyplot as plt
+fig, ax = plt.subplots(2, 1, sharex=True)
+ax[0].plot(p_evaporations / 1e5, errors)
+ax[0].set_ylabel("Error in %")
+ax[1].plot(p_evaporations / 1e5, dT_mins)
+ax[1].set_ylabel("$\Delta T$ in K")
+ax[1].set_xlabel("$p_\mathrm{Eva}$ in bar")
+plt.show()
+
+
+
+
+

Implement your own iteration

+

As the result is still not good, let’s implement this really basic iteration logic. +For iterating, we use a while-loop. Let’s define a max-iteration +counter to avoid an infinite iteration.

+
max_iterations = 100
+n_iteration = 0
+p_eva_next = p_evaporation  # Start with simple assumption
+p_step = 10000  # Pa
+min_step = 1  # Pa
+min_error = 0.1  # 0.1 % maximal error
+errors, dT_mins, p_evaporations = [], [], []  # Store for later plotting
+while n_iteration < max_iterations:
+    evaporator.state_inlet = med_prop.calc_state("PH", p_eva_next, state_condenser_outlet.h)
+    T_eva = med_prop.calc_state("PQ", p_eva_next, 1).T
+    evaporator.state_outlet = med_prop.calc_state("PT", p_eva_next, T_eva + inputs.get("dT_eva_superheating").value)
+    error, dT_min = evaporator.calc(inputs=inputs, fs_state=fs_state)
+    # Store for later plotting
+    errors.append(error)
+    dT_mins.append(dT_min)
+    p_evaporations.append(p_eva_next / 1e5)
+    n_iteration += 1
+    if error < min_error:
+        p_eva_next -= p_step
+        continue
+    elif error > min_error:
+        p_eva_next += p_step  # Go back
+        if p_step <= min_step:
+            print("Error: Can't solve any more accurate with given size of min_step")
+            break
+        p_step /= 10
+        continue
+    else:
+        print(f"Converged")
+else:
+    print("Did not converged in the given max_iterations.")
+print(f"Solution: {error=}, {dT_min=}, p_evaporation={p_evaporations[-1]}. Took {n_iteration=}")
+
+
+

Again, let’s plot the iteration:

+
import matplotlib.pyplot as plt
+fig, ax = plt.subplots(3, 1, sharex=True)
+ax[0].plot(range(n_iteration), errors, marker="s")
+ax[0].set_ylabel("Error in %")
+ax[1].plot(range(n_iteration), dT_mins, marker="s")
+ax[1].set_ylabel("$\Delta T$ in K")
+ax[2].plot(range(n_iteration), p_evaporations, marker="s")
+ax[2].set_ylabel("$p_\mathrm{Eva}$ in bar")
+ax[2].set_xlabel("Iterations in -")
+plt.show()
+
+
+

You can see that the iterative process converges to an error +Close to zero. However, it’s not really an efficient optimization. +This could, and should, be optimized using optimization techniques.

+
+
+

Pinch plotting

+

What also helps to understand the heat exchanger better is to +plot the states and secondary media. We can use the +get_two_phase_limits function of med_prop to quickly plot +those:

+
plt.plot(
+    med_prop.get_two_phase_limits("h") / 1000,
+    med_prop.get_two_phase_limits("T") - 273.15, color="black"
+)
+state_vapor = med_prop.calc_state("PQ", evaporator.state_inlet.p, 1)  # define intermediate state
+states_to_plot = [evaporator.state_inlet, state_vapor, evaporator.state_outlet]
+plt.plot(
+    [state.h / 1000 for state in states_to_plot],
+    [state.T - 273.15 for state in states_to_plot],
+    marker="s", color="red"
+)
+Q_flow = evaporator.calc_Q_flow()
+T_eva_in = T_eva_in - 273.15
+T_eva_out = T_eva_in - Q_flow / inputs.get("m_flow_eva").value / 1000
+plt.plot(
+    [evaporator.state_outlet.h / 1000, evaporator.state_inlet.h / 1000],
+    [T_eva_in, T_eva_out],
+    color="blue"
+)
+plt.ylabel("$T$ in °C")
+plt.xlabel("$h$ in kJ/kgK")
+plt.ylim([evaporator.state_inlet.T - 275.15, T_eva_in + 2])
+plt.show()
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/examples/e5_expansion_valve.html b/docs/0.1.1/docs/examples/e5_expansion_valve.html new file mode 100644 index 0000000..2bce414 --- /dev/null +++ b/docs/0.1.1/docs/examples/e5_expansion_valve.html @@ -0,0 +1,182 @@ + + + + + + + + + Expansion Valve Example — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Expansion Valve Example

+

This example demonstrates how to use the classes ExpansionValve, +and its children.

+

First, let’s import an exemplary valve from vclibpy’s +expansion_valve package. The only one currently implemented +is Bernoulli:

+
from vclibpy.components.expansion_valves import Bernoulli
+
+
+

The valves are not that important for the vapor compression simulation, +as we iterate the pressure levels directly. However, you can still check +if a given valve cross-section area is large enough for your required level of +superheat.

+
help(Bernoulli)
+
+
+

Let’s specify some dummy parameters:

+
d = 5e-3  # 5 mm diameter
+area = 3.14 * d ** 2 / 4
+expansion_valve = Bernoulli(A=area)
+
+
+

Again, we have to start a med-prop, and give some input state:

+
from vclibpy.media import CoolProp
+med_prop = CoolProp(fluid_name="Propane")
+expansion_valve.med_prop = med_prop
+
+
+

Let’s use the inlet state as in the last example +Also, we will use the evaporation pressure level:

+
state_condenser_outlet = med_prop.calc_state("TQ", 273.15 + 40, 0)
+expansion_valve.state_inlet = state_condenser_outlet
+p_evaporation = 3.149034617014494 * 1e5
+
+
+

Now, we can calculate the outlet:

+
expansion_valve.calc_outlet(p_outlet=p_evaporation)
+
+
+

Note that the outlet has the same enthalpy as the inlet:

+
print(f"{expansion_valve.state_inlet.h=}; {expansion_valve.state_outlet.h=}")
+
+
+
+

Valve opening:

+

Let’s assume we want to match the mass flow rate of the last example: +What opening would we require for the given cross section area? +For this, we can use expansion_valve.ca

+
m_flow_ref_goal = 0.01
+opening = expansion_valve.calc_opening_at_m_flow(m_flow=m_flow_ref_goal)
+print(f"Required opening: {opening}")
+
+
+

Not that much. Now, we can repeat the process with different diameters in mm.

+
import numpy as np
+openings = []
+d_mm_array = np.arange(0.5, 5, 0.5)
+for d_mm in d_mm_array:
+    expansion_valve.A = 3.14 * (d_mm * 1e-3) ** 2 / 4
+    opening = expansion_valve.calc_opening_at_m_flow(m_flow=m_flow_ref_goal)
+    print(f"Required opening for area={expansion_valve.A}: {opening * 100} %")
+    openings.append(opening * 100)
+
+
+

Let’s plot the result:

+
import matplotlib.pyplot as plt
+plt.plot(d_mm_array, openings, marker="s")
+plt.ylabel("Opening in %")
+plt.xlabel("$d$ in mm")
+plt.show()
+
+
+

Looking only at this point, the diameter should not be smaller than 1 mm. +You can tweak the assumptions around, check for different mass flow rates +or different pressure levels.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/examples/e6_simple_heat_pump.html b/docs/0.1.1/docs/examples/e6_simple_heat_pump.html new file mode 100644 index 0000000..f5156e9 --- /dev/null +++ b/docs/0.1.1/docs/examples/e6_simple_heat_pump.html @@ -0,0 +1,239 @@ + + + + + + + + + Example for a heat pump with a standard cycle — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Example for a heat pump with a standard cycle

+

Let’s start the complete cycle simulation with the +most basic flowsheet, the standard-cycle. As all flowsheets +contain a condenser and an evaporator, we defined a common BaseCycle +to avoid code-repetition. +We can import this flowsheet and see how to use it. Note that +modern coding IDEs like PyCharm will tell you which arguments belong +to a class or function. If you don’t have that at hand, you need +to look into the documentation.

+
from vclibpy.flowsheets import BaseCycle, StandardCycle
+help(BaseCycle)
+help(StandardCycle)
+
+
+

We fist need to define the components in the cycle. +Here we are using the components developed in the previous examples. +Also, note again that the expansion valve model does not influence the results +for the current algorithm. But, you could size the expansion valve +using vclibpy, including off-design, but this is one for another example.

+
from vclibpy.components.heat_exchangers import moving_boundary_ntu
+from vclibpy.components.heat_exchangers import heat_transfer
+condenser = moving_boundary_ntu.MovingBoundaryNTUCondenser(
+    A=5,
+    secondary_medium="water",
+    flow_type="counter",
+    ratio_outer_to_inner_area=1,
+    two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=5000),
+    gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000),
+    wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3),
+    liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000),
+    secondary_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000)
+)
+evaporator = moving_boundary_ntu.MovingBoundaryNTUEvaporator(
+    A=15,
+    secondary_medium="air",
+    flow_type="counter",
+    ratio_outer_to_inner_area=10,
+    two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=1000),
+    gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=1000),
+    wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3),
+    liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000),
+    secondary_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=25)
+)
+from vclibpy.components.expansion_valves import Bernoulli
+expansion_valve = Bernoulli(A=0.1)
+
+from vclibpy.components.compressors import RotaryCompressor
+compressor = RotaryCompressor(
+    N_max=125,
+    V_h=19e-6
+)
+
+
+

Now, we can plug everything into the flowsheet:

+
heat_pump = StandardCycle(
+    evaporator=evaporator,
+    condenser=condenser,
+    fluid="Propane",
+    compressor=compressor,
+    expansion_valve=expansion_valve,
+)
+
+
+

As in the other example, we can specify save-paths, +solver settings and inputs to vary:

+
save_path = r"D:\00_temp\simple_heat_pump"
+T_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]
+T_con_in_ar = [30 + 273.15, 50 + 273.15, 70 + 273.15]
+n_ar = [0.3, 0.7, 1]
+
+
+

Now, we can generate the full-factorial performance map +using all inputs. The results will be stored under the +save-path. To see some logs, we can import the logging module +and get, for example, all messages equal or above the INFO-level

+
import logging
+logging.basicConfig(level="INFO")
+
+from vclibpy import utils
+save_path_sdf, save_path_csv = utils.full_factorial_map_generation(
+    heat_pump=heat_pump,
+    save_path=save_path,
+    T_con_in_ar=T_con_in_ar,
+    T_eva_in_ar=T_eva_in_ar,
+    n_ar=n_ar,
+    use_multiprocessing=False,
+    save_plots=True,
+    m_flow_con=0.2,
+    m_flow_eva=0.9,
+    dT_eva_superheating=5,
+    dT_con_subcooling=0,
+)
+
+
+

What did just happen? We can analyze all results by listing the +files in the save-path - or just open it in our default system explorer.

+
import os
+print(os.listdir(save_path))
+
+
+

One file should be: Standard_Propane.csv. We can load this file and plot

+
import pandas as pd
+df = pd.read_csv(save_path_csv, index_col=0)
+df
+
+
+

Now, we can plot variables, for example as a scatter plot using matplotlib. +You have to know the names, which are the column headers.

+
import matplotlib.pyplot as plt
+x_name = "n in - (Relative compressor speed)"
+y_name = "COP in - (Coefficient of performance)"
+plt.scatter(df[x_name], df[y_name])
+plt.ylabel(y_name)
+plt.xlabel(x_name)
+plt.show()
+
+
+

Looking at the results, we see that a higher frequency often leads to lower COP values. +However, other inputs (temperatures) have a greater impact on the COP. +We can also use existing 3D-plotting scripts in vclibpy to analyze the +dependencies. For this, we need the .sdf file. In the sdf, the field names are without +the unit and description, as those are accessible in the file-format in other columns.

+
from vclibpy.utils.plotting import plot_sdf_map
+plot_sdf_map(
+    filepath_sdf=save_path_sdf,
+    nd_data="COP",
+    first_dimension="T_eva_in",
+    second_dimension="T_con_in",
+    fluids=["Propane"],
+    flowsheets=["Standard"]
+)
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/examples/e7_vapor_injection.html b/docs/0.1.1/docs/examples/e7_vapor_injection.html new file mode 100644 index 0000000..454d1f9 --- /dev/null +++ b/docs/0.1.1/docs/examples/e7_vapor_injection.html @@ -0,0 +1,261 @@ + + + + + + + + + Example for a heat pump with vapor injection using a phase separator — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + View page source +
  • +
+
+
+
+
+ +
+

Example for a heat pump with vapor injection using a phase separator

+

Let’s use a flowsheet which is more complex, e.g. the vapor injection +with a phase seperator. +We can import this flowsheet and how to use it like this:

+
from vclibpy.flowsheets import VaporInjectionPhaseSeparator
+help(VaporInjectionPhaseSeparator)
+
+
+

As it needs the same heat exchanger model as a standard heat pump, +we will just use the ones from the standard cycle. Also, as +the expansion valve model does not influence the results for +the current algorithm, we will just use the same expansion-valve +twice. Note, that you could size the two expansion valves +using vclibpy, including off-design, but this is one for another +example.

+
from vclibpy.components.heat_exchangers import moving_boundary_ntu
+from vclibpy.components.heat_exchangers import heat_transfer
+condenser = moving_boundary_ntu.MovingBoundaryNTUCondenser(
+    A=5,
+    secondary_medium="water",
+    flow_type="counter",
+    ratio_outer_to_inner_area=1,
+    two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=5000),
+    gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000),
+    wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3),
+    liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000),
+    secondary_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000)
+)
+evaporator = moving_boundary_ntu.MovingBoundaryNTUEvaporator(
+    A=15,
+    secondary_medium="air",
+    flow_type="counter",
+    ratio_outer_to_inner_area=10,
+    two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=1000),
+    gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=1000),
+    wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3),
+    liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=5000),
+    secondary_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=25)
+)
+from vclibpy.components.expansion_valves import Bernoulli
+high_pressure_valve = Bernoulli(A=0.1)
+low_pressure_valve = Bernoulli(A=0.1)
+
+
+

For the compressors, we need to specify low- and high-pressure +compressors. To achieve a somewhat similar heat pump as the +one in the standard-cycle example, we will assume that we +use two smaller compressors instead of one larger one:

+
from vclibpy.components.compressors import RotaryCompressor
+high_pressure_compressor = RotaryCompressor(
+    N_max=125,
+    V_h=19e-6 / 2
+)
+low_pressure_compressor = RotaryCompressor(
+    N_max=125,
+    V_h=19e-6 / 2
+)
+
+
+

Now, we can plug everything into the flowsheet:

+
heat_pump = VaporInjectionPhaseSeparator(
+    evaporator=evaporator,
+    condenser=condenser,
+    fluid="Propane",
+    high_pressure_compressor=high_pressure_compressor,
+    low_pressure_compressor=low_pressure_compressor,
+    high_pressure_valve=high_pressure_valve,
+    low_pressure_valve=low_pressure_valve
+)
+
+
+

As in the other example, we can specify save-paths, +solver settings and inputs to vary:

+
save_path = r"D:\00_temp\vapor_injection"
+T_eva_in_ar = [-10 + 273.15, 273.15, 10 + 273.15]
+T_con_in_ar = [30 + 273.15, 50 + 273.15, 60 + 273.15]
+n_ar = [0.3, 0.7, 1]
+
+
+

Now, we can generate the full-factorial performance map +using all inputs. The results will be stored under the +save-path. To see some logs, we can import the logging module +and get, for example, all messages equal or above the INFO-level

+
import logging
+logging.basicConfig(level="INFO")
+
+from vclibpy import utils
+utils.full_factorial_map_generation(
+    heat_pump=heat_pump,
+    save_path=save_path,
+    T_con_in_ar=T_con_in_ar,
+    T_eva_in_ar=T_eva_in_ar,
+    n_ar=n_ar,
+    use_multiprocessing=False,
+    save_plots=True,
+    m_flow_con=0.2,
+    m_flow_eva=0.9,
+    dT_eva_superheating=5,
+    dT_con_subcooling=0,
+)
+
+
+

As in the prior examples, feel free to load the plots, +.csv or .sdf result files and further analyze them

+
+
+

Vapor injection with an economizer.

+

Aside from the phase-separator flowsheet, we have one with +an economizer (additional heat exchanger). +The assumptions are similar, and the usage as well:

+
from vclibpy.flowsheets import VaporInjectionEconomizer
+help(VaporInjectionEconomizer)
+
+
+

We need an additional economizer, which can be found in the heat exchangers:

+
from vclibpy.components.heat_exchangers.economizer import VaporInjectionEconomizerNTU
+help(VaporInjectionEconomizerNTU)
+
+
+

Let’s assume some dummy parameters:

+
economizer = VaporInjectionEconomizerNTU(
+    A=2,
+    two_phase_heat_transfer=heat_transfer.constant.ConstantTwoPhaseHeatTransfer(alpha=50000),
+    gas_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=50000),
+    wall_heat_transfer=heat_transfer.wall.WallTransfer(lambda_=236, thickness=2e-3),
+    liquid_heat_transfer=heat_transfer.constant.ConstantHeatTransfer(alpha=50000),
+)
+
+
+

And create the heat pump, and run the map generation:

+
heat_pump = VaporInjectionEconomizer(
+    evaporator=evaporator,
+    condenser=condenser,
+    fluid="Propane",
+    economizer=economizer,
+    high_pressure_compressor=high_pressure_compressor,
+    low_pressure_compressor=low_pressure_compressor,
+    high_pressure_valve=high_pressure_valve,
+    low_pressure_valve=low_pressure_valve
+)
+utils.full_factorial_map_generation(
+    heat_pump=heat_pump,
+    save_path=r"D:\00_temp\vapor_injection_economizer",
+    T_con_in_ar=T_con_in_ar,
+    T_eva_in_ar=T_eva_in_ar,
+    n_ar=n_ar,
+    use_multiprocessing=False,
+    save_plots=True,
+    m_flow_con=0.2,
+    m_flow_eva=0.9,
+    dT_eva_superheating=5,
+    dT_con_subcooling=0,
+)
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/genindex.html b/docs/0.1.1/docs/genindex.html new file mode 100644 index 0000000..8a32e2c --- /dev/null +++ b/docs/0.1.1/docs/genindex.html @@ -0,0 +1,1190 @@ + + + + + + + + Index — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ A + | B + | C + | D + | E + | F + | G + | H + | I + | L + | M + | N + | P + | R + | S + | T + | U + | V + | W + +
+

A

+ + + +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + +
+ +

V

+ + + +
+ +

W

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/index.html b/docs/0.1.1/docs/index.html new file mode 100644 index 0000000..5c083e0 --- /dev/null +++ b/docs/0.1.1/docs/index.html @@ -0,0 +1,197 @@ + + + + + + + + + About vcliby — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

About vcliby

+E.ON EBC RWTH Aachen University +pylint +documentation +License +build +Binder +
+

VCLibPy

+

Repository with a Vapor Compression Library in Python for steady state process design and simulation. +It enables use of RefProp and CoolProp as well as different compressors, heat exchangers and flowsheet configurations for heat pumps and chillers.

+
+
+

Installation

+

To install, run

+
pip install vclibpy
+
+
+

To use RefProp, you have to buy the licence and obtain a valid .dll file.

+

In order to help development, install it as an egg:

+
git clone https://github.com/RWTH-EBC/vclibpy
+pip install -e vclibpy
+
+
+
+
+

How to get started?

+

We recommend running our jupyter-notebook to be guided through a helpful tutorial.
+For this, we prepared several examples, which we encourage to check one by one. +To use, you can either run the code locally or in a browser using juypter-notebook:

+

If the web-hosting is not available, you can run the notebooks locally with the following code:

+
pip install jupyter
+git clone https://github.com/RWTH-EBC/vclibpy
+jupyter notebook vclibpy/docs/jupyter_notebooks
+
+
+

Or, clone this repo and look at the folder examples. +Those examples are the same as the jupyter notebooks.

+
+
+

How to cite vclibpy

+

vclibpy is currently in the process of publication. A corresponding DOI will be added soon.

+
+ +
+

Documentation

+

Visit our official Documentation.

+
+
+

Problems?

+

Please raise an issue here.

+
+
+

Acknowledgements

+

We gratefully acknowledge the financial support by the Federal Ministry for Economic Affairs and Climate Action (BMWK), promotional reference 03EN1022B, as well as the European Regional Development Fund (ERDF) (ERDF-0500029).

+

BMWK

+ +
+
+

Indices and tables

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/objects.inv b/docs/0.1.1/docs/objects.inv new file mode 100644 index 0000000..557431d Binary files /dev/null and b/docs/0.1.1/docs/objects.inv differ diff --git a/docs/0.1.1/docs/py-modindex.html b/docs/0.1.1/docs/py-modindex.html new file mode 100644 index 0000000..d11f307 --- /dev/null +++ b/docs/0.1.1/docs/py-modindex.html @@ -0,0 +1,298 @@ + + + + + + + + Python Module Index — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Python Module Index

+ +
+ v +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ v
+ vclibpy +
    + vclibpy.components +
    + vclibpy.components.component +
    + vclibpy.components.compressors +
    + vclibpy.components.compressors.compressor +
    + vclibpy.components.compressors.constant_effectivness +
    + vclibpy.components.compressors.rotary +
    + vclibpy.components.compressors.ten_coefficient +
    + vclibpy.components.expansion_valves +
    + vclibpy.components.expansion_valves.bernoulli +
    + vclibpy.components.expansion_valves.expansion_valve +
    + vclibpy.components.heat_exchangers +
    + vclibpy.components.heat_exchangers.economizer +
    + vclibpy.components.heat_exchangers.heat_exchanger +
    + vclibpy.components.heat_exchangers.heat_transfer +
    + vclibpy.components.heat_exchangers.heat_transfer.air_to_wall +
    + vclibpy.components.heat_exchangers.heat_transfer.constant +
    + vclibpy.components.heat_exchangers.heat_transfer.heat_transfer +
    + vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall +
    + vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall +
    + vclibpy.components.heat_exchangers.heat_transfer.wall +
    + vclibpy.components.heat_exchangers.moving_boundary_ntu +
    + vclibpy.components.heat_exchangers.ntu +
    + vclibpy.components.phase_separator +
    + vclibpy.datamodels +
    + vclibpy.media +
    + vclibpy.media.cool_prop +
    + vclibpy.media.media +
    + vclibpy.media.ref_prop +
    + vclibpy.media.states +
    + vclibpy.utils +
    + vclibpy.utils.automation +
    + vclibpy.utils.nominal_design +
    + vclibpy.utils.plotting +
    + vclibpy.utils.printing +
    + vclibpy.utils.sdf_ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/search.html b/docs/0.1.1/docs/search.html new file mode 100644 index 0000000..4e60c22 --- /dev/null +++ b/docs/0.1.1/docs/search.html @@ -0,0 +1,123 @@ + + + + + + + + Search — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/0.1.1/docs/searchindex.js b/docs/0.1.1/docs/searchindex.js new file mode 100644 index 0000000..77d56b3 --- /dev/null +++ b/docs/0.1.1/docs/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["Contribution", "code/modules", "code/vclibpy", "code/vclibpy.components", "code/vclibpy.components.compressors", "code/vclibpy.components.expansion_valves", "code/vclibpy.components.heat_exchangers", "code/vclibpy.components.heat_exchangers.heat_transfer", "code/vclibpy.flowsheets", "code/vclibpy.media", "code/vclibpy.utils", "examples/e1_refrigerant_data", "examples/e2_compressor", "examples/e3_inputs_and_flowsheet_state", "examples/e4_heat_exchanger", "examples/e5_expansion_valve", "examples/e6_simple_heat_pump", "examples/e7_vapor_injection", "index", "version_his"], "filenames": ["Contribution.md", "code/modules.rst", "code/vclibpy.rst", "code/vclibpy.components.rst", "code/vclibpy.components.compressors.rst", "code/vclibpy.components.expansion_valves.rst", "code/vclibpy.components.heat_exchangers.rst", "code/vclibpy.components.heat_exchangers.heat_transfer.rst", "code/vclibpy.flowsheets.rst", "code/vclibpy.media.rst", "code/vclibpy.utils.rst", "examples/e1_refrigerant_data.md", "examples/e2_compressor.md", "examples/e3_inputs_and_flowsheet_state.md", "examples/e4_heat_exchanger.md", "examples/e5_expansion_valve.md", "examples/e6_simple_heat_pump.md", "examples/e7_vapor_injection.md", "index.rst", "version_his.rst"], "titles": ["Contribute as a user", "vclibpy", "vclibpy package", "vclibpy.components package", "vclibpy.components.compressors package", "vclibpy.components.expansion_valves package", "vclibpy.components.heat_exchangers package", "vclibpy.components.heat_exchangers.heat_transfer package", "vclibpy.flowsheets package", "vclibpy.media package", "vclibpy.utils package", "Refrigerant Data Example", "Compressor Example", "Inputs and FlowsheetState", "Heat Exchanger Example", "Expansion Valve Example", "Example for a heat pump with a standard cycle", "Example for a heat pump with vapor injection using a phase separator", "About vcliby", "Version History"], "terms": {"The": [0, 2, 3, 4, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17], "exampl": [0, 4, 9, 10, 13, 18], "tutori": [0, 18], "should": [0, 9, 10, 13, 14, 15, 16], "understand": [0, 11, 13, 14], "code": [0, 6, 9, 16, 18], "bug": [0, 9], "free": [0, 7, 17], "As": [0, 7, 13, 14, 16, 17], "all": [0, 2, 4, 9, 10, 11, 13, 14, 16, 17], "": [0, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17], "have": [0, 3, 4, 6, 9, 11, 12, 13, 14, 15, 16, 17, 18], "differ": [0, 4, 6, 7, 9, 10, 12, 13, 14, 15, 18], "background": 0, "you": [0, 2, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "mai": [0, 2, 5, 6, 9, 10, 11, 12, 13, 14], "everyth": [0, 9, 16, 17], "encount": 0, "In": [0, 4, 9, 10, 14, 16, 18], "case": [0, 4, 9, 10], "pleas": [0, 10, 18], "rais": [0, 7, 9, 10, 18], "an": [0, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18], "issu": [0, 10, 18], "here": [0, 7, 11, 12, 13, 16, 18], "consid": 0, "label": [0, 10], "us": [0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 18], "flag": [0, 9], "question": 0, "If": [0, 4, 7, 9, 10, 12, 13, 14, 16, 18], "instead": [0, 9, 10, 14, 17], "want": [0, 9, 12, 13, 14, 15], "new": [0, 2, 9, 10, 13], "featur": 0, "fix": [0, 9], "yourself": 0, "we": [0, 11, 12, 13, 14, 15, 16, 17, 18], "ar": [0, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "more": [0, 6, 7, 10, 14, 17], "than": [0, 14, 15], "happi": 0, "also": [0, 12, 13, 14, 15, 16, 17], "creat": [0, 9, 10, 11, 17], "branch": 0, "issuexy_some_nam": 0, "xy": 0, "i": [0, 2, 4, 5, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 18], "number": [0, 4, 6, 7, 9, 11], "your": [0, 4, 13, 15], "some_nam": 0, "meaing": 0, "descript": [0, 1, 2, 9, 13, 16], "onc": 0, "re": [0, 7], "readi": 0, "pull": 0, "request": 0, "check": [0, 6, 7, 9, 12, 14, 15, 18], "pipelin": 0, "succe": 0, "assign": [0, 14], "review": 0, "befor": [0, 12], "merg": [0, 10], "finish": 0, "can": [0, 3, 4, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "implement": [0, 6, 7, 9, 10, 15, 19], "modifi": [0, 4], "modul": [0, 1, 11, 16, 17, 18], "class": [0, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16], "function": [0, 3, 6, 7, 9, 10, 11, 12, 13, 14, 16, 19], "read": 0, "follow": [0, 6, 9, 10, 14, 18], "page": [0, 18], "pep8": 0, "some": [0, 9, 11, 12, 15, 16, 17], "id": [0, 16], "like": [0, 2, 10, 12, 13, 16, 17], "pycharm": [0, 16], "automat": [0, 4, 10, 12], "show": [0, 10, 11, 12, 14, 15, 16], "don": [0, 16], "t": [0, 3, 4, 6, 9, 10, 11, 12, 14, 16], "thi": [0, 2, 3, 4, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "get": [0, 1, 2, 3, 4, 9, 11, 13, 14, 16, 17], "better": [0, 11, 14], "properli": [0, 9], "try": [0, 11], "structur": [0, 10], "alreadi": 0, "present": 0, "possibl": [0, 3, 5, 6, 7, 9, 11, 14], "write": 0, "littl": 0, "doctest": 0, "docstr": 0, "make": [0, 13], "clear": 0, "what": [0, 14, 15, 16], "desir": 0, "output": [0, 4, 5, 13], "non": [0, 11], "self": [0, 4, 9, 13], "explanatori": 0, "line": [0, 9], "includ": [0, 4, 9, 10, 11, 16, 17], "comment": 0, "style": 0, "e": [0, 6, 7, 9, 10, 11, 17, 18], "g": [0, 6, 7, 9, 10, 11, 17], "def": 0, "foo": 0, "dummi": [0, 12, 15, 17], "dummy2": 0, "describ": 0, "doe": [0, 3, 6, 9, 12, 16, 17], "blank": 0, "below": 0, "necessari": [0, 9], "doc": [0, 14, 18], "render": 0, "nice": 0, "arg": [0, 2, 4, 5, 6, 7, 9, 10], "str": [0, 2, 4, 6, 7, 9, 10], "ani": [0, 2, 11, 12, 13, 14], "paramet": [0, 4, 7, 10, 12, 13, 14, 15, 17], "int": [0, 7, 9, 11], "float": [0, 2, 3, 4, 5, 6, 7, 9, 10], "A": [0, 2, 3, 5, 6, 7, 9, 10, 14, 15, 16, 17, 18], "variabl": [0, 1, 2, 6, 7, 9, 10, 13, 16], "two": [0, 6, 7, 9, 10, 11, 12, 13, 17, 18], "type": [0, 4, 6, 10, 11, 13], "espaci": 0, "when": [0, 2, 9, 13], "add": [0, 2, 9, 13], "open": [0, 5, 9, 14, 16], "test_modul": 0, "py": [0, 10, 18], "file": [0, 2, 4, 9, 10, 16, 17, 18], "directori": [0, 9, 10], "testmodul": 0, "name": [0, 1, 2, 4, 6, 7, 9, 10, 13, 16], "test_my_new_funct": 0, "test_my_new_modul": 0, "exist": [0, 16, 18], "other": [0, 10, 12, 13, 16, 17], "familiar": [0, 11], "quick": 0, "summari": [0, 4], "mani": 0, "thing": [0, 12], "even": [0, 9], "seemingli": 0, "silli": 0, "correct": [0, 5, 9], "input": [0, 1, 2, 4, 6, 7, 9, 10, 12, 14, 15, 16, 17], "format": [0, 2, 4, 9, 11, 13, 16], "help": [0, 11, 12, 14, 15, 16, 17, 18], "prevent": 0, "futur": [0, 13, 14], "problem": 0, "assertsometh": 0, "provid": [0, 4, 9, 10], "unittest": 0, "wai": [0, 13], "failur": 0, "correctli": 0, "error": [0, 6, 9, 14], "insid": [0, 6, 7, 14], "handel": 0, "success": 0, "depend": [0, 6, 9, 16], "devic": [0, 14], "decor": 0, "skip": 0, "skipif": 0, "numpi": [0, 9, 10, 12, 14, 15], "__version__": 0, "1": [0, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19], "0": [0, 2, 4, 5, 6, 7, 9, 10, 11, 12, 14, 15, 16, 17, 19], "support": [0, 9, 10, 18], "version": [0, 18], "etc": [0, 9, 11, 13], "setup": 0, "teardown": 0, "call": [0, 9, 11], "after": [0, 2, 11, 12], "each": [0, 10, 11, 12], "defin": [0, 2, 3, 4, 9, 10, 11, 12, 13, 14, 16], "everi": 0, "close": [0, 11, 14], "applic": [0, 18], "dymola": 0, "complet": [0, 16], "see": [0, 5, 6, 9, 12, 13, 14, 16, 17], "further": [0, 2, 7, 9, 11, 14, 17], "inform": [0, 9, 10, 11, 13], "work": [0, 3, 9, 10, 11, 12, 13, 14, 19], "run": [0, 10, 17, 18], "commit": 0, "git": [0, 18], "With": [0, 11, 14], "keep": [0, 14], "our": [0, 14, 16, 18], "clean": 0, "repo": [0, 18], "how": [0, 11, 12, 13, 14, 15, 16, 17], "packag": [1, 12, 14, 15, 18], "subpackag": 1, "compon": [1, 2, 9, 11, 12, 13, 14, 15, 16, 17], "submodul": 1, "phase_separ": [1, 2], "flowsheet": [1, 2, 4, 6, 7, 10, 13, 16, 17, 18], "base": [1, 2, 3, 4, 5, 6, 7, 9, 10, 14, 19], "standard": [1, 2, 14, 17], "vapor_inject": [1, 2, 17], "vapor_injection_econom": [1, 2, 17], "vapor_injection_phase_separ": [1, 2], "media": [1, 2, 6, 11, 12, 14, 15], "coolprop": [1, 2, 9, 11, 12, 14, 15, 18], "medprop": [1, 2, 3, 6, 7, 9, 10, 11], "refprop": [1, 2, 11, 18], "thermodynamicst": [1, 2, 3, 6, 7, 9, 10], "transportproperti": [1, 2, 6, 7, 9], "cool_prop": [1, 2, 11], "ref_prop": [1, 2], "state": [1, 2, 3, 4, 6, 7, 10, 11, 13, 14, 15, 18], "util": [1, 2, 16, 17], "autom": [1, 2], "nominal_design": [1, 2], "plot": [1, 2, 9, 12, 13, 15, 16, 17], "print": [1, 2, 11, 12, 13, 14, 15, 16], "sdf_": [1, 2], "ten_coefficient_compressor_reqress": [1, 2], "datamodel": [1, 6], "flowsheetst": [1, 2, 4, 6, 7, 12, 14], "unit": [1, 2, 6, 9, 13, 16, 18], "valu": [1, 2, 4, 6, 9, 10, 11, 12, 13, 14, 16], "variablecontain": [1, 2], "convert_to_str_value_format": [1, 2], "copi": [1, 2, 9, 13], "get_variable_nam": [1, 2, 13], "get_vari": [1, 2, 13], "item": [1, 2, 13], "set": [1, 2, 3, 4, 6, 7, 9, 10, 12, 13, 14, 16, 17], "stationari": 2, "vapor": [2, 3, 4, 6, 9, 11, 12, 13, 15], "compress": [2, 3, 4, 11, 12, 13, 15], "model": [2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 16, 17], "analysi": [2, 6], "compressor": [2, 3, 11, 13, 16, 17, 18], "constant_effectiv": [2, 3], "rotari": [2, 3], "ten_coeffici": [2, 3], "expansion_valv": [2, 3, 15, 16, 17], "bernoulli": [2, 3, 15, 16, 17], "heat_exchang": [2, 3, 14, 16, 17], "econom": [2, 3, 18], "moving_boundary_ntu": [2, 3, 16, 17], "ntu": [2, 3, 14], "basecompon": [2, 3, 4, 5, 6], "m_flow": [2, 3, 4, 5, 6, 7, 12, 14, 15], "med_prop": [2, 3, 7, 9, 10, 12, 14, 15], "start_secondary_med_prop": [2, 3, 6, 14], "state_inlet": [2, 3, 7, 12, 14, 15], "state_outlet": [2, 3, 7, 12, 14, 15], "terminate_secondary_med_prop": [2, 3, 6], "phasesepar": [2, 3], "state_outlet_liquid": [2, 3], "state_outlet_vapor": [2, 3], "calc_stat": [2, 9, 11, 12, 14, 15], "calc_transport_properti": [2, 9, 11], "get_critical_point": [2, 9, 11], "get_molar_mass": [2, 9], "calc_mean_transport_properti": [2, 9], "get_two_phase_limit": [2, 9, 11, 14], "termin": [2, 3, 6, 9], "calc_satliq_st": [2, 9], "get_available_subst": [2, 9], "get_comp_nam": [2, 9], "get_def_limit": [2, 9], "get_dll_path": [2, 9], "get_fluid_nam": [2, 9], "get_gwp": [2, 9], "get_longnam": [2, 9], "get_mass_fract": [2, 9], "get_mol_fract": [2, 9], "get_molar_composit": [2, 9], "get_nbp": [2, 9], "get_odp": [2, 9], "get_safeti": [2, 9], "get_sat_vap_pressur": [2, 9], "get_triple_point": [2, 9], "get_vers": [2, 9], "is_mixtur": [2, 9], "set_error_flag": [2, 9], "set_warning_flag": [2, 9], "get_pretty_print": [2, 9, 11], "calc_multiple_st": [2, 10], "full_factorial_map_gener": [2, 10, 16, 17], "nominal_hp_design": [2, 10], "plot_cycl": [2, 10, 19], "plot_sdf_map": [2, 10, 16], "set_axis_styl": [2, 10], "print_stat": [2, 10], "merge_sdf": [2, 10], "save_to_sdf": [2, 10], "sdf_to_csv": [2, 10], "which": [2, 4, 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 18], "contain": [2, 9, 10, 11, 14, 16], "librari": 2, "sourc": [2, 3, 4, 5, 6, 7, 9, 10], "uniqu": 2, "heat": [2, 3, 4, 6, 7, 9, 10, 11, 12, 13, 18], "pump": [2, 7, 10, 14, 18], "dynam": [2, 7, 9, 14], "sens": [2, 14], "attribut": 2, "ad": [2, 9, 12, 18], "dure": [2, 6], "calcul": [2, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15], "enabl": [2, 9, 14, 18], "easi": [2, 13], "custom": [2, 9, 10, 13], "analyz": [2, 10, 13, 16, 17], "whole": [2, 12], "restrict": 2, "certain": [2, 13, 14], "convent": 2, "n": [2, 4, 9, 10, 12, 16], "none": [2, 4, 6, 9, 10, 12], "t_eva_in": [2, 10, 14, 16], "t_con_in": [2, 10, 16], "m_flow_eva": [2, 10, 14, 16, 17], "m_flow_con": [2, 10, 16, 17], "dt_eva_superh": [2, 10, 14, 16, 17], "dt_con_subcool": [2, 10, 14, 16, 17], "t_ambient": 2, "while": [2, 11, 12, 14], "pre": [2, 14], "ones": [2, 17], "method": [2, 3, 4, 6, 7, 9, 14], "rel": [2, 4, 12, 16], "speed": [2, 4, 10, 12, 13, 16], "between": [2, 4, 5, 6, 9], "secondari": [2, 3, 6, 13, 14], "side": [2, 6, 7, 13, 14], "evapor": [2, 4, 6, 7, 10, 11, 14, 15, 16, 17], "inlet": [2, 3, 7, 12, 13, 14, 15], "temperatur": [2, 4, 6, 9, 10, 11, 12, 13, 14, 16], "condens": [2, 4, 6, 10, 11, 14, 16, 17], "mass": [2, 3, 4, 5, 7, 9, 10, 13, 14, 15], "flow": [2, 3, 4, 5, 6, 7, 10, 13, 14, 15], "rate": [2, 3, 4, 5, 6, 7, 10, 13, 14, 15], "super": [2, 12], "subcool": [2, 4, 6, 9, 10, 11, 14], "ambient": [2, 13], "machin": 2, "object": [2, 3, 6, 7, 9, 10, 13], "numer": 2, "measur": 2, "option": [2, 4, 6, 7, 9, 10, 11, 13, 14], "hold": [2, 14], "anywher": 2, "addit": [2, 9, 17], "with_unit_and_descript": 2, "bool": [2, 9, 10], "dict": [2, 4, 9, 10, 13], "return": [2, 3, 4, 5, 6, 7, 10], "dictionari": [2, 4, 9, 10], "handi": 2, "store": [2, 10, 13, 14, 16, 17], "result": [2, 4, 10, 12, 13, 14, 15, 16, 17], "csv": [2, 10, 13, 16, 17], "xlsx": [2, 10], "fals": [2, 9, 10, 16, 17], "onli": [2, 4, 6, 9, 10, 11, 13, 14, 15], "string": [2, 9], "deepcopi": 2, "instanc": [2, 3, 6, 9, 11, 13], "mutabl": [2, 13], "default": [2, 3, 4, 6, 9, 10, 13, 14, 16], "specifi": [2, 9, 10, 12, 15, 16, 17], "found": [2, 10, 17], "list": [2, 4, 9, 10, 11, 16], "from": [2, 4, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17], "updat": [2, 10], "calc_electrical_pow": [3, 4, 12], "calc_m_flow": [3, 4, 12], "calc_state_outlet": [3, 4, 12], "get_eta_isentrop": [3, 4], "get_eta_mech": [3, 4], "get_lambda_h": [3, 4], "get_n_absolut": [3, 4], "get_p_outlet": [3, 4], "constanteffectivenesscompressor": [3, 4, 12], "rotarycompressor": [3, 4, 12, 16, 17], "basetencoefficientcompressor": [3, 4], "get_paramet": [3, 4], "datasheetcompressor": [3, 4], "tencoefficientcompressor": [3, 4, 12], "calc_ten_coeffici": [3, 4], "calc_m_flow_at_open": [3, 5], "calc_opening_at_m_flow": [3, 5, 15], "expansionvalv": [3, 5, 15], "calc_outlet": [3, 5, 15], "heat_transf": [3, 6, 14, 16, 17], "air_to_wal": [3, 6], "constant": [3, 4, 6, 12, 14, 16, 17], "pipe_to_wal": [3, 6], "vdi_atlas_air_to_wal": [3, 6], "wall": [3, 6, 14, 16, 17], "vaporinjectioneconomizerntu": [3, 6, 17], "calc": [3, 6, 7, 14], "calc_alpha_secondari": [3, 6], "calc_transport_properties_secondary_medium": [3, 6], "set_secondary_cp": [3, 6], "state_two_phase_inlet": [3, 6], "state_two_phase_outlet": [3, 6], "heatexchang": [3, 6], "calc_q_flow": [3, 6, 14], "calc_alpha_ga": [3, 6], "calc_alpha_liquid": [3, 6], "calc_alpha_two_phas": [3, 6], "calc_secondary_q_flow": [3, 6], "calc_secondary_cp": [3, 6], "calc_wall_heat_transf": [3, 6], "m_flow_secondari": [3, 6], "m_flow_secondary_cp": [3, 6], "movingboundaryntu": [3, 6], "iterate_area": [3, 6], "separate_phas": [3, 6], "movingboundaryntucondens": [3, 6, 16, 17], "movingboundaryntuevapor": [3, 6, 14, 16, 17], "basicntu": [3, 6], "calc_ntu": [3, 6], "calc_q_ntu": [3, 6], "calc_r": [3, 6], "calc_ep": [3, 6], "calc_k": [3, 6], "calc_m_flow_cp_min": [3, 6], "set_primary_cp": [3, 6], "abc": [3, 4, 5, 6, 7, 9], "abstract": [3, 5, 6, 7, 9], "interfac": [3, 9], "cycl": [3, 4, 6, 9, 10, 11, 13, 14, 17], "To": [3, 6, 9, 11, 13, 14, 16, 17, 18], "multiprocess": [3, 9, 10], "start": [3, 6, 9, 10, 11, 14, 15, 16], "main": [3, 6], "thread": [3, 6], "pickl": [3, 6], "exchang": [3, 6, 7, 11, 13, 17, 18], "overrid": [3, 6, 13], "properti": [3, 4, 6, 7, 9, 10, 11, 12], "access": [3, 9, 12, 13, 16], "outlet": [3, 4, 5, 7, 14, 15], "through": [3, 18], "wrapper": [3, 6], "fluid": [3, 7, 9, 10, 11, 16, 17], "multi": [3, 6, 14], "process": [3, 6, 14, 15, 18], "med": [3, 6, 14, 15], "prop": [3, 6, 9, 14, 15], "simpl": [3, 5, 7, 14], "phase": [3, 6, 7, 9, 10, 11], "separ": [3, 6], "getter": 3, "liquid": [3, 6, 9], "n_max": [4, 12, 16, 17], "v_h": [4, 12, 16, 17], "extend": 4, "specif": [4, 6, 9, 10, 11, 13], "maxim": [4, 14], "rotat": 4, "per": 4, "second": [4, 9, 10, 14], "volum": [4, 9], "m": [4, 6, 7, 9, 12], "3": [4, 9, 10, 13, 14, 15, 16, 17], "volumetr": 4, "effici": [4, 7, 12, 13, 14], "p_outlet": [4, 5, 12, 15], "isentrop": [4, 11], "mechan": 4, "pressur": [4, 5, 6, 9, 11, 12, 13, 14, 15, 17], "absolut": 4, "frequenc": [4, 16], "fs_state": [4, 6, 7, 12, 13, 14], "high": [4, 9, 17], "level": [4, 5, 9, 10, 11, 13, 14, 15, 16, 17], "refriger": [4, 6, 7, 9, 10, 12, 14], "electr": 4, "power": 4, "consum": 4, "adiabat": 4, "energi": [4, 9, 18], "balanc": 4, "motor": 4, "invert": 4, "given": [4, 5, 6, 7, 9, 10, 11, 12, 14, 15], "round": [4, 9], "sec": 4, "eta_isentrop": [4, 12], "eta_mech": [4, 12], "lambda_h": [4, 12], "inherit": 4, "basic": [4, 7, 11, 12, 13, 14, 16], "behavior": 4, "eta_invert": 4, "eta_motor": 4, "product": 4, "effect": [4, 6, 12], "thesi": [4, 18], "mirko": 4, "engelpracht": 4, "character": 4, "regress": 4, "famili": 4, "coeffici": [4, 6, 7, 9, 16], "hi": 4, "master": [4, 9], "datasheet": 4, "kwarg": [4, 5, 6, 7, 10], "ten": 4, "tabl": [4, 10], "ha": [4, 12, 15], "order": [4, 9, 10, 14, 18], "column": [4, 16], "import": [4, 6, 11, 12, 13, 14, 15, 16, 17], "must": [4, 10], "same": [4, 6, 9, 10, 12, 13, 14, 15, 17, 18], "tabel": 4, "match": [4, 15], "argument": [4, 5, 6, 7, 12, 13, 16], "parameter_nam": 4, "fiction": 4, "placehold": 4, "capac": [4, 6, 9], "w": [4, 7, 9], "kg": [4, 5, 9, 10, 11, 12], "h": [4, 9, 10, 11, 14, 15], "n1": 4, "n2": 4, "n_last": 4, "p1": 4, "42": 4, "12": [4, 9], "243": 4, "32": 4, "412": 4, "p10": 4, "10": [4, 9, 12, 13, 14, 16, 17, 18], "23": 4, "21": [4, 9], "41": 4, "2434": 4, "path": [4, 9, 10, 16, 17], "intern": [4, 9], "kei": [4, 10], "input_pow": 4, "eta_": 4, "volumentr": 4, "sheet_nam": 4, "sheet": 4, "t_eva": [4, 14], "t_con": 4, "type_": 4, "celsiu": 4, "interpol": 4, "keyword": [4, 5], "pa": [4, 9, 11, 14], "t_sc": 4, "t_sh": 4, "capacity_definit": 4, "assumed_eta_mech": 4, "accord": [4, 7, 13, 14], "data": [4, 10, 12, 13], "cool": [4, 9], "h1": 4, "h4": 4, "h2": 4, "h3": 4, "assum": [4, 7, 11, 12, 14, 15, 17], "otherwis": 4, "For": [4, 6, 7, 9, 11, 12, 13, 14, 15, 16, 17, 18], "p_el": [4, 12], "k": [4, 6, 7, 9, 11, 14], "superh": [4, 6, 9, 10], "definit": [4, 9], "need": [4, 9, 12, 13, 14, 16, 17], "coef_list": 4, "expans": [5, 9, 11, 14, 16, 17], "valv": [5, 14, 16, 17], "cross": [5, 6, 7, 15], "section": [5, 7, 9, 15], "area": [5, 6, 7, 14, 15], "child": 5, "ev": 5, "thei": [5, 14], "isenthalp": [5, 14], "airtowalltransf": [6, 7], "calc_laminar_area_nusselt": [6, 7], "calc_reynold": [6, 7], "wsuairtowal": [6, 7], "constantheattransf": [6, 7, 14, 16, 17], "constanttwophaseheattransf": [6, 7, 14, 16, 17], "heattransf": [6, 7], "twophaseheattransf": [6, 7], "calc_reynolds_pip": [6, 7], "turbulentfluidinpipetowalltransf": [6, 7], "calc_turbulent_tube_nusselt": [6, 7], "airsourceheatexchangergeometri": [6, 7], "a_freieoberflaecherohr": [6, 7], "a_rippen": [6, 7], "a_rohrinnen": [6, 7], "a_rohrunberippt": [6, 7], "alpha_": [6, 7], "char_length": [6, 7], "d_a": [6, 7], "d_i": [6, 7], "dicke_ripp": [6, 7], "eta_r": [6, 7], "hoeh": [6, 7], "laeng": [6, 7], "lambda_r": [6, 7], "n_rippen": [6, 7], "n_rohr": [6, 7], "phi": [6, 7], "t_l": [6, 7], "t_q": [6, 7], "tief": [6, 7], "verjuengungsfaktor": [6, 7], "vdiatlasairtowalltransf": [6, 7], "walltransf": [6, 7, 14, 16, 17], "inject": [6, 13], "pure": [6, 9], "estim": [6, 7, 13], "parent": 6, "assumpt": [6, 7, 11, 14, 15, 17], "flow_typ": [6, 14, 16, 17], "counter_flow": 6, "ratio_outer_to_inner_area": [6, 14, 16, 17], "pipe": [6, 7], "nearli": 6, "diamet": [6, 7, 15], "length": [6, 7], "transfer": [6, 7, 14], "alpha": [6, 7, 14, 16, 17], "disabl": [6, 10], "ga": 6, "both": [6, 10, 14], "save": [6, 10, 13, 16, 17], "later": [6, 14], "valid": [6, 9, 10, 11, 14, 18], "tupl": [6, 9, 10], "percentag": 6, "requir": [6, 10, 11, 12, 13, 14, 15], "dt_min": [6, 14], "minim": [6, 10], "neg": [6, 14], "transport_properti": [6, 7, 11], "medium": [6, 7, 10], "transport": [6, 7, 9, 11, 14], "p": [6, 9, 10, 11, 14, 18], "select": [6, 11], "secondary_medium": [6, 7, 14, 16, 17], "cp": [6, 9], "primari": [6, 10], "m_flow_cp": 6, "up": [6, 9, 10], "wall_heat_transf": [6, 14, 16, 17], "secondary_heat_transf": [6, 14, 16, 17], "gas_heat_transf": [6, 14, 16, 17], "liquid_heat_transf": [6, 14, 16, 17], "two_phase_heat_transf": [6, 14, 16, 17], "he": [6, 7], "2": [6, 7, 9, 10, 11, 12, 14, 15, 16, 17], "water": [6, 7, 16, 17], "air": [6, 7, 14, 16, 17], "total": [6, 7, 9], "state_q0": [6, 7], "state_q1": [6, 7], "qualiti": [6, 9, 11], "q_flow": [6, 14], "move": [6, 14, 19], "boundari": [6, 9, 13, 14], "dt_max": 6, "alpha_pri": 6, "alpha_sec": 6, "q": [6, 9, 11, 14], "iter": [6, 9, 10, 15], "maximum": [6, 9, 11], "differenti": 6, "state_max": 6, "state_min": 6, "chang": [6, 9, 10, 12, 14], "three": [6, 10], "part": 6, "sc": 6, "latent": 6, "lat": 6, "sh": 6, "higher": [6, 9, 14, 16], "enthalpi": [6, 9, 11, 15], "lower": [6, 9, 14, 16], "q_sc": 6, "q_lat": 6, "q_sh": 6, "actual": 6, "No": [6, 11], "over": [6, 9, 11, 13], "counter": [6, 14, 16, 17], "parallel": 6, "overal": 6, "multipli": 6, "outer": 6, "howev": [6, 10, 13, 14, 15, 16], "drastic": 6, "vdi": [6, 7], "atla": [6, 7], "propos": 6, "ratio": [6, 12, 13], "inner": [6, 9], "account": 6, "mismatch": 6, "size": [6, 9, 14, 16, 17], "typic": [6, 14], "around": [6, 11, 12, 15], "20": 6, "30": [6, 16, 17], "static": [6, 9], "r": [6, 10, 16, 17], "ep": 6, "ebc": [6, 18], "lectur": 6, "simmodel": 6, "minimum": [6, 9, 11], "a_cross": 7, "characteristic_length": 7, "m2": 7, "similitud": 7, "approach": [7, 14], "alwai": [7, 11, 12, 14], "laminar": 7, "pr": [7, 9], "lambda_": [7, 14, 16, 17], "nusselt": 7, "reynold": 7, "prandlt": 7, "lambda": 7, "dynamic_viscos": 7, "viscos": [7, 9], "ws\u00fc": 7, "script": [7, 16], "rwth": [7, 18], "prandtl": [7, 9], "allow": 7, "notimplementederror": 7, "subclass": 7, "thermodynam": [7, 9, 10], "begin": 7, "region": [7, 9, 11, 18], "end": [7, 9, 14], "characterist": 7, "turbul": 7, "equat": 7, "note": [7, 11, 12, 14, 15, 16, 17], "just": [7, 11, 12, 13, 16, 17], "one": [7, 9, 10, 13, 15, 16, 17, 18], "taler2016": 7, "domanski1989_sp_smooth": 7, "amalfi2016": 7, "scriptws\u00fc": 7, "regim": [7, 14], "eta_by_eta_w": 7, "refer": [7, 9, 12, 18], "paper": 7, "document": [7, 9, 11, 12, 14, 16], "info": [7, 16, 17], "ref": [7, 9], "calibr": 7, "correl": [7, 14], "nuseelt": 7, "tube": 7, "conderns": 7, "50": [7, 12, 16, 17], "500": 7, "00195": 7, "5e": [7, 15], "05": [7, 9, 13], "04": [7, 9, 10], "64": 7, "geometri": 7, "fin": 7, "row": 7, "shift": 7, "arrang": 7, "w\u00e4rmeatla": 7, "berechnungsbl\u00e4tt": 7, "f\u00fcr": 7, "den": 7, "w\u00e4rme\u00fcbergang": 7, "11": [7, 9], "auflag": 7, "1461": 7, "german": 7, "kept": 7, "well": [7, 9, 12, 14, 17, 18], "surfac": [7, 9, 10], "outsid": [7, 9, 11], "without": [7, 11, 13, 16], "alpha_r": 7, "appar": 7, "averag": [7, 9], "auxiliari": 7, "reduct": 7, "factor": [7, 9, 14], "a_cross_fre": 7, "a_cross_smallest": 7, "geometry_paramet": 7, "thermal": [7, 9], "conduct": [7, 9, 11], "thick": [7, 14, 16, 17], "materi": 7, "km": 7, "fluid_nam": [9, 11, 12, 14, 15], "use_high_level_api": 9, "true": [9, 10, 14, 16, 17], "api": 9, "much": [9, 10, 15], "slower": 9, "mode": 9, "var1": 9, "var2": 9, "chosen": 9, "si": 9, "pt": [9, 12, 14], "might": [9, 13], "fall": 9, "within": 9, "densiti": 9, "where": [9, 10], "know": [9, 16], "invers": 9, "physic": 9, "scope": 9, "998": 9, "999": 9, "supercrit": 9, "pd": [9, 16], "ph": [9, 11, 14], "pq": [9, 11, 12, 14], "entropi": 9, "pu": 9, "td": 9, "th": 9, "tq": [9, 11, 14, 15], "tu": 9, "dh": 9, "d": [9, 15, 16, 17, 18], "du": 9, "abov": [9, 16, 17], "first": [9, 10, 11, 12, 13, 14, 15, 19], "assertionerror": 9, "avail": [9, 18], "current": [9, 10, 13, 14, 15, 16, 17, 18], "retriev": 9, "critic": [9, 11], "point": [9, 10, 11, 14, 15], "tc": 9, "pc": 9, "dc": 9, "molar": 9, "mol": 9, "serv": 9, "comput": 9, "limit": [9, 10, 11], "state_in": 9, "state_out": 9, "quantiti": 9, "p_min": [9, 11], "100000": 9, "p_step": [9, 11, 14], "5000": [9, 14, 16, 17], "arrai": [9, 10, 12], "purpos": 9, "It": [9, 18], "rang": [9, 11, 13, 14], "step": [9, 14], "variat": 9, "ndarrai": [9, 10], "valueerror": 9, "behaviour": 9, "noth": [9, 14], "z": 9, "dll_path": 9, "use_error_check": 9, "use_warn": 9, "ref_prop_path": 9, "copy_dl": 9, "copy_dll_directori": 9, "connect": 9, "param": 9, "composit": 9, "design": [9, 10, 16, 17, 18], "mixtur": 9, "shall": 9, "r32": 9, "fld": 9, "r125": 9, "fraction": 9, "697": 9, "303": 9, "would": [9, 13, 14, 15], "similar": [9, 10, 11, 17], "r410a": [9, 10], "dll": [9, 11, 18], "c": [9, 11, 12, 14, 18], "path_to_dllrefprop64": 9, "determin": 9, "boolean": 9, "whether": 9, "warn": 9, "env": 9, "rpprefix": 9, "simultan": 9, "multipl": [9, 10, 12], "instal": 9, "ctrefprop": 9, "http": [9, 10, 18], "github": [9, 18], "com": [9, 18], "usnistgov": 9, "tree": 9, "python": [9, 11], "deviat": 9, "gui": 9, "last": [9, 10, 12, 15], "somehow": 9, "though": 9, "rp": 9, "now": [9, 11, 12, 14, 15, 16, 17], "header": [9, 16], "global": 9, "warm": 9, "potenti": 9, "ozon": 9, "deplet": 9, "safeti": 9, "substanc": 9, "long": 9, "crit": 9, "2020": 9, "christoph": [9, 10], "hoeg": [9, 10], "gwp": 9, "odp": 9, "wasn": 9, "fulli": 9, "testet": 9, "r455a": 9, "still": [9, 12, 14, 15], "slightli": 9, "25": [9, 14, 16, 17], "command": 9, "instruct": 9, "init": 9, "__init__": 9, "remov": 9, "protect": 9, "due": [9, 12], "adjust": [9, 14], "_call_refprop": 9, "frac": 9, "08": 9, "abflshdll": 9, "abflsh": 9, "convers": [9, 18], "so": [9, 11, 12, 14], "user": [9, 13, 18], "choos": 9, "Not": [9, 15], "4": [9, 15], "19": 9, "debug": 9, "predefin": 9, "5": [9, 10, 12, 15, 16, 17], "22": 9, "6": [9, 12, 16, 17], "06": 9, "fabian": 9, "wuellhorst": 9, "time": [9, 12, 14], "kj": [9, 11, 14], "kgk": [9, 14], "kr": 9, "relev": [9, 11, 12, 13], "include_end": 9, "save_txt": 9, "kind": 9, "mix": 9, "text": 9, "comp_nam": 9, "tmin": 9, "tmax": 9, "dmax": 9, "pmax": 9, "min": 9, "max": [9, 14], "locat": [9, 10], "path_to_dl": 9, "fail": 9, "longnam": 9, "use_round": 9, "exact": 9, "fourth": 9, "mass_frac": 9, "z_molar": 9, "whose": 9, "_mol_frac": 9, "x": 9, "y": 9, "normal": 9, "boil": 9, "bar": [9, 11, 14], "nbp": 9, "t_sat": 9, "satur": 9, "solid": 9, "equilibrium": 9, "p_sat": 9, "tripl": 9, "fine": 9, "t_tpl": 9, "p_tpl": 9, "wrapper_vers": 9, "refprop_vers": 9, "find": [9, 14], "out": [9, 12], "_mix_flag": 9, "err": 9, "notifi": 9, "went": 9, "u": 9, "v": [9, 18], "repres": 9, "necessarili": 9, "j": [9, 11, 18], "initi": 9, "__str__": 9, "represent": 9, "lam": 9, "dyn_vi": 9, "kin_vi": 9, "cv": 9, "beta": 9, "sur_ten": 9, "ace_fac": 9, "kinemat": 9, "isobar": [9, 11], "isochor": 9, "tension": 9, "acentr": 9, "belong": [9, 16], "handl": [9, 13], "databas": 9, "load": [9, 16, 17], "variou": [9, 10], "relat": 9, "1000": [9, 14, 16, 17], "primarili": 9, "visual": [9, 10], "accuraci": [9, 10], "exclus": 9, "append": [9, 11, 12, 13, 14, 15], "form": 9, "revers": 9, "maintain": 9, "author": [9, 10], "jona": 9, "brach": 9, "test": [9, 18], "statu": 9, "exclud": 9, "gener": [10, 16, 17], "hp": 10, "map": [10, 16, 17], "save_path": [10, 16, 17], "heat_pump": [10, 16, 17], "basecycl": [10, 16], "pathlib": 10, "simul": [10, 13, 14, 15, 16, 18], "solver": [10, 16, 17], "t_eva_in_ar": [10, 16, 17], "t_con_in_ar": [10, 16, 17], "n_ar": [10, 16, 17], "use_multiprocess": [10, 16, 17], "save_plot": [10, 16, 17], "full": [10, 16, 17], "factori": [10, 16, 17], "perform": [10, 16, 17], "tool": 10, "modelica": 10, "off": [10, 16, 17], "sdf": [10, 13, 16, 17], "vari": [10, 16, 17], "dimens": 10, "steadi": [10, 13, 14, 18], "dt_con": 10, "dt_eva": 10, "nomin": 10, "achiev": [10, 17], "m_flow_eva_start": 10, "guess": 10, "m_flow_con_start": 10, "001": 10, "about": 10, "diagram": [10, 11], "figur": 10, "ax": [10, 14], "displai": 10, "matplotlib": [10, 11, 12, 14, 15, 16], "filepath_sdf": [10, 16], "nd_data": [10, 16], "first_dimens": [10, 16], "second_dimens": [10, 16], "violin_plot_vari": 10, "third_dimens": 10, "dataset": 10, "3d": [10, 16], "scatter": [10, 16], "violin": 10, "them": [10, 11, 17], "third": [10, 12], "4d": 10, "keyerror": 10, "heatpumpmap": 10, "cop": [10, 13, 16], "optihorn": 10, "org": [10, 18], "galleri": 10, "statist": 10, "customized_violin": 10, "html": 10, "sphx": 10, "glr": 10, "24": 10, "2023": [10, 18], "transform": 10, "datafram": 10, "layout": 10, "declar": 10, "panda": [10, 16], "df_state": 10, "filepath": 10, "Be": 10, "care": 10, "combin": 10, "Then": 10, "latter": [10, 11, 12, 13], "element": 10, "overwrit": 10, "flowsheet_nam": 10, "scale": 10, "Of": 10, "t_amb": 10, "dimension": 10, "scalar": 10, "top": 10, "group": 10, "convert": 10, "excel": 10, "demonstr": [11, 12, 13, 14, 15], "its": [11, 12, 13, 14, 15], "children": [11, 12, 15], "shown": 11, "let": [11, 12, 13, 14, 15, 16, 17], "vclibpi": [11, 12, 13, 14, 15, 16, 17], "purchas": 11, "togeth": 11, "thu": [11, 12, 13, 14], "pass": [11, 12, 13], "go": [11, 12, 14], "propan": [11, 12, 14, 15, 16, 17], "explain": [11, 12], "2e5": 11, "100": [11, 14, 15], "100e3": 11, "plai": [11, 12], "those": [11, 13, 14, 16, 18], "look": [11, 15, 16, 18], "again": [11, 12, 14, 15, 16], "learn": [11, 12], "idea": 11, "loop": [11, 13, 14], "40": [11, 14, 15], "273": [11, 12, 14, 15, 16, 17], "15": [11, 12, 14, 15, 16, 17], "t_crit": 11, "p_crit": 11, "d_crit": 11, "p_max": 11, "q0": 11, "q1": 11, "10000": [11, 14], "reduc": 11, "revert": 11, "comprehens": 11, "quit": 11, "pyplot": [11, 12, 14, 15, 16], "plt": [11, 12, 14, 15, 16], "ylabel": [11, 12, 14, 15, 16], "xlabel": [11, 12, 14, 15, 16], "color": [11, 14], "black": [11, 14], "superheat": [11, 14, 15], "nor": 11, "state_1": 11, "state_3": 11, "state_4": 11, "state_2": 11, "marker": [11, 14, 15], "plot_lines_h": 11, "plot_lines_t": 11, "red": [11, 14], "skill": 11, "ve": 11, "tweak": [11, 15], "log": [11, 16, 17], "next": 11, "exemplari": [12, 15], "constant_efficiency_compressor": 12, "120": 12, "19e": [12, 16, 17], "7": [12, 16, 17], "95": 12, "9": [12, 16, 17], "do": [12, 14], "1bar": 12, "p_inlet": 12, "1e5": [12, 14, 15], "t_superheat": 12, "least": [12, 14], "most": [12, 16], "concept": [12, 13], "instanti": [12, 14], "reli": 12, "6e5": 12, "f": [12, 13, 14, 15, 18], "np": [12, 13, 14, 15], "arang": [12, 15], "t_outlet": 12, "t_": 12, "mathrm": [12, 14], "pi": 12, "continu": [12, 14], "interest": [12, 13], "dot": 12, "influenc": [12, 16, 17], "metric": 12, "deeper": 12, "alter": 12, "extern": 13, "condit": 13, "act": 13, "could": [13, 14, 16, 17], "empti": 13, "except": 13, "loss": 13, "sai": 13, "control": [13, 14], "k_vapor_inject": 13, "along": 13, "easier": 13, "sqrt": 13, "p_1": 13, "p_2": 13, "regist": 13, "essenti": 13, "anyth": 13, "some_interesting_output": 13, "14": [13, 15], "distinct": 13, "t_1": 13, "histori": [13, 18], "preserv": 13, "some_valu": 13, "contrari": 14, "complex": [14, 17], "epsntu": 14, "lot": 14, "236": [14, 16, 17], "2e": [14, 16, 17], "solv": 14, "realiti": 14, "until": 14, "degre": 14, "met": 14, "oscil": 14, "oper": 14, "abl": 14, "meet": 14, "mean": 14, "ensur": 14, "directli": [14, 15], "real": 14, "01": [14, 15], "done": 14, "extra": 14, "correspond": [14, 18], "a2w25": 14, "47": 14, "p_evapor": [14, 15], "state_condenser_outlet": [14, 15], "t_evapor": 14, "logic": 14, "indic": 14, "smaller": [14, 15, 17], "margin": 14, "greater": [14, 16], "zero": 14, "veri": 14, "larg": [14, 15], "q_ntu": 14, "amount": 14, "less": 14, "linspac": 14, "1e4": 14, "fanci": 14, "posit": 14, "back": 14, "old": 14, "decreas": 14, "At": 14, "min_iteration_step": 14, "fig": 14, "subplot": 14, "sharex": 14, "set_ylabel": 14, "delta": 14, "set_xlabel": 14, "p_": 14, "eva": 14, "good": 14, "realli": 14, "avoid": [14, 16], "infinit": 14, "max_iter": 14, "n_iter": 14, "p_eva_next": 14, "min_step": 14, "min_error": 14, "elif": 14, "accur": 14, "break": 14, "els": 14, "converg": 14, "did": [14, 16], "solut": 14, "took": 14, "optim": [14, 18], "techniqu": 14, "quickli": 14, "state_vapor": 14, "intermedi": 14, "states_to_plot": 14, "t_eva_out": 14, "blue": 14, "ylim": 14, "275": 14, "enough": 15, "mm": 15, "give": 15, "149034617014494": 15, "ca": 15, "m_flow_ref_go": 15, "repeat": 15, "d_mm_arrai": 15, "d_mm": 15, "1e": 15, "common": 16, "repetit": 16, "modern": 16, "tell": 16, "hand": 16, "standardcycl": 16, "fist": 16, "develop": [16, 18], "previou": 16, "algorithm": [16, 17], "But": 16, "anoth": [16, 17], "125": [16, 17], "plug": [16, 17], "00_temp": [16, 17], "simple_heat_pump": 16, "70": 16, "under": [16, 17], "messag": [16, 17], "equal": [16, 17], "basicconfig": [16, 17], "save_path_sdf": 16, "save_path_csv": 16, "happen": 16, "system": [16, 18], "explor": 16, "o": 16, "listdir": 16, "One": 16, "standard_propan": 16, "df": 16, "read_csv": 16, "index_col": 16, "x_name": 16, "y_name": 16, "often": 16, "lead": 16, "impact": 16, "field": 16, "seper": 17, "vaporinjectionphasesepar": 17, "twice": 17, "high_pressure_valv": 17, "low_pressure_valv": 17, "low": 17, "somewhat": 17, "larger": 17, "high_pressure_compressor": 17, "low_pressure_compressor": 17, "60": 17, "prior": [17, 19], "feel": 17, "asid": 17, "usag": 17, "vaporinjectioneconom": 17, "50000": 17, "And": 17, "repositori": 18, "apor": 18, "ompress": 18, "lib": 18, "rari": 18, "thon": 18, "configur": 18, "chiller": 18, "pip": 18, "bui": 18, "licenc": 18, "obtain": 18, "egg": 18, "clone": 18, "recommend": 18, "jupyt": 18, "notebook": 18, "guid": 18, "prepar": 18, "sever": 18, "encourag": 18, "either": 18, "local": 18, "browser": 18, "juypter": 18, "web": 18, "host": 18, "jupyter_notebook": 18, "Or": 18, "folder": 18, "doi": 18, "soon": 18, "vere": 18, "w\u00fcllhorst": 18, "mehrfeld": 18, "m\u00fcller": 18, "2021": 18, "toward": 18, "integr": 18, "intensif": 18, "stage": 18, "manag": 18, "250": 18, "114888": 18, "1016": 18, "enconman": 18, "christian": 18, "dirk": 18, "advisor": 18, "elbel": 18, "stefan": 18, "build": 18, "phd": 18, "18154": 18, "04070": 18, "visit": 18, "offici": 18, "gratefulli": 18, "financi": 18, "feder": 18, "ministri": 18, "affair": 18, "climat": 18, "action": 18, "bmwk": 18, "promot": 18, "03en1022b": 18, "european": 18, "fund": 18, "erdf": 18, "0500029": 18, "contribut": 18, "styleguid": 18, "pylint": 18, "index": 18, "search": 18, "v0": 19}, "objects": {"": [[2, 0, 0, "-", "vclibpy"]], "vclibpy": [[3, 0, 0, "-", "components"], [2, 0, 0, "-", "datamodels"], [9, 0, 0, "-", "media"], [10, 0, 0, "-", "utils"]], "vclibpy.components": [[3, 0, 0, "-", "component"], [4, 0, 0, "-", "compressors"], [5, 0, 0, "-", "expansion_valves"], [6, 0, 0, "-", "heat_exchangers"], [3, 0, 0, "-", "phase_separator"]], "vclibpy.components.component": [[3, 1, 1, "", "BaseComponent"]], "vclibpy.components.component.BaseComponent": [[3, 2, 1, "", "m_flow"], [3, 2, 1, "", "med_prop"], [3, 3, 1, "", "start_secondary_med_prop"], [3, 2, 1, "", "state_inlet"], [3, 2, 1, "", "state_outlet"], [3, 3, 1, "", "terminate_secondary_med_prop"]], "vclibpy.components.compressors": [[4, 0, 0, "-", "compressor"], [4, 0, 0, "-", "constant_effectivness"], [4, 0, 0, "-", "rotary"], [4, 0, 0, "-", "ten_coefficient"]], "vclibpy.components.compressors.compressor": [[4, 1, 1, "", "Compressor"]], "vclibpy.components.compressors.compressor.Compressor": [[4, 3, 1, "", "calc_electrical_power"], [4, 3, 1, "", "calc_m_flow"], [4, 3, 1, "", "calc_state_outlet"], [4, 3, 1, "", "get_eta_isentropic"], [4, 3, 1, "", "get_eta_mech"], [4, 3, 1, "", "get_lambda_h"], [4, 3, 1, "", "get_n_absolute"], [4, 3, 1, "", "get_p_outlet"]], "vclibpy.components.compressors.constant_effectivness": [[4, 1, 1, "", "ConstantEffectivenessCompressor"]], "vclibpy.components.compressors.constant_effectivness.ConstantEffectivenessCompressor": [[4, 3, 1, "", "get_eta_isentropic"], [4, 3, 1, "", "get_eta_mech"], [4, 3, 1, "", "get_lambda_h"]], "vclibpy.components.compressors.rotary": [[4, 1, 1, "", "RotaryCompressor"]], "vclibpy.components.compressors.rotary.RotaryCompressor": [[4, 3, 1, "", "get_eta_isentropic"], [4, 3, 1, "", "get_eta_mech"], [4, 3, 1, "", "get_lambda_h"]], "vclibpy.components.compressors.ten_coefficient": [[4, 1, 1, "", "BaseTenCoefficientCompressor"], [4, 1, 1, "", "DataSheetCompressor"], [4, 1, 1, "", "TenCoefficientCompressor"], [4, 4, 1, "", "calc_ten_coefficients"]], "vclibpy.components.compressors.ten_coefficient.BaseTenCoefficientCompressor": [[4, 3, 1, "", "get_parameter"]], "vclibpy.components.compressors.ten_coefficient.DataSheetCompressor": [[4, 3, 1, "", "get_eta_isentropic"], [4, 3, 1, "", "get_eta_mech"], [4, 3, 1, "", "get_lambda_h"]], "vclibpy.components.compressors.ten_coefficient.TenCoefficientCompressor": [[4, 3, 1, "", "get_eta_isentropic"], [4, 3, 1, "", "get_eta_mech"], [4, 3, 1, "", "get_lambda_h"]], "vclibpy.components.expansion_valves": [[5, 0, 0, "-", "bernoulli"], [5, 0, 0, "-", "expansion_valve"]], "vclibpy.components.expansion_valves.bernoulli": [[5, 1, 1, "", "Bernoulli"]], "vclibpy.components.expansion_valves.bernoulli.Bernoulli": [[5, 3, 1, "", "calc_m_flow_at_opening"], [5, 3, 1, "", "calc_opening_at_m_flow"]], "vclibpy.components.expansion_valves.expansion_valve": [[5, 1, 1, "", "ExpansionValve"]], "vclibpy.components.expansion_valves.expansion_valve.ExpansionValve": [[5, 3, 1, "", "calc_m_flow_at_opening"], [5, 3, 1, "", "calc_opening_at_m_flow"], [5, 3, 1, "", "calc_outlet"]], "vclibpy.components.heat_exchangers": [[6, 0, 0, "-", "economizer"], [6, 0, 0, "-", "heat_exchanger"], [7, 0, 0, "-", "heat_transfer"], [6, 0, 0, "-", "moving_boundary_ntu"], [6, 0, 0, "-", "ntu"]], "vclibpy.components.heat_exchangers.economizer": [[6, 1, 1, "", "VaporInjectionEconomizerNTU"]], "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU": [[6, 3, 1, "", "calc"], [6, 3, 1, "", "calc_alpha_secondary"], [6, 3, 1, "", "calc_transport_properties_secondary_medium"], [6, 3, 1, "", "set_secondary_cp"], [6, 3, 1, "", "start_secondary_med_prop"], [6, 2, 1, "", "state_two_phase_inlet"], [6, 2, 1, "", "state_two_phase_outlet"], [6, 3, 1, "", "terminate_secondary_med_prop"]], "vclibpy.components.heat_exchangers.heat_exchanger": [[6, 1, 1, "", "HeatExchanger"]], "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger": [[6, 3, 1, "", "calc"], [6, 3, 1, "", "calc_Q_flow"], [6, 3, 1, "", "calc_alpha_gas"], [6, 3, 1, "", "calc_alpha_liquid"], [6, 3, 1, "", "calc_alpha_secondary"], [6, 3, 1, "", "calc_alpha_two_phase"], [6, 3, 1, "", "calc_secondary_Q_flow"], [6, 3, 1, "", "calc_secondary_cp"], [6, 3, 1, "", "calc_transport_properties_secondary_medium"], [6, 3, 1, "", "calc_wall_heat_transfer"], [6, 2, 1, "", "m_flow_secondary"], [6, 2, 1, "", "m_flow_secondary_cp"], [6, 3, 1, "", "start_secondary_med_prop"], [6, 3, 1, "", "terminate_secondary_med_prop"]], "vclibpy.components.heat_exchangers.heat_transfer": [[7, 0, 0, "-", "air_to_wall"], [7, 0, 0, "-", "constant"], [7, 0, 0, "-", "heat_transfer"], [7, 0, 0, "-", "pipe_to_wall"], [7, 0, 0, "-", "vdi_atlas_air_to_wall"], [7, 0, 0, "-", "wall"]], "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall": [[7, 1, 1, "", "AirToWallTransfer"], [7, 1, 1, "", "WSUAirToWall"]], "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.AirToWallTransfer": [[7, 3, 1, "", "calc"], [7, 3, 1, "", "calc_laminar_area_nusselt"], [7, 3, 1, "", "calc_reynolds"]], "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.WSUAirToWall": [[7, 3, 1, "", "calc_laminar_area_nusselt"], [7, 3, 1, "", "calc_reynolds"]], "vclibpy.components.heat_exchangers.heat_transfer.constant": [[7, 1, 1, "", "ConstantHeatTransfer"], [7, 1, 1, "", "ConstantTwoPhaseHeatTransfer"]], "vclibpy.components.heat_exchangers.heat_transfer.constant.ConstantHeatTransfer": [[7, 3, 1, "", "calc"]], "vclibpy.components.heat_exchangers.heat_transfer.constant.ConstantTwoPhaseHeatTransfer": [[7, 3, 1, "", "calc"]], "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer": [[7, 1, 1, "", "HeatTransfer"], [7, 1, 1, "", "TwoPhaseHeatTransfer"], [7, 4, 1, "", "calc_reynolds_pipe"]], "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.HeatTransfer": [[7, 3, 1, "", "calc"]], "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.TwoPhaseHeatTransfer": [[7, 3, 1, "", "calc"]], "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall": [[7, 1, 1, "", "TurbulentFluidInPipeToWallTransfer"]], "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall.TurbulentFluidInPipeToWallTransfer": [[7, 3, 1, "", "calc"], [7, 3, 1, "", "calc_turbulent_tube_nusselt"]], "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall": [[7, 1, 1, "", "AirSourceHeatExchangerGeometry"], [7, 1, 1, "", "VDIAtlasAirToWallTransfer"]], "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry": [[7, 2, 1, "", "A"], [7, 2, 1, "", "A_FreieOberflaecheRohr"], [7, 2, 1, "", "A_Rippen"], [7, 2, 1, "", "A_RohrInnen"], [7, 2, 1, "", "A_RohrUnberippt"], [7, 5, 1, "", "a"], [7, 3, 1, "", "alpha_S"], [7, 2, 1, "", "char_length"], [7, 5, 1, "", "d_a"], [7, 5, 1, "", "d_i"], [7, 5, 1, "", "dicke_rippe"], [7, 3, 1, "", "eta_R"], [7, 5, 1, "", "hoehe"], [7, 5, 1, "", "laenge"], [7, 5, 1, "", "lambda_R"], [7, 5, 1, "", "n_Rippen"], [7, 5, 1, "", "n_Rohre"], [7, 2, 1, "", "phi"], [7, 5, 1, "", "t_l"], [7, 5, 1, "", "t_q"], [7, 5, 1, "", "tiefe"], [7, 2, 1, "", "verjuengungsfaktor"]], "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.VDIAtlasAirToWallTransfer": [[7, 3, 1, "", "calc_laminar_area_nusselt"], [7, 3, 1, "", "calc_reynolds"]], "vclibpy.components.heat_exchangers.heat_transfer.wall": [[7, 1, 1, "", "WallTransfer"]], "vclibpy.components.heat_exchangers.heat_transfer.wall.WallTransfer": [[7, 3, 1, "", "calc"]], "vclibpy.components.heat_exchangers.moving_boundary_ntu": [[6, 1, 1, "", "MovingBoundaryNTU"], [6, 1, 1, "", "MovingBoundaryNTUCondenser"], [6, 1, 1, "", "MovingBoundaryNTUEvaporator"]], "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTU": [[6, 3, 1, "", "iterate_area"], [6, 3, 1, "", "separate_phases"]], "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTUCondenser": [[6, 3, 1, "", "calc"]], "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTUEvaporator": [[6, 3, 1, "", "calc"]], "vclibpy.components.heat_exchangers.ntu": [[6, 1, 1, "", "BasicNTU"]], "vclibpy.components.heat_exchangers.ntu.BasicNTU": [[6, 3, 1, "", "calc_NTU"], [6, 3, 1, "", "calc_Q_ntu"], [6, 3, 1, "", "calc_R"], [6, 3, 1, "", "calc_eps"], [6, 3, 1, "", "calc_k"], [6, 3, 1, "", "calc_m_flow_cp_min"], [6, 3, 1, "", "set_primary_cp"]], "vclibpy.components.phase_separator": [[3, 1, 1, "", "PhaseSeparator"]], "vclibpy.components.phase_separator.PhaseSeparator": [[3, 2, 1, "", "state_inlet"], [3, 2, 1, "", "state_outlet"], [3, 2, 1, "", "state_outlet_liquid"], [3, 2, 1, "", "state_outlet_vapor"]], "vclibpy.datamodels": [[2, 1, 1, "", "FlowsheetState"], [2, 1, 1, "", "Inputs"], [2, 1, 1, "", "Variable"], [2, 1, 1, "", "VariableContainer"]], "vclibpy.datamodels.Variable": [[2, 5, 1, "", "description"], [2, 5, 1, "", "name"], [2, 5, 1, "", "unit"], [2, 5, 1, "", "value"]], "vclibpy.datamodels.VariableContainer": [[2, 3, 1, "", "convert_to_str_value_format"], [2, 3, 1, "", "copy"], [2, 3, 1, "", "get"], [2, 3, 1, "", "get_variable_names"], [2, 3, 1, "", "get_variables"], [2, 3, 1, "", "items"], [2, 3, 1, "", "set"]], "vclibpy.media": [[9, 1, 1, "", "CoolProp"], [9, 1, 1, "", "MedProp"], [9, 1, 1, "", "RefProp"], [9, 1, 1, "", "ThermodynamicState"], [9, 1, 1, "", "TransportProperties"], [9, 0, 0, "-", "cool_prop"], [9, 0, 0, "-", "media"], [9, 0, 0, "-", "ref_prop"], [9, 0, 0, "-", "states"]], "vclibpy.media.CoolProp": [[9, 3, 1, "", "calc_state"], [9, 3, 1, "", "calc_transport_properties"], [9, 3, 1, "", "get_critical_point"], [9, 3, 1, "", "get_molar_mass"]], "vclibpy.media.MedProp": [[9, 3, 1, "", "calc_mean_transport_properties"], [9, 3, 1, "", "calc_state"], [9, 3, 1, "", "calc_transport_properties"], [9, 3, 1, "", "get_critical_point"], [9, 3, 1, "", "get_molar_mass"], [9, 3, 1, "", "get_two_phase_limits"], [9, 3, 1, "", "terminate"]], "vclibpy.media.RefProp": [[9, 3, 1, "", "calc_satliq_state"], [9, 3, 1, "", "calc_state"], [9, 3, 1, "", "calc_transport_properties"], [9, 3, 1, "", "get_available_substances"], [9, 3, 1, "", "get_comp_names"], [9, 3, 1, "", "get_critical_point"], [9, 3, 1, "", "get_def_limits"], [9, 3, 1, "", "get_dll_path"], [9, 3, 1, "", "get_fluid_name"], [9, 3, 1, "", "get_gwp"], [9, 3, 1, "", "get_longname"], [9, 3, 1, "", "get_mass_fraction"], [9, 3, 1, "", "get_mol_fraction"], [9, 3, 1, "", "get_molar_composition"], [9, 3, 1, "", "get_molar_mass"], [9, 3, 1, "", "get_nbp"], [9, 3, 1, "", "get_odp"], [9, 3, 1, "", "get_safety"], [9, 3, 1, "", "get_sat_vap_pressure"], [9, 3, 1, "", "get_triple_point"], [9, 3, 1, "", "get_version"], [9, 3, 1, "", "is_mixture"], [9, 3, 1, "", "set_error_flag"], [9, 3, 1, "", "set_warning_flag"], [9, 3, 1, "", "terminate"]], "vclibpy.media.ThermodynamicState": [[9, 3, 1, "", "get_pretty_print"]], "vclibpy.media.TransportProperties": [[9, 3, 1, "", "get_pretty_print"]], "vclibpy.media.cool_prop": [[9, 1, 1, "", "CoolProp"]], "vclibpy.media.cool_prop.CoolProp": [[9, 3, 1, "", "calc_state"], [9, 3, 1, "", "calc_transport_properties"], [9, 3, 1, "", "get_critical_point"], [9, 3, 1, "", "get_molar_mass"]], "vclibpy.media.media": [[9, 1, 1, "", "MedProp"], [9, 4, 1, "", "get_two_phase_limits"]], "vclibpy.media.media.MedProp": [[9, 3, 1, "", "calc_mean_transport_properties"], [9, 3, 1, "", "calc_state"], [9, 3, 1, "", "calc_transport_properties"], [9, 3, 1, "", "get_critical_point"], [9, 3, 1, "", "get_molar_mass"], [9, 3, 1, "", "get_two_phase_limits"], [9, 3, 1, "", "terminate"]], "vclibpy.media.ref_prop": [[9, 1, 1, "", "RefProp"]], "vclibpy.media.ref_prop.RefProp": [[9, 3, 1, "", "calc_satliq_state"], [9, 3, 1, "", "calc_state"], [9, 3, 1, "", "calc_transport_properties"], [9, 3, 1, "", "get_available_substances"], [9, 3, 1, "", "get_comp_names"], [9, 3, 1, "", "get_critical_point"], [9, 3, 1, "", "get_def_limits"], [9, 3, 1, "", "get_dll_path"], [9, 3, 1, "", "get_fluid_name"], [9, 3, 1, "", "get_gwp"], [9, 3, 1, "", "get_longname"], [9, 3, 1, "", "get_mass_fraction"], [9, 3, 1, "", "get_mol_fraction"], [9, 3, 1, "", "get_molar_composition"], [9, 3, 1, "", "get_molar_mass"], [9, 3, 1, "", "get_nbp"], [9, 3, 1, "", "get_odp"], [9, 3, 1, "", "get_safety"], [9, 3, 1, "", "get_sat_vap_pressure"], [9, 3, 1, "", "get_triple_point"], [9, 3, 1, "", "get_version"], [9, 3, 1, "", "is_mixture"], [9, 3, 1, "", "set_error_flag"], [9, 3, 1, "", "set_warning_flag"], [9, 3, 1, "", "terminate"]], "vclibpy.media.states": [[9, 1, 1, "", "ThermodynamicState"], [9, 1, 1, "", "TransportProperties"]], "vclibpy.media.states.ThermodynamicState": [[9, 3, 1, "", "get_pretty_print"]], "vclibpy.media.states.TransportProperties": [[9, 3, 1, "", "get_pretty_print"]], "vclibpy.utils": [[10, 0, 0, "-", "automation"], [10, 0, 0, "-", "nominal_design"], [10, 0, 0, "-", "plotting"], [10, 0, 0, "-", "printing"], [10, 0, 0, "-", "sdf_"]], "vclibpy.utils.automation": [[10, 4, 1, "", "calc_multiple_states"], [10, 4, 1, "", "full_factorial_map_generation"]], "vclibpy.utils.nominal_design": [[10, 4, 1, "", "nominal_hp_design"]], "vclibpy.utils.plotting": [[10, 4, 1, "", "plot_cycle"], [10, 4, 1, "", "plot_sdf_map"], [10, 4, 1, "", "set_axis_style"]], "vclibpy.utils.printing": [[10, 4, 1, "", "print_states"]], "vclibpy.utils.sdf_": [[10, 4, 1, "", "merge_sdfs"], [10, 4, 1, "", "save_to_sdf"], [10, 4, 1, "", "sdf_to_csv"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:property", "3": "py:method", "4": "py:function", "5": "py:attribute"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "property", "Python property"], "3": ["py", "method", "Python method"], "4": ["py", "function", "Python function"], "5": ["py", "attribute", "Python attribute"]}, "titleterms": {"contribut": 0, "user": 0, "develop": 0, "styleguid": 0, "document": [0, 18], "unit": 0, "test": 0, "pylint": 0, "vclibpi": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 18], "packag": [2, 3, 4, 5, 6, 7, 8, 9, 10], "subpackag": [2, 3, 6], "submodul": [2, 3, 4, 5, 6, 7, 8, 9, 10], "datamodel": 2, "modul": [2, 3, 4, 5, 6, 7, 8, 9, 10], "compon": [3, 4, 5, 6, 7], "phase_separ": 3, "compressor": [4, 12], "constant_effectiv": 4, "rotari": 4, "ten_coeffici": 4, "expansion_valv": 5, "bernoulli": 5, "heat_exchang": [6, 7], "econom": [6, 17], "moving_boundary_ntu": 6, "ntu": 6, "heat_transf": 7, "air_to_wal": 7, "constant": 7, "pipe_to_wal": 7, "vdi_atlas_air_to_wal": 7, "wall": 7, "flowsheet": 8, "base": 8, "standard": [8, 16], "vapor_inject": 8, "vapor_injection_econom": 8, "vapor_injection_phase_separ": 8, "media": 9, "how": [9, 18], "us": [9, 17], "refprop": 9, "wrapper": 9, "version": [9, 19], "note": 9, "paramet": 9, "return": 9, "cool_prop": 9, "ref_prop": 9, "state": [9, 12], "util": 10, "autom": 10, "nominal_design": 10, "plot": [10, 11, 14], "print": 10, "sdf_": 10, "ten_coefficient_compressor_reqress": 10, "refriger": 11, "data": 11, "exampl": [11, 12, 14, 15, 16, 17], "thermodynamicst": 11, "calcul": 11, "transportproperti": 11, "outlet": 12, "mass": 12, "flow": 12, "rate": 12, "electr": 12, "power": 12, "consumpt": 12, "input": 13, "flowsheetst": 13, "heat": [14, 16, 17], "exchang": 14, "iter": 14, "implement": 14, "your": 14, "own": 14, "pinch": 14, "expans": 15, "valv": 15, "open": 15, "pump": [16, 17], "cycl": 16, "vapor": 17, "inject": 17, "phase": 17, "separ": 17, "an": 17, "about": 18, "vclibi": 18, "instal": 18, "get": 18, "start": 18, "cite": 18, "relat": 18, "public": 18, "problem": 18, "acknowledg": 18, "indic": 18, "tabl": 18, "histori": 19}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"Contribute as a user": [[0, "contribute-as-a-user"]], "Contribute as a developer": [[0, "contribute-as-a-developer"]], "Styleguide": [[0, "styleguide"]], "Documentation": [[0, "documentation"], [18, "documentation"]], "Unit-Tests": [[0, "unit-tests"]], "Pylint": [[0, "pylint"]], "vclibpy": [[1, "vclibpy"]], "vclibpy package": [[2, "module-vclibpy"]], "Subpackages": [[2, "subpackages"], [3, "subpackages"], [6, "subpackages"]], "Submodules": [[2, "submodules"], [3, "submodules"], [4, "submodules"], [5, "submodules"], [6, "submodules"], [7, "submodules"], [8, "submodules"], [9, "submodules"], [10, "submodules"]], "vclibpy.datamodels module": [[2, "module-vclibpy.datamodels"]], "vclibpy.components package": [[3, "module-vclibpy.components"]], "vclibpy.components.component module": [[3, "module-vclibpy.components.component"]], "vclibpy.components.phase_separator module": [[3, "module-vclibpy.components.phase_separator"]], "vclibpy.components.compressors package": [[4, "module-vclibpy.components.compressors"]], "vclibpy.components.compressors.compressor module": [[4, "module-vclibpy.components.compressors.compressor"]], "vclibpy.components.compressors.constant_effectivness module": [[4, "module-vclibpy.components.compressors.constant_effectivness"]], "vclibpy.components.compressors.rotary module": [[4, "module-vclibpy.components.compressors.rotary"]], "vclibpy.components.compressors.ten_coefficient module": [[4, "module-vclibpy.components.compressors.ten_coefficient"]], "vclibpy.components.expansion_valves package": [[5, "module-vclibpy.components.expansion_valves"]], "vclibpy.components.expansion_valves.bernoulli module": [[5, "module-vclibpy.components.expansion_valves.bernoulli"]], "vclibpy.components.expansion_valves.expansion_valve module": [[5, "module-vclibpy.components.expansion_valves.expansion_valve"]], "vclibpy.components.heat_exchangers package": [[6, "module-vclibpy.components.heat_exchangers"]], "vclibpy.components.heat_exchangers.economizer module": [[6, "module-vclibpy.components.heat_exchangers.economizer"]], "vclibpy.components.heat_exchangers.heat_exchanger module": [[6, "module-vclibpy.components.heat_exchangers.heat_exchanger"]], "vclibpy.components.heat_exchangers.moving_boundary_ntu module": [[6, "module-vclibpy.components.heat_exchangers.moving_boundary_ntu"]], "vclibpy.components.heat_exchangers.ntu module": [[6, "module-vclibpy.components.heat_exchangers.ntu"]], "vclibpy.components.heat_exchangers.heat_transfer package": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer"]], "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall module": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.air_to_wall"]], "vclibpy.components.heat_exchangers.heat_transfer.constant module": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.constant"]], "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer module": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.heat_transfer"]], "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall module": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall"]], "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall module": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall"]], "vclibpy.components.heat_exchangers.heat_transfer.wall module": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.wall"]], "vclibpy.flowsheets package": [[8, "vclibpy-flowsheets-package"]], "vclibpy.flowsheets.base module": [[8, "vclibpy-flowsheets-base-module"]], "vclibpy.flowsheets.standard module": [[8, "vclibpy-flowsheets-standard-module"]], "vclibpy.flowsheets.vapor_injection module": [[8, "vclibpy-flowsheets-vapor-injection-module"]], "vclibpy.flowsheets.vapor_injection_economizer module": [[8, "vclibpy-flowsheets-vapor-injection-economizer-module"]], "vclibpy.flowsheets.vapor_injection_phase_separator module": [[8, "vclibpy-flowsheets-vapor-injection-phase-separator-module"]], "vclibpy.media package": [[9, "module-vclibpy.media"]], "How to use RefProp-Wrapper:": [[9, "how-to-use-refprop-wrapper"], [9, "id17"]], "Version notes:": [[9, "version-notes"], [9, "id18"]], "Notes:": [[9, "notes"], [9, "id19"]], "Parameters:": [[9, "parameters"], [9, "id1"], [9, "id3"], [9, "id20"], [9, "id22"], [9, "id24"]], "Return:": [[9, "return"], [9, "id2"], [9, "id4"], [9, "id5"], [9, "id6"], [9, "id7"], [9, "id8"], [9, "id9"], [9, "id10"], [9, "id11"], [9, "id12"], [9, "id13"], [9, "id14"], [9, "id15"], [9, "id16"], [9, "id21"], [9, "id23"], [9, "id25"], [9, "id26"], [9, "id27"], [9, "id28"], [9, "id29"], [9, "id30"], [9, "id31"], [9, "id32"], [9, "id33"], [9, "id34"], [9, "id35"], [9, "id36"], [9, "id37"]], "vclibpy.media.cool_prop module": [[9, "module-vclibpy.media.cool_prop"]], "vclibpy.media.media module": [[9, "module-vclibpy.media.media"]], "vclibpy.media.ref_prop module": [[9, "module-vclibpy.media.ref_prop"]], "vclibpy.media.states module": [[9, "module-vclibpy.media.states"]], "vclibpy.utils package": [[10, "module-vclibpy.utils"]], "vclibpy.utils.automation module": [[10, "module-vclibpy.utils.automation"]], "vclibpy.utils.nominal_design module": [[10, "module-vclibpy.utils.nominal_design"]], "vclibpy.utils.plotting module": [[10, "module-vclibpy.utils.plotting"]], "vclibpy.utils.printing module": [[10, "module-vclibpy.utils.printing"]], "vclibpy.utils.sdf_ module": [[10, "module-vclibpy.utils.sdf_"]], "vclibpy.utils.ten_coefficient_compressor_reqression module": [[10, "vclibpy-utils-ten-coefficient-compressor-reqression-module"]], "Refrigerant Data Example": [[11, "refrigerant-data-example"]], "ThermodynamicState calculation": [[11, "thermodynamicstate-calculation"]], "TransportProperties calculation": [[11, "transportproperties-calculation"]], "Plotting": [[11, "plotting"]], "Compressor Example": [[12, "compressor-example"]], "Outlet state": [[12, "outlet-state"]], "Mass flow rate": [[12, "mass-flow-rate"]], "Electrical power consumption": [[12, "electrical-power-consumption"]], "Inputs and FlowsheetState": [[13, "inputs-and-flowsheetstate"]], "Inputs": [[13, "inputs"]], "FlowsheetState": [[13, "flowsheetstate"]], "Heat Exchanger Example": [[14, "heat-exchanger-example"]], "Heat exchanger iterations": [[14, "heat-exchanger-iterations"]], "Implement your own iteration": [[14, "implement-your-own-iteration"]], "Pinch plotting": [[14, "pinch-plotting"]], "Expansion Valve Example": [[15, "expansion-valve-example"]], "Valve opening:": [[15, "valve-opening"]], "Example for a heat pump with a standard cycle": [[16, "example-for-a-heat-pump-with-a-standard-cycle"]], "Example for a heat pump with vapor injection using a phase separator": [[17, "example-for-a-heat-pump-with-vapor-injection-using-a-phase-separator"]], "Vapor injection with an economizer.": [[17, "vapor-injection-with-an-economizer"]], "About vcliby": [[18, "about-vcliby"]], "VCLibPy": [[18, "vclibpy"]], "Installation": [[18, "installation"]], "How to get started?": [[18, "how-to-get-started"]], "How to cite vclibpy": [[18, "how-to-cite-vclibpy"]], "Related publications": [[18, "related-publications"]], "Problems?": [[18, "problems"]], "Acknowledgements": [[18, "acknowledgements"]], "Indices and tables": [[18, "indices-and-tables"]], "Version History": [[19, "version-history"]]}, "indexentries": {"flowsheetstate (class in vclibpy.datamodels)": [[2, "vclibpy.datamodels.FlowsheetState"]], "inputs (class in vclibpy.datamodels)": [[2, "vclibpy.datamodels.Inputs"]], "variable (class in vclibpy.datamodels)": [[2, "vclibpy.datamodels.Variable"]], "variablecontainer (class in vclibpy.datamodels)": [[2, "vclibpy.datamodels.VariableContainer"]], "convert_to_str_value_format() (vclibpy.datamodels.variablecontainer method)": [[2, "vclibpy.datamodels.VariableContainer.convert_to_str_value_format"]], "copy() (vclibpy.datamodels.variablecontainer method)": [[2, "vclibpy.datamodels.VariableContainer.copy"]], "description (vclibpy.datamodels.variable attribute)": [[2, "vclibpy.datamodels.Variable.description"]], "get() (vclibpy.datamodels.variablecontainer method)": [[2, "vclibpy.datamodels.VariableContainer.get"]], "get_variable_names() (vclibpy.datamodels.variablecontainer method)": [[2, "vclibpy.datamodels.VariableContainer.get_variable_names"]], "get_variables() (vclibpy.datamodels.variablecontainer method)": [[2, "vclibpy.datamodels.VariableContainer.get_variables"]], "items() (vclibpy.datamodels.variablecontainer method)": [[2, "vclibpy.datamodels.VariableContainer.items"]], "module": [[2, "module-vclibpy"], [2, "module-vclibpy.datamodels"], [3, "module-vclibpy.components"], [3, "module-vclibpy.components.component"], [3, "module-vclibpy.components.phase_separator"], [4, "module-vclibpy.components.compressors"], [4, "module-vclibpy.components.compressors.compressor"], [4, "module-vclibpy.components.compressors.constant_effectivness"], [4, "module-vclibpy.components.compressors.rotary"], [4, "module-vclibpy.components.compressors.ten_coefficient"], [5, "module-vclibpy.components.expansion_valves"], [5, "module-vclibpy.components.expansion_valves.bernoulli"], [5, "module-vclibpy.components.expansion_valves.expansion_valve"], [6, "module-vclibpy.components.heat_exchangers"], [6, "module-vclibpy.components.heat_exchangers.economizer"], [6, "module-vclibpy.components.heat_exchangers.heat_exchanger"], [6, "module-vclibpy.components.heat_exchangers.moving_boundary_ntu"], [6, "module-vclibpy.components.heat_exchangers.ntu"], [7, "module-vclibpy.components.heat_exchangers.heat_transfer"], [7, "module-vclibpy.components.heat_exchangers.heat_transfer.air_to_wall"], [7, "module-vclibpy.components.heat_exchangers.heat_transfer.constant"], [7, "module-vclibpy.components.heat_exchangers.heat_transfer.heat_transfer"], [7, "module-vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall"], [7, "module-vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall"], [7, "module-vclibpy.components.heat_exchangers.heat_transfer.wall"], [9, "module-vclibpy.media"], [9, "module-vclibpy.media.cool_prop"], [9, "module-vclibpy.media.media"], [9, "module-vclibpy.media.ref_prop"], [9, "module-vclibpy.media.states"], [10, "module-vclibpy.utils"], [10, "module-vclibpy.utils.automation"], [10, "module-vclibpy.utils.nominal_design"], [10, "module-vclibpy.utils.plotting"], [10, "module-vclibpy.utils.printing"], [10, "module-vclibpy.utils.sdf_"]], "name (vclibpy.datamodels.variable attribute)": [[2, "vclibpy.datamodels.Variable.name"]], "set() (vclibpy.datamodels.variablecontainer method)": [[2, "vclibpy.datamodels.VariableContainer.set"]], "unit (vclibpy.datamodels.variable attribute)": [[2, "vclibpy.datamodels.Variable.unit"]], "value (vclibpy.datamodels.variable attribute)": [[2, "vclibpy.datamodels.Variable.value"]], "vclibpy": [[2, "module-vclibpy"]], "vclibpy.datamodels": [[2, "module-vclibpy.datamodels"]], "basecomponent (class in vclibpy.components.component)": [[3, "vclibpy.components.component.BaseComponent"]], "phaseseparator (class in vclibpy.components.phase_separator)": [[3, "vclibpy.components.phase_separator.PhaseSeparator"]], "m_flow (vclibpy.components.component.basecomponent property)": [[3, "vclibpy.components.component.BaseComponent.m_flow"]], "med_prop (vclibpy.components.component.basecomponent property)": [[3, "vclibpy.components.component.BaseComponent.med_prop"]], "start_secondary_med_prop() (vclibpy.components.component.basecomponent method)": [[3, "vclibpy.components.component.BaseComponent.start_secondary_med_prop"]], "state_inlet (vclibpy.components.component.basecomponent property)": [[3, "vclibpy.components.component.BaseComponent.state_inlet"]], "state_inlet (vclibpy.components.phase_separator.phaseseparator property)": [[3, "vclibpy.components.phase_separator.PhaseSeparator.state_inlet"]], "state_outlet (vclibpy.components.component.basecomponent property)": [[3, "vclibpy.components.component.BaseComponent.state_outlet"]], "state_outlet (vclibpy.components.phase_separator.phaseseparator property)": [[3, "vclibpy.components.phase_separator.PhaseSeparator.state_outlet"]], "state_outlet_liquid (vclibpy.components.phase_separator.phaseseparator property)": [[3, "vclibpy.components.phase_separator.PhaseSeparator.state_outlet_liquid"]], "state_outlet_vapor (vclibpy.components.phase_separator.phaseseparator property)": [[3, "vclibpy.components.phase_separator.PhaseSeparator.state_outlet_vapor"]], "terminate_secondary_med_prop() (vclibpy.components.component.basecomponent method)": [[3, "vclibpy.components.component.BaseComponent.terminate_secondary_med_prop"]], "vclibpy.components": [[3, "module-vclibpy.components"]], "vclibpy.components.component": [[3, "module-vclibpy.components.component"]], "vclibpy.components.phase_separator": [[3, "module-vclibpy.components.phase_separator"]], "basetencoefficientcompressor (class in vclibpy.components.compressors.ten_coefficient)": [[4, "vclibpy.components.compressors.ten_coefficient.BaseTenCoefficientCompressor"]], "compressor (class in vclibpy.components.compressors.compressor)": [[4, "vclibpy.components.compressors.compressor.Compressor"]], "constanteffectivenesscompressor (class in vclibpy.components.compressors.constant_effectivness)": [[4, "vclibpy.components.compressors.constant_effectivness.ConstantEffectivenessCompressor"]], "datasheetcompressor (class in vclibpy.components.compressors.ten_coefficient)": [[4, "vclibpy.components.compressors.ten_coefficient.DataSheetCompressor"]], "rotarycompressor (class in vclibpy.components.compressors.rotary)": [[4, "vclibpy.components.compressors.rotary.RotaryCompressor"]], "tencoefficientcompressor (class in vclibpy.components.compressors.ten_coefficient)": [[4, "vclibpy.components.compressors.ten_coefficient.TenCoefficientCompressor"]], "calc_electrical_power() (vclibpy.components.compressors.compressor.compressor method)": [[4, "vclibpy.components.compressors.compressor.Compressor.calc_electrical_power"]], "calc_m_flow() (vclibpy.components.compressors.compressor.compressor method)": [[4, "vclibpy.components.compressors.compressor.Compressor.calc_m_flow"]], "calc_state_outlet() (vclibpy.components.compressors.compressor.compressor method)": [[4, "vclibpy.components.compressors.compressor.Compressor.calc_state_outlet"]], "calc_ten_coefficients() (in module vclibpy.components.compressors.ten_coefficient)": [[4, "vclibpy.components.compressors.ten_coefficient.calc_ten_coefficients"]], "get_eta_isentropic() (vclibpy.components.compressors.compressor.compressor method)": [[4, "vclibpy.components.compressors.compressor.Compressor.get_eta_isentropic"]], "get_eta_isentropic() (vclibpy.components.compressors.constant_effectivness.constanteffectivenesscompressor method)": [[4, "vclibpy.components.compressors.constant_effectivness.ConstantEffectivenessCompressor.get_eta_isentropic"]], "get_eta_isentropic() (vclibpy.components.compressors.rotary.rotarycompressor method)": [[4, "vclibpy.components.compressors.rotary.RotaryCompressor.get_eta_isentropic"]], "get_eta_isentropic() (vclibpy.components.compressors.ten_coefficient.datasheetcompressor method)": [[4, "vclibpy.components.compressors.ten_coefficient.DataSheetCompressor.get_eta_isentropic"]], "get_eta_isentropic() (vclibpy.components.compressors.ten_coefficient.tencoefficientcompressor method)": [[4, "vclibpy.components.compressors.ten_coefficient.TenCoefficientCompressor.get_eta_isentropic"]], "get_eta_mech() (vclibpy.components.compressors.compressor.compressor method)": [[4, "vclibpy.components.compressors.compressor.Compressor.get_eta_mech"]], "get_eta_mech() (vclibpy.components.compressors.constant_effectivness.constanteffectivenesscompressor method)": [[4, "vclibpy.components.compressors.constant_effectivness.ConstantEffectivenessCompressor.get_eta_mech"]], "get_eta_mech() (vclibpy.components.compressors.rotary.rotarycompressor method)": [[4, "vclibpy.components.compressors.rotary.RotaryCompressor.get_eta_mech"]], "get_eta_mech() (vclibpy.components.compressors.ten_coefficient.datasheetcompressor method)": [[4, "vclibpy.components.compressors.ten_coefficient.DataSheetCompressor.get_eta_mech"]], "get_eta_mech() (vclibpy.components.compressors.ten_coefficient.tencoefficientcompressor method)": [[4, "vclibpy.components.compressors.ten_coefficient.TenCoefficientCompressor.get_eta_mech"]], "get_lambda_h() (vclibpy.components.compressors.compressor.compressor method)": [[4, "vclibpy.components.compressors.compressor.Compressor.get_lambda_h"]], "get_lambda_h() (vclibpy.components.compressors.constant_effectivness.constanteffectivenesscompressor method)": [[4, "vclibpy.components.compressors.constant_effectivness.ConstantEffectivenessCompressor.get_lambda_h"]], "get_lambda_h() (vclibpy.components.compressors.rotary.rotarycompressor method)": [[4, "vclibpy.components.compressors.rotary.RotaryCompressor.get_lambda_h"]], "get_lambda_h() (vclibpy.components.compressors.ten_coefficient.datasheetcompressor method)": [[4, "vclibpy.components.compressors.ten_coefficient.DataSheetCompressor.get_lambda_h"]], "get_lambda_h() (vclibpy.components.compressors.ten_coefficient.tencoefficientcompressor method)": [[4, "vclibpy.components.compressors.ten_coefficient.TenCoefficientCompressor.get_lambda_h"]], "get_n_absolute() (vclibpy.components.compressors.compressor.compressor method)": [[4, "vclibpy.components.compressors.compressor.Compressor.get_n_absolute"]], "get_p_outlet() (vclibpy.components.compressors.compressor.compressor method)": [[4, "vclibpy.components.compressors.compressor.Compressor.get_p_outlet"]], "get_parameter() (vclibpy.components.compressors.ten_coefficient.basetencoefficientcompressor method)": [[4, "vclibpy.components.compressors.ten_coefficient.BaseTenCoefficientCompressor.get_parameter"]], "vclibpy.components.compressors": [[4, "module-vclibpy.components.compressors"]], "vclibpy.components.compressors.compressor": [[4, "module-vclibpy.components.compressors.compressor"]], "vclibpy.components.compressors.constant_effectivness": [[4, "module-vclibpy.components.compressors.constant_effectivness"]], "vclibpy.components.compressors.rotary": [[4, "module-vclibpy.components.compressors.rotary"]], "vclibpy.components.compressors.ten_coefficient": [[4, "module-vclibpy.components.compressors.ten_coefficient"]], "bernoulli (class in vclibpy.components.expansion_valves.bernoulli)": [[5, "vclibpy.components.expansion_valves.bernoulli.Bernoulli"]], "expansionvalve (class in vclibpy.components.expansion_valves.expansion_valve)": [[5, "vclibpy.components.expansion_valves.expansion_valve.ExpansionValve"]], "calc_m_flow_at_opening() (vclibpy.components.expansion_valves.bernoulli.bernoulli method)": [[5, "vclibpy.components.expansion_valves.bernoulli.Bernoulli.calc_m_flow_at_opening"]], "calc_m_flow_at_opening() (vclibpy.components.expansion_valves.expansion_valve.expansionvalve method)": [[5, "vclibpy.components.expansion_valves.expansion_valve.ExpansionValve.calc_m_flow_at_opening"]], "calc_opening_at_m_flow() (vclibpy.components.expansion_valves.bernoulli.bernoulli method)": [[5, "vclibpy.components.expansion_valves.bernoulli.Bernoulli.calc_opening_at_m_flow"]], "calc_opening_at_m_flow() (vclibpy.components.expansion_valves.expansion_valve.expansionvalve method)": [[5, "vclibpy.components.expansion_valves.expansion_valve.ExpansionValve.calc_opening_at_m_flow"]], "calc_outlet() (vclibpy.components.expansion_valves.expansion_valve.expansionvalve method)": [[5, "vclibpy.components.expansion_valves.expansion_valve.ExpansionValve.calc_outlet"]], "vclibpy.components.expansion_valves": [[5, "module-vclibpy.components.expansion_valves"]], "vclibpy.components.expansion_valves.bernoulli": [[5, "module-vclibpy.components.expansion_valves.bernoulli"]], "vclibpy.components.expansion_valves.expansion_valve": [[5, "module-vclibpy.components.expansion_valves.expansion_valve"]], "basicntu (class in vclibpy.components.heat_exchangers.ntu)": [[6, "vclibpy.components.heat_exchangers.ntu.BasicNTU"]], "heatexchanger (class in vclibpy.components.heat_exchangers.heat_exchanger)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger"]], "movingboundaryntu (class in vclibpy.components.heat_exchangers.moving_boundary_ntu)": [[6, "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTU"]], "movingboundaryntucondenser (class in vclibpy.components.heat_exchangers.moving_boundary_ntu)": [[6, "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTUCondenser"]], "movingboundaryntuevaporator (class in vclibpy.components.heat_exchangers.moving_boundary_ntu)": [[6, "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTUEvaporator"]], "vaporinjectioneconomizerntu (class in vclibpy.components.heat_exchangers.economizer)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU"]], "calc() (vclibpy.components.heat_exchangers.economizer.vaporinjectioneconomizerntu method)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU.calc"]], "calc() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc"]], "calc() (vclibpy.components.heat_exchangers.moving_boundary_ntu.movingboundaryntucondenser method)": [[6, "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTUCondenser.calc"]], "calc() (vclibpy.components.heat_exchangers.moving_boundary_ntu.movingboundaryntuevaporator method)": [[6, "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTUEvaporator.calc"]], "calc_ntu() (vclibpy.components.heat_exchangers.ntu.basicntu static method)": [[6, "vclibpy.components.heat_exchangers.ntu.BasicNTU.calc_NTU"]], "calc_q_flow() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_Q_flow"]], "calc_q_ntu() (vclibpy.components.heat_exchangers.ntu.basicntu method)": [[6, "vclibpy.components.heat_exchangers.ntu.BasicNTU.calc_Q_ntu"]], "calc_r() (vclibpy.components.heat_exchangers.ntu.basicntu method)": [[6, "vclibpy.components.heat_exchangers.ntu.BasicNTU.calc_R"]], "calc_alpha_gas() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_alpha_gas"]], "calc_alpha_liquid() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_alpha_liquid"]], "calc_alpha_secondary() (vclibpy.components.heat_exchangers.economizer.vaporinjectioneconomizerntu method)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU.calc_alpha_secondary"]], "calc_alpha_secondary() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_alpha_secondary"]], "calc_alpha_two_phase() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_alpha_two_phase"]], "calc_eps() (vclibpy.components.heat_exchangers.ntu.basicntu method)": [[6, "vclibpy.components.heat_exchangers.ntu.BasicNTU.calc_eps"]], "calc_k() (vclibpy.components.heat_exchangers.ntu.basicntu method)": [[6, "vclibpy.components.heat_exchangers.ntu.BasicNTU.calc_k"]], "calc_m_flow_cp_min() (vclibpy.components.heat_exchangers.ntu.basicntu method)": [[6, "vclibpy.components.heat_exchangers.ntu.BasicNTU.calc_m_flow_cp_min"]], "calc_secondary_q_flow() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_secondary_Q_flow"]], "calc_secondary_cp() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_secondary_cp"]], "calc_transport_properties_secondary_medium() (vclibpy.components.heat_exchangers.economizer.vaporinjectioneconomizerntu method)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU.calc_transport_properties_secondary_medium"]], "calc_transport_properties_secondary_medium() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_transport_properties_secondary_medium"]], "calc_wall_heat_transfer() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.calc_wall_heat_transfer"]], "iterate_area() (vclibpy.components.heat_exchangers.moving_boundary_ntu.movingboundaryntu method)": [[6, "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTU.iterate_area"]], "m_flow_secondary (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger property)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.m_flow_secondary"]], "m_flow_secondary_cp (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger property)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.m_flow_secondary_cp"]], "separate_phases() (vclibpy.components.heat_exchangers.moving_boundary_ntu.movingboundaryntu method)": [[6, "vclibpy.components.heat_exchangers.moving_boundary_ntu.MovingBoundaryNTU.separate_phases"]], "set_primary_cp() (vclibpy.components.heat_exchangers.ntu.basicntu method)": [[6, "vclibpy.components.heat_exchangers.ntu.BasicNTU.set_primary_cp"]], "set_secondary_cp() (vclibpy.components.heat_exchangers.economizer.vaporinjectioneconomizerntu method)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU.set_secondary_cp"]], "start_secondary_med_prop() (vclibpy.components.heat_exchangers.economizer.vaporinjectioneconomizerntu method)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU.start_secondary_med_prop"]], "start_secondary_med_prop() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.start_secondary_med_prop"]], "state_two_phase_inlet (vclibpy.components.heat_exchangers.economizer.vaporinjectioneconomizerntu property)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU.state_two_phase_inlet"]], "state_two_phase_outlet (vclibpy.components.heat_exchangers.economizer.vaporinjectioneconomizerntu property)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU.state_two_phase_outlet"]], "terminate_secondary_med_prop() (vclibpy.components.heat_exchangers.economizer.vaporinjectioneconomizerntu method)": [[6, "vclibpy.components.heat_exchangers.economizer.VaporInjectionEconomizerNTU.terminate_secondary_med_prop"]], "terminate_secondary_med_prop() (vclibpy.components.heat_exchangers.heat_exchanger.heatexchanger method)": [[6, "vclibpy.components.heat_exchangers.heat_exchanger.HeatExchanger.terminate_secondary_med_prop"]], "vclibpy.components.heat_exchangers": [[6, "module-vclibpy.components.heat_exchangers"]], "vclibpy.components.heat_exchangers.economizer": [[6, "module-vclibpy.components.heat_exchangers.economizer"]], "vclibpy.components.heat_exchangers.heat_exchanger": [[6, "module-vclibpy.components.heat_exchangers.heat_exchanger"]], "vclibpy.components.heat_exchangers.moving_boundary_ntu": [[6, "module-vclibpy.components.heat_exchangers.moving_boundary_ntu"]], "vclibpy.components.heat_exchangers.ntu": [[6, "module-vclibpy.components.heat_exchangers.ntu"]], "a (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry property)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.A"]], "a_freieoberflaecherohr (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry property)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.A_FreieOberflaecheRohr"]], "a_rippen (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry property)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.A_Rippen"]], "a_rohrinnen (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry property)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.A_RohrInnen"]], "a_rohrunberippt (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry property)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.A_RohrUnberippt"]], "airsourceheatexchangergeometry (class in vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry"]], "airtowalltransfer (class in vclibpy.components.heat_exchangers.heat_transfer.air_to_wall)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.AirToWallTransfer"]], "constantheattransfer (class in vclibpy.components.heat_exchangers.heat_transfer.constant)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.constant.ConstantHeatTransfer"]], "constanttwophaseheattransfer (class in vclibpy.components.heat_exchangers.heat_transfer.constant)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.constant.ConstantTwoPhaseHeatTransfer"]], "heattransfer (class in vclibpy.components.heat_exchangers.heat_transfer.heat_transfer)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.HeatTransfer"]], "turbulentfluidinpipetowalltransfer (class in vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall.TurbulentFluidInPipeToWallTransfer"]], "twophaseheattransfer (class in vclibpy.components.heat_exchangers.heat_transfer.heat_transfer)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.TwoPhaseHeatTransfer"]], "vdiatlasairtowalltransfer (class in vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.VDIAtlasAirToWallTransfer"]], "wsuairtowall (class in vclibpy.components.heat_exchangers.heat_transfer.air_to_wall)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.WSUAirToWall"]], "walltransfer (class in vclibpy.components.heat_exchangers.heat_transfer.wall)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.wall.WallTransfer"]], "a (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.a"]], "alpha_s() (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.alpha_S"]], "calc() (vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.airtowalltransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.AirToWallTransfer.calc"]], "calc() (vclibpy.components.heat_exchangers.heat_transfer.constant.constantheattransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.constant.ConstantHeatTransfer.calc"]], "calc() (vclibpy.components.heat_exchangers.heat_transfer.constant.constanttwophaseheattransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.constant.ConstantTwoPhaseHeatTransfer.calc"]], "calc() (vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.heattransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.HeatTransfer.calc"]], "calc() (vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.twophaseheattransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.TwoPhaseHeatTransfer.calc"]], "calc() (vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall.turbulentfluidinpipetowalltransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall.TurbulentFluidInPipeToWallTransfer.calc"]], "calc() (vclibpy.components.heat_exchangers.heat_transfer.wall.walltransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.wall.WallTransfer.calc"]], "calc_laminar_area_nusselt() (vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.airtowalltransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.AirToWallTransfer.calc_laminar_area_nusselt"]], "calc_laminar_area_nusselt() (vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.wsuairtowall method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.WSUAirToWall.calc_laminar_area_nusselt"]], "calc_laminar_area_nusselt() (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.vdiatlasairtowalltransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt"]], "calc_reynolds() (vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.airtowalltransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.AirToWallTransfer.calc_reynolds"]], "calc_reynolds() (vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.wsuairtowall method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall.WSUAirToWall.calc_reynolds"]], "calc_reynolds() (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.vdiatlasairtowalltransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.VDIAtlasAirToWallTransfer.calc_reynolds"]], "calc_reynolds_pipe() (in module vclibpy.components.heat_exchangers.heat_transfer.heat_transfer)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer.calc_reynolds_pipe"]], "calc_turbulent_tube_nusselt() (vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall.turbulentfluidinpipetowalltransfer method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall.TurbulentFluidInPipeToWallTransfer.calc_turbulent_tube_nusselt"]], "char_length (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry property)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.char_length"]], "d_a (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.d_a"]], "d_i (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.d_i"]], "dicke_rippe (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.dicke_rippe"]], "eta_r() (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry method)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.eta_R"]], "hoehe (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.hoehe"]], "laenge (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.laenge"]], "lambda_r (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.lambda_R"]], "n_rippen (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.n_Rippen"]], "n_rohre (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.n_Rohre"]], "phi (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry property)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.phi"]], "t_l (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.t_l"]], "t_q (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.t_q"]], "tiefe (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry attribute)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.tiefe"]], "vclibpy.components.heat_exchangers.heat_transfer": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer"]], "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.air_to_wall"]], "vclibpy.components.heat_exchangers.heat_transfer.constant": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.constant"]], "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.heat_transfer"]], "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall"]], "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall"]], "vclibpy.components.heat_exchangers.heat_transfer.wall": [[7, "module-vclibpy.components.heat_exchangers.heat_transfer.wall"]], "verjuengungsfaktor (vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.airsourceheatexchangergeometry property)": [[7, "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall.AirSourceHeatExchangerGeometry.verjuengungsfaktor"]], "coolprop (class in vclibpy.media)": [[9, "vclibpy.media.CoolProp"]], "coolprop (class in vclibpy.media.cool_prop)": [[9, "vclibpy.media.cool_prop.CoolProp"]], "medprop (class in vclibpy.media)": [[9, "vclibpy.media.MedProp"]], "medprop (class in vclibpy.media.media)": [[9, "vclibpy.media.media.MedProp"]], "refprop (class in vclibpy.media)": [[9, "vclibpy.media.RefProp"]], "refprop (class in vclibpy.media.ref_prop)": [[9, "vclibpy.media.ref_prop.RefProp"]], "thermodynamicstate (class in vclibpy.media)": [[9, "vclibpy.media.ThermodynamicState"]], "thermodynamicstate (class in vclibpy.media.states)": [[9, "vclibpy.media.states.ThermodynamicState"]], "transportproperties (class in vclibpy.media)": [[9, "vclibpy.media.TransportProperties"]], "transportproperties (class in vclibpy.media.states)": [[9, "vclibpy.media.states.TransportProperties"]], "calc_mean_transport_properties() (vclibpy.media.medprop method)": [[9, "vclibpy.media.MedProp.calc_mean_transport_properties"]], "calc_mean_transport_properties() (vclibpy.media.media.medprop method)": [[9, "vclibpy.media.media.MedProp.calc_mean_transport_properties"]], "calc_satliq_state() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.calc_satliq_state"]], "calc_satliq_state() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.calc_satliq_state"]], "calc_state() (vclibpy.media.coolprop method)": [[9, "vclibpy.media.CoolProp.calc_state"]], "calc_state() (vclibpy.media.medprop method)": [[9, "vclibpy.media.MedProp.calc_state"]], "calc_state() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.calc_state"]], "calc_state() (vclibpy.media.cool_prop.coolprop method)": [[9, "vclibpy.media.cool_prop.CoolProp.calc_state"]], "calc_state() (vclibpy.media.media.medprop method)": [[9, "vclibpy.media.media.MedProp.calc_state"]], "calc_state() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.calc_state"]], "calc_transport_properties() (vclibpy.media.coolprop method)": [[9, "vclibpy.media.CoolProp.calc_transport_properties"]], "calc_transport_properties() (vclibpy.media.medprop method)": [[9, "vclibpy.media.MedProp.calc_transport_properties"]], "calc_transport_properties() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.calc_transport_properties"]], "calc_transport_properties() (vclibpy.media.cool_prop.coolprop method)": [[9, "vclibpy.media.cool_prop.CoolProp.calc_transport_properties"]], "calc_transport_properties() (vclibpy.media.media.medprop method)": [[9, "vclibpy.media.media.MedProp.calc_transport_properties"]], "calc_transport_properties() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.calc_transport_properties"]], "get_available_substances() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_available_substances"]], "get_available_substances() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_available_substances"]], "get_comp_names() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_comp_names"]], "get_comp_names() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_comp_names"]], "get_critical_point() (vclibpy.media.coolprop method)": [[9, "vclibpy.media.CoolProp.get_critical_point"]], "get_critical_point() (vclibpy.media.medprop method)": [[9, "vclibpy.media.MedProp.get_critical_point"]], "get_critical_point() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_critical_point"]], "get_critical_point() (vclibpy.media.cool_prop.coolprop method)": [[9, "vclibpy.media.cool_prop.CoolProp.get_critical_point"]], "get_critical_point() (vclibpy.media.media.medprop method)": [[9, "vclibpy.media.media.MedProp.get_critical_point"]], "get_critical_point() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_critical_point"]], "get_def_limits() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_def_limits"]], "get_def_limits() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_def_limits"]], "get_dll_path() (vclibpy.media.refprop static method)": [[9, "vclibpy.media.RefProp.get_dll_path"]], "get_dll_path() (vclibpy.media.ref_prop.refprop static method)": [[9, "vclibpy.media.ref_prop.RefProp.get_dll_path"]], "get_fluid_name() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_fluid_name"]], "get_fluid_name() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_fluid_name"]], "get_gwp() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_gwp"]], "get_gwp() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_gwp"]], "get_longname() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_longname"]], "get_longname() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_longname"]], "get_mass_fraction() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_mass_fraction"]], "get_mass_fraction() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_mass_fraction"]], "get_mol_fraction() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_mol_fraction"]], "get_mol_fraction() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_mol_fraction"]], "get_molar_composition() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_molar_composition"]], "get_molar_composition() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_molar_composition"]], "get_molar_mass() (vclibpy.media.coolprop method)": [[9, "vclibpy.media.CoolProp.get_molar_mass"]], "get_molar_mass() (vclibpy.media.medprop method)": [[9, "vclibpy.media.MedProp.get_molar_mass"]], "get_molar_mass() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_molar_mass"]], "get_molar_mass() (vclibpy.media.cool_prop.coolprop method)": [[9, "vclibpy.media.cool_prop.CoolProp.get_molar_mass"]], "get_molar_mass() (vclibpy.media.media.medprop method)": [[9, "vclibpy.media.media.MedProp.get_molar_mass"]], "get_molar_mass() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_molar_mass"]], "get_nbp() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_nbp"]], "get_nbp() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_nbp"]], "get_odp() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_odp"]], "get_odp() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_odp"]], "get_pretty_print() (vclibpy.media.thermodynamicstate method)": [[9, "vclibpy.media.ThermodynamicState.get_pretty_print"]], "get_pretty_print() (vclibpy.media.transportproperties method)": [[9, "vclibpy.media.TransportProperties.get_pretty_print"]], "get_pretty_print() (vclibpy.media.states.thermodynamicstate method)": [[9, "vclibpy.media.states.ThermodynamicState.get_pretty_print"]], "get_pretty_print() (vclibpy.media.states.transportproperties method)": [[9, "vclibpy.media.states.TransportProperties.get_pretty_print"]], "get_safety() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_safety"]], "get_safety() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_safety"]], "get_sat_vap_pressure() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_sat_vap_pressure"]], "get_sat_vap_pressure() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_sat_vap_pressure"]], "get_triple_point() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_triple_point"]], "get_triple_point() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_triple_point"]], "get_two_phase_limits() (in module vclibpy.media.media)": [[9, "vclibpy.media.media.get_two_phase_limits"]], "get_two_phase_limits() (vclibpy.media.medprop method)": [[9, "vclibpy.media.MedProp.get_two_phase_limits"]], "get_two_phase_limits() (vclibpy.media.media.medprop method)": [[9, "vclibpy.media.media.MedProp.get_two_phase_limits"]], "get_version() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.get_version"]], "get_version() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.get_version"]], "is_mixture() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.is_mixture"]], "is_mixture() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.is_mixture"]], "set_error_flag() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.set_error_flag"]], "set_error_flag() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.set_error_flag"]], "set_warning_flag() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.set_warning_flag"]], "set_warning_flag() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.set_warning_flag"]], "terminate() (vclibpy.media.medprop method)": [[9, "vclibpy.media.MedProp.terminate"]], "terminate() (vclibpy.media.refprop method)": [[9, "vclibpy.media.RefProp.terminate"]], "terminate() (vclibpy.media.media.medprop method)": [[9, "vclibpy.media.media.MedProp.terminate"]], "terminate() (vclibpy.media.ref_prop.refprop method)": [[9, "vclibpy.media.ref_prop.RefProp.terminate"]], "vclibpy.media": [[9, "module-vclibpy.media"]], "vclibpy.media.cool_prop": [[9, "module-vclibpy.media.cool_prop"]], "vclibpy.media.media": [[9, "module-vclibpy.media.media"]], "vclibpy.media.ref_prop": [[9, "module-vclibpy.media.ref_prop"]], "vclibpy.media.states": [[9, "module-vclibpy.media.states"]], "calc_multiple_states() (in module vclibpy.utils.automation)": [[10, "vclibpy.utils.automation.calc_multiple_states"]], "full_factorial_map_generation() (in module vclibpy.utils.automation)": [[10, "vclibpy.utils.automation.full_factorial_map_generation"]], "merge_sdfs() (in module vclibpy.utils.sdf_)": [[10, "vclibpy.utils.sdf_.merge_sdfs"]], "nominal_hp_design() (in module vclibpy.utils.nominal_design)": [[10, "vclibpy.utils.nominal_design.nominal_hp_design"]], "plot_cycle() (in module vclibpy.utils.plotting)": [[10, "vclibpy.utils.plotting.plot_cycle"]], "plot_sdf_map() (in module vclibpy.utils.plotting)": [[10, "vclibpy.utils.plotting.plot_sdf_map"]], "print_states() (in module vclibpy.utils.printing)": [[10, "vclibpy.utils.printing.print_states"]], "save_to_sdf() (in module vclibpy.utils.sdf_)": [[10, "vclibpy.utils.sdf_.save_to_sdf"]], "sdf_to_csv() (in module vclibpy.utils.sdf_)": [[10, "vclibpy.utils.sdf_.sdf_to_csv"]], "set_axis_style() (in module vclibpy.utils.plotting)": [[10, "vclibpy.utils.plotting.set_axis_style"]], "vclibpy.utils": [[10, "module-vclibpy.utils"]], "vclibpy.utils.automation": [[10, "module-vclibpy.utils.automation"]], "vclibpy.utils.nominal_design": [[10, "module-vclibpy.utils.nominal_design"]], "vclibpy.utils.plotting": [[10, "module-vclibpy.utils.plotting"]], "vclibpy.utils.printing": [[10, "module-vclibpy.utils.printing"]], "vclibpy.utils.sdf_": [[10, "module-vclibpy.utils.sdf_"]]}}) \ No newline at end of file diff --git a/docs/0.1.1/docs/version_his.html b/docs/0.1.1/docs/version_his.html new file mode 100644 index 0000000..78f995c --- /dev/null +++ b/docs/0.1.1/docs/version_his.html @@ -0,0 +1,122 @@ + + + + + + + + + Version History — vclibpy 0.1.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Version History

+
    +
  • v0.1.0:

    +
      +
    • First implementation based on prior work

    • +
    +
  • +
  • v0.1.1:

    +
      +
    • Move plot_cycle function

    • +
    +
  • +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/pylint/pylint.html b/docs/0.1.1/pylint/pylint.html new file mode 100644 index 0000000..7a3f9f1 --- /dev/null +++ b/docs/0.1.1/pylint/pylint.html @@ -0,0 +1,7178 @@ + + + + Pylint report + + + + + +

Pylint report from report.jinja2

+ + +

Score

+ 7.41 / 10 + + (previous score: 7.41 / 10) + + + +

Messages

+ +

Module vclibpy.components.component (vclibpy/components/component.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
110conventionline-too-longC0301
Line too long (107/100)
120conventionline-too-longC0301
Line too long (101/100)
390conventionline-too-longC0301
Line too long (103/100)
438warningunnecessary-passW0107BaseComponent.start_secondary_med_prop
Unnecessary pass statement
558warningunnecessary-passW0107BaseComponent.terminate_secondary_med_prop
Unnecessary pass statement
+ +

Module vclibpy.components.compressors (vclibpy/components/compressors/__init__.py)

+ + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
+ +

Module vclibpy.components.compressors.compressor (vclibpy/components/compressors/compressor.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
400conventionline-too-longC0301
Line too long (107/100)
528conventioninvalid-nameC0103Compressor.__init__
Attribute name "N_max" doesn't conform to snake_case naming style
538conventioninvalid-nameC0103Compressor.__init__
Attribute name "V_h" doesn't conform to snake_case naming style
1458conventioninvalid-nameC0103Compressor.calc_m_flow
Variable name "V_flow_ref" doesn't conform to snake_case naming style
1520conventionline-too-longC0301
Line too long (114/100)
1530conventionline-too-longC0301
Line too long (113/100)
1580conventionline-too-longC0301
Line too long (103/100)
1688conventioninvalid-nameC0103Compressor.calc_electrical_power
Variable name "P_t" doesn't conform to snake_case naming style
1718conventioninvalid-nameC0103Compressor.calc_electrical_power
Variable name "P_el" doesn't conform to snake_case naming style
+ +

Module vclibpy.components.compressors.constant_effectivness (vclibpy/components/compressors/constant_effectivness.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
90conventionline-too-longC0301
Line too long (114/100)
250conventionline-too-longC0301
Line too long (117/100)
404refactortoo-many-argumentsR0913ConstantEffectivenessCompressor.__init__
Too many arguments (6/5)
+ +

Module vclibpy.components.compressors.rotary (vclibpy/components/compressors/rotary.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
90conventionline-too-longC0301
Line too long (110/100)
284refactortoo-many-localsR0914RotaryCompressor.get_lambda_h
Too many local variables (18/15)
390conventionline-too-longC0301
Line too long (107/100)
418conventioninvalid-nameC0103RotaryCompressor.get_lambda_h
Variable name "T_1" doesn't conform to snake_case naming style
488conventioninvalid-nameC0103RotaryCompressor.get_lambda_h
Variable name "sigma_T_1" doesn't conform to snake_case naming style
498conventioninvalid-nameC0103RotaryCompressor.get_lambda_h
Variable name "T_1_ave" doesn't conform to snake_case naming style
568conventioninvalid-nameC0103RotaryCompressor.get_lambda_h
Variable name "pi" doesn't conform to snake_case naming style
770conventionline-too-longC0301
Line too long (107/100)
848conventioninvalid-nameC0103RotaryCompressor.get_eta_isentropic
Variable name "pi" doesn't conform to snake_case naming style
954refactortoo-many-localsR0914RotaryCompressor.get_eta_mech
Too many local variables (17/15)
1070conventionline-too-longC0301
Line too long (107/100)
1208conventioninvalid-nameC0103RotaryCompressor.get_eta_mech
Variable name "pi" doesn't conform to snake_case naming style
1240conventionline-too-longC0301
Line too long (116/100)
+ +

Module vclibpy.components.compressors.ten_coefficient (vclibpy/components/compressors/ten_coefficient.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
1026conventioninvalid-nameC0103calc_ten_coefficients
Argument name "T_eva" doesn't conform to snake_case naming style
1033conventioninvalid-nameC0103calc_ten_coefficients
Argument name "T_con" doesn't conform to snake_case naming style
234conventioninvalid-nameC0103calc_ten_coefficients
Variable name "z" doesn't conform to snake_case naming style
250conventionline-too-longC0301
Line too long (105/100)
400conventionline-too-longC0301
Line too long (105/100)
520conventionline-too-longC0301
Line too long (106/100)
798conventioninvalid-nameC0103BaseTenCoefficientCompressor.__init__
Attribute name "md" doesn't conform to snake_case naming style
9328conventioninvalid-nameC0103BaseTenCoefficientCompressor.get_parameter
Argument name "T_eva" doesn't conform to snake_case naming style
9335conventioninvalid-nameC0103BaseTenCoefficientCompressor.get_parameter
Argument name "T_con" doesn't conform to snake_case naming style
1100conventionline-too-longC0301
Line too long (119/100)
1230refactortoo-many-instance-attributesR0902TenCoefficientCompressor
Too many instance attributes (8/7)
1340conventionline-too-longC0301
Line too long (105/100)
1400conventionline-too-longC0301
Line too long (112/100)
1410conventionline-too-longC0301
Line too long (117/100)
1430conventionline-too-longC0301
Line too long (117/100)
1530conventionline-too-longC0301
Line too long (101/100)
1540conventionline-too-longC0301
Line too long (107/100)
1580conventionline-too-longC0301
Line too long (106/100)
1680conventionline-too-longC0301
Line too long (107/100)
1684refactortoo-many-argumentsR0913TenCoefficientCompressor.__init__
Too many arguments (8/5)
1708conventioninvalid-nameC0103TenCoefficientCompressor.__init__
Attribute name "T_sc" doesn't conform to snake_case naming style
1718conventioninvalid-nameC0103TenCoefficientCompressor.__init__
Attribute name "T_sh" doesn't conform to snake_case naming style
1918conventioninvalid-nameC0103TenCoefficientCompressor.get_lambda_h
Variable name "T_eva" doesn't conform to snake_case naming style
1928conventioninvalid-nameC0103TenCoefficientCompressor.get_lambda_h
Variable name "T_con" doesn't conform to snake_case naming style
2040conventionline-too-longC0301
Line too long (110/100)
2228conventioninvalid-nameC0103TenCoefficientCompressor.get_eta_isentropic
Variable name "T_con" doesn't conform to snake_case naming style
2268conventioninvalid-nameC0103TenCoefficientCompressor.get_eta_isentropic
Variable name "h3" doesn't conform to snake_case naming style
23012conventioninvalid-nameC0103TenCoefficientCompressor.get_eta_isentropic
Variable name "h2" doesn't conform to snake_case naming style
23212conventioninvalid-nameC0103TenCoefficientCompressor.get_eta_isentropic
Variable name "h2" doesn't conform to snake_case naming style
2350conventionline-too-longC0301
Line too long (113/100)
2558conventioninvalid-nameC0103TenCoefficientCompressor.get_eta_mech
Variable name "T_con" doesn't conform to snake_case naming style
2598conventioninvalid-nameC0103TenCoefficientCompressor.get_eta_mech
Variable name "h3" doesn't conform to snake_case naming style
2608conventioninvalid-nameC0103TenCoefficientCompressor.get_eta_mech
Variable name "h2" doesn't conform to snake_case naming style
2768conventioninvalid-nameC0103TenCoefficientCompressor._calculate_values
Variable name "T_eva" doesn't conform to snake_case naming style
2778conventioninvalid-nameC0103TenCoefficientCompressor._calculate_values
Variable name "T_con" doesn't conform to snake_case naming style
2790conventionline-too-longC0301
Line too long (110/100)
3110conventionline-too-longC0301
Line too long (106/100)
3358conventioninvalid-nameC0103DataSheetCompressor.get_lambda_h
Variable name "T_eva" doesn't conform to snake_case naming style
3368conventioninvalid-nameC0103DataSheetCompressor.get_lambda_h
Variable name "T_con" doesn't conform to snake_case naming style
3508conventioninvalid-nameC0103DataSheetCompressor.get_eta_isentropic
Variable name "T_eva" doesn't conform to snake_case naming style
3518conventioninvalid-nameC0103DataSheetCompressor.get_eta_isentropic
Variable name "T_con" doesn't conform to snake_case naming style
3658conventioninvalid-nameC0103DataSheetCompressor.get_eta_mech
Variable name "T_eva" doesn't conform to snake_case naming style
3668conventioninvalid-nameC0103DataSheetCompressor.get_eta_mech
Variable name "T_con" doesn't conform to snake_case naming style
+ +

Module vclibpy.components.expansion_valves (vclibpy/components/expansion_valves/__init__.py)

+ + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
+ +

Module vclibpy.components.expansion_valves.__init__ (vclibpy/components/expansion_valves/__init__.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10refactorcyclic-importR0401
Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.standard)
10refactorcyclic-importR0401
Cyclic import (vclibpy.media -> vclibpy.media.cool_prop -> vclibpy.media.media)
10refactorcyclic-importR0401
Cyclic import (vclibpy.components.expansion_valves -> vclibpy.components.expansion_valves.bernoulli)
10refactorcyclic-importR0401
Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.vapor_injection_phase_separator -> vclibpy.flowsheets.vapor_injection)
10refactorcyclic-importR0401
Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.vapor_injection_economizer -> vclibpy.flowsheets.vapor_injection)
10refactorcyclic-importR0401
Cyclic import (vclibpy.utils -> vclibpy.utils.automation)
10refactorcyclic-importR0401
Cyclic import (vclibpy.media -> vclibpy.media.ref_prop)
10refactorcyclic-importR0401
Cyclic import (vclibpy.media -> vclibpy.media.media)
+ +

Module vclibpy.components.expansion_valves.bernoulli (vclibpy/components/expansion_valves/bernoulli.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
160conventionline-too-longC0301
Line too long (110/100)
210conventionline-too-longC0301
Line too long (103/100)
+ +

Module vclibpy.components.expansion_valves.expansion_valve (vclibpy/components/expansion_valves/expansion_valve.py)

+ + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
208conventioninvalid-nameC0103ExpansionValve.__init__
Attribute name "A" doesn't conform to snake_case naming style
+ +

Module vclibpy.components.heat_exchangers (vclibpy/components/heat_exchangers/__init__.py)

+ + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
+ +

Module vclibpy.components.heat_exchangers.economizer (vclibpy/components/heat_exchangers/economizer.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
404conventionmissing-function-docstringC0116VaporInjectionEconomizerNTU.state_two_phase_inlet
Missing function or method docstring
484conventionmissing-function-docstringC0116VaporInjectionEconomizerNTU.state_two_phase_outlet
Missing function or method docstring
+ +

Module vclibpy.components.heat_exchangers.heat_exchanger (vclibpy/components/heat_exchangers/heat_exchanger.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
80conventionline-too-longC0301
Line too long (109/100)
110refactortoo-many-instance-attributesR0902HeatExchanger
Too many instance attributes (11/7)
324refactortoo-many-argumentsR0913HeatExchanger.__init__
Too many arguments (8/5)
438conventioninvalid-nameC0103HeatExchanger.__init__
Attribute name "A" doesn't conform to snake_case naming style
980conventionline-too-longC0301
Line too long (106/100)
1814conventionmissing-function-docstringC0116HeatExchanger.m_flow_secondary
Missing function or method docstring
1904conventionmissing-function-docstringC0116HeatExchanger.m_flow_secondary_cp
Missing function or method docstring
2044conventionmissing-function-docstringC0116HeatExchanger.calc_secondary_Q_flow
Missing function or method docstring
2044conventioninvalid-nameC0103HeatExchanger.calc_secondary_Q_flow
Method name "calc_secondary_Q_flow" doesn't conform to snake_case naming style
20436conventioninvalid-nameC0103HeatExchanger.calc_secondary_Q_flow
Argument name "Q_flow" doesn't conform to snake_case naming style
2074conventioninvalid-nameC0103HeatExchanger.calc_Q_flow
Method name "calc_Q_flow" doesn't conform to snake_case naming style
2340conventionline-too-longC0301
Line too long (109/100)
+ +

Module vclibpy.components.heat_exchangers.heat_transfer (vclibpy/components/heat_exchangers/heat_transfer/__init__.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
20conventionwrong-import-orderC0411
first party import "from vclibpy.components.heat_exchangers.heat_transfer import constant" should be placed before "from .heat_transfer import TwoPhaseHeatTransfer, HeatTransfer, calc_reynolds_pipe"
30conventionwrong-import-orderC0411
first party import "from vclibpy.components.heat_exchangers.heat_transfer import wall" should be placed before "from .heat_transfer import TwoPhaseHeatTransfer, HeatTransfer, calc_reynolds_pipe"
+ +

Module vclibpy.components.heat_exchangers.heat_transfer.air_to_wall (vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
50conventionwrong-import-orderC0411
first party import "from vclibpy.media import TransportProperties" should be placed before "from .heat_transfer import HeatTransfer"
2323conventioninvalid-nameC0103AirToWallTransfer.__init__
Argument name "A_cross" doesn't conform to snake_case naming style
248conventioninvalid-nameC0103AirToWallTransfer.__init__
Attribute name "A_cross" doesn't conform to snake_case naming style
358conventioninvalid-nameC0103AirToWallTransfer.calc
Variable name "Re" doesn't conform to snake_case naming style
360conventionline-too-longC0301
Line too long (113/100)
5440conventioninvalid-nameC0103AirToWallTransfer.calc_laminar_area_nusselt
Argument name "Re" doesn't conform to snake_case naming style
+ +

Module vclibpy.components.heat_exchangers.heat_transfer.constant (vclibpy/components/heat_exchangers/heat_transfer/constant.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
90refactortoo-few-public-methodsR0903ConstantHeatTransfer
Too few public methods (1/2)
2119warningunused-argumentW0613ConstantHeatTransfer.calc
Unused argument 'transport_properties'
2162warningunused-argumentW0613ConstantHeatTransfer.calc
Unused argument 'm_flow'
260conventionline-too-longC0301
Line too long (102/100)
360refactortoo-few-public-methodsR0903ConstantTwoPhaseHeatTransfer
Too few public methods (1/2)
480warningunused-argumentW0613ConstantTwoPhaseHeatTransfer.calc
Unused argument 'kwargs'
530conventionline-too-longC0301
Line too long (106/100)
+ +

Module vclibpy.components.heat_exchangers.heat_transfer.heat_transfer (vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
120refactortoo-few-public-methodsR0903HeatTransfer
Too few public methods (1/2)
400refactortoo-few-public-methodsR0903TwoPhaseHeatTransfer
Too few public methods (1/2)
464refactortoo-many-argumentsR0913TwoPhaseHeatTransfer.calc
Too many arguments (9/5)
610conventionline-too-longC0301
Line too long (104/100)
790conventionline-too-longC0301
Line too long (103/100)
+ +

Module vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall (vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
60conventionwrong-import-orderC0411
first party import "from vclibpy.media import TransportProperties" should be placed before "from .heat_transfer import HeatTransfer, calc_reynolds_pipe"
518conventioninvalid-nameC0103TurbulentFluidInPipeToWallTransfer.calc
Variable name "Re" doesn't conform to snake_case naming style
5942conventioninvalid-nameC0103TurbulentFluidInPipeToWallTransfer.calc_turbulent_tube_nusselt
Argument name "Re" doesn't conform to snake_case naming style
594refactortoo-many-branchesR0912TurbulentFluidInPipeToWallTransfer.calc_turbulent_tube_nusselt
Too many branches (14/12)
730conventionline-too-longC0301
Line too long (104/100)
7412refactorno-else-returnR1705TurbulentFluidInPipeToWallTransfer.calc_turbulent_tube_nusselt
Unnecessary "elif" after "return", remove the leading "el" from "elif"
810conventionline-too-longC0301
Line too long (104/100)
840conventionline-too-longC0301
Line too long (104/100)
930conventionline-too-longC0301
Line too long (104/100)
+ +

Module vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall (vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
120refactortoo-many-instance-attributesR0902AirSourceHeatExchangerGeometry
Too many instance attributes (12/7)
254conventioninvalid-nameC0103AirSourceHeatExchangerGeometry
Attribute name "lambda_R" doesn't conform to snake_case naming style
264conventioninvalid-nameC0103AirSourceHeatExchangerGeometry
Attribute name "n_Rohre" doesn't conform to snake_case naming style
274conventioninvalid-nameC0103AirSourceHeatExchangerGeometry
Attribute name "n_Rippen" doesn't conform to snake_case naming style
284conventioninvalid-nameC0103AirSourceHeatExchangerGeometry
Attribute name "a" doesn't conform to snake_case naming style
394conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.A_Rippen
Attribute name "A_Rippen" doesn't conform to snake_case naming style
410conventionline-too-longC0301
Line too long (106/100)
444conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.A
Attribute name "A" doesn't conform to snake_case naming style
494conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.A_FreieOberflaecheRohr
Attribute name "A_FreieOberflaecheRohr" doesn't conform to snake_case naming style
544conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.A_RohrInnen
Attribute name "A_RohrInnen" doesn't conform to snake_case naming style
594conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.A_RohrUnberippt
Attribute name "A_RohrUnberippt" doesn't conform to snake_case naming style
824conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.eta_R
Method name "eta_R" doesn't conform to snake_case naming style
8220conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.eta_R
Argument name "alpha_R" doesn't conform to snake_case naming style
928conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.eta_R
Variable name "X" doesn't conform to snake_case naming style
954conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.alpha_S
Method name "alpha_S" doesn't conform to snake_case naming style
9522conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.alpha_S
Argument name "alpha_R" doesn't conform to snake_case naming style
1058conventioninvalid-nameC0103AirSourceHeatExchangerGeometry.alpha_S
Variable name "A_R_to_A" doesn't conform to snake_case naming style
1558conventioninvalid-nameC0103VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt
Variable name "C" doesn't conform to snake_case naming style
1588conventioninvalid-nameC0103VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt
Variable name "A_div_A_0" doesn't conform to snake_case naming style
1668conventioninvalid-nameC0103VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt
Variable name "alpha_R" doesn't conform to snake_case naming style
1678conventioninvalid-nameC0103VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt
Variable name "alpha_S" doesn't conform to snake_case naming style
+ +

Module vclibpy.components.heat_exchangers.heat_transfer.wall (vclibpy/components/heat_exchangers/heat_transfer/wall.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
40conventionwrong-import-orderC0411
first party import "from vclibpy.media import TransportProperties" should be placed before "from .heat_transfer import HeatTransfer"
100refactortoo-few-public-methodsR0903WallTransfer
Too few public methods (1/2)
+ +

Module vclibpy.components.heat_exchangers.moving_boundary_ntu (vclibpy/components/heat_exchangers/moving_boundary_ntu.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
190conventionline-too-longC0301
Line too long (102/100)
418conventioninvalid-nameC0103MovingBoundaryNTU.separate_phases
Variable name "Q_sc" doesn't conform to snake_case naming style
448conventioninvalid-nameC0103MovingBoundaryNTU.separate_phases
Variable name "Q_lat" doesn't conform to snake_case naming style
478conventioninvalid-nameC0103MovingBoundaryNTU.separate_phases
Variable name "Q_sh" doesn't conform to snake_case naming style
5227conventioninvalid-nameC0103MovingBoundaryNTU.iterate_area
Argument name "dT_max" doesn't conform to snake_case naming style
8612conventioninvalid-nameC0103MovingBoundaryNTU.iterate_area
Variable name "NTU" doesn't conform to snake_case naming style
8916refactorno-else-breakR1723MovingBoundaryNTU.iterate_area
Unnecessary "else" after "break", remove the "else" and de-indent the code inside it
1144refactortoo-many-localsR0914MovingBoundaryNTUCondenser.calc
Too many local variables (31/15)
1368conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_sc" doesn't conform to snake_case naming style
13614conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_lat" doesn't conform to snake_case naming style
13621conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_sh" doesn't conform to snake_case naming style
1468conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "T_mean" doesn't conform to snake_case naming style
1528conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "T_sc" doesn't conform to snake_case naming style
1538conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "T_sh" doesn't conform to snake_case naming style
1548conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "T_out" doesn't conform to snake_case naming style
1578conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_sc_ntu" doesn't conform to snake_case naming style
15718conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "A_sc" doesn't conform to snake_case naming style
1590conventionline-too-longC0301
Line too long (104/100)
1610conventionline-too-longC0301
Line too long (104/100)
16512conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "A_sc" doesn't conform to snake_case naming style
16912conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "A_sc" doesn't conform to snake_case naming style
17112conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_sc_ntu" doesn't conform to snake_case naming style
17122warningunused-variableW0612MovingBoundaryNTUCondenser.calc
Unused variable 'k_sc'
1778conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_lat_ntu" doesn't conform to snake_case naming style
17719conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "A_lat" doesn't conform to snake_case naming style
18812conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "A_lat" doesn't conform to snake_case naming style
19312conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "A_lat" doesn't conform to snake_case naming style
19512conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_lat_ntu" doesn't conform to snake_case naming style
19523warningunused-variableW0612MovingBoundaryNTUCondenser.calc
Unused variable 'k_lat'
1990conventionline-too-longC0301
Line too long (101/100)
19912warninglogging-fstring-interpolationW1203MovingBoundaryNTUCondenser.calc
Use lazy % formatting in logging functions
2028conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_sh_ntu" doesn't conform to snake_case naming style
20218conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "A_sh" doesn't conform to snake_case naming style
2040conventionline-too-longC0301
Line too long (102/100)
2060conventionline-too-longC0301
Line too long (103/100)
21012conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "A_sh" doesn't conform to snake_case naming style
21212conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_sh_ntu" doesn't conform to snake_case naming style
21222warningunused-variableW0612MovingBoundaryNTUCondenser.calc
Unused variable 'k_sh'
21612warninglogging-fstring-interpolationW1203MovingBoundaryNTUCondenser.calc
Use lazy % formatting in logging functions
2188conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "Q_ntu" doesn't conform to snake_case naming style
2218conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "dT_min_in" doesn't conform to snake_case naming style
2228conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "dT_min_out" doesn't conform to snake_case naming style
2238conventioninvalid-nameC0103MovingBoundaryNTUCondenser.calc
Variable name "dT_min_LatSH" doesn't conform to snake_case naming style
2250conventionline-too-longC0301
Line too long (121/100)
2260conventionline-too-longC0301
Line too long (120/100)
2270conventionline-too-longC0301
Line too long (122/100)
2454refactortoo-many-localsR0914MovingBoundaryNTUEvaporator.calc
Too many local variables (30/15)
2678conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_sc" doesn't conform to snake_case naming style
26714conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_lat" doesn't conform to snake_case naming style
26721conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_sh" doesn't conform to snake_case naming style
2778conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "T_mean" doesn't conform to snake_case naming style
2828conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "T_sh" doesn't conform to snake_case naming style
2838conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "T_sc" doesn't conform to snake_case naming style
2848conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "T_out" doesn't conform to snake_case naming style
2878conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_sh_ntu" doesn't conform to snake_case naming style
28718conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_sh" doesn't conform to snake_case naming style
2890conventionline-too-longC0301
Line too long (104/100)
2910conventionline-too-longC0301
Line too long (104/100)
29516conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_sh" doesn't conform to snake_case naming style
30116conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_sh" doesn't conform to snake_case naming style
30412conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_sh" doesn't conform to snake_case naming style
30612conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_sh_ntu" doesn't conform to snake_case naming style
30622warningunused-variableW0612MovingBoundaryNTUEvaporator.calc
Unused variable 'k_sh'
31112warninglogging-fstring-interpolationW1203MovingBoundaryNTUEvaporator.calc
Use lazy % formatting in logging functions
3148conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_lat_ntu" doesn't conform to snake_case naming style
31419conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_lat" doesn't conform to snake_case naming style
32616conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_lat" doesn't conform to snake_case naming style
33116conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_lat" doesn't conform to snake_case naming style
33412conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_lat" doesn't conform to snake_case naming style
33512conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_lat_ntu" doesn't conform to snake_case naming style
33523warningunused-variableW0612MovingBoundaryNTUEvaporator.calc
Unused variable 'k_lat'
3390conventionline-too-longC0301
Line too long (101/100)
33912warninglogging-fstring-interpolationW1203MovingBoundaryNTUEvaporator.calc
Use lazy % formatting in logging functions
3428conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_sc_ntu" doesn't conform to snake_case naming style
34218conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_sc" doesn't conform to snake_case naming style
3440conventionline-too-longC0301
Line too long (102/100)
3460conventionline-too-longC0301
Line too long (103/100)
35012conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "A_sc" doesn't conform to snake_case naming style
35212conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_sc_ntu" doesn't conform to snake_case naming style
35222warningunused-variableW0612MovingBoundaryNTUEvaporator.calc
Unused variable 'k_sc'
3578conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "Q_ntu" doesn't conform to snake_case naming style
3608conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "dT_min_in" doesn't conform to snake_case naming style
3618conventioninvalid-nameC0103MovingBoundaryNTUEvaporator.calc
Variable name "dT_min_out" doesn't conform to snake_case naming style
3630conventionline-too-longC0301
Line too long (122/100)
3640conventionline-too-longC0301
Line too long (121/100)
+ +

Module vclibpy.components.heat_exchangers.ntu (vclibpy/components/heat_exchangers/ntu.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
6733conventioninvalid-nameC0103BasicNTU.calc_eps
Argument name "NTU" doesn't conform to snake_case naming style
934conventioninvalid-nameC0103BasicNTU.calc_R
Method name "calc_R" doesn't conform to snake_case naming style
950conventionline-too-longC0301
Line too long (120/100)
1264conventioninvalid-nameC0103BasicNTU.calc_NTU
Method name "calc_NTU" doesn't conform to snake_case naming style
12617conventioninvalid-nameC0103BasicNTU.calc_NTU
Argument name "A" doesn't conform to snake_case naming style
1330conventionline-too-longC0301
Line too long (106/100)
1420conventionline-too-longC0301
Line too long (118/100)
1520conventionline-too-longC0301
Line too long (104/100)
1524conventioninvalid-nameC0103BasicNTU.calc_Q_ntu
Method name "calc_Q_ntu" doesn't conform to snake_case naming style
15225conventioninvalid-nameC0103BasicNTU.calc_Q_ntu
Argument name "dT_max" doesn't conform to snake_case naming style
15276conventioninvalid-nameC0103BasicNTU.calc_Q_ntu
Argument name "A" doesn't conform to snake_case naming style
1540conventionline-too-longC0301
Line too long (110/100)
1688conventioninvalid-nameC0103BasicNTU.calc_Q_ntu
Variable name "NTU" doesn't conform to snake_case naming style
1728conventioninvalid-nameC0103BasicNTU.calc_Q_ntu
Variable name "Q_max" doesn't conform to snake_case naming style
+ +

Module vclibpy.datamodels (vclibpy/datamodels.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
6519errorno-memberE1101VariableContainer.__getattr__
Super of 'VariableContainer' has no '__getattr__' member
1664refactortoo-many-argumentsR0913Inputs.__init__
Too many arguments (9/5)
+ +

Module vclibpy.flowsheets (vclibpy/flowsheets/__init__.py)

+ + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
+ +

Module vclibpy.flowsheets.base (vclibpy/flowsheets/base.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
50conventionwrong-import-orderC0411
standard import "from abc import abstractmethod" should be placed before "import numpy as np"
474conventionmissing-function-docstringC0116BaseCycle.setup_new_fluid
Missing function or method docstring
674conventionmissing-function-docstringC0116BaseCycle.terminate
Missing function or method docstring
724conventionmissing-function-docstringC0116BaseCycle.get_all_components
Missing function or method docstring
754refactortoo-many-localsR0914BaseCycle.calc_steady_state
Too many local variables (45/15)
754refactortoo-many-branchesR0912BaseCycle.calc_steady_state
Too many branches (28/12)
754refactortoo-many-statementsR0915BaseCycle.calc_steady_state
Too many statements (132/50)
754refactorinconsistent-return-statementsR1710BaseCycle.calc_steady_state
Either all return statements in a function should return an expression, or none of them should.
1358conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "err_dT_min" doesn't conform to snake_case naming style
1538conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "T_1_start" doesn't conform to snake_case naming style
1548conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "T_3_start" doesn't conform to snake_case naming style
2180conventionline-too-longC0301
Line too long (118/100)
22123conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "dT_min_eva" doesn't conform to snake_case naming style
22412refactorno-else-continueR1724BaseCycle.calc_steady_state
Unnecessary "else" after "continue", remove the "else" and de-indent the code inside it
22816refactorno-else-continueR1724BaseCycle.calc_steady_state
Unnecessary "elif" after "continue", remove the leading "el" from "elif"
23723conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "dT_min_con" doesn't conform to snake_case naming style
23812refactorno-else-continueR1724BaseCycle.calc_steady_state
Unnecessary "else" after "continue", remove the "else" and de-indent the code inside it
24216refactorno-else-continueR1724BaseCycle.calc_steady_state
Unnecessary "elif" after "continue", remove the leading "el" from "elif"
2788conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "Q_con" doesn't conform to snake_case naming style
2798conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "Q_con_outer" doesn't conform to snake_case naming style
2808conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "Q_eva" doesn't conform to snake_case naming style
2818conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "Q_eva_outer" doesn't conform to snake_case naming style
2848conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "P_el" doesn't conform to snake_case naming style
2858conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "T_con_out" doesn't conform to snake_case naming style
2888conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "COP_inner" doesn't conform to snake_case naming style
2898conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "COP_outer" doesn't conform to snake_case naming style
2910conventionsuperfluous-parensC0325
Unnecessary parens after '=' keyword
2918conventioninvalid-nameC0103BaseCycle.calc_steady_state
Variable name "COP_carnot" doesn't conform to snake_case naming style
3250conventionline-too-longC0301
Line too long (112/100)
3518conventioninvalid-nameC0103BaseCycle.set_evaporator_outlet_based_on_superheating
Variable name "T_1" doesn't conform to snake_case naming style
3668conventioninvalid-nameC0103BaseCycle.set_condenser_outlet_based_on_subcooling
Variable name "T_3" doesn't conform to snake_case naming style
37513conventioninvalid-nameC0103BaseCycle.plot_cycle
Variable name "ax" doesn't conform to snake_case naming style
38546conventioninvalid-nameC0103BaseCycle._plot_secondary_heat_flow_rates
Argument name "ax" doesn't conform to snake_case naming style
3868conventioninvalid-nameC0103BaseCycle._plot_secondary_heat_flow_rates
Variable name "Q_con" doesn't conform to snake_case naming style
3878conventioninvalid-nameC0103BaseCycle._plot_secondary_heat_flow_rates
Variable name "Q_eva" doesn't conform to snake_case naming style
3898conventioninvalid-nameC0103BaseCycle._plot_secondary_heat_flow_rates
Variable name "delta_H_con" doesn't conform to snake_case naming style
3938conventioninvalid-nameC0103BaseCycle._plot_secondary_heat_flow_rates
Variable name "delta_H_eva" doesn't conform to snake_case naming style
+ +

Module vclibpy.flowsheets.standard (vclibpy/flowsheets/standard.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
680conventionline-too-longC0301
Line too long (111/100)
+ +

Module vclibpy.flowsheets.vapor_injection (vclibpy/flowsheets/vapor_injection.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
848conventioninvalid-nameC0103BaseVaporInjection.calc_states
Variable name "h_1_VI_mixed" doesn't conform to snake_case naming style
1488conventioninvalid-nameC0103BaseVaporInjection.calc_electrical_power
Variable name "P_el_low" doesn't conform to snake_case naming style
1518conventioninvalid-nameC0103BaseVaporInjection.calc_electrical_power
Variable name "P_el_high" doesn't conform to snake_case naming style
+ +

Module vclibpy.flowsheets.vapor_injection_economizer (vclibpy/flowsheets/vapor_injection_economizer.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
464refactortoo-many-localsR0914VaporInjectionEconomizer.calc_injection
Too many local variables (20/15)
858conventioninvalid-nameC0103VaporInjectionEconomizer.calc_injection
Variable name "dT_secondary" doesn't conform to snake_case naming style
10612conventioninvalid-nameC0103VaporInjectionEconomizer.calc_injection
Variable name "Q_flow_goal" doesn't conform to snake_case naming style
11412conventioninvalid-nameC0103VaporInjectionEconomizer.calc_injection
Variable name "Q_flow" doesn't conform to snake_case naming style
11420warningunused-variableW0612VaporInjectionEconomizer.calc_injection
Unused variable 'k'
+ +

Module vclibpy.flowsheets.vapor_injection_phase_separator (vclibpy/flowsheets/vapor_injection_phase_separator.py)

+ + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
+ +

Module vclibpy.media (vclibpy/media/__init__.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
274warningglobal-statementW0603set_global_media_properties
Using the global statement
384warningglobal-variable-not-assignedW0602get_global_med_prop_and_kwargs
Using global for 'USED_MED_PROP' but no assignment is done
+ +

Module vclibpy.media.cool_prop (vclibpy/media/cool_prop.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
2715infoc-extension-no-memberI1101CoolProp
Module 'CoolProp.CoolProp' has no 'PT_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
2815infoc-extension-no-memberI1101CoolProp
Module 'CoolProp.CoolProp' has no 'QT_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
2915infoc-extension-no-memberI1101CoolProp
Module 'CoolProp.CoolProp' has no 'PSmass_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
3015infoc-extension-no-memberI1101CoolProp
Module 'CoolProp.CoolProp' has no 'HmassP_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
3115infoc-extension-no-memberI1101CoolProp
Module 'CoolProp.CoolProp' has no 'PQ_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
3844infoc-extension-no-memberI1101CoolProp.__init__
Module 'CoolProp.CoolProp' has no 'AbstractState' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
4816infoc-extension-no-memberI1101CoolProp.calc_state
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
5016infoc-extension-no-memberI1101CoolProp.calc_state
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
5216infoc-extension-no-memberI1101CoolProp.calc_state
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
5416infoc-extension-no-memberI1101CoolProp.calc_state
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
5616infoc-extension-no-memberI1101CoolProp.calc_state
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
5816infoc-extension-no-memberI1101CoolProp.calc_state
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
6016infoc-extension-no-memberI1101CoolProp.calc_state
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
8812conventioninvalid-nameC0103CoolProp.calc_transport_properties
Variable name "pr" doesn't conform to snake_case naming style
8817infoc-extension-no-memberI1101CoolProp.calc_transport_properties
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
9017infoc-extension-no-memberI1101CoolProp.calc_transport_properties
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
9217infoc-extension-no-memberI1101CoolProp.calc_transport_properties
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
9418infoc-extension-no-memberI1101CoolProp.calc_transport_properties
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
9622infoc-extension-no-memberI1101CoolProp.calc_transport_properties
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
13213infoc-extension-no-memberI1101CoolProp.get_critical_point
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
1338conventioninvalid-nameC0103CoolProp.get_critical_point
Variable name "pc" doesn't conform to snake_case naming style
13313infoc-extension-no-memberI1101CoolProp.get_critical_point
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
1348conventioninvalid-nameC0103CoolProp.get_critical_point
Variable name "dc" doesn't conform to snake_case naming style
13413infoc-extension-no-memberI1101CoolProp.get_critical_point
Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.
+ +

Module vclibpy.media.media (vclibpy/media/media.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
100conventionline-too-longC0301
Line too long (105/100)
5036warningunused-argumentW0613MedProp.calc_state
Unused argument 'var1'
5049warningunused-argumentW0613MedProp.calc_state
Unused argument 'var2'
530conventionline-too-longC0301
Line too long (111/100)
580conventionline-too-longC0301
Line too long (118/100)
1028warningunnecessary-passW0107MedProp.terminate
Unnecessary pass statement
1148warningunnecessary-passW0107MedProp.calc_transport_properties
Unnecessary pass statement
1248warningunnecessary-passW0107MedProp.get_critical_point
Unnecessary pass statement
1338warningunnecessary-passW0107MedProp.get_molar_mass
Unnecessary pass statement
1390conventionline-too-longC0301
Line too long (110/100)
1400conventionline-too-longC0301
Line too long (113/100)
1410conventionline-too-longC0301
Line too long (104/100)
1450conventionline-too-longC0301
Line too long (103/100)
1600conventionline-too-longC0301
Line too long (108/100)
1610conventionline-too-longC0301
Line too long (105/100)
2060conventionline-too-longC0301
Line too long (115/100)
2100conventionline-too-longC0301
Line too long (118/100)
2180conventionline-too-longC0301
Line too long (107/100)
2210conventionline-too-longC0301
Line too long (116/100)
2220conventionline-too-longC0301
Line too long (110/100)
2230conventionline-too-longC0301
Line too long (108/100)
2274conventioninvalid-nameC0103get_two_phase_limits
Variable name "q0" doesn't conform to snake_case naming style
2278conventioninvalid-nameC0103get_two_phase_limits
Variable name "q1" doesn't conform to snake_case naming style
+ +

Module vclibpy.media.ref_prop (vclibpy/media/ref_prop.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventiontoo-many-linesC0302
Too many lines in module (1231/1000)
100conventionline-too-longC0301
Line too long (120/100)
270refactortoo-many-instance-attributesR0902RefProp
Too many instance attributes (15/7)
270refactortoo-many-public-methodsR0904RefProp
Too many public methods (25/20)
350conventionline-too-longC0301
Line too long (109/100)
660conventionline-too-longC0301
Line too long (113/100)
670conventionline-too-longC0301
Line too long (106/100)
730conventionline-too-longC0301
Line too long (120/100)
740conventionline-too-longC0301
Line too long (109/100)
1150conventionline-too-longC0301
Line too long (103/100)
1170conventionline-too-longC0301
Line too long (117/100)
1394refactortoo-many-argumentsR0913RefProp.__init__
Too many arguments (9/5)
1808conventioninvalid-nameC0103RefProp.__init__
Attribute name "rp" doesn't conform to snake_case naming style
2090conventionline-too-longC0301
Line too long (116/100)
21012conventionimport-outside-toplevelC0415RefProp._delete_dll
Import outside toplevel (_ctypes)
21112conventionimport-outside-toplevelC0415RefProp._delete_dll
Import outside toplevel (sys)
21222warningprotected-accessW0212RefProp._delete_dll
Access to a protected member _handle of a client class
21416errorno-memberE1101RefProp._delete_dll
Module '_ctypes' has no 'FreeLibrary' member
2509warningfixmeW0511
TODO
2554refactortoo-many-argumentsR0913RefProp._call_refprop_allprop
Too many arguments (6/5)
25730conventioninvalid-nameC0103RefProp._call_refprop_allprop
Argument name "T_val" doesn't conform to snake_case naming style
2710conventionline-too-longC0301
Line too long (111/100)
2740conventionline-too-longC0301
Line too long (111/100)
2790conventionline-too-longC0301
Line too long (116/100)
2820conventionline-too-longC0301
Line too long (119/100)
3030conventionline-too-longC0301
Line too long (111/100)
30329conventionconsider-using-f-stringC0209RefProp._call_refprop_allprop
Formatting a regular string which could be a f-string
3104refactortoo-many-argumentsR0913RefProp._call_refprop
Too many arguments (9/5)
3240conventionline-too-longC0301
Line too long (103/100)
3360conventionline-too-longC0301
Line too long (144/100)
3390conventionline-too-longC0301
Line too long (116/100)
35842warningfixmeW0511
TODO: in general not necessary, decreases performance
37037conventionconsider-using-f-stringC0209RefProp._call_refprop
Formatting a regular string which could be a f-string
4060conventionline-too-longC0301
Line too long (112/100)
40634conventionconsider-using-f-stringC0209RefProp._check_error
Formatting a regular string which could be a f-string
4070conventionline-too-longC0301
Line too long (110/100)
4080conventionline-too-longC0301
Line too long (117/100)
4110conventionline-too-longC0301
Line too long (104/100)
41136conventionconsider-using-f-stringC0209RefProp._check_error
Formatting a regular string which could be a f-string
4120conventionline-too-longC0301
Line too long (115/100)
4144refactortoo-many-branchesR0912RefProp._get_comp_names
Too many branches (13/12)
4150conventionline-too-longC0301
Line too long (105/100)
4250conventionline-too-longC0301
Line too long (103/100)
44416refactorno-else-continueR1724RefProp._get_comp_names
Unnecessary "else" after "continue", remove the "else" and de-indent the code inside it
45629conventioninvalid-nameC0103RefProp._get_comp_frac
Argument name "z" doesn't conform to snake_case naming style
4780conventionline-too-longC0301
Line too long (110/100)
4790conventionline-too-longC0301
Line too long (110/100)
4900conventionline-too-longC0301
Line too long (120/100)
49637conventionconsider-using-f-stringC0209RefProp._get_comp_frac
Formatting a regular string which could be a f-string
5100conventionline-too-longC0301
Line too long (120/100)
52817warningfixmeW0511
TODO: Ending is not necessary to create mixtures....
53312warningunused-variableW0612RefProp._setup_rp
Unused variable 'setref'
54016refactorno-else-raiseR1720RefProp._setup_rp
Unnecessary "else" after "raise", remove the "else" and de-indent the code inside it
5420conventionline-too-longC0301
Line too long (110/100)
54224conventionconsider-using-f-stringC0209RefProp._setup_rp
Formatting a regular string which could be a f-string
5450conventionline-too-longC0301
Line too long (110/100)
54524conventionconsider-using-f-stringC0209RefProp._setup_rp
Formatting a regular string which could be a f-string
5490conventionline-too-longC0301
Line too long (111/100)
54924conventionconsider-using-f-stringC0209RefProp._setup_rp
Formatting a regular string which could be a f-string
5520conventionline-too-longC0301
Line too long (113/100)
55224conventionconsider-using-f-stringC0209RefProp._setup_rp
Formatting a regular string which could be a f-string
5904refactortoo-many-localsR0914RefProp.calc_state
Too many local variables (19/15)
5904refactortoo-many-branchesR0912RefProp.calc_state
Too many branches (29/12)
5904refactortoo-many-statementsR0915RefProp.calc_state
Too many statements (123/50)
5910conventionline-too-longC0301
Line too long (118/100)
5970conventionline-too-longC0301
Line too long (112/100)
6750conventionline-too-longC0301
Line too long (105/100)
7160conventionline-too-longC0301
Line too long (105/100)
8240conventionline-too-longC0301
Line too long (118/100)
8480conventionline-too-longC0301
Line too long (117/100)
87329conventionconsider-using-f-stringC0209RefProp.get_available_substances
Formatting a regular string which could be a f-string
89017warningunspecified-encodingW1514RefProp.get_available_substances
Using open without explicitly specifying an encoding
89233conventionconsider-using-f-stringC0209RefProp.get_available_substances
Formatting a regular string which could be a f-string
8950conventionline-too-longC0301
Line too long (120/100)
89529conventionconsider-using-f-stringC0209RefProp.get_available_substances
Formatting a regular string which could be a f-string
9270conventionline-too-longC0301
Line too long (105/100)
93712conventioninvalid-nameC0103RefProp.get_molar_composition
Variable name "z" doesn't conform to snake_case naming style
94012conventioninvalid-nameC0103RefProp.get_molar_composition
Variable name "z" doesn't conform to snake_case naming style
98312conventioninvalid-nameC0103RefProp.get_critical_point
Variable name "pc" doesn't conform to snake_case naming style
98412conventioninvalid-nameC0103RefProp.get_critical_point
Variable name "dc" doesn't conform to snake_case naming style
98812conventioninvalid-nameC0103RefProp.get_critical_point
Variable name "pc" doesn't conform to snake_case naming style
98912conventioninvalid-nameC0103RefProp.get_critical_point
Variable name "dc" doesn't conform to snake_case naming style
9990conventionline-too-longC0301
Line too long (114/100)
10518refactorconsider-using-max-builtinR1731RefProp.get_gwp
Consider using 'gwp = max(gwp, 0)' instead of unnecessary if block
10610conventionline-too-longC0301
Line too long (114/100)
10710conventionline-too-longC0301
Line too long (107/100)
10980conventionline-too-longC0301
Line too long (107/100)
112414warningnested-min-maxW3301RefProp.get_odp
Do not use nested call of 'max'; it's possible to do 'max(tmp.Output, 0)' instead
11268refactorconsider-using-max-builtinR1731RefProp.get_odp
Consider using 'odp = max(odp, 0)' instead of unnecessary if block
114735conventioninvalid-nameC0103RefProp.get_sat_vap_pressure
Argument name "T_sat" doesn't conform to snake_case naming style
11650conventionline-too-longC0301
Line too long (108/100)
+ +

Module vclibpy.media.states (vclibpy/media/states.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
130refactortoo-many-instance-attributesR0902ThermodynamicState
Too many instance attributes (8/7)
364refactortoo-many-argumentsR0913ThermodynamicState.__init__
Too many arguments (9/5)
590conventionline-too-longC0301
Line too long (119/100)
1020refactortoo-many-instance-attributesR0902TransportProperties
Too many instance attributes (10/7)
1244refactortoo-many-argumentsR0913TransportProperties.__init__
Too many arguments (11/5)
12817conventioninvalid-nameC0103TransportProperties.__init__
Argument name "pr" doesn't conform to snake_case naming style
1730conventionline-too-longC0301
Line too long (102/100)
1740conventionline-too-longC0301
Line too long (104/100)
1750conventionline-too-longC0301
Line too long (107/100)
1770conventionline-too-longC0301
Line too long (112/100)
1780conventionline-too-longC0301
Line too long (113/100)
1790conventionline-too-longC0301
Line too long (109/100)
1800conventionline-too-longC0301
Line too long (101/100)
+ +

Module vclibpy.utils (vclibpy/utils/__init__.py)

+ + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
+ +

Module vclibpy.utils.automation (vclibpy/utils/automation.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
368warninglogging-fstring-interpolationW1203calc_multiple_states
Use lazy % formatting in logging functions
4015warningbroad-exception-caughtW0718calc_multiple_states
Catching too general exception Exception
408conventioninvalid-nameC0103calc_multiple_states
Variable name "e" doesn't conform to snake_case naming style
4212warninglogging-fstring-interpolationW1203calc_multiple_states
Use lazy % formatting in logging functions
504conventioninvalid-nameC0103calc_multiple_states
Variable name "df" doesn't conform to snake_case naming style
520conventionline-too-longC0301
Line too long (119/100)
550refactortoo-many-argumentsR0913full_factorial_map_generation
Too many arguments (11/5)
550refactortoo-many-localsR0914full_factorial_map_generation
Too many local variables (44/15)
550refactortoo-many-branchesR0912full_factorial_map_generation
Too many branches (16/12)
550refactortoo-many-statementsR0915full_factorial_map_generation
Too many statements (51/50)
578conventioninvalid-nameC0103full_factorial_map_generation
Argument name "T_eva_in_ar" doesn't conform to snake_case naming style
588conventioninvalid-nameC0103full_factorial_map_generation
Argument name "T_con_in_ar" doesn't conform to snake_case naming style
638conventioninvalid-nameC0103full_factorial_map_generation
Argument name "dT_eva_superheating" doesn't conform to snake_case naming style
648conventioninvalid-nameC0103full_factorial_map_generation
Argument name "dT_con_subcooling" doesn't conform to snake_case naming style
1010conventionline-too-longC0301
Line too long (123/100)
1078conventioninvalid-nameC0103full_factorial_map_generation
Variable name "i_T_eva_in" doesn't conform to snake_case naming style
10720conventioninvalid-nameC0103full_factorial_map_generation
Variable name "T_eva_in" doesn't conform to snake_case naming style
10916conventioninvalid-nameC0103full_factorial_map_generation
Variable name "i_T_con_in" doesn't conform to snake_case naming style
10928conventioninvalid-nameC0103full_factorial_map_generation
Variable name "T_con_in" doesn't conform to snake_case naming style
12315refactorconsider-using-withR1732full_factorial_map_generation
Consider using 'with' for resource-allocating operations
12712warninglogging-fstring-interpolationW1203full_factorial_map_generation
Use lazy % formatting in logging functions
13312warninglogging-fstring-interpolationW1203full_factorial_map_generation
Use lazy % formatting in logging functions
1450conventionline-too-longC0301
Line too long (104/100)
14534refactorunnecessary-comprehensionR1721full_factorial_map_generation
Unnecessary use of a comprehension, use dict(fs_state.get_variables().items()) instead.
15913conventioninvalid-nameC0103full_factorial_map_generation
Variable name "i_T_con_in" doesn't conform to snake_case naming style
15925conventioninvalid-nameC0103full_factorial_map_generation
Variable name "i_T_eva_in" doesn't conform to snake_case naming style
21511warningbroad-exception-caughtW0718_calc_single_hp_state
Catching too general exception Exception
2154conventioninvalid-nameC0103_calc_single_hp_state
Variable name "e" doesn't conform to snake_case naming style
2168warninglogging-fstring-interpolationW1203_calc_single_hp_state
Use lazy % formatting in logging functions
+ +

Module vclibpy.utils.nominal_design (vclibpy/utils/nominal_design.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
100refactortoo-many-localsR0914nominal_hp_design
Too many local variables (19/15)
1129conventiontrailing-whitespaceC0303
Trailing whitespace
1223conventiontrailing-whitespaceC0303
Trailing whitespace
148conventioninvalid-nameC0103nominal_hp_design
Argument name "dT_con" doesn't conform to snake_case naming style
158conventioninvalid-nameC0103nominal_hp_design
Argument name "dT_eva" doesn't conform to snake_case naming style
434conventioninvalid-nameC0103nominal_hp_design
Variable name "t0" doesn't conform to snake_case naming style
6921warningprotected-accessW0212nominal_hp_design
Access to a protected member _secondary_cp of a client class
7021warningprotected-accessW0212nominal_hp_design
Access to a protected member _secondary_cp of a client class
720conventionline-too-longC0301
Line too long (105/100)
740conventionline-too-longC0301
Line too long (107/100)
+ +

Module vclibpy.utils.plotting (vclibpy/utils/plotting.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
110refactorinconsistent-return-statementsR1710plot_cycle
Either all return statements in a function should return an expression, or none of them should.
394conventioninvalid-nameC0103plot_cycle
Variable name "h_T" doesn't conform to snake_case naming style
449conventioninvalid-nameC0103plot_cycle
Variable name "ax" doesn't conform to snake_case naming style
770refactortoo-many-argumentsR0913plot_sdf_map
Too many arguments (8/5)
770refactortoo-many-localsR0914plot_sdf_map
Too many local variables (53/15)
770refactortoo-many-branchesR0912plot_sdf_map
Too many branches (50/12)
770refactortoo-many-statementsR0915plot_sdf_map
Too many statements (133/50)
900conventionline-too-longC0301
Line too long (103/100)
1424conventioninvalid-nameC0103plot_sdf_map
Variable name "plot_4D" doesn't conform to snake_case naming style
1448conventioninvalid-nameC0103plot_sdf_map
Variable name "plot_4D" doesn't conform to snake_case naming style
1824refactortoo-many-nested-blocksR1702plot_sdf_map
Too many nested blocks (7/5)
1824refactortoo-many-nested-blocksR1702plot_sdf_map
Too many nested blocks (7/5)
1824refactortoo-many-nested-blocksR1702plot_sdf_map
Too many nested blocks (6/5)
18912conventioninvalid-nameC0103plot_sdf_map
Variable name "nd" doesn't conform to snake_case naming style
18916conventioninvalid-nameC0103plot_sdf_map
Variable name "fd" doesn't conform to snake_case naming style
18920conventioninvalid-nameC0103plot_sdf_map
Variable name "sd" doesn't conform to snake_case naming style
18934conventioninvalid-nameC0103plot_sdf_map
Variable name "td" doesn't conform to snake_case naming style
19116conventioninvalid-nameC0103plot_sdf_map
Variable name "ds" doesn't conform to snake_case naming style
19320conventioninvalid-nameC0103plot_sdf_map
Variable name "nd" doesn't conform to snake_case naming style
19520conventioninvalid-nameC0103plot_sdf_map
Variable name "fd" doesn't conform to snake_case naming style
19720conventioninvalid-nameC0103plot_sdf_map
Variable name "sd" doesn't conform to snake_case naming style
20420conventioninvalid-nameC0103plot_sdf_map
Variable name "td" doesn't conform to snake_case naming style
22416conventioninvalid-nameC0103plot_sdf_map
Variable name "ax" doesn't conform to snake_case naming style
2320conventionline-too-longC0301
Line too long (105/100)
23416conventionimport-outside-toplevelC0415plot_sdf_map
Import outside toplevel (itertools)
23539refactorunnecessary-comprehensionR1721plot_sdf_map
Unnecessary use of a comprehension, use list(itertools.product(*inp)) instead.
24528conventioninvalid-nameC0103plot_sdf_map
Variable name "Z" doesn't conform to snake_case naming style
25128conventioninvalid-nameC0103plot_sdf_map
Variable name "Z" doesn't conform to snake_case naming style
25728conventioninvalid-nameC0103plot_sdf_map
Variable name "Z" doesn't conform to snake_case naming style
2640conventionline-too-longC0301
Line too long (116/100)
26628conventioninvalid-nameC0103plot_sdf_map
Variable name "ax" doesn't conform to snake_case naming style
26928conventioninvalid-nameC0103plot_sdf_map
Variable name "X" doesn't conform to snake_case naming style
26931conventioninvalid-nameC0103plot_sdf_map
Variable name "Y" doesn't conform to snake_case naming style
2700conventionline-too-longC0301
Line too long (111/100)
29119conventioninvalid-nameC0103set_axis_style
Argument name "ax" doesn't conform to snake_case naming style
2930conventionline-too-longC0301
Line too long (129/100)
+ +

Module vclibpy.utils.printing (vclibpy/utils/printing.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
2215conventionconsider-iterating-dictionaryC0201print_states
Consider iterating the dictionary directly instead of calling .keys()
310conventionline-too-longC0301
Line too long (107/100)
+ +

Module vclibpy.utils.sdf_ (vclibpy/utils/sdf_.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
80refactortoo-many-localsR0914save_to_sdf
Too many local variables (20/15)
630conventionline-too-longC0301
Line too long (108/100)
12912conventioninvalid-nameC0103sdf_to_csv
Variable name "df" doesn't conform to snake_case naming style
13012conventioninvalid-nameC0103sdf_to_csv
Variable name "df" doesn't conform to snake_case naming style
1470conventionline-too-longC0301
Line too long (103/100)
14723refactorunnecessary-comprehensionR1721_unpack_nd_data
Unnecessary use of a comprehension, use list(enumerate(scale.data)) instead.
15018refactorconsider-using-generatorR1728_unpack_nd_data
Consider using a generator instead 'tuple(scale[0] for scale in scales)'
15414refactorunnecessary-comprehensionR1721_unpack_nd_data
Unnecessary use of a comprehension, use dict(zip(scale_names, values)) instead.
+ +

Module vclibpy.utils.ten_coefficient_compressor_reqression (vclibpy/utils/ten_coefficient_compressor_reqression.py)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineCol.TypeSymbolIDObjMessage
10conventionmissing-module-docstringC0114
Missing module docstring
134warningraise-missing-fromW0707
Consider explicitly re-raising using 'raise ImportError('You have to install xlsxwriter and sklearn to use this regression tool') from err'
170refactortoo-many-argumentsR0913create_regression_data
Too many arguments (13/5)
170refactortoo-many-localsR0914create_regression_data
Too many local variables (42/15)
198conventioninvalid-nameC0103create_regression_data
Argument name "T_con" doesn't conform to snake_case naming style
1928conventioninvalid-nameC0103create_regression_data
Argument name "T_eva" doesn't conform to snake_case naming style
208conventioninvalid-nameC0103create_regression_data
Argument name "T_sh" doesn't conform to snake_case naming style
2021conventioninvalid-nameC0103create_regression_data
Argument name "T_sc" doesn't conform to snake_case naming style
2046conventioninvalid-nameC0103create_regression_data
Argument name "V_h" doesn't conform to snake_case naming style
878conventioninvalid-nameC0103create_regression_data
Variable name "m" doesn't conform to snake_case naming style
874refactortoo-many-nested-blocksR1702create_regression_data
Too many nested blocks (6/5)
8912conventioninvalid-nameC0103create_regression_data
Variable name "T_eva_list" doesn't conform to snake_case naming style
9012conventioninvalid-nameC0103create_regression_data
Variable name "T_con_list" doesn't conform to snake_case naming style
9312conventionconsider-using-enumerateC0200create_regression_data
Consider using enumerate instead of iterating with range and len
9516conventionconsider-using-enumerateC0200create_regression_data
Consider using enumerate instead of iterating with range and len
9724conventioninvalid-nameC0103create_regression_data
Variable name "p1" doesn't conform to snake_case naming style
10024conventioninvalid-nameC0103create_regression_data
Variable name "p2" doesn't conform to snake_case naming style
10325warningfixmeW0511
TODO: Enable calculation of get_lambda_h etc. with p2 only
11912conventioninvalid-nameC0103create_regression_data
Variable name "df" doesn't conform to snake_case naming style
1325warningfixmeW0511
TODO: Revert once this feature is in pandas.
13775conventioninvalid-nameC0103create_regression_data
Variable name "f" doesn't conform to snake_case naming style
13912conventioninvalid-nameC0103create_regression_data
Variable name "r" doesn't conform to snake_case naming style
14016conventioninvalid-nameC0103create_regression_data
Variable name "c" doesn't conform to snake_case naming style
14533conventioninvalid-nameC0103create_regression_parameters
Argument name "df" doesn't conform to snake_case naming style
1684conventioninvalid-nameC0103create_regression_parameters
Variable name "z" doesn't conform to snake_case naming style
1724conventioninvalid-nameC0103create_regression_parameters
Variable name "X" doesn't conform to snake_case naming style
+ + +

Metrics

+ + +

Count per types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCount
error2
refactor77
convention444
warning43
info21
+ + +

Count per messages

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCount
no-member2
too-many-arguments13
missing-module-docstring27
too-many-locals12
invalid-name231
unused-variable8
line-too-long150
superfluous-parens1
missing-function-docstring8
no-else-continue5
too-many-branches6
too-many-statements4
inconsistent-return-statements2
wrong-import-order6
unnecessary-comprehension4
consider-using-generator1
trailing-whitespace2
protected-access3
fixme5
raise-missing-from1
consider-using-enumerate2
too-many-nested-blocks4
consider-iterating-dictionary1
import-outside-toplevel3
logging-fstring-interpolation9
broad-exception-caught2
consider-using-with1
too-many-instance-attributes6
global-statement1
global-variable-not-assigned1
unused-argument5
unnecessary-pass6
too-many-lines1
consider-using-f-string12
no-else-raise1
unspecified-encoding1
consider-using-max-builtin2
nested-min-max1
too-many-public-methods1
c-extension-no-member21
no-else-break1
no-else-return1
too-few-public-methods5
cyclic-import8
+ + +

Count per modules

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCount
vclibpy.datamodels2
vclibpy.flowsheets.vapor_injection_economizer6
vclibpy.flowsheets.vapor_injection_phase_separator1
vclibpy.flowsheets1
vclibpy.flowsheets.base38
vclibpy.flowsheets.vapor_injection4
vclibpy.flowsheets.standard2
vclibpy.utils.sdf_9
vclibpy.utils.nominal_design11
vclibpy.utils.ten_coefficient_compressor_reqression26
vclibpy.utils.printing2
vclibpy.utils1
vclibpy.utils.plotting37
vclibpy.utils.automation29
vclibpy.media.states13
vclibpy.media3
vclibpy.media.media23
vclibpy.media.ref_prop91
vclibpy.media.cool_prop24
vclibpy.components.component6
vclibpy.components.compressors.ten_coefficient44
vclibpy.components.compressors.compressor9
vclibpy.components.compressors.rotary14
vclibpy.components.compressors1
vclibpy.components.compressors.constant_effectivness4
vclibpy.components.heat_exchangers1
vclibpy.components.heat_exchangers.moving_boundary_ntu86
vclibpy.components.heat_exchangers.economizer3
vclibpy.components.heat_exchangers.heat_exchanger13
vclibpy.components.heat_exchangers.ntu15
vclibpy.components.heat_exchangers.heat_transfer.air_to_wall7
vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall9
vclibpy.components.heat_exchangers.heat_transfer3
vclibpy.components.heat_exchangers.heat_transfer.constant7
vclibpy.components.heat_exchangers.heat_transfer.heat_transfer5
vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall22
vclibpy.components.heat_exchangers.heat_transfer.wall3
vclibpy.components.expansion_valves.expansion_valve1
vclibpy.components.expansion_valves.bernoulli2
vclibpy.components.expansion_valves1
vclibpy.components.expansion_valves.__init__8
+ + +

Count per path

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameCount
vclibpy/datamodels.py2
vclibpy/flowsheets/vapor_injection_economizer.py6
vclibpy/flowsheets/vapor_injection_phase_separator.py1
vclibpy/flowsheets/__init__.py1
vclibpy/flowsheets/base.py38
vclibpy/flowsheets/vapor_injection.py4
vclibpy/flowsheets/standard.py2
vclibpy/utils/sdf_.py9
vclibpy/utils/nominal_design.py11
vclibpy/utils/ten_coefficient_compressor_reqression.py26
vclibpy/utils/printing.py2
vclibpy/utils/__init__.py1
vclibpy/utils/plotting.py37
vclibpy/utils/automation.py29
vclibpy/media/states.py13
vclibpy/media/__init__.py3
vclibpy/media/media.py23
vclibpy/media/ref_prop.py91
vclibpy/media/cool_prop.py24
vclibpy/components/component.py6
vclibpy/components/compressors/ten_coefficient.py44
vclibpy/components/compressors/compressor.py9
vclibpy/components/compressors/rotary.py14
vclibpy/components/compressors/__init__.py1
vclibpy/components/compressors/constant_effectivness.py4
vclibpy/components/heat_exchangers/__init__.py1
vclibpy/components/heat_exchangers/moving_boundary_ntu.py86
vclibpy/components/heat_exchangers/economizer.py3
vclibpy/components/heat_exchangers/heat_exchanger.py13
vclibpy/components/heat_exchangers/ntu.py15
vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py7
vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py9
vclibpy/components/heat_exchangers/heat_transfer/__init__.py3
vclibpy/components/heat_exchangers/heat_transfer/constant.py7
vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py5
vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py22
vclibpy/components/heat_exchangers/heat_transfer/wall.py3
vclibpy/components/expansion_valves/expansion_valve.py1
vclibpy/components/expansion_valves/bernoulli.py2
vclibpy/components/expansion_valves/__init__.py9
+ + + + \ No newline at end of file diff --git a/docs/0.1.1/pylint/pylint.json b/docs/0.1.1/pylint/pylint.json new file mode 100644 index 0000000..380015d --- /dev/null +++ b/docs/0.1.1/pylint/pylint.json @@ -0,0 +1,7823 @@ +{ + "messages": [ + { + "type": "error", + "module": "vclibpy.datamodels", + "obj": "VariableContainer.__getattr__", + "line": 65, + "column": 19, + "path": "vclibpy/datamodels.py", + "symbol": "no-member", + "message": "Super of 'VariableContainer' has no '__getattr__' member", + "message-id": "E1101" + }, + { + "type": "refactor", + "module": "vclibpy.datamodels", + "obj": "Inputs.__init__", + "line": 166, + "column": 4, + "path": "vclibpy/datamodels.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (9/5)", + "message-id": "R0913" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection_economizer", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/flowsheets/vapor_injection_economizer.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.vapor_injection_economizer", + "obj": "VaporInjectionEconomizer.calc_injection", + "line": 46, + "column": 4, + "path": "vclibpy/flowsheets/vapor_injection_economizer.py", + "symbol": "too-many-locals", + "message": "Too many local variables (20/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection_economizer", + "obj": "VaporInjectionEconomizer.calc_injection", + "line": 85, + "column": 8, + "path": "vclibpy/flowsheets/vapor_injection_economizer.py", + "symbol": "invalid-name", + "message": "Variable name \"dT_secondary\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection_economizer", + "obj": "VaporInjectionEconomizer.calc_injection", + "line": 106, + "column": 12, + "path": "vclibpy/flowsheets/vapor_injection_economizer.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_flow_goal\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection_economizer", + "obj": "VaporInjectionEconomizer.calc_injection", + "line": 114, + "column": 12, + "path": "vclibpy/flowsheets/vapor_injection_economizer.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_flow\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.flowsheets.vapor_injection_economizer", + "obj": "VaporInjectionEconomizer.calc_injection", + "line": 114, + "column": 20, + "path": "vclibpy/flowsheets/vapor_injection_economizer.py", + "symbol": "unused-variable", + "message": "Unused variable 'k'", + "message-id": "W0612" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection_phase_separator", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/flowsheets/vapor_injection_phase_separator.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/flowsheets/__init__.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "", + "line": 218, + "column": 0, + "path": "vclibpy/flowsheets/base.py", + "symbol": "line-too-long", + "message": "Line too long (118/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "", + "line": 291, + "column": 0, + "path": "vclibpy/flowsheets/base.py", + "symbol": "superfluous-parens", + "message": "Unnecessary parens after '=' keyword", + "message-id": "C0325" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "", + "line": 325, + "column": 0, + "path": "vclibpy/flowsheets/base.py", + "symbol": "line-too-long", + "message": "Line too long (112/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/flowsheets/base.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.setup_new_fluid", + "line": 47, + "column": 4, + "path": "vclibpy/flowsheets/base.py", + "symbol": "missing-function-docstring", + "message": "Missing function or method docstring", + "message-id": "C0116" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.terminate", + "line": 67, + "column": 4, + "path": "vclibpy/flowsheets/base.py", + "symbol": "missing-function-docstring", + "message": "Missing function or method docstring", + "message-id": "C0116" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.get_all_components", + "line": 72, + "column": 4, + "path": "vclibpy/flowsheets/base.py", + "symbol": "missing-function-docstring", + "message": "Missing function or method docstring", + "message-id": "C0116" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 75, + "column": 4, + "path": "vclibpy/flowsheets/base.py", + "symbol": "too-many-locals", + "message": "Too many local variables (45/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 135, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"err_dT_min\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 153, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"T_1_start\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 154, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"T_3_start\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 221, + "column": 23, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"dT_min_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 224, + "column": 12, + "path": "vclibpy/flowsheets/base.py", + "symbol": "no-else-continue", + "message": "Unnecessary \"else\" after \"continue\", remove the \"else\" and de-indent the code inside it", + "message-id": "R1724" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 228, + "column": 16, + "path": "vclibpy/flowsheets/base.py", + "symbol": "no-else-continue", + "message": "Unnecessary \"elif\" after \"continue\", remove the leading \"el\" from \"elif\"", + "message-id": "R1724" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 237, + "column": 23, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"dT_min_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 238, + "column": 12, + "path": "vclibpy/flowsheets/base.py", + "symbol": "no-else-continue", + "message": "Unnecessary \"else\" after \"continue\", remove the \"else\" and de-indent the code inside it", + "message-id": "R1724" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 242, + "column": 16, + "path": "vclibpy/flowsheets/base.py", + "symbol": "no-else-continue", + "message": "Unnecessary \"elif\" after \"continue\", remove the leading \"el\" from \"elif\"", + "message-id": "R1724" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 278, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 279, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_con_outer\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 280, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 281, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_eva_outer\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 284, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"P_el\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 285, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con_out\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 288, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"COP_inner\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 289, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"COP_outer\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 291, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"COP_carnot\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 75, + "column": 4, + "path": "vclibpy/flowsheets/base.py", + "symbol": "too-many-branches", + "message": "Too many branches (28/12)", + "message-id": "R0912" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 75, + "column": 4, + "path": "vclibpy/flowsheets/base.py", + "symbol": "too-many-statements", + "message": "Too many statements (132/50)", + "message-id": "R0915" + }, + { + "type": "refactor", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.calc_steady_state", + "line": 75, + "column": 4, + "path": "vclibpy/flowsheets/base.py", + "symbol": "inconsistent-return-statements", + "message": "Either all return statements in a function should return an expression, or none of them should.", + "message-id": "R1710" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.set_evaporator_outlet_based_on_superheating", + "line": 351, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"T_1\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.set_condenser_outlet_based_on_subcooling", + "line": 366, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"T_3\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle.plot_cycle", + "line": 375, + "column": 13, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"ax\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle._plot_secondary_heat_flow_rates", + "line": 385, + "column": 46, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Argument name \"ax\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle._plot_secondary_heat_flow_rates", + "line": 386, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle._plot_secondary_heat_flow_rates", + "line": 387, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle._plot_secondary_heat_flow_rates", + "line": 389, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"delta_H_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "BaseCycle._plot_secondary_heat_flow_rates", + "line": 393, + "column": 8, + "path": "vclibpy/flowsheets/base.py", + "symbol": "invalid-name", + "message": "Variable name \"delta_H_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.base", + "obj": "", + "line": 5, + "column": 0, + "path": "vclibpy/flowsheets/base.py", + "symbol": "wrong-import-order", + "message": "standard import \"from abc import abstractmethod\" should be placed before \"import numpy as np\"", + "message-id": "C0411" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/flowsheets/vapor_injection.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection", + "obj": "BaseVaporInjection.calc_states", + "line": 84, + "column": 8, + "path": "vclibpy/flowsheets/vapor_injection.py", + "symbol": "invalid-name", + "message": "Variable name \"h_1_VI_mixed\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection", + "obj": "BaseVaporInjection.calc_electrical_power", + "line": 148, + "column": 8, + "path": "vclibpy/flowsheets/vapor_injection.py", + "symbol": "invalid-name", + "message": "Variable name \"P_el_low\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.vapor_injection", + "obj": "BaseVaporInjection.calc_electrical_power", + "line": 151, + "column": 8, + "path": "vclibpy/flowsheets/vapor_injection.py", + "symbol": "invalid-name", + "message": "Variable name \"P_el_high\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.standard", + "obj": "", + "line": 68, + "column": 0, + "path": "vclibpy/flowsheets/standard.py", + "symbol": "line-too-long", + "message": "Line too long (111/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.flowsheets.standard", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/flowsheets/standard.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.utils.sdf_", + "obj": "", + "line": 63, + "column": 0, + "path": "vclibpy/utils/sdf_.py", + "symbol": "line-too-long", + "message": "Line too long (108/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.sdf_", + "obj": "", + "line": 147, + "column": 0, + "path": "vclibpy/utils/sdf_.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.sdf_", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/utils/sdf_.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "refactor", + "module": "vclibpy.utils.sdf_", + "obj": "save_to_sdf", + "line": 8, + "column": 0, + "path": "vclibpy/utils/sdf_.py", + "symbol": "too-many-locals", + "message": "Too many local variables (20/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.utils.sdf_", + "obj": "sdf_to_csv", + "line": 129, + "column": 12, + "path": "vclibpy/utils/sdf_.py", + "symbol": "invalid-name", + "message": "Variable name \"df\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.sdf_", + "obj": "sdf_to_csv", + "line": 130, + "column": 12, + "path": "vclibpy/utils/sdf_.py", + "symbol": "invalid-name", + "message": "Variable name \"df\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.sdf_", + "obj": "_unpack_nd_data", + "line": 147, + "column": 23, + "path": "vclibpy/utils/sdf_.py", + "symbol": "unnecessary-comprehension", + "message": "Unnecessary use of a comprehension, use list(enumerate(scale.data)) instead.", + "message-id": "R1721" + }, + { + "type": "refactor", + "module": "vclibpy.utils.sdf_", + "obj": "_unpack_nd_data", + "line": 150, + "column": 18, + "path": "vclibpy/utils/sdf_.py", + "symbol": "consider-using-generator", + "message": "Consider using a generator instead 'tuple(scale[0] for scale in scales)'", + "message-id": "R1728" + }, + { + "type": "refactor", + "module": "vclibpy.utils.sdf_", + "obj": "_unpack_nd_data", + "line": 154, + "column": 14, + "path": "vclibpy/utils/sdf_.py", + "symbol": "unnecessary-comprehension", + "message": "Unnecessary use of a comprehension, use dict(zip(scale_names, values)) instead.", + "message-id": "R1721" + }, + { + "type": "convention", + "module": "vclibpy.utils.nominal_design", + "obj": "", + "line": 11, + "column": 29, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "trailing-whitespace", + "message": "Trailing whitespace", + "message-id": "C0303" + }, + { + "type": "convention", + "module": "vclibpy.utils.nominal_design", + "obj": "", + "line": 12, + "column": 23, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "trailing-whitespace", + "message": "Trailing whitespace", + "message-id": "C0303" + }, + { + "type": "convention", + "module": "vclibpy.utils.nominal_design", + "obj": "", + "line": 72, + "column": 0, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.nominal_design", + "obj": "", + "line": 74, + "column": 0, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.nominal_design", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.utils.nominal_design", + "obj": "nominal_hp_design", + "line": 14, + "column": 8, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "invalid-name", + "message": "Argument name \"dT_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.nominal_design", + "obj": "nominal_hp_design", + "line": 15, + "column": 8, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "invalid-name", + "message": "Argument name \"dT_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.nominal_design", + "obj": "nominal_hp_design", + "line": 10, + "column": 0, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "too-many-locals", + "message": "Too many local variables (19/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.utils.nominal_design", + "obj": "nominal_hp_design", + "line": 43, + "column": 4, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "invalid-name", + "message": "Variable name \"t0\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.utils.nominal_design", + "obj": "nominal_hp_design", + "line": 69, + "column": 21, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "protected-access", + "message": "Access to a protected member _secondary_cp of a client class", + "message-id": "W0212" + }, + { + "type": "warning", + "module": "vclibpy.utils.nominal_design", + "obj": "nominal_hp_design", + "line": 70, + "column": 21, + "path": "vclibpy/utils/nominal_design.py", + "symbol": "protected-access", + "message": "Access to a protected member _secondary_cp of a client class", + "message-id": "W0212" + }, + { + "type": "warning", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "", + "line": 103, + "column": 25, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "fixme", + "message": "TODO: Enable calculation of get_lambda_h etc. with p2 only", + "message-id": "W0511" + }, + { + "type": "warning", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "", + "line": 132, + "column": 5, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "fixme", + "message": "TODO: Revert once this feature is in pandas.", + "message-id": "W0511" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "warning", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "", + "line": 13, + "column": 4, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "raise-missing-from", + "message": "Consider explicitly re-raising using 'raise ImportError('You have to install xlsxwriter and sklearn to use this regression tool') from err'", + "message-id": "W0707" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 19, + "column": 8, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Argument name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 19, + "column": 28, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Argument name \"T_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 20, + "column": 8, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Argument name \"T_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 20, + "column": 21, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Argument name \"T_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 20, + "column": 46, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Argument name \"V_h\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 17, + "column": 0, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (13/5)", + "message-id": "R0913" + }, + { + "type": "refactor", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 17, + "column": 0, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "too-many-locals", + "message": "Too many local variables (42/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 87, + "column": 8, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"m\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 89, + "column": 12, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"T_eva_list\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 90, + "column": 12, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con_list\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 93, + "column": 12, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "consider-using-enumerate", + "message": "Consider using enumerate instead of iterating with range and len", + "message-id": "C0200" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 95, + "column": 16, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "consider-using-enumerate", + "message": "Consider using enumerate instead of iterating with range and len", + "message-id": "C0200" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 97, + "column": 24, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"p1\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 100, + "column": 24, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"p2\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 119, + "column": 12, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"df\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 137, + "column": 75, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"f\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 87, + "column": 4, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "too-many-nested-blocks", + "message": "Too many nested blocks (6/5)", + "message-id": "R1702" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 139, + "column": 12, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"r\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_data", + "line": 140, + "column": 16, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"c\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_parameters", + "line": 145, + "column": 33, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Argument name \"df\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_parameters", + "line": 168, + "column": 4, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"z\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.ten_coefficient_compressor_reqression", + "obj": "create_regression_parameters", + "line": 172, + "column": 4, + "path": "vclibpy/utils/ten_coefficient_compressor_reqression.py", + "symbol": "invalid-name", + "message": "Variable name \"X\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.printing", + "obj": "", + "line": 31, + "column": 0, + "path": "vclibpy/utils/printing.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.printing", + "obj": "print_states", + "line": 22, + "column": 15, + "path": "vclibpy/utils/printing.py", + "symbol": "consider-iterating-dictionary", + "message": "Consider iterating the dictionary directly instead of calling .keys()", + "message-id": "C0201" + }, + { + "type": "convention", + "module": "vclibpy.utils", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/utils/__init__.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "", + "line": 90, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "", + "line": 232, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "", + "line": 264, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "line-too-long", + "message": "Line too long (116/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "", + "line": 270, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "line-too-long", + "message": "Line too long (111/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "", + "line": 293, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "line-too-long", + "message": "Line too long (129/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_cycle", + "line": 39, + "column": 4, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"h_T\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_cycle", + "line": 44, + "column": 9, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"ax\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_cycle", + "line": 11, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "inconsistent-return-statements", + "message": "Either all return statements in a function should return an expression, or none of them should.", + "message-id": "R1710" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 77, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (8/5)", + "message-id": "R0913" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 77, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "too-many-locals", + "message": "Too many local variables (53/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 142, + "column": 4, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"plot_4D\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 144, + "column": 8, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"plot_4D\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 189, + "column": 12, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"nd\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 189, + "column": 16, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"fd\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 189, + "column": 20, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"sd\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 189, + "column": 34, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"td\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 191, + "column": 16, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"ds\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 193, + "column": 20, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"nd\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 195, + "column": 20, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"fd\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 197, + "column": 20, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"sd\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 204, + "column": 20, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"td\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 224, + "column": 16, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"ax\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 234, + "column": 16, + "path": "vclibpy/utils/plotting.py", + "symbol": "import-outside-toplevel", + "message": "Import outside toplevel (itertools)", + "message-id": "C0415" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 235, + "column": 39, + "path": "vclibpy/utils/plotting.py", + "symbol": "unnecessary-comprehension", + "message": "Unnecessary use of a comprehension, use list(itertools.product(*inp)) instead.", + "message-id": "R1721" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 245, + "column": 28, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"Z\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 182, + "column": 4, + "path": "vclibpy/utils/plotting.py", + "symbol": "too-many-nested-blocks", + "message": "Too many nested blocks (7/5)", + "message-id": "R1702" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 251, + "column": 28, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"Z\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 257, + "column": 28, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"Z\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 182, + "column": 4, + "path": "vclibpy/utils/plotting.py", + "symbol": "too-many-nested-blocks", + "message": "Too many nested blocks (7/5)", + "message-id": "R1702" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 266, + "column": 28, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"ax\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 269, + "column": 28, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"X\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 269, + "column": 31, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Variable name \"Y\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 182, + "column": 4, + "path": "vclibpy/utils/plotting.py", + "symbol": "too-many-nested-blocks", + "message": "Too many nested blocks (6/5)", + "message-id": "R1702" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 77, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "too-many-branches", + "message": "Too many branches (50/12)", + "message-id": "R0912" + }, + { + "type": "refactor", + "module": "vclibpy.utils.plotting", + "obj": "plot_sdf_map", + "line": 77, + "column": 0, + "path": "vclibpy/utils/plotting.py", + "symbol": "too-many-statements", + "message": "Too many statements (133/50)", + "message-id": "R0915" + }, + { + "type": "convention", + "module": "vclibpy.utils.plotting", + "obj": "set_axis_style", + "line": 291, + "column": 19, + "path": "vclibpy/utils/plotting.py", + "symbol": "invalid-name", + "message": "Argument name \"ax\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "", + "line": 52, + "column": 0, + "path": "vclibpy/utils/automation.py", + "symbol": "line-too-long", + "message": "Line too long (119/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "", + "line": 101, + "column": 0, + "path": "vclibpy/utils/automation.py", + "symbol": "line-too-long", + "message": "Line too long (123/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "", + "line": 145, + "column": 0, + "path": "vclibpy/utils/automation.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "warning", + "module": "vclibpy.utils.automation", + "obj": "calc_multiple_states", + "line": 36, + "column": 8, + "path": "vclibpy/utils/automation.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "warning", + "module": "vclibpy.utils.automation", + "obj": "calc_multiple_states", + "line": 40, + "column": 15, + "path": "vclibpy/utils/automation.py", + "symbol": "broad-exception-caught", + "message": "Catching too general exception Exception", + "message-id": "W0718" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "calc_multiple_states", + "line": 40, + "column": 8, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"e\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.utils.automation", + "obj": "calc_multiple_states", + "line": 42, + "column": 12, + "path": "vclibpy/utils/automation.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "calc_multiple_states", + "line": 50, + "column": 4, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"df\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 57, + "column": 8, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Argument name \"T_eva_in_ar\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 58, + "column": 8, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Argument name \"T_con_in_ar\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 63, + "column": 8, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Argument name \"dT_eva_superheating\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 64, + "column": 8, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Argument name \"dT_con_subcooling\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 55, + "column": 0, + "path": "vclibpy/utils/automation.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (11/5)", + "message-id": "R0913" + }, + { + "type": "refactor", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 55, + "column": 0, + "path": "vclibpy/utils/automation.py", + "symbol": "too-many-locals", + "message": "Too many local variables (44/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 107, + "column": 8, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"i_T_eva_in\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 107, + "column": 20, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"T_eva_in\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 109, + "column": 16, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"i_T_con_in\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 109, + "column": 28, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con_in\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 127, + "column": 12, + "path": "vclibpy/utils/automation.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "warning", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 133, + "column": 12, + "path": "vclibpy/utils/automation.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "refactor", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 145, + "column": 34, + "path": "vclibpy/utils/automation.py", + "symbol": "unnecessary-comprehension", + "message": "Unnecessary use of a comprehension, use dict(fs_state.get_variables().items()) instead.", + "message-id": "R1721" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 159, + "column": 13, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"i_T_con_in\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 159, + "column": 25, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"i_T_eva_in\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 55, + "column": 0, + "path": "vclibpy/utils/automation.py", + "symbol": "too-many-branches", + "message": "Too many branches (16/12)", + "message-id": "R0912" + }, + { + "type": "refactor", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 55, + "column": 0, + "path": "vclibpy/utils/automation.py", + "symbol": "too-many-statements", + "message": "Too many statements (51/50)", + "message-id": "R0915" + }, + { + "type": "refactor", + "module": "vclibpy.utils.automation", + "obj": "full_factorial_map_generation", + "line": 123, + "column": 15, + "path": "vclibpy/utils/automation.py", + "symbol": "consider-using-with", + "message": "Consider using 'with' for resource-allocating operations", + "message-id": "R1732" + }, + { + "type": "warning", + "module": "vclibpy.utils.automation", + "obj": "_calc_single_hp_state", + "line": 215, + "column": 11, + "path": "vclibpy/utils/automation.py", + "symbol": "broad-exception-caught", + "message": "Catching too general exception Exception", + "message-id": "W0718" + }, + { + "type": "convention", + "module": "vclibpy.utils.automation", + "obj": "_calc_single_hp_state", + "line": 215, + "column": 4, + "path": "vclibpy/utils/automation.py", + "symbol": "invalid-name", + "message": "Variable name \"e\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.utils.automation", + "obj": "_calc_single_hp_state", + "line": 216, + "column": 8, + "path": "vclibpy/utils/automation.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "", + "line": 59, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "line-too-long", + "message": "Line too long (119/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "", + "line": 173, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "line-too-long", + "message": "Line too long (102/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "", + "line": 174, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "", + "line": 175, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "", + "line": 177, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "line-too-long", + "message": "Line too long (112/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "", + "line": 178, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "line-too-long", + "message": "Line too long (113/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "", + "line": 179, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "line-too-long", + "message": "Line too long (109/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "", + "line": 180, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "line-too-long", + "message": "Line too long (101/100)", + "message-id": "C0301" + }, + { + "type": "refactor", + "module": "vclibpy.media.states", + "obj": "ThermodynamicState", + "line": 13, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "too-many-instance-attributes", + "message": "Too many instance attributes (8/7)", + "message-id": "R0902" + }, + { + "type": "refactor", + "module": "vclibpy.media.states", + "obj": "ThermodynamicState.__init__", + "line": 36, + "column": 4, + "path": "vclibpy/media/states.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (9/5)", + "message-id": "R0913" + }, + { + "type": "refactor", + "module": "vclibpy.media.states", + "obj": "TransportProperties", + "line": 102, + "column": 0, + "path": "vclibpy/media/states.py", + "symbol": "too-many-instance-attributes", + "message": "Too many instance attributes (10/7)", + "message-id": "R0902" + }, + { + "type": "convention", + "module": "vclibpy.media.states", + "obj": "TransportProperties.__init__", + "line": 128, + "column": 17, + "path": "vclibpy/media/states.py", + "symbol": "invalid-name", + "message": "Argument name \"pr\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.media.states", + "obj": "TransportProperties.__init__", + "line": 124, + "column": 4, + "path": "vclibpy/media/states.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (11/5)", + "message-id": "R0913" + }, + { + "type": "convention", + "module": "vclibpy.media", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/media/__init__.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "warning", + "module": "vclibpy.media", + "obj": "set_global_media_properties", + "line": 27, + "column": 4, + "path": "vclibpy/media/__init__.py", + "symbol": "global-statement", + "message": "Using the global statement", + "message-id": "W0603" + }, + { + "type": "warning", + "module": "vclibpy.media", + "obj": "get_global_med_prop_and_kwargs", + "line": 38, + "column": 4, + "path": "vclibpy/media/__init__.py", + "symbol": "global-variable-not-assigned", + "message": "Using global for 'USED_MED_PROP' but no assignment is done", + "message-id": "W0602" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 10, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 53, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (111/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 58, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (118/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 139, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 140, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (113/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 141, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 145, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 160, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (108/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 161, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 206, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (115/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 210, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (118/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 218, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 221, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (116/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 222, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "", + "line": 223, + "column": 0, + "path": "vclibpy/media/media.py", + "symbol": "line-too-long", + "message": "Line too long (108/100)", + "message-id": "C0301" + }, + { + "type": "warning", + "module": "vclibpy.media.media", + "obj": "MedProp.calc_state", + "line": 50, + "column": 36, + "path": "vclibpy/media/media.py", + "symbol": "unused-argument", + "message": "Unused argument 'var1'", + "message-id": "W0613" + }, + { + "type": "warning", + "module": "vclibpy.media.media", + "obj": "MedProp.calc_state", + "line": 50, + "column": 49, + "path": "vclibpy/media/media.py", + "symbol": "unused-argument", + "message": "Unused argument 'var2'", + "message-id": "W0613" + }, + { + "type": "warning", + "module": "vclibpy.media.media", + "obj": "MedProp.terminate", + "line": 102, + "column": 8, + "path": "vclibpy/media/media.py", + "symbol": "unnecessary-pass", + "message": "Unnecessary pass statement", + "message-id": "W0107" + }, + { + "type": "warning", + "module": "vclibpy.media.media", + "obj": "MedProp.calc_transport_properties", + "line": 114, + "column": 8, + "path": "vclibpy/media/media.py", + "symbol": "unnecessary-pass", + "message": "Unnecessary pass statement", + "message-id": "W0107" + }, + { + "type": "warning", + "module": "vclibpy.media.media", + "obj": "MedProp.get_critical_point", + "line": 124, + "column": 8, + "path": "vclibpy/media/media.py", + "symbol": "unnecessary-pass", + "message": "Unnecessary pass statement", + "message-id": "W0107" + }, + { + "type": "warning", + "module": "vclibpy.media.media", + "obj": "MedProp.get_molar_mass", + "line": 133, + "column": 8, + "path": "vclibpy/media/media.py", + "symbol": "unnecessary-pass", + "message": "Unnecessary pass statement", + "message-id": "W0107" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "get_two_phase_limits", + "line": 227, + "column": 4, + "path": "vclibpy/media/media.py", + "symbol": "invalid-name", + "message": "Variable name \"q0\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.media.media", + "obj": "get_two_phase_limits", + "line": 227, + "column": 8, + "path": "vclibpy/media/media.py", + "symbol": "invalid-name", + "message": "Variable name \"q1\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 10, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (120/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 35, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (109/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 66, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (113/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 67, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (106/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 73, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (120/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 74, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (109/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 115, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 117, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (117/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 209, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (116/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 271, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (111/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 274, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (111/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 279, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (116/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 282, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (119/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 303, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (111/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 324, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 336, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (144/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 339, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (116/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 406, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (112/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 407, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 408, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (117/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 411, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 412, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (115/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 415, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 425, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 478, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 479, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 490, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (120/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 510, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (120/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 542, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 545, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 549, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (111/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 552, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (113/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 591, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (118/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 597, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (112/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 675, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 716, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 824, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (118/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 848, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (117/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 895, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (120/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 927, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 999, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (114/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 1061, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (114/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 1071, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 1098, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 1165, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "line-too-long", + "message": "Line too long (108/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-lines", + "message": "Too many lines in module (1231/1000)", + "message-id": "C0302" + }, + { + "type": "warning", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 250, + "column": 9, + "path": "vclibpy/media/ref_prop.py", + "symbol": "fixme", + "message": "TODO", + "message-id": "W0511" + }, + { + "type": "warning", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 358, + "column": 42, + "path": "vclibpy/media/ref_prop.py", + "symbol": "fixme", + "message": "TODO: in general not necessary, decreases performance", + "message-id": "W0511" + }, + { + "type": "warning", + "module": "vclibpy.media.ref_prop", + "obj": "", + "line": 528, + "column": 17, + "path": "vclibpy/media/ref_prop.py", + "symbol": "fixme", + "message": "TODO: Ending is not necessary to create mixtures....", + "message-id": "W0511" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.__init__", + "line": 180, + "column": 8, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Attribute name \"rp\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp", + "line": 27, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-instance-attributes", + "message": "Too many instance attributes (15/7)", + "message-id": "R0902" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.__init__", + "line": 139, + "column": 4, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (9/5)", + "message-id": "R0913" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._delete_dll", + "line": 210, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "import-outside-toplevel", + "message": "Import outside toplevel (_ctypes)", + "message-id": "C0415" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._delete_dll", + "line": 211, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "import-outside-toplevel", + "message": "Import outside toplevel (sys)", + "message-id": "C0415" + }, + { + "type": "warning", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._delete_dll", + "line": 212, + "column": 22, + "path": "vclibpy/media/ref_prop.py", + "symbol": "protected-access", + "message": "Access to a protected member _handle of a client class", + "message-id": "W0212" + }, + { + "type": "error", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._delete_dll", + "line": 214, + "column": 16, + "path": "vclibpy/media/ref_prop.py", + "symbol": "no-member", + "message": "Module '_ctypes' has no 'FreeLibrary' member", + "message-id": "E1101" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._call_refprop_allprop", + "line": 257, + "column": 30, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Argument name \"T_val\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._call_refprop_allprop", + "line": 255, + "column": 4, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (6/5)", + "message-id": "R0913" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._call_refprop_allprop", + "line": 303, + "column": 29, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._call_refprop", + "line": 310, + "column": 4, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (9/5)", + "message-id": "R0913" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._call_refprop", + "line": 370, + "column": 37, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._check_error", + "line": 406, + "column": 34, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._check_error", + "line": 411, + "column": 36, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._get_comp_names", + "line": 444, + "column": 16, + "path": "vclibpy/media/ref_prop.py", + "symbol": "no-else-continue", + "message": "Unnecessary \"else\" after \"continue\", remove the \"else\" and de-indent the code inside it", + "message-id": "R1724" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._get_comp_names", + "line": 414, + "column": 4, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-branches", + "message": "Too many branches (13/12)", + "message-id": "R0912" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._get_comp_frac", + "line": 456, + "column": 29, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Argument name \"z\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._get_comp_frac", + "line": 496, + "column": 37, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._setup_rp", + "line": 540, + "column": 16, + "path": "vclibpy/media/ref_prop.py", + "symbol": "no-else-raise", + "message": "Unnecessary \"else\" after \"raise\", remove the \"else\" and de-indent the code inside it", + "message-id": "R1720" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._setup_rp", + "line": 542, + "column": 24, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._setup_rp", + "line": 545, + "column": 24, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._setup_rp", + "line": 549, + "column": 24, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._setup_rp", + "line": 552, + "column": 24, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "warning", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp._setup_rp", + "line": 533, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "unused-variable", + "message": "Unused variable 'setref'", + "message-id": "W0612" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.calc_state", + "line": 590, + "column": 4, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-locals", + "message": "Too many local variables (19/15)", + "message-id": "R0914" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.calc_state", + "line": 590, + "column": 4, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-branches", + "message": "Too many branches (29/12)", + "message-id": "R0912" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.calc_state", + "line": 590, + "column": 4, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-statements", + "message": "Too many statements (123/50)", + "message-id": "R0915" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_available_substances", + "line": 873, + "column": 29, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "warning", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_available_substances", + "line": 890, + "column": 17, + "path": "vclibpy/media/ref_prop.py", + "symbol": "unspecified-encoding", + "message": "Using open without explicitly specifying an encoding", + "message-id": "W1514" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_available_substances", + "line": 892, + "column": 33, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_available_substances", + "line": 895, + "column": 29, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-f-string", + "message": "Formatting a regular string which could be a f-string", + "message-id": "C0209" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_molar_composition", + "line": 937, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"z\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_molar_composition", + "line": 940, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"z\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_critical_point", + "line": 983, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"pc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_critical_point", + "line": 984, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"dc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_critical_point", + "line": 988, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"pc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_critical_point", + "line": 989, + "column": 12, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"dc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_gwp", + "line": 1051, + "column": 8, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-max-builtin", + "message": "Consider using 'gwp = max(gwp, 0)' instead of unnecessary if block", + "message-id": "R1731" + }, + { + "type": "warning", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_odp", + "line": 1124, + "column": 14, + "path": "vclibpy/media/ref_prop.py", + "symbol": "nested-min-max", + "message": "Do not use nested call of 'max'; it's possible to do 'max(tmp.Output, 0)' instead", + "message-id": "W3301" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_odp", + "line": 1126, + "column": 8, + "path": "vclibpy/media/ref_prop.py", + "symbol": "consider-using-max-builtin", + "message": "Consider using 'odp = max(odp, 0)' instead of unnecessary if block", + "message-id": "R1731" + }, + { + "type": "convention", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp.get_sat_vap_pressure", + "line": 1147, + "column": 35, + "path": "vclibpy/media/ref_prop.py", + "symbol": "invalid-name", + "message": "Argument name \"T_sat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.media.ref_prop", + "obj": "RefProp", + "line": 27, + "column": 0, + "path": "vclibpy/media/ref_prop.py", + "symbol": "too-many-public-methods", + "message": "Too many public methods (25/20)", + "message-id": "R0904" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp", + "line": 27, + "column": 15, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PT_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp", + "line": 28, + "column": 15, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'QT_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp", + "line": 29, + "column": 15, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PSmass_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp", + "line": 30, + "column": 15, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'HmassP_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp", + "line": 31, + "column": 15, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PQ_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.__init__", + "line": 38, + "column": 44, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'AbstractState' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_state", + "line": 48, + "column": 16, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_state", + "line": 50, + "column": 16, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_state", + "line": 52, + "column": 16, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_state", + "line": 54, + "column": 16, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_state", + "line": 56, + "column": 16, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_state", + "line": 58, + "column": 16, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_state", + "line": 60, + "column": 16, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "convention", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_transport_properties", + "line": 88, + "column": 12, + "path": "vclibpy/media/cool_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"pr\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_transport_properties", + "line": 88, + "column": 17, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_transport_properties", + "line": 90, + "column": 17, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_transport_properties", + "line": 92, + "column": 17, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_transport_properties", + "line": 94, + "column": 18, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.calc_transport_properties", + "line": 96, + "column": 22, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.get_critical_point", + "line": 132, + "column": 13, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "convention", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.get_critical_point", + "line": 133, + "column": 8, + "path": "vclibpy/media/cool_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"pc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.get_critical_point", + "line": 133, + "column": 13, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "convention", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.get_critical_point", + "line": 134, + "column": 8, + "path": "vclibpy/media/cool_prop.py", + "symbol": "invalid-name", + "message": "Variable name \"dc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "info", + "module": "vclibpy.media.cool_prop", + "obj": "CoolProp.get_critical_point", + "line": 134, + "column": 13, + "path": "vclibpy/media/cool_prop.py", + "symbol": "c-extension-no-member", + "message": "Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects.", + "message-id": "I1101" + }, + { + "type": "convention", + "module": "vclibpy.components.component", + "obj": "", + "line": 11, + "column": 0, + "path": "vclibpy/components/component.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.component", + "obj": "", + "line": 12, + "column": 0, + "path": "vclibpy/components/component.py", + "symbol": "line-too-long", + "message": "Line too long (101/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.component", + "obj": "", + "line": 39, + "column": 0, + "path": "vclibpy/components/component.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.component", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/component.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "warning", + "module": "vclibpy.components.component", + "obj": "BaseComponent.start_secondary_med_prop", + "line": 43, + "column": 8, + "path": "vclibpy/components/component.py", + "symbol": "unnecessary-pass", + "message": "Unnecessary pass statement", + "message-id": "W0107" + }, + { + "type": "warning", + "module": "vclibpy.components.component", + "obj": "BaseComponent.terminate_secondary_med_prop", + "line": 55, + "column": 8, + "path": "vclibpy/components/component.py", + "symbol": "unnecessary-pass", + "message": "Unnecessary pass statement", + "message-id": "W0107" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 25, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 40, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 52, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (106/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 110, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (119/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 134, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (105/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 140, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (112/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 141, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (117/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 143, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (117/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 153, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (101/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 154, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 158, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (106/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 168, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 204, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 235, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (113/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 279, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 311, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "line-too-long", + "message": "Line too long (106/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "calc_ten_coefficients", + "line": 10, + "column": 26, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Argument name \"T_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "calc_ten_coefficients", + "line": 10, + "column": 33, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Argument name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "calc_ten_coefficients", + "line": 23, + "column": 4, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"z\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "BaseTenCoefficientCompressor.__init__", + "line": 79, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Attribute name \"md\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "BaseTenCoefficientCompressor.get_parameter", + "line": 93, + "column": 28, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Argument name \"T_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "BaseTenCoefficientCompressor.get_parameter", + "line": 93, + "column": 35, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Argument name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.__init__", + "line": 170, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Attribute name \"T_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.__init__", + "line": 171, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Attribute name \"T_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor", + "line": 123, + "column": 0, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "too-many-instance-attributes", + "message": "Too many instance attributes (8/7)", + "message-id": "R0902" + }, + { + "type": "refactor", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.__init__", + "line": 168, + "column": 4, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (8/5)", + "message-id": "R0913" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_lambda_h", + "line": 191, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_lambda_h", + "line": 192, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_eta_isentropic", + "line": 222, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_eta_isentropic", + "line": 226, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"h3\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_eta_isentropic", + "line": 230, + "column": 12, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"h2\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_eta_isentropic", + "line": 232, + "column": 12, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"h2\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_eta_mech", + "line": 255, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_eta_mech", + "line": 259, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"h3\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor.get_eta_mech", + "line": 260, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"h2\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor._calculate_values", + "line": 276, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "TenCoefficientCompressor._calculate_values", + "line": 277, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "DataSheetCompressor.get_lambda_h", + "line": 335, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "DataSheetCompressor.get_lambda_h", + "line": 336, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "DataSheetCompressor.get_eta_isentropic", + "line": 350, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "DataSheetCompressor.get_eta_isentropic", + "line": 351, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "DataSheetCompressor.get_eta_mech", + "line": 365, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_eva\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.ten_coefficient", + "obj": "DataSheetCompressor.get_eta_mech", + "line": 366, + "column": 8, + "path": "vclibpy/components/compressors/ten_coefficient.py", + "symbol": "invalid-name", + "message": "Variable name \"T_con\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "", + "line": 40, + "column": 0, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "", + "line": 152, + "column": 0, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "line-too-long", + "message": "Line too long (114/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "", + "line": 153, + "column": 0, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "line-too-long", + "message": "Line too long (113/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "", + "line": 158, + "column": 0, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "Compressor.__init__", + "line": 52, + "column": 8, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "invalid-name", + "message": "Attribute name \"N_max\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "Compressor.__init__", + "line": 53, + "column": 8, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "invalid-name", + "message": "Attribute name \"V_h\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "Compressor.calc_m_flow", + "line": 145, + "column": 8, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "invalid-name", + "message": "Variable name \"V_flow_ref\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "Compressor.calc_electrical_power", + "line": 168, + "column": 8, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "invalid-name", + "message": "Variable name \"P_t\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.compressor", + "obj": "Compressor.calc_electrical_power", + "line": 171, + "column": 8, + "path": "vclibpy/components/compressors/compressor.py", + "symbol": "invalid-name", + "message": "Variable name \"P_el\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "", + "line": 9, + "column": 0, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "", + "line": 39, + "column": 0, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "", + "line": 77, + "column": 0, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "", + "line": 107, + "column": 0, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "line-too-long", + "message": "Line too long (107/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "", + "line": 124, + "column": 0, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "line-too-long", + "message": "Line too long (116/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "refactor", + "module": "vclibpy.components.compressors.rotary", + "obj": "RotaryCompressor.get_lambda_h", + "line": 28, + "column": 4, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "too-many-locals", + "message": "Too many local variables (18/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "RotaryCompressor.get_lambda_h", + "line": 41, + "column": 8, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "invalid-name", + "message": "Variable name \"T_1\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "RotaryCompressor.get_lambda_h", + "line": 48, + "column": 8, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "invalid-name", + "message": "Variable name \"sigma_T_1\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "RotaryCompressor.get_lambda_h", + "line": 49, + "column": 8, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "invalid-name", + "message": "Variable name \"T_1_ave\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "RotaryCompressor.get_lambda_h", + "line": 56, + "column": 8, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "invalid-name", + "message": "Variable name \"pi\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "RotaryCompressor.get_eta_isentropic", + "line": 84, + "column": 8, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "invalid-name", + "message": "Variable name \"pi\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.components.compressors.rotary", + "obj": "RotaryCompressor.get_eta_mech", + "line": 95, + "column": 4, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "too-many-locals", + "message": "Too many local variables (17/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.rotary", + "obj": "RotaryCompressor.get_eta_mech", + "line": 120, + "column": 8, + "path": "vclibpy/components/compressors/rotary.py", + "symbol": "invalid-name", + "message": "Variable name \"pi\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/compressors/__init__.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.constant_effectivness", + "obj": "", + "line": 9, + "column": 0, + "path": "vclibpy/components/compressors/constant_effectivness.py", + "symbol": "line-too-long", + "message": "Line too long (114/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.constant_effectivness", + "obj": "", + "line": 25, + "column": 0, + "path": "vclibpy/components/compressors/constant_effectivness.py", + "symbol": "line-too-long", + "message": "Line too long (117/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.compressors.constant_effectivness", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/compressors/constant_effectivness.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "refactor", + "module": "vclibpy.components.compressors.constant_effectivness", + "obj": "ConstantEffectivenessCompressor.__init__", + "line": 40, + "column": 4, + "path": "vclibpy/components/compressors/constant_effectivness.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (6/5)", + "message-id": "R0913" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/__init__.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 19, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (102/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 159, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 161, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 199, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (101/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 204, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (102/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 206, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 225, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (121/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 226, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (120/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 227, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (122/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 289, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 291, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 339, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (101/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 344, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (102/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 346, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 363, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (122/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 364, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "line-too-long", + "message": "Line too long (121/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTU.separate_phases", + "line": 41, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTU.separate_phases", + "line": 44, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTU.separate_phases", + "line": 47, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTU.iterate_area", + "line": 52, + "column": 27, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Argument name \"dT_max\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTU.iterate_area", + "line": 86, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"NTU\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTU.iterate_area", + "line": 89, + "column": 16, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "no-else-break", + "message": "Unnecessary \"else\" after \"break\", remove the \"else\" and de-indent the code inside it", + "message-id": "R1723" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 114, + "column": 4, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "too-many-locals", + "message": "Too many local variables (31/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 136, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 136, + "column": 14, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 136, + "column": 21, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 146, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"T_mean\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 152, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"T_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 153, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"T_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 154, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"T_out\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 157, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sc_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 157, + "column": 18, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 165, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 169, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 171, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sc_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 177, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_lat_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 177, + "column": 19, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 188, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 193, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 195, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_lat_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 199, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 202, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sh_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 202, + "column": 18, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 210, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 212, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sh_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 216, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 218, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 221, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"dT_min_in\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 222, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"dT_min_out\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 223, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"dT_min_LatSH\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 171, + "column": 22, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "unused-variable", + "message": "Unused variable 'k_sc'", + "message-id": "W0612" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 195, + "column": 23, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "unused-variable", + "message": "Unused variable 'k_lat'", + "message-id": "W0612" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUCondenser.calc", + "line": 212, + "column": 22, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "unused-variable", + "message": "Unused variable 'k_sh'", + "message-id": "W0612" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 245, + "column": 4, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "too-many-locals", + "message": "Too many local variables (30/15)", + "message-id": "R0914" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 267, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 267, + "column": 14, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 267, + "column": 21, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 277, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"T_mean\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 282, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"T_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 283, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"T_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 284, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"T_out\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 287, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sh_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 287, + "column": 18, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 295, + "column": 16, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 301, + "column": 16, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 304, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sh\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 306, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sh_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 311, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 314, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_lat_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 314, + "column": 19, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 326, + "column": 16, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 331, + "column": 16, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 334, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_lat\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 335, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_lat_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 339, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "logging-fstring-interpolation", + "message": "Use lazy % formatting in logging functions", + "message-id": "W1203" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 342, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sc_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 342, + "column": 18, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 350, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"A_sc\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 352, + "column": 12, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_sc_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 357, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 360, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"dT_min_in\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 361, + "column": 8, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"dT_min_out\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 306, + "column": 22, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "unused-variable", + "message": "Unused variable 'k_sh'", + "message-id": "W0612" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 335, + "column": 23, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "unused-variable", + "message": "Unused variable 'k_lat'", + "message-id": "W0612" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.moving_boundary_ntu", + "obj": "MovingBoundaryNTUEvaporator.calc", + "line": 352, + "column": 22, + "path": "vclibpy/components/heat_exchangers/moving_boundary_ntu.py", + "symbol": "unused-variable", + "message": "Unused variable 'k_sc'", + "message-id": "W0612" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.economizer", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/economizer.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.economizer", + "obj": "VaporInjectionEconomizerNTU.state_two_phase_inlet", + "line": 40, + "column": 4, + "path": "vclibpy/components/heat_exchangers/economizer.py", + "symbol": "missing-function-docstring", + "message": "Missing function or method docstring", + "message-id": "C0116" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.economizer", + "obj": "VaporInjectionEconomizerNTU.state_two_phase_outlet", + "line": 48, + "column": 4, + "path": "vclibpy/components/heat_exchangers/economizer.py", + "symbol": "missing-function-docstring", + "message": "Missing function or method docstring", + "message-id": "C0116" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "", + "line": 8, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "line-too-long", + "message": "Line too long (109/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "", + "line": 98, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "line-too-long", + "message": "Line too long (106/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "", + "line": 234, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "line-too-long", + "message": "Line too long (109/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger.__init__", + "line": 43, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "invalid-name", + "message": "Attribute name \"A\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger", + "line": 11, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "too-many-instance-attributes", + "message": "Too many instance attributes (11/7)", + "message-id": "R0902" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger.__init__", + "line": 32, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (8/5)", + "message-id": "R0913" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger.m_flow_secondary", + "line": 181, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "missing-function-docstring", + "message": "Missing function or method docstring", + "message-id": "C0116" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger.m_flow_secondary_cp", + "line": 190, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "missing-function-docstring", + "message": "Missing function or method docstring", + "message-id": "C0116" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger.calc_secondary_Q_flow", + "line": 204, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "missing-function-docstring", + "message": "Missing function or method docstring", + "message-id": "C0116" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger.calc_secondary_Q_flow", + "line": 204, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "invalid-name", + "message": "Method name \"calc_secondary_Q_flow\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger.calc_secondary_Q_flow", + "line": 204, + "column": 36, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "invalid-name", + "message": "Argument name \"Q_flow\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_exchanger", + "obj": "HeatExchanger.calc_Q_flow", + "line": 207, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_exchanger.py", + "symbol": "invalid-name", + "message": "Method name \"calc_Q_flow\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "", + "line": 95, + "column": 0, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "line-too-long", + "message": "Line too long (120/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "", + "line": 133, + "column": 0, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "line-too-long", + "message": "Line too long (106/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "", + "line": 142, + "column": 0, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "line-too-long", + "message": "Line too long (118/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "", + "line": 152, + "column": 0, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "", + "line": 154, + "column": 0, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_eps", + "line": 67, + "column": 33, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Argument name \"NTU\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_R", + "line": 93, + "column": 4, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Method name \"calc_R\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_NTU", + "line": 126, + "column": 4, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Method name \"calc_NTU\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_NTU", + "line": 126, + "column": 17, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Argument name \"A\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_Q_ntu", + "line": 152, + "column": 4, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Method name \"calc_Q_ntu\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_Q_ntu", + "line": 152, + "column": 25, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Argument name \"dT_max\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_Q_ntu", + "line": 152, + "column": 76, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Argument name \"A\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_Q_ntu", + "line": 168, + "column": 8, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"NTU\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.ntu", + "obj": "BasicNTU.calc_Q_ntu", + "line": 172, + "column": 8, + "path": "vclibpy/components/heat_exchangers/ntu.py", + "symbol": "invalid-name", + "message": "Variable name \"Q_max\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "obj": "", + "line": 36, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py", + "symbol": "line-too-long", + "message": "Line too long (113/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "obj": "AirToWallTransfer.__init__", + "line": 24, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"A_cross\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "obj": "AirToWallTransfer.__init__", + "line": 23, + "column": 23, + "path": "vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py", + "symbol": "invalid-name", + "message": "Argument name \"A_cross\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "obj": "AirToWallTransfer.calc", + "line": 35, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py", + "symbol": "invalid-name", + "message": "Variable name \"Re\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "obj": "AirToWallTransfer.calc_laminar_area_nusselt", + "line": 54, + "column": 40, + "path": "vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py", + "symbol": "invalid-name", + "message": "Argument name \"Re\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "obj": "", + "line": 5, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py", + "symbol": "wrong-import-order", + "message": "first party import \"from vclibpy.media import TransportProperties\" should be placed before \"from .heat_transfer import HeatTransfer\"", + "message-id": "C0411" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "", + "line": 73, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "", + "line": 81, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "", + "line": 84, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "", + "line": 93, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "TurbulentFluidInPipeToWallTransfer.calc", + "line": 51, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "invalid-name", + "message": "Variable name \"Re\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "TurbulentFluidInPipeToWallTransfer.calc_turbulent_tube_nusselt", + "line": 59, + "column": 42, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "invalid-name", + "message": "Argument name \"Re\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "TurbulentFluidInPipeToWallTransfer.calc_turbulent_tube_nusselt", + "line": 74, + "column": 12, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "no-else-return", + "message": "Unnecessary \"elif\" after \"return\", remove the leading \"el\" from \"elif\"", + "message-id": "R1705" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "TurbulentFluidInPipeToWallTransfer.calc_turbulent_tube_nusselt", + "line": 59, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "too-many-branches", + "message": "Too many branches (14/12)", + "message-id": "R0912" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "obj": "", + "line": 6, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py", + "symbol": "wrong-import-order", + "message": "first party import \"from vclibpy.media import TransportProperties\" should be placed before \"from .heat_transfer import HeatTransfer, calc_reynolds_pipe\"", + "message-id": "C0411" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/__init__.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer", + "obj": "", + "line": 2, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/__init__.py", + "symbol": "wrong-import-order", + "message": "first party import \"from vclibpy.components.heat_exchangers.heat_transfer import constant\" should be placed before \"from .heat_transfer import TwoPhaseHeatTransfer, HeatTransfer, calc_reynolds_pipe\"", + "message-id": "C0411" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer", + "obj": "", + "line": 3, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/__init__.py", + "symbol": "wrong-import-order", + "message": "first party import \"from vclibpy.components.heat_exchangers.heat_transfer import wall\" should be placed before \"from .heat_transfer import TwoPhaseHeatTransfer, HeatTransfer, calc_reynolds_pipe\"", + "message-id": "C0411" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.constant", + "obj": "", + "line": 26, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/constant.py", + "symbol": "line-too-long", + "message": "Line too long (102/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.constant", + "obj": "", + "line": 53, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/constant.py", + "symbol": "line-too-long", + "message": "Line too long (106/100)", + "message-id": "C0301" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.heat_transfer.constant", + "obj": "ConstantHeatTransfer.calc", + "line": 21, + "column": 19, + "path": "vclibpy/components/heat_exchangers/heat_transfer/constant.py", + "symbol": "unused-argument", + "message": "Unused argument 'transport_properties'", + "message-id": "W0613" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.heat_transfer.constant", + "obj": "ConstantHeatTransfer.calc", + "line": 21, + "column": 62, + "path": "vclibpy/components/heat_exchangers/heat_transfer/constant.py", + "symbol": "unused-argument", + "message": "Unused argument 'm_flow'", + "message-id": "W0613" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.constant", + "obj": "ConstantHeatTransfer", + "line": 9, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/constant.py", + "symbol": "too-few-public-methods", + "message": "Too few public methods (1/2)", + "message-id": "R0903" + }, + { + "type": "warning", + "module": "vclibpy.components.heat_exchangers.heat_transfer.constant", + "obj": "ConstantTwoPhaseHeatTransfer.calc", + "line": 48, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/constant.py", + "symbol": "unused-argument", + "message": "Unused argument 'kwargs'", + "message-id": "W0613" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.constant", + "obj": "ConstantTwoPhaseHeatTransfer", + "line": 36, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/constant.py", + "symbol": "too-few-public-methods", + "message": "Too few public methods (1/2)", + "message-id": "R0903" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "obj": "", + "line": 61, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py", + "symbol": "line-too-long", + "message": "Line too long (104/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "obj": "", + "line": 79, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "obj": "HeatTransfer", + "line": 12, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py", + "symbol": "too-few-public-methods", + "message": "Too few public methods (1/2)", + "message-id": "R0903" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "obj": "TwoPhaseHeatTransfer.calc", + "line": 46, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py", + "symbol": "too-many-arguments", + "message": "Too many arguments (9/5)", + "message-id": "R0913" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "obj": "TwoPhaseHeatTransfer", + "line": 40, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py", + "symbol": "too-few-public-methods", + "message": "Too few public methods (1/2)", + "message-id": "R0903" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "", + "line": 41, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "line-too-long", + "message": "Line too long (106/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry", + "line": 25, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"lambda_R\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry", + "line": 26, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"n_Rohre\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry", + "line": 27, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"n_Rippen\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry", + "line": 28, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"a\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry", + "line": 12, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "too-many-instance-attributes", + "message": "Too many instance attributes (12/7)", + "message-id": "R0902" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.A_Rippen", + "line": 39, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"A_Rippen\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.A", + "line": 44, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"A\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.A_FreieOberflaecheRohr", + "line": 49, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"A_FreieOberflaecheRohr\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.A_RohrInnen", + "line": 54, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"A_RohrInnen\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.A_RohrUnberippt", + "line": 59, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Attribute name \"A_RohrUnberippt\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.eta_R", + "line": 82, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Method name \"eta_R\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.eta_R", + "line": 82, + "column": 20, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Argument name \"alpha_R\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.eta_R", + "line": 92, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Variable name \"X\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.alpha_S", + "line": 95, + "column": 4, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Method name \"alpha_S\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.alpha_S", + "line": 95, + "column": 22, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Argument name \"alpha_R\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "AirSourceHeatExchangerGeometry.alpha_S", + "line": 105, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Variable name \"A_R_to_A\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt", + "line": 155, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Variable name \"C\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt", + "line": 158, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Variable name \"A_div_A_0\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt", + "line": 166, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Variable name \"alpha_R\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "obj": "VDIAtlasAirToWallTransfer.calc_laminar_area_nusselt", + "line": 167, + "column": 8, + "path": "vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py", + "symbol": "invalid-name", + "message": "Variable name \"alpha_S\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.wall", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/wall.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "refactor", + "module": "vclibpy.components.heat_exchangers.heat_transfer.wall", + "obj": "WallTransfer", + "line": 10, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/wall.py", + "symbol": "too-few-public-methods", + "message": "Too few public methods (1/2)", + "message-id": "R0903" + }, + { + "type": "convention", + "module": "vclibpy.components.heat_exchangers.heat_transfer.wall", + "obj": "", + "line": 4, + "column": 0, + "path": "vclibpy/components/heat_exchangers/heat_transfer/wall.py", + "symbol": "wrong-import-order", + "message": "first party import \"from vclibpy.media import TransportProperties\" should be placed before \"from .heat_transfer import HeatTransfer\"", + "message-id": "C0411" + }, + { + "type": "convention", + "module": "vclibpy.components.expansion_valves.expansion_valve", + "obj": "ExpansionValve.__init__", + "line": 20, + "column": 8, + "path": "vclibpy/components/expansion_valves/expansion_valve.py", + "symbol": "invalid-name", + "message": "Attribute name \"A\" doesn't conform to snake_case naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "vclibpy.components.expansion_valves.bernoulli", + "obj": "", + "line": 16, + "column": 0, + "path": "vclibpy/components/expansion_valves/bernoulli.py", + "symbol": "line-too-long", + "message": "Line too long (110/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.expansion_valves.bernoulli", + "obj": "", + "line": 21, + "column": 0, + "path": "vclibpy/components/expansion_valves/bernoulli.py", + "symbol": "line-too-long", + "message": "Line too long (103/100)", + "message-id": "C0301" + }, + { + "type": "convention", + "module": "vclibpy.components.expansion_valves", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "missing-module-docstring", + "message": "Missing module docstring", + "message-id": "C0114" + }, + { + "type": "refactor", + "module": "vclibpy.components.expansion_valves.__init__", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "cyclic-import", + "message": "Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.standard)", + "message-id": "R0401" + }, + { + "type": "refactor", + "module": "vclibpy.components.expansion_valves.__init__", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "cyclic-import", + "message": "Cyclic import (vclibpy.media -> vclibpy.media.cool_prop -> vclibpy.media.media)", + "message-id": "R0401" + }, + { + "type": "refactor", + "module": "vclibpy.components.expansion_valves.__init__", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "cyclic-import", + "message": "Cyclic import (vclibpy.components.expansion_valves -> vclibpy.components.expansion_valves.bernoulli)", + "message-id": "R0401" + }, + { + "type": "refactor", + "module": "vclibpy.components.expansion_valves.__init__", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "cyclic-import", + "message": "Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.vapor_injection_phase_separator -> vclibpy.flowsheets.vapor_injection)", + "message-id": "R0401" + }, + { + "type": "refactor", + "module": "vclibpy.components.expansion_valves.__init__", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "cyclic-import", + "message": "Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.vapor_injection_economizer -> vclibpy.flowsheets.vapor_injection)", + "message-id": "R0401" + }, + { + "type": "refactor", + "module": "vclibpy.components.expansion_valves.__init__", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "cyclic-import", + "message": "Cyclic import (vclibpy.utils -> vclibpy.utils.automation)", + "message-id": "R0401" + }, + { + "type": "refactor", + "module": "vclibpy.components.expansion_valves.__init__", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "cyclic-import", + "message": "Cyclic import (vclibpy.media -> vclibpy.media.ref_prop)", + "message-id": "R0401" + }, + { + "type": "refactor", + "module": "vclibpy.components.expansion_valves.__init__", + "obj": "", + "line": 1, + "column": 0, + "path": "vclibpy/components/expansion_valves/__init__.py", + "symbol": "cyclic-import", + "message": "Cyclic import (vclibpy.media -> vclibpy.media.media)", + "message-id": "R0401" + } + ], + "stats": { + "bad_names": { + "argument": 33, + "attr": 18, + "klass": 0, + "class_attribute": 0, + "class_const": 0, + "const": 0, + "inlinevar": 0, + "function": 0, + "method": 7, + "module": 0, + "variable": 173, + "typevar": 0, + "typealias": 0 + }, + "by_module": { + "vclibpy": { + "convention": 0, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 2, + "warning": 0 + }, + "vclibpy.datamodels": { + "convention": 0, + "error": 1, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 51, + "warning": 0 + }, + "vclibpy.flowsheets.vapor_injection_economizer": { + "convention": 4, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 49, + "warning": 1 + }, + "vclibpy.flowsheets.vapor_injection_phase_separator": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 18, + "warning": 0 + }, + "vclibpy.flowsheets.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 4, + "warning": 0 + }, + "vclibpy.flowsheets.base": { + "convention": 30, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 8, + "statement": 211, + "warning": 0 + }, + "vclibpy.flowsheets.vapor_injection": { + "convention": 4, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 64, + "warning": 0 + }, + "vclibpy.flowsheets.standard": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 36, + "warning": 0 + }, + "vclibpy.utils.sdf_": { + "convention": 5, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 4, + "statement": 75, + "warning": 0 + }, + "vclibpy.utils.nominal_design": { + "convention": 8, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 35, + "warning": 2 + }, + "vclibpy.utils.ten_coefficient_compressor_reqression": { + "convention": 20, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 3, + "statement": 65, + "warning": 3 + }, + "vclibpy.utils.printing": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 12, + "warning": 0 + }, + "vclibpy.utils.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 2, + "warning": 0 + }, + "vclibpy.utils.plotting": { + "convention": 28, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 9, + "statement": 169, + "warning": 0 + }, + "vclibpy.utils.automation": { + "convention": 16, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 6, + "statement": 99, + "warning": 7 + }, + "vclibpy.media.states": { + "convention": 9, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 4, + "statement": 60, + "warning": 0 + }, + "vclibpy.media.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 12, + "warning": 2 + }, + "vclibpy.media.media": { + "convention": 17, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 50, + "warning": 6 + }, + "vclibpy.media.ref_prop": { + "convention": 70, + "error": 1, + "fatal": 0, + "info": 0, + "refactor": 13, + "statement": 427, + "warning": 7 + }, + "vclibpy.media.cool_prop": { + "convention": 3, + "error": 0, + "fatal": 0, + "info": 21, + "refactor": 0, + "statement": 59, + "warning": 0 + }, + "vclibpy.components.__init__": { + "convention": 0, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 0, + "warning": 0 + }, + "vclibpy.components.phase_separator": { + "convention": 0, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 21, + "warning": 0 + }, + "vclibpy.components.component": { + "convention": 4, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 28, + "warning": 2 + }, + "vclibpy.components.compressors.ten_coefficient": { + "convention": 42, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 95, + "warning": 0 + }, + "vclibpy.components.compressors.compressor": { + "convention": 9, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 38, + "warning": 0 + }, + "vclibpy.components.compressors.rotary": { + "convention": 12, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 49, + "warning": 0 + }, + "vclibpy.components.compressors.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 4, + "warning": 0 + }, + "vclibpy.components.compressors.constant_effectivness": { + "convention": 3, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 14, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 2, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.moving_boundary_ntu": { + "convention": 73, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 3, + "statement": 134, + "warning": 10 + }, + "vclibpy.components.heat_exchangers.economizer": { + "convention": 3, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 31, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_exchanger": { + "convention": 11, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 68, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.ntu": { + "convention": 15, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 49, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall": { + "convention": 7, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 31, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall": { + "convention": 7, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 36, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.__init__": { + "convention": 3, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 3, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.constant": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 12, + "warning": 3 + }, + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 3, + "statement": 12, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall": { + "convention": 21, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 63, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.wall": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 10, + "warning": 0 + }, + "vclibpy.components.expansion_valves.expansion_valve": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 12, + "warning": 0 + }, + "vclibpy.components.expansion_valves.bernoulli": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 6, + "warning": 0 + }, + "vclibpy.components.expansion_valves.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 8, + "statement": 2, + "warning": 0 + } + }, + "by_msg": { + "no-member": 2, + "too-many-arguments": 13, + "missing-module-docstring": 27, + "too-many-locals": 12, + "invalid-name": 231, + "unused-variable": 8, + "line-too-long": 150, + "superfluous-parens": 1, + "missing-function-docstring": 8, + "no-else-continue": 5, + "too-many-branches": 6, + "too-many-statements": 4, + "inconsistent-return-statements": 2, + "wrong-import-order": 6, + "unnecessary-comprehension": 4, + "consider-using-generator": 1, + "trailing-whitespace": 2, + "protected-access": 3, + "fixme": 5, + "raise-missing-from": 1, + "consider-using-enumerate": 2, + "too-many-nested-blocks": 4, + "consider-iterating-dictionary": 1, + "import-outside-toplevel": 3, + "logging-fstring-interpolation": 9, + "broad-exception-caught": 2, + "consider-using-with": 1, + "too-many-instance-attributes": 6, + "global-statement": 1, + "global-variable-not-assigned": 1, + "unused-argument": 5, + "unnecessary-pass": 6, + "too-many-lines": 1, + "consider-using-f-string": 12, + "no-else-raise": 1, + "unspecified-encoding": 1, + "consider-using-max-builtin": 2, + "nested-min-max": 1, + "too-many-public-methods": 1, + "c-extension-no-member": 21, + "no-else-break": 1, + "no-else-return": 1, + "too-few-public-methods": 5, + "cyclic-import": 8 + }, + "code_type_count": { + "code": 0, + "comment": 0, + "docstring": 0, + "empty": 0, + "total": 0 + }, + "dependencies": { + "vclibpy.datamodels": [ + "vclibpy.utils.automation", + "vclibpy.components.heat_exchangers.heat_exchanger", + "vclibpy.media.states", + "vclibpy.flowsheets.base", + "vclibpy.components.compressors.constant_effectivness", + "vclibpy", + "vclibpy.components.compressors.rotary", + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "vclibpy.flowsheets.standard", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.components.compressors.ten_coefficient", + "vclibpy.components.compressors.compressor", + "vclibpy.components.heat_exchangers.moving_boundary_ntu" + ], + "numpy": [ + "vclibpy.utils.automation", + "vclibpy.flowsheets.base", + "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "vclibpy.media.media", + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "vclibpy.flowsheets.vapor_injection_economizer", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.components.compressors.ten_coefficient", + "vclibpy.components.heat_exchangers.ntu", + "vclibpy.utils.plotting", + "vclibpy.components.heat_exchangers.moving_boundary_ntu" + ], + "vclibpy.flowsheets.vapor_injection": [ + "vclibpy.flowsheets.vapor_injection_phase_separator", + "vclibpy.flowsheets.vapor_injection_economizer" + ], + "vclibpy.components.heat_exchangers.economizer": [ + "vclibpy.flowsheets.vapor_injection_economizer" + ], + "vclibpy.components.phase_separator": [ + "vclibpy.flowsheets.vapor_injection_phase_separator" + ], + "vclibpy.flowsheets.base": [ + "vclibpy.flowsheets" + ], + "vclibpy.flowsheets.standard": [ + "vclibpy.flowsheets" + ], + "vclibpy.flowsheets.vapor_injection_economizer": [ + "vclibpy.flowsheets" + ], + "vclibpy.flowsheets.vapor_injection_phase_separator": [ + "vclibpy.flowsheets" + ], + "matplotlib.pyplot": [ + "vclibpy.utils.plotting", + "vclibpy.flowsheets.base" + ], + "vclibpy.media": [ + "vclibpy.components.phase_separator", + "vclibpy.components.heat_exchangers.heat_exchanger", + "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "vclibpy.flowsheets.base", + "vclibpy.utils.ten_coefficient_compressor_reqression", + "vclibpy.utils.plotting", + "vclibpy.media.ref_prop", + "vclibpy.components.heat_exchangers.economizer", + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "vclibpy.components.heat_exchangers.heat_transfer.constant", + "vclibpy.components.component", + "vclibpy.components.heat_exchangers.heat_transfer.wall", + "vclibpy.media.media", + "vclibpy.components.heat_exchangers.moving_boundary_ntu" + ], + "vclibpy": [ + "vclibpy.utils.ten_coefficient_compressor_reqression", + "vclibpy.utils.nominal_design", + "vclibpy.flowsheets.base" + ], + "vclibpy.components.heat_exchangers": [ + "vclibpy.flowsheets.base" + ], + "vclibpy.components.component": [ + "vclibpy.components.phase_separator", + "vclibpy.components.heat_exchangers.heat_exchanger", + "vclibpy.flowsheets.base", + "vclibpy.components.expansion_valves.expansion_valve", + "vclibpy.components.compressors.compressor" + ], + "vclibpy.utils.plotting": [ + "vclibpy.flowsheets.base" + ], + "vclibpy.flowsheets": [ + "vclibpy.utils.automation", + "vclibpy.flowsheets.standard", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.utils.nominal_design" + ], + "vclibpy.components.compressors": [ + "vclibpy.utils.ten_coefficient_compressor_reqression", + "vclibpy.flowsheets.standard", + "vclibpy.flowsheets.vapor_injection" + ], + "vclibpy.components.expansion_valves": [ + "vclibpy.flowsheets.standard", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.components.expansion_valves.bernoulli" + ], + "pandas": [ + "vclibpy.utils.automation", + "vclibpy.utils.ten_coefficient_compressor_reqression", + "vclibpy.components.compressors.ten_coefficient", + "vclibpy.utils.sdf_", + "vclibpy.utils.printing" + ], + "sdf": [ + "vclibpy.utils.sdf_", + "vclibpy.utils.plotting" + ], + "vclibpy.utils.automation": [ + "vclibpy.utils" + ], + "vclibpy.utils.sdf_": [ + "vclibpy.utils" + ], + "vclibpy.utils": [ + "vclibpy.utils.automation" + ], + "vclibpy.media.states": [ + "vclibpy.media", + "vclibpy.media.cool_prop" + ], + "vclibpy.media.media": [ + "vclibpy.media", + "vclibpy.media.cool_prop" + ], + "vclibpy.media.cool_prop": [ + "vclibpy.media" + ], + "vclibpy.media.ref_prop": [ + "vclibpy.media" + ], + "ctREFPROP.ctREFPROP": [ + "vclibpy.media.ref_prop" + ], + "CoolProp.CoolProp": [ + "vclibpy.media.cool_prop" + ], + "vclibpy.components.compressors.compressor": [ + "vclibpy.components.compressors.constant_effectivness", + "vclibpy.components.compressors.ten_coefficient", + "vclibpy.components.compressors.rotary", + "vclibpy.components.compressors" + ], + "vclibpy.components.compressors.rotary": [ + "vclibpy.components.compressors" + ], + "vclibpy.components.compressors.ten_coefficient": [ + "vclibpy.components.compressors" + ], + "vclibpy.components.compressors.constant_effectivness": [ + "vclibpy.components.compressors" + ], + "vclibpy.components.heat_exchangers.heat_exchanger": [ + "vclibpy.components.heat_exchangers", + "vclibpy.components.heat_exchangers.ntu" + ], + "vclibpy.components.heat_exchangers.moving_boundary_ntu": [ + "vclibpy.components.heat_exchangers" + ], + "vclibpy.components.heat_exchangers.ntu": [ + "vclibpy.components.heat_exchangers.economizer", + "vclibpy.components.heat_exchangers.moving_boundary_ntu" + ], + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer": [ + "vclibpy.components.heat_exchangers.heat_transfer", + "vclibpy.components.heat_exchangers.heat_exchanger", + "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "vclibpy.components.heat_exchangers.heat_transfer.wall" + ], + "vclibpy.components.heat_exchangers.heat_transfer.constant": [ + "vclibpy.components.heat_exchangers.heat_transfer" + ], + "vclibpy.components.heat_exchangers.heat_transfer.wall": [ + "vclibpy.components.heat_exchangers.heat_transfer" + ], + "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall": [ + "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall" + ], + "vclibpy.components.expansion_valves.expansion_valve": [ + "vclibpy.components.expansion_valves" + ], + "vclibpy.components.expansion_valves.bernoulli": [ + "vclibpy.components.expansion_valves" + ] + }, + "duplicated_lines": { + "nb_duplicated_lines": 0, + "percent_duplicated_lines": 0.0 + }, + "node_count": { + "function": 21, + "klass": 40, + "method": 219, + "module": 43 + }, + "undocumented": { + "function": 0, + "klass": 0, + "method": 8, + "module": 27 + }, + "convention": 444, + "error": 2, + "fatal": 0, + "info": 21, + "refactor": 77, + "statement": 2220, + "warning": 43, + "global_note": 0, + "nb_duplicated_lines": 0, + "percent_duplicated_lines": 0.0 + }, + "previous": { + "bad_names": { + "argument": 33, + "attr": 18, + "klass": 0, + "class_attribute": 0, + "class_const": 0, + "const": 0, + "inlinevar": 0, + "function": 0, + "method": 7, + "module": 0, + "variable": 173, + "typevar": 0, + "typealias": 0 + }, + "by_module": { + "vclibpy": { + "convention": 0, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 2, + "warning": 0 + }, + "vclibpy.datamodels": { + "convention": 0, + "error": 1, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 51, + "warning": 0 + }, + "vclibpy.flowsheets.vapor_injection_economizer": { + "convention": 4, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 49, + "warning": 1 + }, + "vclibpy.flowsheets.vapor_injection_phase_separator": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 18, + "warning": 0 + }, + "vclibpy.flowsheets.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 4, + "warning": 0 + }, + "vclibpy.flowsheets.base": { + "convention": 30, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 8, + "statement": 211, + "warning": 0 + }, + "vclibpy.flowsheets.vapor_injection": { + "convention": 4, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 64, + "warning": 0 + }, + "vclibpy.flowsheets.standard": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 36, + "warning": 0 + }, + "vclibpy.utils.sdf_": { + "convention": 5, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 4, + "statement": 75, + "warning": 0 + }, + "vclibpy.utils.nominal_design": { + "convention": 8, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 35, + "warning": 2 + }, + "vclibpy.utils.ten_coefficient_compressor_reqression": { + "convention": 20, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 3, + "statement": 65, + "warning": 3 + }, + "vclibpy.utils.printing": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 12, + "warning": 0 + }, + "vclibpy.utils.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 2, + "warning": 0 + }, + "vclibpy.utils.plotting": { + "convention": 28, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 9, + "statement": 169, + "warning": 0 + }, + "vclibpy.utils.automation": { + "convention": 16, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 6, + "statement": 99, + "warning": 7 + }, + "vclibpy.media.states": { + "convention": 9, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 4, + "statement": 60, + "warning": 0 + }, + "vclibpy.media.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 12, + "warning": 2 + }, + "vclibpy.media.media": { + "convention": 17, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 50, + "warning": 6 + }, + "vclibpy.media.ref_prop": { + "convention": 70, + "error": 1, + "fatal": 0, + "info": 0, + "refactor": 13, + "statement": 427, + "warning": 7 + }, + "vclibpy.media.cool_prop": { + "convention": 3, + "error": 0, + "fatal": 0, + "info": 21, + "refactor": 0, + "statement": 59, + "warning": 0 + }, + "vclibpy.components.__init__": { + "convention": 0, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 0, + "warning": 0 + }, + "vclibpy.components.phase_separator": { + "convention": 0, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 21, + "warning": 0 + }, + "vclibpy.components.component": { + "convention": 4, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 28, + "warning": 2 + }, + "vclibpy.components.compressors.ten_coefficient": { + "convention": 42, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 95, + "warning": 0 + }, + "vclibpy.components.compressors.compressor": { + "convention": 9, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 38, + "warning": 0 + }, + "vclibpy.components.compressors.rotary": { + "convention": 12, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 49, + "warning": 0 + }, + "vclibpy.components.compressors.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 4, + "warning": 0 + }, + "vclibpy.components.compressors.constant_effectivness": { + "convention": 3, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 14, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 2, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.moving_boundary_ntu": { + "convention": 73, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 3, + "statement": 134, + "warning": 10 + }, + "vclibpy.components.heat_exchangers.economizer": { + "convention": 3, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 31, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_exchanger": { + "convention": 11, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 68, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.ntu": { + "convention": 15, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 49, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall": { + "convention": 7, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 31, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall": { + "convention": 7, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 36, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.__init__": { + "convention": 3, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 3, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.constant": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 2, + "statement": 12, + "warning": 3 + }, + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 3, + "statement": 12, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall": { + "convention": 21, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 63, + "warning": 0 + }, + "vclibpy.components.heat_exchangers.heat_transfer.wall": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 1, + "statement": 10, + "warning": 0 + }, + "vclibpy.components.expansion_valves.expansion_valve": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 12, + "warning": 0 + }, + "vclibpy.components.expansion_valves.bernoulli": { + "convention": 2, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 0, + "statement": 6, + "warning": 0 + }, + "vclibpy.components.expansion_valves.__init__": { + "convention": 1, + "error": 0, + "fatal": 0, + "info": 0, + "refactor": 8, + "statement": 2, + "warning": 0 + } + }, + "by_msg": { + "no-member": 2, + "too-many-arguments": 13, + "missing-module-docstring": 27, + "too-many-locals": 12, + "invalid-name": 231, + "unused-variable": 8, + "line-too-long": 150, + "superfluous-parens": 1, + "missing-function-docstring": 8, + "no-else-continue": 5, + "too-many-branches": 6, + "too-many-statements": 4, + "inconsistent-return-statements": 2, + "wrong-import-order": 6, + "unnecessary-comprehension": 4, + "consider-using-generator": 1, + "trailing-whitespace": 2, + "protected-access": 3, + "fixme": 5, + "raise-missing-from": 1, + "consider-using-enumerate": 2, + "too-many-nested-blocks": 4, + "consider-iterating-dictionary": 1, + "import-outside-toplevel": 3, + "logging-fstring-interpolation": 9, + "broad-exception-caught": 2, + "consider-using-with": 1, + "too-many-instance-attributes": 6, + "global-statement": 1, + "global-variable-not-assigned": 1, + "unused-argument": 5, + "unnecessary-pass": 6, + "too-many-lines": 1, + "consider-using-f-string": 12, + "no-else-raise": 1, + "unspecified-encoding": 1, + "consider-using-max-builtin": 2, + "nested-min-max": 1, + "too-many-public-methods": 1, + "c-extension-no-member": 21, + "no-else-break": 1, + "no-else-return": 1, + "too-few-public-methods": 5, + "cyclic-import": 8 + }, + "code_type_count": { + "code": 0, + "comment": 0, + "docstring": 0, + "empty": 0, + "total": 0 + }, + "dependencies": { + "vclibpy.datamodels": [ + "vclibpy.utils.automation", + "vclibpy.components.heat_exchangers.heat_exchanger", + "vclibpy.media.states", + "vclibpy.components.compressors.constant_effectivness", + "vclibpy.flowsheets.base", + "vclibpy", + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "vclibpy.components.compressors.rotary", + "vclibpy.flowsheets.standard", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.components.compressors.ten_coefficient", + "vclibpy.components.compressors.compressor", + "vclibpy.components.heat_exchangers.moving_boundary_ntu" + ], + "numpy": [ + "vclibpy.utils.automation", + "vclibpy.flowsheets.base", + "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall", + "vclibpy.media.media", + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "vclibpy.flowsheets.vapor_injection_economizer", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.components.compressors.ten_coefficient", + "vclibpy.components.heat_exchangers.ntu", + "vclibpy.utils.plotting", + "vclibpy.components.heat_exchangers.moving_boundary_ntu" + ], + "vclibpy.flowsheets.vapor_injection": [ + "vclibpy.flowsheets.vapor_injection_phase_separator", + "vclibpy.flowsheets.vapor_injection_economizer" + ], + "vclibpy.components.heat_exchangers.economizer": [ + "vclibpy.flowsheets.vapor_injection_economizer" + ], + "vclibpy.components.phase_separator": [ + "vclibpy.flowsheets.vapor_injection_phase_separator" + ], + "vclibpy.flowsheets.base": [ + "vclibpy.flowsheets" + ], + "vclibpy.flowsheets.standard": [ + "vclibpy.flowsheets" + ], + "vclibpy.flowsheets.vapor_injection_economizer": [ + "vclibpy.flowsheets" + ], + "vclibpy.flowsheets.vapor_injection_phase_separator": [ + "vclibpy.flowsheets" + ], + "matplotlib.pyplot": [ + "vclibpy.utils.plotting", + "vclibpy.flowsheets.base" + ], + "vclibpy.media": [ + "vclibpy.components.phase_separator", + "vclibpy.components.heat_exchangers.heat_exchanger", + "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "vclibpy.flowsheets.base", + "vclibpy.utils.ten_coefficient_compressor_reqression", + "vclibpy.utils.plotting", + "vclibpy.media.ref_prop", + "vclibpy.components.heat_exchangers.economizer", + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "vclibpy.components.heat_exchangers.heat_transfer.constant", + "vclibpy.components.component", + "vclibpy.components.heat_exchangers.heat_transfer.wall", + "vclibpy.media.media", + "vclibpy.components.heat_exchangers.moving_boundary_ntu" + ], + "vclibpy": [ + "vclibpy.utils.ten_coefficient_compressor_reqression", + "vclibpy.utils.nominal_design", + "vclibpy.flowsheets.base" + ], + "vclibpy.components.heat_exchangers": [ + "vclibpy.flowsheets.base" + ], + "vclibpy.components.component": [ + "vclibpy.components.phase_separator", + "vclibpy.components.heat_exchangers.heat_exchanger", + "vclibpy.flowsheets.base", + "vclibpy.components.expansion_valves.expansion_valve", + "vclibpy.components.compressors.compressor" + ], + "vclibpy.utils.plotting": [ + "vclibpy.flowsheets.base" + ], + "vclibpy.flowsheets": [ + "vclibpy.utils.automation", + "vclibpy.flowsheets.standard", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.utils.nominal_design" + ], + "vclibpy.components.compressors": [ + "vclibpy.utils.ten_coefficient_compressor_reqression", + "vclibpy.flowsheets.standard", + "vclibpy.flowsheets.vapor_injection" + ], + "vclibpy.components.expansion_valves": [ + "vclibpy.flowsheets.standard", + "vclibpy.flowsheets.vapor_injection", + "vclibpy.components.expansion_valves.bernoulli" + ], + "pandas": [ + "vclibpy.utils.automation", + "vclibpy.utils.ten_coefficient_compressor_reqression", + "vclibpy.utils.sdf_", + "vclibpy.components.compressors.ten_coefficient", + "vclibpy.utils.printing" + ], + "sdf": [ + "vclibpy.utils.sdf_", + "vclibpy.utils.plotting" + ], + "vclibpy.utils.automation": [ + "vclibpy.utils" + ], + "vclibpy.utils.sdf_": [ + "vclibpy.utils" + ], + "vclibpy.utils": [ + "vclibpy.utils.automation" + ], + "vclibpy.media.states": [ + "vclibpy.media", + "vclibpy.media.cool_prop" + ], + "vclibpy.media.media": [ + "vclibpy.media", + "vclibpy.media.cool_prop" + ], + "vclibpy.media.cool_prop": [ + "vclibpy.media" + ], + "vclibpy.media.ref_prop": [ + "vclibpy.media" + ], + "ctREFPROP.ctREFPROP": [ + "vclibpy.media.ref_prop" + ], + "CoolProp.CoolProp": [ + "vclibpy.media.cool_prop" + ], + "vclibpy.components.compressors.compressor": [ + "vclibpy.components.compressors.constant_effectivness", + "vclibpy.components.compressors.ten_coefficient", + "vclibpy.components.compressors.rotary", + "vclibpy.components.compressors" + ], + "vclibpy.components.compressors.rotary": [ + "vclibpy.components.compressors" + ], + "vclibpy.components.compressors.ten_coefficient": [ + "vclibpy.components.compressors" + ], + "vclibpy.components.compressors.constant_effectivness": [ + "vclibpy.components.compressors" + ], + "vclibpy.components.heat_exchangers.heat_exchanger": [ + "vclibpy.components.heat_exchangers", + "vclibpy.components.heat_exchangers.ntu" + ], + "vclibpy.components.heat_exchangers.moving_boundary_ntu": [ + "vclibpy.components.heat_exchangers" + ], + "vclibpy.components.heat_exchangers.ntu": [ + "vclibpy.components.heat_exchangers.economizer", + "vclibpy.components.heat_exchangers.moving_boundary_ntu" + ], + "vclibpy.components.heat_exchangers.heat_transfer.heat_transfer": [ + "vclibpy.components.heat_exchangers.heat_transfer", + "vclibpy.components.heat_exchangers.heat_exchanger", + "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall", + "vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall", + "vclibpy.components.heat_exchangers.heat_transfer.wall" + ], + "vclibpy.components.heat_exchangers.heat_transfer.constant": [ + "vclibpy.components.heat_exchangers.heat_transfer" + ], + "vclibpy.components.heat_exchangers.heat_transfer.wall": [ + "vclibpy.components.heat_exchangers.heat_transfer" + ], + "vclibpy.components.heat_exchangers.heat_transfer.air_to_wall": [ + "vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall" + ], + "vclibpy.components.expansion_valves.expansion_valve": [ + "vclibpy.components.expansion_valves" + ], + "vclibpy.components.expansion_valves.bernoulli": [ + "vclibpy.components.expansion_valves" + ] + }, + "duplicated_lines": { + "nb_duplicated_lines": 0, + "percent_duplicated_lines": 0.0 + }, + "node_count": { + "function": 21, + "klass": 40, + "method": 219, + "module": 43 + }, + "undocumented": { + "function": 0, + "klass": 0, + "method": 8, + "module": 27 + }, + "convention": 444, + "error": 2, + "fatal": 0, + "info": 21, + "refactor": 77, + "statement": 2220, + "warning": 43, + "global_note": 7.414414414414415, + "nb_duplicated_lines": 0, + "percent_duplicated_lines": 0.0 + } +} diff --git a/docs/0.1.1/pylint/pylint.svg b/docs/0.1.1/pylint/pylint.svg new file mode 100644 index 0000000..0e96335 --- /dev/null +++ b/docs/0.1.1/pylint/pylint.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + pylint + pylint + + + 7.41 + 7.41 + + diff --git a/docs/0.1.1/pylint/pylint.txt b/docs/0.1.1/pylint/pylint.txt new file mode 100644 index 0000000..7f7a847 --- /dev/null +++ b/docs/0.1.1/pylint/pylint.txt @@ -0,0 +1,632 @@ +************* Module vclibpy.datamodels +vclibpy/datamodels.py:65:19: E1101: Super of 'VariableContainer' has no '__getattr__' member (no-member) +vclibpy/datamodels.py:166:4: R0913: Too many arguments (9/5) (too-many-arguments) +************* Module vclibpy.flowsheets.vapor_injection_economizer +vclibpy/flowsheets/vapor_injection_economizer.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/flowsheets/vapor_injection_economizer.py:46:4: R0914: Too many local variables (20/15) (too-many-locals) +vclibpy/flowsheets/vapor_injection_economizer.py:85:8: C0103: Variable name "dT_secondary" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/vapor_injection_economizer.py:106:12: C0103: Variable name "Q_flow_goal" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/vapor_injection_economizer.py:114:12: C0103: Variable name "Q_flow" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/vapor_injection_economizer.py:114:20: W0612: Unused variable 'k' (unused-variable) +************* Module vclibpy.flowsheets.vapor_injection_phase_separator +vclibpy/flowsheets/vapor_injection_phase_separator.py:1:0: C0114: Missing module docstring (missing-module-docstring) +************* Module vclibpy.flowsheets +vclibpy/flowsheets/__init__.py:1:0: C0114: Missing module docstring (missing-module-docstring) +************* Module vclibpy.flowsheets.base +vclibpy/flowsheets/base.py:218:0: C0301: Line too long (118/100) (line-too-long) +vclibpy/flowsheets/base.py:291:0: C0325: Unnecessary parens after '=' keyword (superfluous-parens) +vclibpy/flowsheets/base.py:325:0: C0301: Line too long (112/100) (line-too-long) +vclibpy/flowsheets/base.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/flowsheets/base.py:47:4: C0116: Missing function or method docstring (missing-function-docstring) +vclibpy/flowsheets/base.py:67:4: C0116: Missing function or method docstring (missing-function-docstring) +vclibpy/flowsheets/base.py:72:4: C0116: Missing function or method docstring (missing-function-docstring) +vclibpy/flowsheets/base.py:75:4: R0914: Too many local variables (45/15) (too-many-locals) +vclibpy/flowsheets/base.py:135:8: C0103: Variable name "err_dT_min" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:153:8: C0103: Variable name "T_1_start" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:154:8: C0103: Variable name "T_3_start" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:221:23: C0103: Variable name "dT_min_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:224:12: R1724: Unnecessary "else" after "continue", remove the "else" and de-indent the code inside it (no-else-continue) +vclibpy/flowsheets/base.py:228:16: R1724: Unnecessary "elif" after "continue", remove the leading "el" from "elif" (no-else-continue) +vclibpy/flowsheets/base.py:237:23: C0103: Variable name "dT_min_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:238:12: R1724: Unnecessary "else" after "continue", remove the "else" and de-indent the code inside it (no-else-continue) +vclibpy/flowsheets/base.py:242:16: R1724: Unnecessary "elif" after "continue", remove the leading "el" from "elif" (no-else-continue) +vclibpy/flowsheets/base.py:278:8: C0103: Variable name "Q_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:279:8: C0103: Variable name "Q_con_outer" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:280:8: C0103: Variable name "Q_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:281:8: C0103: Variable name "Q_eva_outer" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:284:8: C0103: Variable name "P_el" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:285:8: C0103: Variable name "T_con_out" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:288:8: C0103: Variable name "COP_inner" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:289:8: C0103: Variable name "COP_outer" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:291:8: C0103: Variable name "COP_carnot" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:75:4: R0912: Too many branches (28/12) (too-many-branches) +vclibpy/flowsheets/base.py:75:4: R0915: Too many statements (132/50) (too-many-statements) +vclibpy/flowsheets/base.py:75:4: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements) +vclibpy/flowsheets/base.py:351:8: C0103: Variable name "T_1" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:366:8: C0103: Variable name "T_3" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:375:13: C0103: Variable name "ax" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:385:46: C0103: Argument name "ax" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:386:8: C0103: Variable name "Q_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:387:8: C0103: Variable name "Q_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:389:8: C0103: Variable name "delta_H_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:393:8: C0103: Variable name "delta_H_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/base.py:5:0: C0411: standard import "from abc import abstractmethod" should be placed before "import numpy as np" (wrong-import-order) +************* Module vclibpy.flowsheets.vapor_injection +vclibpy/flowsheets/vapor_injection.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/flowsheets/vapor_injection.py:84:8: C0103: Variable name "h_1_VI_mixed" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/vapor_injection.py:148:8: C0103: Variable name "P_el_low" doesn't conform to snake_case naming style (invalid-name) +vclibpy/flowsheets/vapor_injection.py:151:8: C0103: Variable name "P_el_high" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.flowsheets.standard +vclibpy/flowsheets/standard.py:68:0: C0301: Line too long (111/100) (line-too-long) +vclibpy/flowsheets/standard.py:1:0: C0114: Missing module docstring (missing-module-docstring) +************* Module vclibpy.utils.sdf_ +vclibpy/utils/sdf_.py:63:0: C0301: Line too long (108/100) (line-too-long) +vclibpy/utils/sdf_.py:147:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/utils/sdf_.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/utils/sdf_.py:8:0: R0914: Too many local variables (20/15) (too-many-locals) +vclibpy/utils/sdf_.py:129:12: C0103: Variable name "df" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/sdf_.py:130:12: C0103: Variable name "df" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/sdf_.py:147:23: R1721: Unnecessary use of a comprehension, use list(enumerate(scale.data)) instead. (unnecessary-comprehension) +vclibpy/utils/sdf_.py:150:18: R1728: Consider using a generator instead 'tuple(scale[0] for scale in scales)' (consider-using-generator) +vclibpy/utils/sdf_.py:154:14: R1721: Unnecessary use of a comprehension, use dict(zip(scale_names, values)) instead. (unnecessary-comprehension) +************* Module vclibpy.utils.nominal_design +vclibpy/utils/nominal_design.py:11:29: C0303: Trailing whitespace (trailing-whitespace) +vclibpy/utils/nominal_design.py:12:23: C0303: Trailing whitespace (trailing-whitespace) +vclibpy/utils/nominal_design.py:72:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/utils/nominal_design.py:74:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/utils/nominal_design.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/utils/nominal_design.py:14:8: C0103: Argument name "dT_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/nominal_design.py:15:8: C0103: Argument name "dT_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/nominal_design.py:10:0: R0914: Too many local variables (19/15) (too-many-locals) +vclibpy/utils/nominal_design.py:43:4: C0103: Variable name "t0" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/nominal_design.py:69:21: W0212: Access to a protected member _secondary_cp of a client class (protected-access) +vclibpy/utils/nominal_design.py:70:21: W0212: Access to a protected member _secondary_cp of a client class (protected-access) +************* Module vclibpy.utils.ten_coefficient_compressor_reqression +vclibpy/utils/ten_coefficient_compressor_reqression.py:103:25: W0511: TODO: Enable calculation of get_lambda_h etc. with p2 only (fixme) +vclibpy/utils/ten_coefficient_compressor_reqression.py:132:5: W0511: TODO: Revert once this feature is in pandas. (fixme) +vclibpy/utils/ten_coefficient_compressor_reqression.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/utils/ten_coefficient_compressor_reqression.py:13:4: W0707: Consider explicitly re-raising using 'raise ImportError('You have to install xlsxwriter and sklearn to use this regression tool') from err' (raise-missing-from) +vclibpy/utils/ten_coefficient_compressor_reqression.py:19:8: C0103: Argument name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:19:28: C0103: Argument name "T_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:20:8: C0103: Argument name "T_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:20:21: C0103: Argument name "T_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:20:46: C0103: Argument name "V_h" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:17:0: R0913: Too many arguments (13/5) (too-many-arguments) +vclibpy/utils/ten_coefficient_compressor_reqression.py:17:0: R0914: Too many local variables (42/15) (too-many-locals) +vclibpy/utils/ten_coefficient_compressor_reqression.py:87:8: C0103: Variable name "m" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:89:12: C0103: Variable name "T_eva_list" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:90:12: C0103: Variable name "T_con_list" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:93:12: C0200: Consider using enumerate instead of iterating with range and len (consider-using-enumerate) +vclibpy/utils/ten_coefficient_compressor_reqression.py:95:16: C0200: Consider using enumerate instead of iterating with range and len (consider-using-enumerate) +vclibpy/utils/ten_coefficient_compressor_reqression.py:97:24: C0103: Variable name "p1" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:100:24: C0103: Variable name "p2" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:119:12: C0103: Variable name "df" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:137:75: C0103: Variable name "f" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:87:4: R1702: Too many nested blocks (6/5) (too-many-nested-blocks) +vclibpy/utils/ten_coefficient_compressor_reqression.py:139:12: C0103: Variable name "r" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:140:16: C0103: Variable name "c" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:145:33: C0103: Argument name "df" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:168:4: C0103: Variable name "z" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/ten_coefficient_compressor_reqression.py:172:4: C0103: Variable name "X" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.utils.printing +vclibpy/utils/printing.py:31:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/utils/printing.py:22:15: C0201: Consider iterating the dictionary directly instead of calling .keys() (consider-iterating-dictionary) +************* Module vclibpy.utils +vclibpy/utils/__init__.py:1:0: C0114: Missing module docstring (missing-module-docstring) +************* Module vclibpy.utils.plotting +vclibpy/utils/plotting.py:90:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/utils/plotting.py:232:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/utils/plotting.py:264:0: C0301: Line too long (116/100) (line-too-long) +vclibpy/utils/plotting.py:270:0: C0301: Line too long (111/100) (line-too-long) +vclibpy/utils/plotting.py:293:0: C0301: Line too long (129/100) (line-too-long) +vclibpy/utils/plotting.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/utils/plotting.py:39:4: C0103: Variable name "h_T" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:44:9: C0103: Variable name "ax" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:11:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements) +vclibpy/utils/plotting.py:77:0: R0913: Too many arguments (8/5) (too-many-arguments) +vclibpy/utils/plotting.py:77:0: R0914: Too many local variables (53/15) (too-many-locals) +vclibpy/utils/plotting.py:142:4: C0103: Variable name "plot_4D" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:144:8: C0103: Variable name "plot_4D" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:189:12: C0103: Variable name "nd" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:189:16: C0103: Variable name "fd" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:189:20: C0103: Variable name "sd" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:189:34: C0103: Variable name "td" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:191:16: C0103: Variable name "ds" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:193:20: C0103: Variable name "nd" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:195:20: C0103: Variable name "fd" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:197:20: C0103: Variable name "sd" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:204:20: C0103: Variable name "td" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:224:16: C0103: Variable name "ax" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:234:16: C0415: Import outside toplevel (itertools) (import-outside-toplevel) +vclibpy/utils/plotting.py:235:39: R1721: Unnecessary use of a comprehension, use list(itertools.product(*inp)) instead. (unnecessary-comprehension) +vclibpy/utils/plotting.py:245:28: C0103: Variable name "Z" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:182:4: R1702: Too many nested blocks (7/5) (too-many-nested-blocks) +vclibpy/utils/plotting.py:251:28: C0103: Variable name "Z" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:257:28: C0103: Variable name "Z" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:182:4: R1702: Too many nested blocks (7/5) (too-many-nested-blocks) +vclibpy/utils/plotting.py:266:28: C0103: Variable name "ax" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:269:28: C0103: Variable name "X" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:269:31: C0103: Variable name "Y" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/plotting.py:182:4: R1702: Too many nested blocks (6/5) (too-many-nested-blocks) +vclibpy/utils/plotting.py:77:0: R0912: Too many branches (50/12) (too-many-branches) +vclibpy/utils/plotting.py:77:0: R0915: Too many statements (133/50) (too-many-statements) +vclibpy/utils/plotting.py:291:19: C0103: Argument name "ax" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.utils.automation +vclibpy/utils/automation.py:52:0: C0301: Line too long (119/100) (line-too-long) +vclibpy/utils/automation.py:101:0: C0301: Line too long (123/100) (line-too-long) +vclibpy/utils/automation.py:145:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/utils/automation.py:36:8: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +vclibpy/utils/automation.py:40:15: W0718: Catching too general exception Exception (broad-exception-caught) +vclibpy/utils/automation.py:40:8: C0103: Variable name "e" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:42:12: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +vclibpy/utils/automation.py:50:4: C0103: Variable name "df" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:57:8: C0103: Argument name "T_eva_in_ar" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:58:8: C0103: Argument name "T_con_in_ar" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:63:8: C0103: Argument name "dT_eva_superheating" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:64:8: C0103: Argument name "dT_con_subcooling" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:55:0: R0913: Too many arguments (11/5) (too-many-arguments) +vclibpy/utils/automation.py:55:0: R0914: Too many local variables (44/15) (too-many-locals) +vclibpy/utils/automation.py:107:8: C0103: Variable name "i_T_eva_in" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:107:20: C0103: Variable name "T_eva_in" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:109:16: C0103: Variable name "i_T_con_in" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:109:28: C0103: Variable name "T_con_in" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:127:12: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +vclibpy/utils/automation.py:133:12: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +vclibpy/utils/automation.py:145:34: R1721: Unnecessary use of a comprehension, use dict(fs_state.get_variables().items()) instead. (unnecessary-comprehension) +vclibpy/utils/automation.py:159:13: C0103: Variable name "i_T_con_in" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:159:25: C0103: Variable name "i_T_eva_in" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:55:0: R0912: Too many branches (16/12) (too-many-branches) +vclibpy/utils/automation.py:55:0: R0915: Too many statements (51/50) (too-many-statements) +vclibpy/utils/automation.py:123:15: R1732: Consider using 'with' for resource-allocating operations (consider-using-with) +vclibpy/utils/automation.py:215:11: W0718: Catching too general exception Exception (broad-exception-caught) +vclibpy/utils/automation.py:215:4: C0103: Variable name "e" doesn't conform to snake_case naming style (invalid-name) +vclibpy/utils/automation.py:216:8: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +************* Module vclibpy.media.states +vclibpy/media/states.py:59:0: C0301: Line too long (119/100) (line-too-long) +vclibpy/media/states.py:173:0: C0301: Line too long (102/100) (line-too-long) +vclibpy/media/states.py:174:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/media/states.py:175:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/media/states.py:177:0: C0301: Line too long (112/100) (line-too-long) +vclibpy/media/states.py:178:0: C0301: Line too long (113/100) (line-too-long) +vclibpy/media/states.py:179:0: C0301: Line too long (109/100) (line-too-long) +vclibpy/media/states.py:180:0: C0301: Line too long (101/100) (line-too-long) +vclibpy/media/states.py:13:0: R0902: Too many instance attributes (8/7) (too-many-instance-attributes) +vclibpy/media/states.py:36:4: R0913: Too many arguments (9/5) (too-many-arguments) +vclibpy/media/states.py:102:0: R0902: Too many instance attributes (10/7) (too-many-instance-attributes) +vclibpy/media/states.py:128:17: C0103: Argument name "pr" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/states.py:124:4: R0913: Too many arguments (11/5) (too-many-arguments) +************* Module vclibpy.media +vclibpy/media/__init__.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/media/__init__.py:27:4: W0603: Using the global statement (global-statement) +vclibpy/media/__init__.py:38:4: W0602: Using global for 'USED_MED_PROP' but no assignment is done (global-variable-not-assigned) +************* Module vclibpy.media.media +vclibpy/media/media.py:10:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/media/media.py:53:0: C0301: Line too long (111/100) (line-too-long) +vclibpy/media/media.py:58:0: C0301: Line too long (118/100) (line-too-long) +vclibpy/media/media.py:139:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/media/media.py:140:0: C0301: Line too long (113/100) (line-too-long) +vclibpy/media/media.py:141:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/media/media.py:145:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/media/media.py:160:0: C0301: Line too long (108/100) (line-too-long) +vclibpy/media/media.py:161:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/media/media.py:206:0: C0301: Line too long (115/100) (line-too-long) +vclibpy/media/media.py:210:0: C0301: Line too long (118/100) (line-too-long) +vclibpy/media/media.py:218:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/media/media.py:221:0: C0301: Line too long (116/100) (line-too-long) +vclibpy/media/media.py:222:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/media/media.py:223:0: C0301: Line too long (108/100) (line-too-long) +vclibpy/media/media.py:50:36: W0613: Unused argument 'var1' (unused-argument) +vclibpy/media/media.py:50:49: W0613: Unused argument 'var2' (unused-argument) +vclibpy/media/media.py:102:8: W0107: Unnecessary pass statement (unnecessary-pass) +vclibpy/media/media.py:114:8: W0107: Unnecessary pass statement (unnecessary-pass) +vclibpy/media/media.py:124:8: W0107: Unnecessary pass statement (unnecessary-pass) +vclibpy/media/media.py:133:8: W0107: Unnecessary pass statement (unnecessary-pass) +vclibpy/media/media.py:227:4: C0103: Variable name "q0" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/media.py:227:8: C0103: Variable name "q1" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.media.ref_prop +vclibpy/media/ref_prop.py:10:0: C0301: Line too long (120/100) (line-too-long) +vclibpy/media/ref_prop.py:35:0: C0301: Line too long (109/100) (line-too-long) +vclibpy/media/ref_prop.py:66:0: C0301: Line too long (113/100) (line-too-long) +vclibpy/media/ref_prop.py:67:0: C0301: Line too long (106/100) (line-too-long) +vclibpy/media/ref_prop.py:73:0: C0301: Line too long (120/100) (line-too-long) +vclibpy/media/ref_prop.py:74:0: C0301: Line too long (109/100) (line-too-long) +vclibpy/media/ref_prop.py:115:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/media/ref_prop.py:117:0: C0301: Line too long (117/100) (line-too-long) +vclibpy/media/ref_prop.py:209:0: C0301: Line too long (116/100) (line-too-long) +vclibpy/media/ref_prop.py:271:0: C0301: Line too long (111/100) (line-too-long) +vclibpy/media/ref_prop.py:274:0: C0301: Line too long (111/100) (line-too-long) +vclibpy/media/ref_prop.py:279:0: C0301: Line too long (116/100) (line-too-long) +vclibpy/media/ref_prop.py:282:0: C0301: Line too long (119/100) (line-too-long) +vclibpy/media/ref_prop.py:303:0: C0301: Line too long (111/100) (line-too-long) +vclibpy/media/ref_prop.py:324:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/media/ref_prop.py:336:0: C0301: Line too long (144/100) (line-too-long) +vclibpy/media/ref_prop.py:339:0: C0301: Line too long (116/100) (line-too-long) +vclibpy/media/ref_prop.py:406:0: C0301: Line too long (112/100) (line-too-long) +vclibpy/media/ref_prop.py:407:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/media/ref_prop.py:408:0: C0301: Line too long (117/100) (line-too-long) +vclibpy/media/ref_prop.py:411:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/media/ref_prop.py:412:0: C0301: Line too long (115/100) (line-too-long) +vclibpy/media/ref_prop.py:415:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/media/ref_prop.py:425:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/media/ref_prop.py:478:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/media/ref_prop.py:479:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/media/ref_prop.py:490:0: C0301: Line too long (120/100) (line-too-long) +vclibpy/media/ref_prop.py:510:0: C0301: Line too long (120/100) (line-too-long) +vclibpy/media/ref_prop.py:542:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/media/ref_prop.py:545:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/media/ref_prop.py:549:0: C0301: Line too long (111/100) (line-too-long) +vclibpy/media/ref_prop.py:552:0: C0301: Line too long (113/100) (line-too-long) +vclibpy/media/ref_prop.py:591:0: C0301: Line too long (118/100) (line-too-long) +vclibpy/media/ref_prop.py:597:0: C0301: Line too long (112/100) (line-too-long) +vclibpy/media/ref_prop.py:675:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/media/ref_prop.py:716:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/media/ref_prop.py:824:0: C0301: Line too long (118/100) (line-too-long) +vclibpy/media/ref_prop.py:848:0: C0301: Line too long (117/100) (line-too-long) +vclibpy/media/ref_prop.py:895:0: C0301: Line too long (120/100) (line-too-long) +vclibpy/media/ref_prop.py:927:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/media/ref_prop.py:999:0: C0301: Line too long (114/100) (line-too-long) +vclibpy/media/ref_prop.py:1061:0: C0301: Line too long (114/100) (line-too-long) +vclibpy/media/ref_prop.py:1071:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/media/ref_prop.py:1098:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/media/ref_prop.py:1165:0: C0301: Line too long (108/100) (line-too-long) +vclibpy/media/ref_prop.py:1:0: C0302: Too many lines in module (1231/1000) (too-many-lines) +vclibpy/media/ref_prop.py:250:9: W0511: TODO (fixme) +vclibpy/media/ref_prop.py:358:42: W0511: TODO: in general not necessary, decreases performance (fixme) +vclibpy/media/ref_prop.py:528:17: W0511: TODO: Ending is not necessary to create mixtures.... (fixme) +vclibpy/media/ref_prop.py:180:8: C0103: Attribute name "rp" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:27:0: R0902: Too many instance attributes (15/7) (too-many-instance-attributes) +vclibpy/media/ref_prop.py:139:4: R0913: Too many arguments (9/5) (too-many-arguments) +vclibpy/media/ref_prop.py:210:12: C0415: Import outside toplevel (_ctypes) (import-outside-toplevel) +vclibpy/media/ref_prop.py:211:12: C0415: Import outside toplevel (sys) (import-outside-toplevel) +vclibpy/media/ref_prop.py:212:22: W0212: Access to a protected member _handle of a client class (protected-access) +vclibpy/media/ref_prop.py:214:16: E1101: Module '_ctypes' has no 'FreeLibrary' member (no-member) +vclibpy/media/ref_prop.py:257:30: C0103: Argument name "T_val" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:255:4: R0913: Too many arguments (6/5) (too-many-arguments) +vclibpy/media/ref_prop.py:303:29: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:310:4: R0913: Too many arguments (9/5) (too-many-arguments) +vclibpy/media/ref_prop.py:370:37: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:406:34: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:411:36: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:444:16: R1724: Unnecessary "else" after "continue", remove the "else" and de-indent the code inside it (no-else-continue) +vclibpy/media/ref_prop.py:414:4: R0912: Too many branches (13/12) (too-many-branches) +vclibpy/media/ref_prop.py:456:29: C0103: Argument name "z" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:496:37: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:540:16: R1720: Unnecessary "else" after "raise", remove the "else" and de-indent the code inside it (no-else-raise) +vclibpy/media/ref_prop.py:542:24: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:545:24: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:549:24: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:552:24: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:533:12: W0612: Unused variable 'setref' (unused-variable) +vclibpy/media/ref_prop.py:590:4: R0914: Too many local variables (19/15) (too-many-locals) +vclibpy/media/ref_prop.py:590:4: R0912: Too many branches (29/12) (too-many-branches) +vclibpy/media/ref_prop.py:590:4: R0915: Too many statements (123/50) (too-many-statements) +vclibpy/media/ref_prop.py:873:29: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:890:17: W1514: Using open without explicitly specifying an encoding (unspecified-encoding) +vclibpy/media/ref_prop.py:892:33: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:895:29: C0209: Formatting a regular string which could be a f-string (consider-using-f-string) +vclibpy/media/ref_prop.py:937:12: C0103: Variable name "z" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:940:12: C0103: Variable name "z" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:983:12: C0103: Variable name "pc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:984:12: C0103: Variable name "dc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:988:12: C0103: Variable name "pc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:989:12: C0103: Variable name "dc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:1051:8: R1731: Consider using 'gwp = max(gwp, 0)' instead of unnecessary if block (consider-using-max-builtin) +vclibpy/media/ref_prop.py:1124:14: W3301: Do not use nested call of 'max'; it's possible to do 'max(tmp.Output, 0)' instead (nested-min-max) +vclibpy/media/ref_prop.py:1126:8: R1731: Consider using 'odp = max(odp, 0)' instead of unnecessary if block (consider-using-max-builtin) +vclibpy/media/ref_prop.py:1147:35: C0103: Argument name "T_sat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/ref_prop.py:27:0: R0904: Too many public methods (25/20) (too-many-public-methods) +************* Module vclibpy.media.cool_prop +vclibpy/media/cool_prop.py:27:15: I1101: Module 'CoolProp.CoolProp' has no 'PT_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:28:15: I1101: Module 'CoolProp.CoolProp' has no 'QT_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:29:15: I1101: Module 'CoolProp.CoolProp' has no 'PSmass_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:30:15: I1101: Module 'CoolProp.CoolProp' has no 'HmassP_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:31:15: I1101: Module 'CoolProp.CoolProp' has no 'PQ_INPUTS' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:38:44: I1101: Module 'CoolProp.CoolProp' has no 'AbstractState' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:48:16: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:50:16: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:52:16: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:54:16: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:56:16: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:58:16: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:60:16: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:88:12: C0103: Variable name "pr" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/cool_prop.py:88:17: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:90:17: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:92:17: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:94:18: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:96:22: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:132:13: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:133:8: C0103: Variable name "pc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/cool_prop.py:133:13: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +vclibpy/media/cool_prop.py:134:8: C0103: Variable name "dc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/media/cool_prop.py:134:13: I1101: Module 'CoolProp.CoolProp' has no 'PropsSI' member, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. (c-extension-no-member) +************* Module vclibpy.components.component +vclibpy/components/component.py:11:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/components/component.py:12:0: C0301: Line too long (101/100) (line-too-long) +vclibpy/components/component.py:39:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/components/component.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/component.py:43:8: W0107: Unnecessary pass statement (unnecessary-pass) +vclibpy/components/component.py:55:8: W0107: Unnecessary pass statement (unnecessary-pass) +************* Module vclibpy.components.compressors.ten_coefficient +vclibpy/components/compressors/ten_coefficient.py:25:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:40:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:52:0: C0301: Line too long (106/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:110:0: C0301: Line too long (119/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:134:0: C0301: Line too long (105/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:140:0: C0301: Line too long (112/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:141:0: C0301: Line too long (117/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:143:0: C0301: Line too long (117/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:153:0: C0301: Line too long (101/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:154:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:158:0: C0301: Line too long (106/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:168:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:204:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:235:0: C0301: Line too long (113/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:279:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:311:0: C0301: Line too long (106/100) (line-too-long) +vclibpy/components/compressors/ten_coefficient.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/compressors/ten_coefficient.py:10:26: C0103: Argument name "T_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:10:33: C0103: Argument name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:23:4: C0103: Variable name "z" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:79:8: C0103: Attribute name "md" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:93:28: C0103: Argument name "T_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:93:35: C0103: Argument name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:170:8: C0103: Attribute name "T_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:171:8: C0103: Attribute name "T_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:123:0: R0902: Too many instance attributes (8/7) (too-many-instance-attributes) +vclibpy/components/compressors/ten_coefficient.py:168:4: R0913: Too many arguments (8/5) (too-many-arguments) +vclibpy/components/compressors/ten_coefficient.py:191:8: C0103: Variable name "T_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:192:8: C0103: Variable name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:222:8: C0103: Variable name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:226:8: C0103: Variable name "h3" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:230:12: C0103: Variable name "h2" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:232:12: C0103: Variable name "h2" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:255:8: C0103: Variable name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:259:8: C0103: Variable name "h3" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:260:8: C0103: Variable name "h2" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:276:8: C0103: Variable name "T_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:277:8: C0103: Variable name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:335:8: C0103: Variable name "T_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:336:8: C0103: Variable name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:350:8: C0103: Variable name "T_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:351:8: C0103: Variable name "T_con" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:365:8: C0103: Variable name "T_eva" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/ten_coefficient.py:366:8: C0103: Variable name "T_con" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.components.compressors.compressor +vclibpy/components/compressors/compressor.py:40:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/components/compressors/compressor.py:152:0: C0301: Line too long (114/100) (line-too-long) +vclibpy/components/compressors/compressor.py:153:0: C0301: Line too long (113/100) (line-too-long) +vclibpy/components/compressors/compressor.py:158:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/components/compressors/compressor.py:52:8: C0103: Attribute name "N_max" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/compressor.py:53:8: C0103: Attribute name "V_h" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/compressor.py:145:8: C0103: Variable name "V_flow_ref" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/compressor.py:168:8: C0103: Variable name "P_t" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/compressor.py:171:8: C0103: Variable name "P_el" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.components.compressors.rotary +vclibpy/components/compressors/rotary.py:9:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/components/compressors/rotary.py:39:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/components/compressors/rotary.py:77:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/components/compressors/rotary.py:107:0: C0301: Line too long (107/100) (line-too-long) +vclibpy/components/compressors/rotary.py:124:0: C0301: Line too long (116/100) (line-too-long) +vclibpy/components/compressors/rotary.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/compressors/rotary.py:28:4: R0914: Too many local variables (18/15) (too-many-locals) +vclibpy/components/compressors/rotary.py:41:8: C0103: Variable name "T_1" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/rotary.py:48:8: C0103: Variable name "sigma_T_1" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/rotary.py:49:8: C0103: Variable name "T_1_ave" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/rotary.py:56:8: C0103: Variable name "pi" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/rotary.py:84:8: C0103: Variable name "pi" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/compressors/rotary.py:95:4: R0914: Too many local variables (17/15) (too-many-locals) +vclibpy/components/compressors/rotary.py:120:8: C0103: Variable name "pi" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.components.compressors +vclibpy/components/compressors/__init__.py:1:0: C0114: Missing module docstring (missing-module-docstring) +************* Module vclibpy.components.compressors.constant_effectivness +vclibpy/components/compressors/constant_effectivness.py:9:0: C0301: Line too long (114/100) (line-too-long) +vclibpy/components/compressors/constant_effectivness.py:25:0: C0301: Line too long (117/100) (line-too-long) +vclibpy/components/compressors/constant_effectivness.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/compressors/constant_effectivness.py:40:4: R0913: Too many arguments (6/5) (too-many-arguments) +************* Module vclibpy.components.heat_exchangers +vclibpy/components/heat_exchangers/__init__.py:1:0: C0114: Missing module docstring (missing-module-docstring) +************* Module vclibpy.components.heat_exchangers.moving_boundary_ntu +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:19:0: C0301: Line too long (102/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:159:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:161:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:199:0: C0301: Line too long (101/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:204:0: C0301: Line too long (102/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:206:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:225:0: C0301: Line too long (121/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:226:0: C0301: Line too long (120/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:227:0: C0301: Line too long (122/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:289:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:291:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:339:0: C0301: Line too long (101/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:344:0: C0301: Line too long (102/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:346:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:363:0: C0301: Line too long (122/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:364:0: C0301: Line too long (121/100) (line-too-long) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:41:8: C0103: Variable name "Q_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:44:8: C0103: Variable name "Q_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:47:8: C0103: Variable name "Q_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:52:27: C0103: Argument name "dT_max" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:86:12: C0103: Variable name "NTU" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:89:16: R1723: Unnecessary "else" after "break", remove the "else" and de-indent the code inside it (no-else-break) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:114:4: R0914: Too many local variables (31/15) (too-many-locals) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:136:8: C0103: Variable name "Q_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:136:14: C0103: Variable name "Q_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:136:21: C0103: Variable name "Q_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:146:8: C0103: Variable name "T_mean" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:152:8: C0103: Variable name "T_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:153:8: C0103: Variable name "T_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:154:8: C0103: Variable name "T_out" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:157:8: C0103: Variable name "Q_sc_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:157:18: C0103: Variable name "A_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:165:12: C0103: Variable name "A_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:169:12: C0103: Variable name "A_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:171:12: C0103: Variable name "Q_sc_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:177:8: C0103: Variable name "Q_lat_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:177:19: C0103: Variable name "A_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:188:12: C0103: Variable name "A_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:193:12: C0103: Variable name "A_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:195:12: C0103: Variable name "Q_lat_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:199:12: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:202:8: C0103: Variable name "Q_sh_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:202:18: C0103: Variable name "A_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:210:12: C0103: Variable name "A_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:212:12: C0103: Variable name "Q_sh_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:216:12: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:218:8: C0103: Variable name "Q_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:221:8: C0103: Variable name "dT_min_in" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:222:8: C0103: Variable name "dT_min_out" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:223:8: C0103: Variable name "dT_min_LatSH" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:171:22: W0612: Unused variable 'k_sc' (unused-variable) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:195:23: W0612: Unused variable 'k_lat' (unused-variable) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:212:22: W0612: Unused variable 'k_sh' (unused-variable) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:245:4: R0914: Too many local variables (30/15) (too-many-locals) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:267:8: C0103: Variable name "Q_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:267:14: C0103: Variable name "Q_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:267:21: C0103: Variable name "Q_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:277:8: C0103: Variable name "T_mean" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:282:8: C0103: Variable name "T_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:283:8: C0103: Variable name "T_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:284:8: C0103: Variable name "T_out" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:287:8: C0103: Variable name "Q_sh_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:287:18: C0103: Variable name "A_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:295:16: C0103: Variable name "A_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:301:16: C0103: Variable name "A_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:304:12: C0103: Variable name "A_sh" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:306:12: C0103: Variable name "Q_sh_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:311:12: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:314:8: C0103: Variable name "Q_lat_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:314:19: C0103: Variable name "A_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:326:16: C0103: Variable name "A_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:331:16: C0103: Variable name "A_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:334:12: C0103: Variable name "A_lat" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:335:12: C0103: Variable name "Q_lat_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:339:12: W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:342:8: C0103: Variable name "Q_sc_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:342:18: C0103: Variable name "A_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:350:12: C0103: Variable name "A_sc" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:352:12: C0103: Variable name "Q_sc_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:357:8: C0103: Variable name "Q_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:360:8: C0103: Variable name "dT_min_in" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:361:8: C0103: Variable name "dT_min_out" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:306:22: W0612: Unused variable 'k_sh' (unused-variable) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:335:23: W0612: Unused variable 'k_lat' (unused-variable) +vclibpy/components/heat_exchangers/moving_boundary_ntu.py:352:22: W0612: Unused variable 'k_sc' (unused-variable) +************* Module vclibpy.components.heat_exchangers.economizer +vclibpy/components/heat_exchangers/economizer.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/heat_exchangers/economizer.py:40:4: C0116: Missing function or method docstring (missing-function-docstring) +vclibpy/components/heat_exchangers/economizer.py:48:4: C0116: Missing function or method docstring (missing-function-docstring) +************* Module vclibpy.components.heat_exchangers.heat_exchanger +vclibpy/components/heat_exchangers/heat_exchanger.py:8:0: C0301: Line too long (109/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_exchanger.py:98:0: C0301: Line too long (106/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_exchanger.py:234:0: C0301: Line too long (109/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_exchanger.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/heat_exchangers/heat_exchanger.py:43:8: C0103: Attribute name "A" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_exchanger.py:11:0: R0902: Too many instance attributes (11/7) (too-many-instance-attributes) +vclibpy/components/heat_exchangers/heat_exchanger.py:32:4: R0913: Too many arguments (8/5) (too-many-arguments) +vclibpy/components/heat_exchangers/heat_exchanger.py:181:4: C0116: Missing function or method docstring (missing-function-docstring) +vclibpy/components/heat_exchangers/heat_exchanger.py:190:4: C0116: Missing function or method docstring (missing-function-docstring) +vclibpy/components/heat_exchangers/heat_exchanger.py:204:4: C0116: Missing function or method docstring (missing-function-docstring) +vclibpy/components/heat_exchangers/heat_exchanger.py:204:4: C0103: Method name "calc_secondary_Q_flow" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_exchanger.py:204:36: C0103: Argument name "Q_flow" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_exchanger.py:207:4: C0103: Method name "calc_Q_flow" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.components.heat_exchangers.ntu +vclibpy/components/heat_exchangers/ntu.py:95:0: C0301: Line too long (120/100) (line-too-long) +vclibpy/components/heat_exchangers/ntu.py:133:0: C0301: Line too long (106/100) (line-too-long) +vclibpy/components/heat_exchangers/ntu.py:142:0: C0301: Line too long (118/100) (line-too-long) +vclibpy/components/heat_exchangers/ntu.py:152:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/ntu.py:154:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/components/heat_exchangers/ntu.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/heat_exchangers/ntu.py:67:33: C0103: Argument name "NTU" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/ntu.py:93:4: C0103: Method name "calc_R" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/ntu.py:126:4: C0103: Method name "calc_NTU" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/ntu.py:126:17: C0103: Argument name "A" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/ntu.py:152:4: C0103: Method name "calc_Q_ntu" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/ntu.py:152:25: C0103: Argument name "dT_max" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/ntu.py:152:76: C0103: Argument name "A" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/ntu.py:168:8: C0103: Variable name "NTU" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/ntu.py:172:8: C0103: Variable name "Q_max" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.components.heat_exchangers.heat_transfer.air_to_wall +vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py:36:0: C0301: Line too long (113/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py:24:8: C0103: Attribute name "A_cross" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py:23:23: C0103: Argument name "A_cross" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py:35:8: C0103: Variable name "Re" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py:54:40: C0103: Argument name "Re" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/air_to_wall.py:5:0: C0411: first party import "from vclibpy.media import TransportProperties" should be placed before "from .heat_transfer import HeatTransfer" (wrong-import-order) +************* Module vclibpy.components.heat_exchangers.heat_transfer.pipe_to_wall +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:73:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:81:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:84:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:93:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:51:8: C0103: Variable name "Re" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:59:42: C0103: Argument name "Re" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:74:12: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:59:4: R0912: Too many branches (14/12) (too-many-branches) +vclibpy/components/heat_exchangers/heat_transfer/pipe_to_wall.py:6:0: C0411: first party import "from vclibpy.media import TransportProperties" should be placed before "from .heat_transfer import HeatTransfer, calc_reynolds_pipe" (wrong-import-order) +************* Module vclibpy.components.heat_exchangers.heat_transfer +vclibpy/components/heat_exchangers/heat_transfer/__init__.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/heat_exchangers/heat_transfer/__init__.py:2:0: C0411: first party import "from vclibpy.components.heat_exchangers.heat_transfer import constant" should be placed before "from .heat_transfer import TwoPhaseHeatTransfer, HeatTransfer, calc_reynolds_pipe" (wrong-import-order) +vclibpy/components/heat_exchangers/heat_transfer/__init__.py:3:0: C0411: first party import "from vclibpy.components.heat_exchangers.heat_transfer import wall" should be placed before "from .heat_transfer import TwoPhaseHeatTransfer, HeatTransfer, calc_reynolds_pipe" (wrong-import-order) +************* Module vclibpy.components.heat_exchangers.heat_transfer.constant +vclibpy/components/heat_exchangers/heat_transfer/constant.py:26:0: C0301: Line too long (102/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/constant.py:53:0: C0301: Line too long (106/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/constant.py:21:19: W0613: Unused argument 'transport_properties' (unused-argument) +vclibpy/components/heat_exchangers/heat_transfer/constant.py:21:62: W0613: Unused argument 'm_flow' (unused-argument) +vclibpy/components/heat_exchangers/heat_transfer/constant.py:9:0: R0903: Too few public methods (1/2) (too-few-public-methods) +vclibpy/components/heat_exchangers/heat_transfer/constant.py:48:0: W0613: Unused argument 'kwargs' (unused-argument) +vclibpy/components/heat_exchangers/heat_transfer/constant.py:36:0: R0903: Too few public methods (1/2) (too-few-public-methods) +************* Module vclibpy.components.heat_exchangers.heat_transfer.heat_transfer +vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py:61:0: C0301: Line too long (104/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py:79:0: C0301: Line too long (103/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py:12:0: R0903: Too few public methods (1/2) (too-few-public-methods) +vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py:46:4: R0913: Too many arguments (9/5) (too-many-arguments) +vclibpy/components/heat_exchangers/heat_transfer/heat_transfer.py:40:0: R0903: Too few public methods (1/2) (too-few-public-methods) +************* Module vclibpy.components.heat_exchangers.heat_transfer.vdi_atlas_air_to_wall +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:41:0: C0301: Line too long (106/100) (line-too-long) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:25:4: C0103: Attribute name "lambda_R" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:26:4: C0103: Attribute name "n_Rohre" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:27:4: C0103: Attribute name "n_Rippen" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:28:4: C0103: Attribute name "a" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:12:0: R0902: Too many instance attributes (12/7) (too-many-instance-attributes) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:39:4: C0103: Attribute name "A_Rippen" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:44:4: C0103: Attribute name "A" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:49:4: C0103: Attribute name "A_FreieOberflaecheRohr" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:54:4: C0103: Attribute name "A_RohrInnen" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:59:4: C0103: Attribute name "A_RohrUnberippt" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:82:4: C0103: Method name "eta_R" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:82:20: C0103: Argument name "alpha_R" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:92:8: C0103: Variable name "X" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:95:4: C0103: Method name "alpha_S" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:95:22: C0103: Argument name "alpha_R" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:105:8: C0103: Variable name "A_R_to_A" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:155:8: C0103: Variable name "C" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:158:8: C0103: Variable name "A_div_A_0" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:166:8: C0103: Variable name "alpha_R" doesn't conform to snake_case naming style (invalid-name) +vclibpy/components/heat_exchangers/heat_transfer/vdi_atlas_air_to_wall.py:167:8: C0103: Variable name "alpha_S" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.components.heat_exchangers.heat_transfer.wall +vclibpy/components/heat_exchangers/heat_transfer/wall.py:1:0: C0114: Missing module docstring (missing-module-docstring) +vclibpy/components/heat_exchangers/heat_transfer/wall.py:10:0: R0903: Too few public methods (1/2) (too-few-public-methods) +vclibpy/components/heat_exchangers/heat_transfer/wall.py:4:0: C0411: first party import "from vclibpy.media import TransportProperties" should be placed before "from .heat_transfer import HeatTransfer" (wrong-import-order) +************* Module vclibpy.components.expansion_valves.expansion_valve +vclibpy/components/expansion_valves/expansion_valve.py:20:8: C0103: Attribute name "A" doesn't conform to snake_case naming style (invalid-name) +************* Module vclibpy.components.expansion_valves.bernoulli +vclibpy/components/expansion_valves/bernoulli.py:16:0: C0301: Line too long (110/100) (line-too-long) +vclibpy/components/expansion_valves/bernoulli.py:21:0: C0301: Line too long (103/100) (line-too-long) +************* Module vclibpy.components.expansion_valves +vclibpy/components/expansion_valves/__init__.py:1:0: C0114: Missing module docstring (missing-module-docstring) +************* Module vclibpy.components.expansion_valves.__init__ +vclibpy/components/expansion_valves/__init__.py:1:0: R0401: Cyclic import (vclibpy.media -> vclibpy.media.media) (cyclic-import) +vclibpy/components/expansion_valves/__init__.py:1:0: R0401: Cyclic import (vclibpy.components.expansion_valves -> vclibpy.components.expansion_valves.bernoulli) (cyclic-import) +vclibpy/components/expansion_valves/__init__.py:1:0: R0401: Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.vapor_injection_phase_separator -> vclibpy.flowsheets.vapor_injection) (cyclic-import) +vclibpy/components/expansion_valves/__init__.py:1:0: R0401: Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.standard) (cyclic-import) +vclibpy/components/expansion_valves/__init__.py:1:0: R0401: Cyclic import (vclibpy.flowsheets -> vclibpy.flowsheets.vapor_injection_economizer -> vclibpy.flowsheets.vapor_injection) (cyclic-import) +vclibpy/components/expansion_valves/__init__.py:1:0: R0401: Cyclic import (vclibpy.utils -> vclibpy.utils.automation) (cyclic-import) +vclibpy/components/expansion_valves/__init__.py:1:0: R0401: Cyclic import (vclibpy.media -> vclibpy.media.ref_prop) (cyclic-import) +vclibpy/components/expansion_valves/__init__.py:1:0: R0401: Cyclic import (vclibpy.media -> vclibpy.media.cool_prop -> vclibpy.media.media) (cyclic-import) + +----------------------------------- +Your code has been rated at 7.41/10 +